while loop isn't working - python

I have a quick question. I have the following code...
def abc(c):
a = 1
my = set()
while a <= c:
b = randrange(1, 365)
my.add(b)
a = a + 1
print(my)
Now c is in my main function. c is a integer that the user is prompted for. For instance, if c = 10, then as long as a < 10 it will run the while loop and print out the set with 10 numbers randomly generated between 1 and 365. The only problem is that it's not printing out the set my correctly.

a = a+1 should be what you want.

a + 1 just increments the value of a, but does not store it anywhere. So, using a = a+1, will increment the value of a and update the value of a.
The second part: You are generating the random numbers and storing them in a set, and printing them at last. To print each and every element in the list, use:
for i in my:
print i
This will print each value in the set

Related

How to return the value of a while loop counter

I want to return the counter of the while loops, i and b after every loop repetition to use in another function. I haven't found anything related to returning these values.
def dis(reps, towards, back):
t = 0 # move towards t times
b = 0 # move back b times
i = 0 # repetitions
n = 1 # counts every step
while i < reps:
while t < towards:
do_something()
i += 1
n +=1
while b < back:
do_something()
n += 1
b += 1
t = 0
b = 0
i += 1
I thought of adding another variable like counter_towards and counter_back and add a value each time but that would not fix my problem since I still would have to return these values every rep. Adding the related functions to a class might work aswlel but that would be lot of work and i thought there might be an easy answer to this question.
You have to watch on python Generators. Here's a link!

Get "None" Instead of Zero Value in a Python Function

I want to make a program which puts an array(1x9 has numbers from 0 to 9) in memory and I want to check if an array I created is previously used. There will be 2 functions I will use.
addMemory(list,previousStates) adds the newly created array into memory and checkMemory(list,previousStates) checks if the array is previously used or not. It returns 1 if the array is used and 0 if it is not.
I convert the array to a number by assuming that every element of the array is a digit for a 9-digit number.
Ex: [2,5,3,4,1,6,8,9,7] is stored as 253.416.897. I want to test my functions. First print has the empty memory and the memory is checked and the array is added and the new memory is checked.
The output should have been
0
1
but I get
None
1
Why I get 'None' instead of 0? Can you help please?
def addMemory(newlist,previousStates):
count = 0
for i in range(0,8):
count += count + newlist[i] * 10**(8-i)
previousStates.append(count)
return previousStates
def checkMemory(newlist,previousStates):
count = 0
for i in range(0,8):
count += count + newlist[i] * 10**(8-i)
for i in range(len(previousStates)):
if(previousStates[i] == count):
return 1
return 0
def main():
a = [5,3,4,7,8,9,1,2,6]
previousStates = []
print(checkMemory(a,previousStates))
addMemory(a,previousStates)
print(checkMemory(a,previousStates))
main()
In your checkMemory function, because len(previousStates) is zero at first, your for statement is never executed and hence your function never reaches any return

While loop not exiting Python

Given a list of inputs. The last x of the list, are a number that I want to use for a test. So, the beginning n-x elements are the ones I want to test using the elements in x.
For example:
test_case = [0.18677649597722776, 0.21992417009282958, 0.21001370207789635, 0.2576939078119566, -0.26790678064174844, 0.23723906040549575, 0.23796810219833633, 0.12311570730540798, 0.291222989748139, -0.46589179980005796, -0.5679935337540711, -0.541967302717414, 0.2797199715268191, -0.0462338707795437, 0.3352382038488532, -0.6395453091791992, -0.7116194799285872, -0.6827853559995019, 0.4131897184013285, 0.07125041194386302, 0.47179441094288416, -0.5670171363969451, -0.6493889334859158, -0.6214861349381114, 0.6332084272531783, 0.2946607775328391, 0.7252115985158697, -0.48494480580385074, -0.5584250339723696, -0.5329318548632481, 0, 1, 0, 5, 5, 5]
The last 6 numbers I want to use as part of my test on the first 30 numbers. I want to cycle through the 30 numbers such that when test_case[31] < 3, give me test_case[0], else give me -999. This iterates until test_case[36] < 3, give me test_case[5]. Then I want test_case[31] to go back and be used on test_case[6] and loop again.
After I'm at test_case[30], I want it to stop.
Here's what I have:
def test_inputs(x, comp_size):
counts = x[-comp_size:]
inputs = x[:(len(x)-comp_size+1)]
counts_pos = 0
inputs_pos = 0
while inputs_pos < (len(x)-comp_size+1):
if counts_pos == 6:
counts_pos = 0
if counts[counts_pos] < 3:
x.append(inputs[inputs_pos])
print inputs_pos
print counts_pos
inputs_pos += 1
counts_pos += 1
else:
x.append(-999)
print inputs_pos
print counts_pos
inputs_pos += 1
counts_pos += 1
I'm trying to make a generalized function. In this case, should be able to run:
test_inputs(test_case, 6)
However, this doesn't stop at inputs_pos == 31. I put in print statements, and it looks like it just keeps going.
Is there a simpler way using a filter?
Am I understanding correctly that you want:
from itertools import cycle
def test_inputs(x, comp_size):
return [(input if count<3 else -999) for (input,count)
in zip(x[:-comp_size], cycle(x[-comp_size:]))]
You can restore the in-place modification behaviour by using x.extend instead of return. As the slices are performed before the extend call, it will produce the exact same items. Still, I don't think it's generally a good idea to mix data types in one list like this, when it would be as easy to pass (inputs,counts) tuples.
The loop doesn't stop because len(x) is evaluated at each iteration. In your cycle you increment count_pos and append a new element to x.

Is there a better way to write the following method in python?

I am writing a small program, in python, which will find a lone missing element from an arithmetic progression (where the starting element could be both positive and negative and the series could be ascending or descending).
so for example: if the input is 1 3 5 9 11, then the function should return 7 as this is the lone missing element in the above AP series.
The input format: the input elements are separated by 1 white space and not commas as is commonly done.
Here is the code:
def find_missing_elm_ap_series(n, series):
ap = series
ap = ap.split(' ')
ap = [int(i) for i in ap]
cd = []
for i in range(n-1):
cd.append(ap[i+1]-ap[i])
common_diff = 0
if len(set(cd)) == 1:
print 'The series is complete'
return series
else:
cd = [abs(i) for i in cd]
common_diff = min(cd)
if ap[0] > ap[1]:
common_diff = (-1)*common_diff
new_ap = []
for i in range(n+1):
new_ap.append(ap[0] + i*common_diff)
missing_element = set(new_ap).difference(set(ap))
return missing_element
where n is the length of the series provided (the series with the missing element:5 in the above example).
I am sure there are other shorter and more elegant way of writing this code in python. Can anybody help ?
Thanks
BTW: i am learning python by myself and hence the question.
Based on the fact that if an element is missing it is exactly expected-sum(series) - actual-sum(series). The expected sum for a series with n elements starting at a and ending at b is (a+b)*n/2. The rest is Python:
def find_missing(series):
A = map(int, series.split(' '))
a, b, n, sumA = A[0], A[-1], len(A), sum(A)
if (a+b)*n/2 == sumA:
return None #no element missing
return (a+b)*(n+1)/2-sumA
print find_missing("1 3 5 9") #7
print find_missing("-1 1 3 5 9") #7
print find_missing("9 6 0") #3
print find_missing("1 2 3") #None
print find_missing("-3 1 3 5") #-1
Well... You can do simpler, but it would completely change your algorithm.
First, you can prove that the step for the arithmetic progression is ap[1] - ap[0], unless ap[2] - ap[1] is lower in magnitude than it, in which case the missing element is between terms 0 and 1. (This is true as there is a single missing element.)
Then you can just take ap[0] + n * step and print the first one that doesn't match.
Here is the source code (also implementing some minor shortcuts, such as grouping your first three lines into one):
def find_missing_elm_ap_series(n, series):
ap = [int(i) for i in series.split(' ')]
step = ap[1] - ap[0]
if (abs(ap[2] - ap[1]) <= abs(step)): # Check missing elt is not between 0 and 1
return ap[0] + ap[2] - ap[1]
for (i, val) in zip(range(len(ap)), ap): # And check position of missing element
if ap[0] + i * step != val:
return ap[0] + i * step
return series # missing element not found
The code appears to be working. There is perhaps a slightly easier way to get it done. This is due to the fact that you don't have to attempt to look through all of the values to get the common difference. The following code simply looks at the difference between the 1st and 2nd as well as the last and second last.
This works in the event that only a single value is missing (and the length of the list is at least 3). As the min difference between the values will provide you the common difference.
def find_missing(prog):
# First we cast them to numbers.
items = [int(x) for x in prog.split()]
#Then we compare the first and second
first_to_second = items[1] - items[0]
#then we compare the last to second last
last_to_second_last = items[-1] - items[-2]
#Now we have to care about which one is closes
# to zero
if abs(first_to_second) < abs(last_to_second_last):
change = first_to_second
else:
change = last_to_second_last
#Iterate through the list. As soon as we find a gap
#that is larger than change, we fill in and return
for i in range(1, len(items)):
comp = items[i] - items[i-1]
if comp != change:
return items[i-1] + change
#There was no gap
return None
print(find_missing("1 3 5 9")) #7
print(find_missing("-1 1 3 5 9")) #7
print(find_missing("9 6 0")) #3
print(find_missing("1 2 3")) #None
The previous code shows this example. First of all attempting to find change between each of the values of the list. Then iterating till the change is missed, and returning the value that has been expected.
Here's the way I thought about it: find the position of the maximum difference between the elements of the array; then regenerate the expected number in the sequence from the other differences (which should be all the same and the minimum number in the differences list):
def find_missing(a):
d = [a[i+1] - a[i] for i in range(len(a)-1)]
i = d.index(max(d))
x = min(d)
return a[0] + (i+1)*x
print find_missing([1,3,5,9,11])
7
print find_missing([1,5,7,9,11])
3
Here are some ideas:
Passing the length of the series seems like a bad idea. The function can more easily calculate the length
There is no reason to assign series to ap, just do a function using series and assign the result to ap
When splitting the string, don't give the sep argument. If you don't give the argument, then consecutive white space will also be removed and leading and trailing white space will also be ignored. This is more friendly on the format of the data.
I've combined a few operations. For example the split and the list comprehension converting to integer make sense to group together. There is also no need to create cd as a list and then convert that to a set. Just build it as a set to start with.
I don't like that the function returns the original series in the case of no missing element. The value None would be more in keeping with the name of the function.
Your original function returned a one item set as the result. That seems odd, so I've used pop() to extract that item and return just the missing element.
The last item was more of an experiment with combining all of the code at the bottom into a single statement. Don't know if it is better, but it's something to think about. I built a set with all the correct numbers and a set with the given numbers and then subtracted them and returned the number that was missing.
Here's the code that I came up with:
def find_missing_elm_ap_series(series):
ap = [int(i) for i in series.split()]
n = len(ap)
cd = {ap[i+1]-ap[i] for i in range(n-1)}
if len(cd) == 1:
print 'The series is complete'
return None
else:
common_diff = min([abs(i) for i in cd])
if ap[0] > ap[1]:
common_diff = (-1)*common_diff
return set(range(ap[0],ap[0]+common_diff*n,common_diff)).difference(set(ap)).pop()
Assuming the first & last items are not missing, we can also make use of range() or xrange() with the step of the common difference, getting rid of the n altogether, it can also return more than 1 missing item (although not reliably depending on number of items missing):
In [13]: def find_missing_elm(series):
ap = map(int, series.split())
cd = map(lambda x: x[1]-x[0], zip(ap[:-1], ap[1:]))
if len(set(cd)) == 1:
print 'complete series'
return ap
mcd = min(cd) if ap[0] < ap[1] else max(cd)
sap = set(ap)
return filter(lambda x: x not in sap, xrange(ap[0], ap[-1], mcd))
....:
In [14]: find_missing_elm('1 3 5 9 11 15')
Out[14]: [7, 13]
In [15]: find_missing_elm('15 11 9 5 3 1')
Out[15]: [13, 7]

How to use loop outputs in another function

I have an input and then a loop that outputs 5 numbers I want to use in another function but I don't have any clue how to do this as I am a beginner.
mass_of_rider_kg = float(input('input mass of rider in kilograms:'))
a = mass_of_rider_kg
while a < mass_of_rider_kg+16:
a = a + 4
print(a)
This gives me the numbers I want but I am unsure how to put each of them into another equation to get 5 results.
def otherfunction(a):
...
...
mass_of_rider_kg = float(input('input mass of rider in kilograms:'))
a = mass_of_rider_kg
while a < mass_of_rider_kg+16:
a = a + 4
otherfunction(a)
If you want to use numbers, you have to store them somewhere. If you just print them out, they go to the screen and are immediately forgotten.
You've already got each value stored in a. If all you want to do is use each value, separately, in another equation, just use a:
while a < mass_of_rider_kg+16:
a = a + 4
print(a)
eggs = a * 20
print(eggs)
But if you want to use all of the a values, how do you do that? Each time through the loop, you lose the previous a when you get the new one.
To store all of them, you put them in a list, and then you can use the list after the loop is done. For example:
masses = []
while a < mass_of_rider_kg+16:
a = a + 4
print(a)
masses.append(a)
total = sum(masses)
print(total)

Categories

Resources