I am practicing Python with Project Euler, question 1, but the function I wrote to solve it is taking way too long.
I figure it's because the way I coded it not the actual method itself.
When I run this function with 10 or 15 iterations it spits out an answer instantly, but as soon as I jump it up to even 20, it doesn't show me anything for even minutes.
This is obviously a big problem if I need to go to 1000 iterations.
def pe1(n):
counter = 1
total = 0
while counter < n:
if counter%3==0:
total=total+counter
if counter%5==0:
if counter%3==0:
continue
total=total+counter
if counter % 25 == 0:
print (total)
counter=counter+1
return (total)
Because as soon as counter hits 15, your loop goes into an infinite continue - it's always going to hit the second if statement's case.
You need to move your counter = counter + 1 line before the continue, or better yet, use something like for counter in range(1,n).
Consider the case if counter equals 15 and look at what happens where counter%5==0 and counter%3==0, which will first occur at that time.
Consider also what will not happen for that value of counter, specifically, the line counter=counter+1 won't be executed.
To avoid traps like this one, consider using
if ...
elif ...
elif ...
else ...
You can use table-driven. Like this.
counter_map = {3:fun1, 5:func2, 25:fun3} # key is remainder.Of course,fun can be replaced with lambda.
Related
I have a piece of code. Here, I am running a for loop. If the if statement is not met, I want to restart that for loop. How should I do this? sp is a library btw.
for i in range (10000):
#my codes
a= sp.levene(#my variables)
if a[1] < 0.05:
#I want to restart for loop again
else:
#doing something
You probably don't want to use a for loop, since you aren't iterating over a particular sequence of numbers (i is going to jump around based on what happens inside the loop). Using a while you'd do:
i = 0:
while i < 10000:
# my code
a = sp.levene() # my variables
if a[1] < 0.05:
i = 0
continue
i += 1
# doing something
continue restarts the loop at the beginning of the loop body, and having set i = 0 it's now in the same state it was in at the first iteration.
The simplest way to handle this is:
while True:
for i in range(100000):
...
if a[1] < 0.05:
# this will exit out of the for loop, but the while
# loop will keep going
break
else:
....
# if we've successfully finished the "for" loop, then break out of
# the while loop
break
If your logic is a little bit more complicated:
done = False
while not done:
for i in range(100000):
...
if a[1] < 0.05:
# this will exit out of the for loop, but the while
# loop will keep going
break
else:
# set done to True if you've decided you don't need to perform
# the outer loop any more
other stuff
# likewise, set done to True if you're done with the outer while loop
To build on Frank Yellin's answer if you don't want to use break else break.
continueloop=True
while(continueloop):
for i in range (10000):
#my codes
a=sp.levene #my variables
if a[1] < 0.05:
#I want to restart for loop again
continueloop=True
else:
continueloop=False
#doing something
Hope you find a suitable answer!
I think what you are looking to do is have that function inside a loop. If the statement fails then on the else statement call the function again with new parameters. Basically, you want recursion on your loop is what I'm understanding.
def RecursionFunc() #3) when this function is called code runs from here
for i in range (10000):
#my codes
a= sp.levene(#my variables)
if a[1] < 0.05:
RecursionFunc() #2) will make you jump to the top again basically calling itself
break #4) will exit the current loop
else:
RecursionFunc() # 1)This will be the first code that gets executed
And the recursion will keep the function going and you can do plenty of other stuff with this. I know you want to break the loop and run again you can also change the "i" value on the next recursion run. If you give recursionFunc(int i) then you can basically set yours for loop to a new I value on the next run too. Can do a lot of cool things like this.
I have a use case where I need to repeat some block of code:
Sometimes I need to repeat the code block a finite number of times
Sometimes I need to repeat the code block indefinitely.
I am wondering, is there some Python built-in way to:
No limit supplied --> code block is repeated via something like a while loop
Limit supplied --> code block is repeated via something like a for loop
Note: I know I can use an if statement (depending on if upper limit is present), and switch between a for or while loop. I am trying to not have the code block repeated twice, or it broken out into another function.
Current Implementation
I wrote the below flawed (see below) for_while_hybrid.py using Python 3.8.2.
from typing import Iterator
def iter_for_while(num_yield: int = None) -> Iterator[int]:
"""Generate an incrementing counter.
This enables one to make a for loop or a while loop, depending on args.
Args:
num_yield: Number of times to yield.
If left as None, the generator makes a while loop
If an integer, the generator makes a for loop
"""
counter = 0
condition = True if num_yield is None else counter < num_yield
while condition:
yield counter
counter += 1
if num_yield is not None:
condition = counter < num_yield
upper_limit = 5
for _ in iter_for_while(upper_limit):
print("Some code block") # Run 5 times
for _ in iter_for_while():
print("Some code block") # Run infinitely
This implementation works.
The downside is, if run for a very long time, I am worried the counter will take up lots of memory, or will eventually max out. My computer is 64-bit, so sys.maxsize = 2 ** 63 - 1 = 9,223,372,036,854,775,807.
Just use count or range, depending on the upper bound:
from itertools import count
def iter_for_while(bound=None):
return count() if bound is None else range(bound)
use a while loop but you can say while X < Y: do something and then X += 1
this means you can control how many times it repeats with X or if you want it indefinitely then don't say X + 1
I have this recursion function I wrote (Simplified, it is much longer but the idea stays the same)
def rec(point,length):
if 1<length<=8:
str_adj = '23456'
for adj in str_adj:
return rec(adj, length-1)
elif length == 1:
return 1
else:
return 0
rec('1',2)
[Disclaimer: I know the code looks weird and some parts are not needed because I simplified the function. ]
Now, when I run this code I get: 1, however the output needs to be 5 as I iterate over each letter of the string '23456' (which has 5 letters) and for each letter I call it with length of 1 (as I decrease it 2-1=1) and each time we get length=1 we return 1, so it should return 1 five times..
I've sat down to debug and break down the code into multiple parts and tried many many different version of it, such as removing 'return' in the loop, but when doing it, the output is None...
Can someone please help me to spot the mistake? thanks!
In python code, I am trying to do the following:
rec('2',1)+rec('3',1)+rec('4',1)+rec('5',1)+rec('6',1) = 1 + 1 + 1 + 1 +1 = 5
as each time we call rec(?,1) = 1
Let's say the str_adj = '123456789' and length = 2
then I want to output to be:
rec('1',1)+rec('2',1)+ etc.. until + rec('9',1)
each time we call rec(?,1) = 1 so it should return 9
I'm not sure what the end goal is, but your logic is breaking the code. When you call rec the first time, it enters the first "if" statement, and from there calls
rec('2', 1)
This call of the function enters the "elif" statement, returns 1, and then ends.
If you could clarify what you are trying to accomplish I can try to help fix this logic.
Your expected behavior does not match what is happening. You're never modifying str_adj and setting str_adj each time to equal 23456. In your for loop, adj will always be 2 unless you change it. In order to do so, it will also have to not be a variable local to the function.
You will also need something to keep track of your iterations.
Doing your example like this, will give you the result you want. You could make it much better, but I did my best to change it and match your format.
def rec(point,length, str_adj, iterations):
print("rec(", point, ", ", length, ", ", str_adj, ", ", iterations, ")")
if 1<length<=8:
for adj in str_adj:
str_adj = str_adj[1:]
iterations = iterations + 1
return rec(adj, length-1, str_adj, iterations)
elif length == 1:
return iterations
else:
return 0
iterations = 1;
str_adj = '23456'
print(rec('1',4, str_adj, iterations))
I am trying to make a simple loop where it prints the output numbers 0-9 on separate lines. What am I doing wrong? I have looked at the examples on here and they don't really help me. If you could explain where I went wrong that would be very helpful.
def singleline(item):
number = 0
while number < 10:
print(number)
number = number + 1
You've defined a function but you haven't called it. Just add
singleline(1)
to the end of the script.
Try using a for loop with range.
for num in range(10):
print(num)
This is more concise than using a while loop.
Also, if you are using a while loop, I would recommend using number+=1. It is the same as number=number+1, but just looks cleaner.
Firstly remember to call the function at the end of your otherwise you have just executed it singleline(). Also you haven't used the item you put into the parameters.
A better way to write this using a while loop would be.
def singleline():
num = 0
while num < 10:
print(num)
num += num
The += just means add one to of the variable on the left to the variable on the right. For example
a = 1
b = 2
a += b
a would not equal 3 because it adds b to it's original value.
However if you wanted something more efficient you could use this:
for num in range(10):
print(num)
for loops work in the same way as a while loop (take a condition and do content until stopped) but does it for the amount of times set. So in simple terms all this code means is print num plus 1.
Woah, your code is way too complicated -
for x in range (0, 10):
print x
Should work perfectly (python), Good Luck!
#hello , i wounder why my code keep stoping at the secound while loop and doesn't do anything
print"*******************************"
a = 0
deg_list =[]
deg_list_a=[]
deg_list_b=[]
deg_list_c=[]
degree=input("Enter the students Degree:")
while a<=degree:
deg_list.append(degree);
degree=input("Enter the students Degree:")
print "Degree List :",deg_list
print len(deg_list)
while len(deg_list)>=0:
if deg_list[a]>=16:
deg_list_a.append(deg_list[a])
x=+1
elif 15>deg_list[a]>=10:
deg_list_b.append(deg_list[a])
x=+1
else :
deg_list_b.append(deg_list[a])
x=+1
print deg_list_a
print deg_list_b
print deg_list_c
Your code enters an endless loop.
Both of your while loops have problems with the condition which allows them to terminate. Since your code never changes the value of a, the first loop becomes while 0<=degree, and so the first loop terminates when the user inputs a negative value. But the variable a can be removed from your program.
The while loop continues as long as len(deg_list) >= 0. However, no code within the loop decreases the length of deg_list, so the while loop continues forever.
The code below could help you get this working:
deg_list =[]
deg_list_a=[]
deg_list_b=[]
deg_list_c=[]
degree=input("Enter the students Degree:")
while degree > 0:
deg_list.append(degree);
degree=input("Enter the students Degree:")
print len(deg_list)
while len(deg_list) > 0: # Strictly greater than 0, not equal to 0.
if deg_list[0] >= 16:
# Use pop to access first element
deg_list_a.append(deg_list.pop(0))
elif deg_list[0] >= 10: # One comparison per statement, only.
deg_list_b.append(deg_list.pop(0))
else:
deg_list_c.append(deg_list.pop(0)) # c, not b.
print deg_list_a
print deg_list_b
print deg_list_c
You're never modifying deg_list, so your loop becomes infinite. Even removing all elements wouldn't help since you're comparing against 0 -- the loop condition will never be false.
Well.
It looks to me that a is set to 0 in the beginning and then never changed, so doing something with deg_list[a], that is the first element in the list, isn't going to do very much. In addition, your looping condition is len(deg_list) >= 0, and len(deg_list) will never change.
But there are more fundamental issues with your code. Imagine you were changing the length of deg_list: in this case you would be changing the very list you're looping over, which is usually (if you are not very very certain what you're doing) a recipe for disaster. What I think you should envisage doing is a loop along the lines of:
for degree in deg_list:
if [degree fulfils some condition]:
[do something with degree]
elif [degree fulfils some other condition]:
[do something else]
...
else:
[whatever]
Last, from your comparison it seems that the "degrees" are all small integers. You may want to test for that -- it's user input and you have to expect anything being thrown at your input -- before doing things like if degree >= 16.
It looks like you are trying to loop through all the members of deg_list, but you are waiting for deg_list to be empty, and each time through the loop you are incrementing "x," which is never even read.
If you really are trying to traverse through deg_list, try this for your second loop:
for degree in deg_list:
if degree >= 16:
deg_list_a.append(degree)
elif degree >= 10:
deg_list_b.append(degree)
else :
deg_list_c.append(degree)