Producing a list that can be sorted - python

I have a piece of code, which is a function called within a loop over a dictionary, it is as follows:
hope = []
seconds = []
hope.append(self.date)
for those in hope:
date = those
pattern = '%m/%d/%Y'
epoch = int(time.mktime(time.strptime(date, pattern)))
seconds.append(epoch)
print seconds
I am getting results like
[1505084400]
[1500850800]
[1509926400]
[1496617200]
[1492383600]
[1488758400]
[1499036400]
[1511136000]
[1511136000]
…
But I want the results of seconds to be like:
[1505084400,1500850800,1509926400,1496617200,1492383600,1488758400,1499036400,1511136000,1511136000.....]
So that the sort and sorted functions will work on it.

Just take the print statement out of the for loop and maintain the state of the lists:
class someclass(object):
def __init__(self):
self.hope = []
self.seconds = []
def appendtoseconds(self):
self.hope.append(self.date)
for those in self.hope:
date = those
pattern = '%m/%d/%Y'
epoch = int(time.mktime(time.strptime(date, pattern)))
self.seconds.append(epoch)
print self.seconds

Related

Accessing cumulative values without initialising class with None

The functionality I'm looking for is to:
Call get_values() for each number of times.
A Metric object is initialised passing the date values in.
Find the datetime and then append it to the cumulative list.
Once the 'x in y' loop has finished, return the list.
The problem I've having is that I don't have any instance variables to pass through, which means I have to pass a 'None' object. I guess returning the Metric object is viable but I'd prefer if there was another option.
class Metric():
cumulative_time = []
def __init__(self, first_date, second_date):
self.first_date = first_date
self.second_date= second_date
def get_datetime(self):
datetime = self.first_date - self.second_date
return datetime
def append_cumulative_value(self, value):
self.cumulative_time.append(value)
def get_time_list(self):
return self.cumulative_time
def get_values():
first_date = ...
second_date = ...
metric = Metric(first_date, second_date)
date = metric.get_datetime()
metric.append_cumulative_value(date)
def main():
for x in y:
get_values()
cumulative_time_list = Metric(None, None).get_time_list()
if __name__ == "__main__":
main()

Update text in real time by calling two functions Pygame

I have program that takes input from the user and displays multiple variations of the input using the Population() function. The store_fit function adds these different variations to a list then deletes them so that the list is only populated with one variation at a time.
I want to be able to get the variation from the list and use it to update my text. However, my program only updates the text after the Population function is completed. How could I run the Population function and update my text simultaneously?
code:
fit = []
...
def store_fit(fittest): # fittest is each variation from Population
clear.fit()
fit.append(fittest)
...
pg.init()
...
done = False
while not done:
...
if event.key == pg.K_RETURN:
print(text)
target = text
Population(1000) #1000 variations
store_fit(value)
# I want this to run at the same time as Population
fittest = fit[0]
...
top_sentence = font.render(("test: " + fittest), 1, pg.Color('lightskyblue3'))
screen.blit(top_sentence, (400, 400))
I recommend to make Population a generator function. See The Python yield keyword explained:
def Populate(text, c):
for i in range(c):
# compute variation
# [...]
yield variation
Create an iterator and use next() to retrieve the next variation in the loop, so you can print every single variation:
populate_iter = Populate(text, 1000)
final_variation = None
while not done:
next_variation = next(populate_iter, None)
if next_variation :
final_variation = next_variation
# print current variation
# [...]
else:
done = True
Edit according to the comment:
In order to keep my question simple, I didn't mention that Population, was a class [...]
Of course Populate can be a class, too. I this case you've to implement the object.__iter__(self) method. e.g.:
class Populate:
def __init__(self, text, c):
self.text = text
self.c = c
def __iter__(self):
for i in range(self.c):
# compute variation
# [...]
yield variation
Create an iterator by iter(). e.g.:
populate_iter = iter(Populate(text, 1000))
final_variation = None
while not done:
next_variation = next(populate_iter, None)
if next_variation :
final_variation = next_variation
# print current variation
# [...]
else:
done = True

How to slow down asynchrounous API calls to match API limits?

I have a list of ~300K URLs for an API i need to get data from.
The API limit is 100 calls per second.
I have made a class for the asynchronous but this is working to fast and I am hitting an error on the API.
How do I slow down the asynchronous, so that I can make 100 calls per second?
import grequests
lst = ['url.com','url2.com']
class Test:
def __init__(self):
self.urls = lst
def exception(self, request, exception):
print ("Problem: {}: {}".format(request.url, exception))
def async(self):
return grequests.map((grequests.get(u) for u in self.urls), exception_handler=self.exception, size=5)
def collate_responses(self, results):
return [x.text for x in results]
test = Test()
#here we collect the results returned by the async function
results = test.async()
response_text = test.collate_responses(results)
The first step that I took was to create an object who can distribute a maximum of n coins every t ms.
import time
class CoinsDistribution:
"""Object that distribute a maximum of maxCoins every timeLimit ms"""
def __init__(self, maxCoins, timeLimit):
self.maxCoins = maxCoins
self.timeLimit = timeLimit
self.coin = maxCoins
self.time = time.perf_counter()
def getCoin(self):
if self.coin <= 0 and not self.restock():
return False
self.coin -= 1
return True
def restock(self):
t = time.perf_counter()
if (t - self.time) * 1000 < self.timeLimit:
return False
self.coin = self.maxCoins
self.time = t
return True
Now we need a way of forcing function to only get called if they can get a coin.
To do that we can write a decorator function that we could use like that:
#limitCalls(callLimit=1, timeLimit=1000)
def uniqFunctionRequestingServer1():
return 'response from s1'
But sometimes, multiple functions are calling requesting the same server so we would want them to get coins from the the same CoinsDistribution object.
Therefor, another use of the decorator would be by supplying the CoinsDistribution object:
server_2_limit = CoinsDistribution(3, 1000)
#limitCalls(server_2_limit)
def sendRequestToServer2():
return 'it worked !!'
#limitCalls(server_2_limit)
def sendAnOtherRequestToServer2():
return 'it worked too !!'
We now have to create the decorator, it can take either a CoinsDistribution object or enough data to create a new one.
import functools
def limitCalls(obj=None, *, callLimit=100, timeLimit=1000):
if obj is None:
obj = CoinsDistribution(callLimit, timeLimit)
def limit_decorator(func):
#functools.wraps(func)
def limit_wrapper(*args, **kwargs):
if obj.getCoin():
return func(*args, **kwargs)
return 'limit reached, please wait'
return limit_wrapper
return limit_decorator
And it's done ! Now you can limit the number of calls any API that you use and you can build a dictionary to keep track of your CoinsDistribution objects if you have to manage a lot of them (to differrent API endpoints or to different APIs).
Note: Here I have choosen to return an error message if there are no coins available. You should adapt this behaviour to your needs.
You can just keep track of how much time has passed and decide if you want to do more requests or not.
This will print 100 numbers per second, for example:
from datetime import datetime
import time
start = datetime.now()
time.sleep(1);
counter = 0
while (True):
end = datetime.now()
s = (end-start).seconds
if (counter >= 100):
if (s <= 1):
time.sleep(1) # You can keep track of the time and sleep less, actually
start = datetime.now()
counter = 0
print(counter)
counter += 1
This other question in SO shows exactly how to do this. By the way, what you need is usually called throttling.

Feedback tester python

Hi for a given function I have 2 parameters which are string and an Int but I don't know which comes first. So I have a function "pick_type()" that tries to guess the order of the parameters. So my question is when "pick_type()" incorrectly guesses the order, how do I record this and make sure "pick_type()" never tries that specific order again ?
for iteration in range(0, 10):
args = []
print("\n def test%d(self):" % (iteration))
for input in range(num_arguments):
args += pick_type()
try:
result = target(*args)
code = test_to_string(target, args, result)
except TypeError as error:
code = test_to_string_exc(target, args, error)
for line in code.splitlines():
print(" "+line)
def pick_type():
lista = []
words = ['rhythms', 'rhythms', 'manager', 'training', 'hotel', 'destroy']
word = choice(words)
num = random.randint(-100, 100)
lists = [word,num]
choices = choice(lists)
if choices == word:
lista.append(word)
else:
lista.append(num)
return lista
I would suggest wrapping your method in a class, then you can have a persistent list of bad orders. It's not clear to me what you mean by an "order", but whatever it is, hopefully this pseudo-code helps:
class PickType:
def __init__(self):
self._bad_orders = []
def pick_type(self):
...# insert body here
if order in self._bad_orders:
## pick another order
## test the new order
if <order is bad>:
self._bad_orders.append(order)
## if your test for bad orders is performed outside pick_type(), you just need a method to add to the list of bad_orders
def add_bad_order(self, order):
self._bad_orders.append(order)

Function as argument in python

I need to pass some function as argument in another function. So, I want to add current time to class attribute every second, for example
import time
class Measurement():
values = []
def add_value(self, value):
print "added value"
self.values.append(value)
def smart_delay(input_function,args):
start_time = time.time()
while 5 > (time.time() - start_time):
print "Calling function"
input_function(args)
time.sleep(1)
measurement = Measurement()
smart_delay(measurement.add_value,time.time())
Ok, but after checking contents of measurement.values, I get
[1425980407.173, 1425980407.173, 1425980407.173, 1425980407.173] - so values are the same!!!
What happened? And how to get proper values?
Updated:
Actually, this question is about the way to allow to call some function, passed as the argument to another function. What do you think about this:
import time
class Measurement():
values = []
def add_value(self, value):
print "added value"
self.values.append(value)
def smart_delay(input_function):
start_time = time.time()
while 5 > (time.time() - start_time):
print "Calling function"
input_function()
time.sleep(1)
measurement = Measurement()
smart_delay(lambda: measurement.add_value(time.time()))
Your call to time.time() is executed before the call to smart_delay(...), so smart_delay(measurement.addvalue, time.time()) will first get the return value from time.time() and pass that forward to smart_delay.
You need to pass the time.time function itself, and call it inside of the smart_delay method, instead of passing its return value:
import time
class Measurement():
values = []
def add_value(self, value):
print "added value"
self.values.append(value)
def smart_delay(output_f, input_f):
start_time = time.time()
while 5 > (time.time() - start_time):
print "Calling function"
output_f(input_f())
time.sleep(1)
measurement = Measurement()
smart_delay(measurement.add_value, time.time)
Notice, that this is not the best way to do what you're doing, but it works.
Here's how I'd do it:
import time
# Why do you need a measurement class which only acts as a list anyways?
my_measurements = []
def repeat(duration, function, args=(), kwargs={}, interval=1):
"""Repeat a function call for the given duration."""
start_time = time.time()
while duration > time.time() - start_time:
function(*args, **kwargs)
time.sleep(interval)
def add_time_measurement(measurements):
measurements.append(time.time())
repeat(5, add_time_measurement, (my_measurements,))
And if you want some prints, you can just add them in the add_time_measurement function.

Categories

Resources