I am a bit new in python, i tried to read similar example but i cannot find my answer.
I am just trying to return two values in my generator, one is the number and the other one is the timestamp. It works fine with just the number but i cannot "print" the timestamp, can someone please help me on this?
import random
import datetime
mynumber = 1000
def generator():
i = 0
while 1:
yield random.randint(-1, 1)
now = datetime.datetime.now()
i = i + 1
for random_number in generator():
mynumber = mynumber + random_number
print mynumber
It's not quite clear what you want to do, but Python will allow you to yield and return multiple items (in the form of a tuple):
def generator():
while 1:
yield random.randint(-1, 1), datetime.datetime.now()
mynumber = 1000
for random_number, current_time in generator():
mynumber += random_number
print mynumber, current_time
There's a static analysis thing for python that is good at spotting basic stuff
$ pyflakes f.py
f.py:10: local variable 'now' is assigned to but never used
Related
Hi :) my question is basically what the title says. How do i create a function that calls another function ten times and only if all those times the function2 returns True function 1 prints “good job”
For example:
def function_one(s) #returns true if string is increasing
x = all(x <= y for x, y in itertools.pairwise(seq))
return x
Function 2 should only print good job if function one returns true when called ten times.
I tried:
s = random.randint(0,10)
for i in range (10):
if function_one(s) == True:
print (“Good job”)
But this prints it the second function one is true, no matter how many other falses there were prior. Please help :)
Just use all as you did in function_one.
Here is an example with a different function_one:
import random
# make example reproducible
random.seed(0)
# dummy function that returns True with p=0.9
# and also prints an indicator ./× for True/False
def function_one():
# return True with a probability of 9/10
n = random.random() > 0.1
print('⋅' if n else '×', end='')
return n
def function_two():
if all(function_one() for _ in range(10)): # important stuff here
print(' Good job')
else:
print(' failed!')
# repeat the experiment a few times
for i in range(5):
function_two()
output:
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ Good job
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ Good job
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ Good job
⋅⋅⋅⋅⋅× failed!
⋅⋅⋅⋅× failed!
You can use a list and then min:
lst=[]
for i in range (10):
s = random.randint(0,10)
lst.append(function_one(s))
if min(lst) == True:
print (“Good job”)
Note that the random.randint(0,10) should be inside the loop otherwise you use the same value all the time
You need to "link" all 10 calls to function 1. For example this should do what you want (I left the s assignment at its original position since I don't know what it's for. Perhaps it should be in the for loop):
def func2 ():
s = random.randint(0,10)
flag = True
for i in range (10):
newtry = function_one(s)
flag = flag and newtry
if flag:
print (“Good job”)
I'm trying to time all the different sorting algorithms to see which is fastest but every time I do that I need to rewrite the bottom half of the code again (under #####) except I have to change all the variable names (and instead of selectionsort(mylist) I do bubblesort(mylist) etc). I guess it's not the end of the world but I can't help but imagine it can be written much better. I know there are other options for timing it that may be better but I've been told I have to use perf_count.
def selectionsort(mylist):
sortedlist=[]
while len(mylist) > 0:
lowest = mylist[0]
for i in mylist:
if i < lowest:
lowest=i
sortedlist.append(lowest)
mylist.remove(lowest)
return sortedlist
ivalues = [2,4,8,16,32,64,128,256,512,1024]
#####
sorttimelist = []
for i in range(1,11):
mylist=[]
for j in range(2**i):
mylist.append(random.random())
start_time=time.perf_counter()
selectionsort(mylist)
end_time=time.perf_counter()
sorttime=end_time-start_time
sorttimelist.append(sorttime)
You can use a for loop to go through different functions to use in your code. Since functions are essentially variables, you can assign one to func in the for loop, and call it like func(my_list)
#####
for func in [selectionsort, bubblesort]:
for i in range(1,11):
mylist=[]
for j in range(2**i):
mylist.append(random.random())
start_time = time.perf_counter()
func(mylist) # use func instead of selectionsort
end_time = time.perf_counter()
sorttime = end_time - start_time
sorttimelist.append(sorttime)
You can iterate over collection of functions you are going to benchmark. See example:
def selection_sort(my_list):
pass
def bubble_sort(my_list):
pass
functions = [selection_sort, bubble_sort]
for func in functions:
func(list_to_sort)
Use a decorator, put #timit above your function.
import time
def timit(func):
'''
A Decorator that times how long it takes to return the function. Added time.sleep because some functions run under a seconds and would return 0 seconds.
'''
def inner(*args, **kwargs):
start = float(time.time())
time.sleep(1)
test = func(*args, **kwargs)
end = float(time.time())
print(f'Funtion {func.__name__} took {end-start-1} seconds to complete')
return test
return inner
#timit
def bubble_sort(array):
for last_idx in range(1,len(array)):
is_sorted = True
for idx in range(len(array)-last_idx-1):
if array[idx] > array[idx+1]:
is_sorted = False
swap(array, idx, idx+1)
if is_sorted is True:
break
return array
#timit
def selection_sort(array):
for first_idx in range(len(array)-1):
smallest = array[first_idx]
for idx in range(first_idx+1, len(array)):
if array[idx] < smallest:
smallest = array[idx]
swap(array, idx, first_idx)
return array
New to python, so I have this setup where I file gets created, and I have to add an extension number. The first file will have an extension number of 1 since being the first. A second file gets created and the extension number will increment, so it will be 2. So each files gets created, the extension number will increment.
Now, if it's a different day then that extension number will reset to 1, and it will increment if new files are created. So each day, the extension number needs to be reset to 1
def get_counter(date):
counter = 1
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date != now:
now = date
counter = 1
return counter
counter += 1
return counter
I have set up this function but it will not work because the now and counter variable will get overwritten. So will need these variables somewhere else. Just wondering if there is a work around this process or is there a python library that can handle this type of situation. Your suggestions will be appreciated!
You could assign the counter outside of that function and send it as a parameter, that way you don't overwrite it every single time you call your function, like so:
counter = 1
for file_to_be_writen in file_collection:
counter = get_counter(date, counter)
and leave your function like this:
def get_counter(date, counter):
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date == now:
counter += 1
return counter
return counter
When you need to preserve state across function calls that is a hint that you need a custom object. You could use global variables as well but encapsulating the state inside an object is usually better.
Here I implement a class Counter that takes care of everything. It has a __next__ method that returns the next number so the calling code only needs to call next(counter). It also has an __iter__ method so it can be used in for loops.
You need to provide a function to get the current (date_getter) time when creating an instance. Besides making the code more testable this allows you to decide if you want to use utc time, local time, the first day of the week so the counter resets each week, etc.
import datetime
class TimeArrowReversedError(Exception):
pass
class Counter:
def __init__(self, date_getter):
self._date_getter = date_getter
self._current_date = date_getter()
self._current_value = 0
def _check_date(self):
current_date = self._date_getter()
if self._current_date > current_date:
message = 'Time arrow got reversed. Abandon all hope.'
raise TimeArrowReversedError(message)
if self._current_date < current_date:
self._current_date = current_date
self._current_value = 0
def __next__(self):
self._check_date()
self._current_value += 1
return self._current_value
def __iter__(self):
return self
This is the code I used to test it. Note that I am using as date_getter a function that actually returns whatever date I want. I do not want to wait until 23:59 to run the test. Instead I tell the function which date to return (including going backwards in time) and see how the counter behaves.
current_date = datetime.date(year=2018, month=5, day=9)
get_current_date = lambda: current_date
counter = Counter(get_current_date)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
for expected, result in zip([3, 4], counter):
assert expected == result
current_date = current_date + datetime.timedelta(days=1)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
current_date = current_date - datetime.timedelta(days=2)
try:
n = next(counter)
except TimeArrowReversedError:
pass
else:
raise AssertionError('"TimeArrowReversedError" expected.')
Here is a more realistic way in which yo could use this class:
def create_counter():
return Counter(datetime.datetime.utcnow().date)
counter = create_counter()
Print the first couple of numbers:
print(next(counter))
print(next(counter))
Output:
1
2
Using a loop to add numbers to names in a list:
names = ['foo', 'bar']
for name, n in zip(names, counter):
print('{}_{}'.format(name, n))
Output:
foo_3
bar_4
Now I realize that Counter is a really bad choice because there is already a completely unrelated Counter class in the standard library. But I cannot think of a better name right now so I will leave it as is.
possibleRequests = ['test', 'test1']
def inboxReader():
global inbox
tempInbox = []
tempInbox = inbox.inboxMessage #inboxMesage remains filled?
print(inbox.inboxMessage, 'inboxReader')
i = 0
while (i < len(tempInbox)):
if (tempInbox[i] in possibleRequests):
print('THIS IS WORKING')
#print(i)
i+=1
I want to be able to have possible requests point towards a method to run rather than have a long list of if statments. What am I able to do in order to have a variable point towards and run a method.
Cheers,
Marc
You can first create a dictionary of functions then refer to it with tempInbox[i]. Example code below:
def func_a(x):
return x
def func_b(x):
return x*10
tempInbox = (2,3)
fn_dict = {"a":func_a,"b":func_b}
print fn_dict["a"](tempInbox[0]) # returns 2
print fn_dict["b"](tempInbox[1]) # returns 30
Basically, my question is about how to run this code? Finding the second smallest number from the given list using divide-and-conquer. I tried with print..But it gives me nothing. Just wanna see how this code works. Sorry for simple question, totally New in Python.
Well, just use a function call to run it, and a print to print it:
def two_min(arr):
n = len(arr)
if n==2: # Oops, we don't consider this as comparison, right?
if arr[0]<arr[1]: # Line 1
return (arr[0], arr[1])
else:
return (arr[1], arr[0])
(least_left, sec_least_left) = two_min(arr[0:n/2])
(least_right, sec_least_right) = two_min(arr[n/2:])
if least_left < least_right: # Line 2
least = least_left
if least_right < sec_least_left: # Line 3
return (least, least_right)
else:
return (least, sec_least_left)
else:
least = least_right
if least_left < sec_least_right: # Line 4
return (least, least_left)
else:
return (least, sec_least_right)
print two_main([12,2])
If you'd like to know how this works, you can take a look at the online python visualizer. Link.