AttributeError: 'Float' object has no attribute 'time' - python

I am currently getting this error in my code
AttributeError: 'Float' object has no attribute 'time'
I have not seen an exact instance to mine I have seen some changes to dtype=object but I am unsure how to implement that and why I would need to. This is a pretty straight forward function.
import time
class lastCycle():
def __init__(self):
self.lastTime = time.time()
self.time = 0.0
def timer(self, time):
if (time.time() - self.lastTime) > self.time:
self.lastTime = time.time()
return True
else:
return False
statusUpdate = lastCycle().timer(1.0)

Don't use module name time as keyword here:
def timer(self, time):
if (time.time() - self.lastTime) > self.time:
self.lastTime = time.time()
return True
else:
return False
I guess this is the solution you are looking for:
def timer(self, timeVal):
if (timeVal - self.lastTime) > self.time:
self.lastTime = time.time()
return True
else:
return False

import time
class lastCycle():
def init(self):
self.lastTime = time.time()
self.time = 0.0
def timer(self, threshold):
if (time.time() - self.lastTime) > threshold:
self.lastTime = time.time()
return True
else:
return False

Related

How to get args from a decorator that uses class

I was trying to make a loop function that uses class, and to make it easier i think i will make it as decorator, but there are a few problem when i tried my code,
When i tried this code, it says that I'm missing 1 required argument and it's "self"
I tried doing this to my code, but realized that it used __call__, which i don't want to because it will executed at the time the function is called. (I dont know if this true)
And this is how i used it, and https://hastebin.com/onozarogac.py (for the full code):
#looper(seconds=3) # this code is from other class
def print(self):
print(len(self.cache.get_available_guilds_view()))
self.print.start() # and by using this to trigger it
def looper(seconds):
def decorator(func):
return Looper(func, seconds * 1000)
return decorator
class Looper:
def __init__(self, fn, seconds):
self.fn = fn
self.interval_ms = seconds / 1000
self.time_last = time()
self.started = False
def loop(self):
time_now = time()
if time_now >= self.time_last + self.interval_ms:
self.fn()
self.time_last = time_now
return True
else:
return False
def set_interval_ms(self, interval_ms):
self.interval_ms = interval_ms / 1000
def set_interval_s(self, set_interval):
self.interval_ms = set_interval
def get_interval_ms(self):
return self.interval_ms
def get_interval_s(self):
return self.interval_ms * 1000
def start(self):
self.started = True
while True:
if self.started:
self.loop()
else:
break
def stop(self):
self.started = False
Its giving me the TypeError which:
TypeError: print() missing 1 required positional argument: 'self'
convert looper function to this
from functools import wraps
def looper(seconds):
def inner(func):
#wraps(func)
def wrapper(*args, **kwargs):
return Looper(func, seconds * 1000)
return wrapper
return inner

decorator with parameter and counting how many times func called

I got a code like below:
import functools
def change_time(_func=None, *, time=None):
def wrapper_external(func):
#functools.wraps(func)
def wrapper_internal(*args, **kwargs):
# WHAT I WANT:
# if how_many_times_func_called >= time:
# how_many_times_func_called = 0
return func(*args, **kwargs, new_time=how_many_times_func_called)
return wrapper_internal
if _func is None:
return wrapper_external
else:
return wrapper_external(_func)
#change_time(time=3)
def my_func(some_text, new_time):
some_text += 'abc'
some_text += f': {new_time}'
return some_text
print(my_func('blabla'))
and i am trying to modify that i can also count how many times i was using that func and pass that value for wrapped func, but got no idea how to modify that?
I had a similar need in the past so I made a class that can be used as a decorator. Sharing the code here in case it could help or inspire your solution:
# chrono.py
# ---------
# decorator and class to get function/method execution statistics
#
# #Chrono decorator
# -----------------
# Wraps function/method to track time statistics
#
# #Chrono
# def myFunction(a,b,c):
# ...
#
# for _ in range(13): myFunction(1,2,3)
#
# myfunction.stats # prints...
#
# myFunction:
# Last time: 0.0066 sec.
# Total time: 0.0941 sec.
# Call Count: 13
# Average time: 0.0072 sec.
# Maximum time: 0.0098 sec.
# Recursion: 39
# Max. Depth: 3
#
# myFunction.count # 13
# myFunction.recursed # 39
# myFunction.totalTime # 0.0941
# myFunction.lastTime # 0.0066
# myFunction.maxDepth # 3
# myFunction.maxTime # 0.0098
# myFunction.average # 0.0072
#
# myFunction.clear() # resets statistics
# myfunction.depth # current recursion depth
#
#
# global 'chrono' object
# ----------------------
# computes time of parameter execution
#
# t,r = chrono.time(len(str(factorial(5000))))
#
# returns time and result: t: 0.005331993103027344 r:16326
#
# chrono.print('5000! :',scale=1000)(len(str(factorial(5000))))
# 5.2319 5000! : 16326
from time import time
class Chrono:
def __init__(self,func):
self.func = func
self._name = None
self.clear()
def clear(self):
self.count = 0
self.recursed = 0
self.totalTime = 0
self.start = None
self.depth = -1
self.lastTime = None
self.maxDepth = 0
self.maxTime = 0
def __call__(self,*args,**kwargs):
self.depth += 1
self.count += self.depth == 0
self.recursed += self.depth > 0
if self.depth == 0:
self.start = time()
result = self.func(*args,**kwargs)
if self.depth == 0:
self.lastTime = time()-self.start
self.totalTime += self.lastTime
self.maxTime = max(self.lastTime,self.maxTime)
else:
self.maxDepth = max(self.maxDepth,self.depth)
self.depth -= 1
return result
#property
def name(self):
if self._name is None:
self._name = ""
for n,f in globals().items():
if f is self: self._name = n;break
return self._name
def methodCaller(self,obj):
def withObject(*args,**kwargs):
return self(obj,*args,**kwargs) # inject object instance
return withObject
def __get__(self,obj,objtype=None): # return method call or CallCounter
return self.methodCaller(obj) if obj else self
#property
def average(self): return self.totalTime/max(1,self.count)
#property
def stats(self):
print(f"{self.name}:")
print(f" Last time: {self.lastTime:3.4f} sec.")
print(f" Total time: {self.totalTime:5.4f} sec.")
print(f" Call Count: {self.count}")
print(f" Average time: {self.average:3.4f} sec.")
print(f" Maximum time: {self.maxTime:3.4f} sec.")
print(f" Recursion: {self.recursed}")
print(f" Max. Depth: {self.maxDepth}")
#property
def time(self):
start = time()
self.count += 1
def execute(result):
self.lastTime = time()-start
self.totalTime += self.lastTime
return self.lastTime,result
return execute
def print(self,label="",scale=1):
start = time()
self.count += 1
def execute(result):
self.lastTime = time()-start
self.totalTime += self.lastTime
print(f"{self.lastTime*scale:3.4f}",label,end=" ")
if ":" in label:print(result)
else: print()
return result
return execute
chrono = Chrono(None)
if __name__ == '__main__':
#Chrono
def myFunction(a,b,c,r=3):
for _ in range(100000*a): pass
if r>0: myFunction(1,b,c,r-1)
return a+b+c
for i in range(13): myFunction(1,2,3)
myFunction.stats
"""
myFunction:
Last time: 0.0062 sec.
Total time: 0.1005 sec.
Call Count: 13
Average time: 0.0077 sec.
Maximum time: 0.0106 sec.
Recursion: 39
Max. Depth: 3
"""
just as sahasrara62 mentions
a global dictionary may save your issue
import functools
func_counts = {}
def change_time(_func=None, *, time=None):
def wrapper_external(func):
#functools.wraps(func)
def wrapper_internal(*args, **kwargs):
global func_counts
key = f"{func.__module__}.{func.__name__}"
if key in func_counts:
func_counts[key] += 1
else:
func_counts[key] = 1
if func_counts[key] >= time:
func_counts[key] = 0
how_many_times_func_called = func_counts[key]
print(f"{key} called {how_many_times_func_called}")
# WHAT I WANT:
# if how_many_times_func_called >= time:
# how_many_times_func_called = 0
return func(*args, **kwargs, new_time=how_many_times_func_called)
return wrapper_internal
if _func is None:
return wrapper_external
else:
return wrapper_external(_func)

most pythonic way to time a loop

So I have a loop which takes a while to run and I wanted to print a rough estimation of the ETA (time required to end), I have written some code to do this but it's quite intricate and I'm sure there must be a cleaner way of doing it, any tip?
my class:
from timeit import default_timer as timer
from datetime import datetime, timedelta
import sys
class Measure:
def __init__(self):
self.initial = None
self.end = None
self.average = None
def start_end(self):
if self.initial is not None:
self.end = timer()
else:
self.initial = timer()
def avg(self):
self.start_end()
if self.end is not None:
if self.average is None:
self.average = round((self.end - self.initial), 3)
else:
self.average = round((self.average + (self.end - self.initial)) / 2, 3)
self.initial = timer()
def avg_time(self):
self.avg()
if self.average is not None:
sys.stdout.write('\r' + "Avg. Time elapsed: " + str(self.average) + " seconds")
def how_long(self):
self.start_end()
if self.end is not None:
print("Time elapsed: " + str(round((self.end - self.initial), 3)) + " seconds")
self.initial = timer()
def estimated_time(self, length):
self.avg()
if self.average is not None:
x = datetime.now() + timedelta(seconds=self.average * length)
sys.stdout.write('\r' + "I still need to work for at least...: " + str(round(self.average * length, 3))
+ " seconds. Which means I'll be done by: " + x.strftime("%d/%m/%Y %H:%M:%S"))
You can time any aspect of your code in regards to how long it takes to run, not just a particular chunk of it. But if you want to get just the time taken for the loop itself to compute, you can do something like:
import time
starttime= time.time()
**add your loop/other code here**
endtime= time.time()
print("time elapsed:", endtime - starttime)

Stopwatch implementing python

I got this code for an assignment:
from stop_watch import StopWatch
size = 1000000
stopWatch = StopWatch()
sum = 0
for i in range(1, size + 1):
sum += i
stopWatch.stop()
print("The loop time is", stopWatch.get_elapsed_time(), "milliseconds")
I have to create a class which generates a stopwatch and this is my code:
import time
class StopWatch:
def __init__(self):
pass
def start(self):
self.start = time.time()
return self.start
def stop(self):
self.stop = time.time()
return self.stop
def get_elapsed_time(self):
print(str(self.stop-self.start))
I get this error:
File "week33.py", line 10, in <module>
print("The loop time is", stopWatch.get_elapsed_time(), "milliseconds")
File "/Users/Marinkton/Desktop/stop_watch.py", line 16, in get_elapsed_time
print(str(self.stop-self.start))
TypeError: unsupported operand type(s) for -: 'float' and 'method'
What am I doing wrong? I could not discover a mistake.
You can't name your functions and your properties the same thing. When you do self.stop = time.time(), you overwrite the function stop.
You need to change the name of the internal fields.
import time
class StopWatch:
def __init__(self):
self.start_time = 0
self.stop_time = 0
def start(self):
self.start_time = time.time()
return self.start_time
def stop(self):
self.stop_time = time.time()
return self.stop_time
def get_elapsed_time(self):
print(str(self.stop_time - self.start_time))
PS: You're never calling start in your code.

Class and external method call

I am going through a data structures course and I am not understanding how a Class can call a method that's in another Class.
The code below has 2 classes: Printer and Task.
Notice that class Printer has a method called startNext, and this has a variable self.timeRemaining that gets assigned the result of newTask.getPages() * 60/self.pagerate.
How can newTaks reference the getPages() method from the Task class?
The code that passes this object to the Printer class never references the Task class.
The code works, since this is what the course gives out but, I just cannot understand how that method is accessed.
Code:
from pythonds.basic.queue import Queue
import random
class Printer:
def __init__(self, ppm):
self.pagerate = ppm
self.currentTask = None
self.timeRemaining = 0
def tick(self):
if self.currentTask != None:
self.timeRemaining = self.timeRemaining - 1
if self.timeRemaining <= 0:
self.currentTask = None
def busy(self):
if self.currentTask != None:
return True
else:
return False
def startNext(self, newTask):
self.currentTask = newTask
self.timeRemaining = newTask.getPages() * 60/self.pagerate
class Task:
def __init__(self, time):
self.timeStamp = time
self.pages = random.randrange(1, 21)
def getStamp(self):
return self.timeStamp
def getPages(self):
return self.pages
def waitTime(self, currentTime):
return currentTime - self.timeStamp
def simulation(numSeconds, pagesPerMinute):
labPrinter = Printer(pagesPerMinute)
printQueue = Queue()
waitingTimes = []
for currentSecond in range(numSeconds):
if newPrintTask():
task = Task(currentSecond)
printQueue.enqueue(task)
if (not labPrinter.busy()) and (not printQueue.isEmpty()):
nextTask = printQueue.dequeue()
waitingTimes.append(nextTask.waitTime(currentSecond))
labPrinter.startNext(nextTask)
labPrinter.tick()
averageWait = sum(waitingTimes)/len(waitingTimes)
print "Average Wait %6.2f secs %3d tasks remaining." % (averageWait, printQueue.size())
def newPrintTask():
num = random.randrange(1, 181)
if num == 180:
return True
else:
return False
for i in range(10):
simulation(3600, 5)
If I understand clearly your question, it is because you are adding task object to Queue list. Then when you are getting object (list item) back, you are getting again Task object:
#creating Task object and adding to Queque list
task = Task(currentSecond)
printQueue.enqueue(task)
class Queue:
def __init__(self):
#list of task objects
self.items = []
def enqueue(self, item):
#you are inserting Task object item to list
self.items.insert(0,item)
def dequeue(self):
#returns task object
return self.items.pop()
So then you can call startNext() method from Printer class, because the dequeue() method is returning Task object.
And because of the object in startNext() is type of Task, you can call getPages() method on that object.
Is it sufficient answer?

Categories

Resources