I am taking a beginner Python class and the instructor has asked us to countdown to zero without using recursion. I am trying to use a for loop and range to do so, but he says we must include the zero.
I searched on the internet and on this website extensively but cannot find the answer to my question. Is there a way I can get range to count down and include the zero at the end when it prints?
Edit:
def countDown2(start):
#Add your code here!
for i in range(start, 0, -1):
print(i)
The range() function in Python has 3 parameters: range([start], stop[, step]). If you want to count down instead of up, you can set the step to a negative number:
for i in range(5, -1, -1):
print(i)
Output:
5
4
3
2
1
0
As another option to #chrisz's answer, Python has a built-in reversed() function which produces an iterator in the reversed order.
start_inclusive = 4
for i in reversed(range(start_inclusive + 1)):
print(i)
outputs
4
3
2
1
0
This can be sometimes easier to read, and for a well-written iterator (e.g. built-in range function), the performance should be the same.
In the below code n_range doesn't need to be told to count up or down, it can just tell if the numbers ascend or descend through the power of math. A positive value divided by it's negative equivalent will output a -1 otherwise it outputs a 1.
def n_range(start, stop):
return range(start, stop, int(abs(stop-start)/(stop-start)))
An input of 5, -1 will output
5
4
3
2
1
0
Related
I have used this code to determine the value of e^pi with a specified tolerance in spyder(Python 3.8).
from math import*
term=1
sum=0
n=1
while (abs(e**pi-term))>0.0001:
term=term*pi/n
sum+=term
n+=1
print(sum,e**pi)
I ran this code several times. But spyder is not showing anything when I run this code. I am new to python. So now I have no way to know whether this code is correct or not. It would be beneficial if you could verify whether this code is valid or not.
Okay, so the taylor series for e^x is sum n=0 to inf of x^n / n! which you seem to be doing correctly by multiplying by pi/n during each iteration.
One problem I noticed was with your while loop condition. To check the error of the function, you should be subtracting your current sum from the actual value. This is why you enter the infinite loop, because your term will approach 0, so the difference will approach the actual value, e^pi, which is always greater than .0001 or whatever your error is.
Additionally, since we start n at 1, we should also start sum at 1 because the 0th term of the taylor series is already 1. This is why you enter the infinite loop, because
Therefore, our code should look like this:
from math import*
term = 1
sum = 1
n = 1
while (abs(e ** pi - sum)) > 0.0001:
term = term * pi / n
sum += term
n += 1
print(sum,e**pi)
Output:
23.140665453179782 23.140692632779263
I hope this helped answer your question! Please let me know if you need any further clarification or details :)
The while loop does not end.
I have stuck in a condition to break out of the loop (at 10,000 cycles) to show this:
from math import*
term=1
sum=0
n=1
while (abs(e**pi-term))>0.0001:
term=term*pi/n
sum+=term
n+=1
if n > 10_000:
print('large n')
break
print(sum,e**pi)
If you replace the while loop with a for loop, then you can see each iteration as follows.
term=1
sum=0
for n in range(1, 101):
term=term*(math.pi)/n
sum+=term
print(n, sum, math.e**math.pi)
And this is the result for the first 10 items:
1 3.141592653589793 23.140692632779263
2 8.076394854134472 23.140692632779263
3 13.244107634184441 23.140692632779263
4 17.30281976060121 23.140692632779263
5 19.852983800478555 23.140692632779263
6 21.188246569333145 23.140692632779263
7 21.787511098653937 23.140692632779263
8 22.02284172901283 23.140692632779263
9 22.104987615623955 23.140692632779263
10 22.13079450701397 23.140692632779263
The numbers are getting larger, hence the while loop was never exited (and your laptop probably got quite hot in the process !!).
I have a hard time understanding this:
for i in range(1, 4):
for j in range(i):
print(i)
when the inner loop's range is a number I understand it, but on the code above, the inner loop is running in range(i). What does that mean? Thank you.
Let's go step by step:
The function range(start, stop, step) has these 3 parameters.
The parameters start and step are optional, but the parameter stop is required.
If you only send one parameter to the function, for example, range(5), the function automatically will set start = 0 and step = 1. Then, range(5) is equal to range(0, 5, 1).
The parameters start, stop and step must be integers. In your case, i is an integer variable that is taking the values 1, 2 and 3, and that's why range(i) is valid.
i is a variable set by the loop it is inside of. i is the number iterating (that's why it's commonly called i). j then iterated through all the numbers up to i.
For example, range(1,4) could be 3 sizes of sweets where each size up has one more sweet (1 packet with 1 sweet, 1 packet with 2 sweets, 1 packet with 3 sweets). The second loop iterates through each of the sweets in the packet (where packet is i and sweet is j). You're then printing the packet you ate.
I'm currently taking a course in Computer Science, I got an assignment to use either Python or pseudocode to ask the user to enter a digit, then divide it by 2, and then count how many divisions it takes to reach 1 (and add 1 more as it reaches 1). I've never coded before but I came up with this; but it only returns a 1 no matter what I input.
def divTime (t):
if d <= 1:
return t + 1
else:
return t + 1, divTime(d / 2)
d = input("Enter a number:")
t = 0
print (divTime)(t)
You can add 1 to the recursive call with the input number floor-divided by 2, until the input number becomes 1, at which point return 1:
def divTime(d):
if d == 1:
return 1
return 1 + divTime(d // 2)
so that:
print(divTime(1))
print(divTime(3))
print(divTime(9))
outputs:
1
2
4
This works:
def div_time(d, t=0):
if d < 1:
return t
else:
return div_time(d/2, t+1)
d = input("Enter a number:")
print(f"t = {div_time(int(d))}")
It always returns 1 because you're always passing it 0.
It looks like you're "thinking in loops" – you don't need a separate counter variable.
How many times does it take to divide:
k smaller than 2? None.
k greater than or equal to 2? One more than it takes to divide k // 2.
That is,
def divTime(x):
if x < 2:
return 0
return 1 + divTime(x // 2)
or
def divTime(x):
return 0 if x < 2 else 1 + divTime(x //2)
Instead of providing a straight forward answer, I'll break the problem out into a few steps for students:
Ignore the input and edge cases for now, let's focus on writing a function that solves the problem at hand, then we may come back to providing an input to this function.
Problem statement confusion - You will often divide an odd number with a remainder, skipping the exact number 1 due to remainders. There is ambiguity with your problem from dealing with remainders - we will reword the problem statement:
Write a function that returns the number of times it takes to divide an input integer to become less than or equal to 1.
The next part is identifying the type of algorithm that can solve this type of problem. Since we want to run the function an unknown amount of times using the same function, this seems to be a perfect use case of recursion.
Say I provide 10 as an input. We then want to say 10/2=5 (count 1), 5/2=2.5 (count 2), 2.5/2=1.25 (count 3), 1.25/2=0.625 (count 4), return [4] counts.
Now we know we need a counter (x = x+1), recursion, and a return/print statement.
class solution:
''' this class will print the number of times it takes to divide an integer by 2 to become less than or equal to 1 '''
def __init__(self):
#this global counter will help us keep track of how many times we divide by two. we can use it in functions inside of this class.
self.counter=0
def counter_2(self, input_integer):
#if the input number is less than or equal to 1 (our goal), then we finish by printing the counter.
if input_integer<=1:
print(self.counter, input_integer)
#if the input is greater than 1, we need to keep dividing by 2.
else:
input_integer=input_integer/2
#we divided by two, so make our counter increase by +1.
self.counter=self.counter+1
#use recursion to call our function again, using our current inputer_integer that we just divided by 2 and reassigned the value.
self.counter_2(input_integer)
s=solution()
s.counter_2(10)
I was just trying to solve this problem on Codeforces: Check whether it's posible to split a number w (1 ≤ w ≤ 100) into a sum of 2 even numbers
I solved the problem and started to look others solutions for the problem. The I found that solution:
w=int(input())
print("YNEOS"[(w%2)|(w<=2)::2])
it took half of time to solve the problem then mine. Unfortunately I am not getting how it is working and why it is faster than mine. My solution is :
n = int(input())
if (n-2)%2==0 and n > 2:
print("YES")
else:
print("NO")
I am a beginner in python. So it will be very helpful for me it i get a proper explanation.
The :: part is called slicing. The general syntax is start:stop[:step] which will make a new array or string from the original one, beginning from index start to before stop every step (default = 1). It's essentially a syntactic sugar for slice(start, stop, step) which returns a slice object. If stop is omitted then all the elements till the end of the string will be extracted
Understanding slice notation
How do I use the slice notation in Python?
https://docs.python.org/2.3/whatsnew/section-slices.html
You may want to read An Informal Introduction to Python for more information about slicing
Now (w%2)|(w<=2) calculates the start index. | is the bitwise-OR operator. w<=2 is a bool expression, but in Python "Booleans are a subtype of integers", so True and False will be converted to 1 and 0 respectively
If w is an odd number then w % 2 == 1. Regardless of the remaining part, (w%2)|(w<=2) will always be 1 in this case and the expression becomes "YNEOS"[1::2] which takes every second letter in the string starting from index 1. The result is the string NO
If w is an even number then w % 2 == 0. According to the problem description 1 ≤ w ≤ 100 the only valid even numbers belong to the range [2, 100]
If w == 2 then w <= 2 returns 1 and the output is NO like above
If w > 2 then both the sides of (w%2)|(w<=2) is 0, and "YNEOS"[0::2] takes the 1st, 3rd and 5th letters which is YES
Realizing that the expression always returns 0 or 1 we'll have an alternative more readable solution that uses direct addressing instead of slicing
w=int(input())
print(['YES', 'NO'][(w % 2) | (w <= 2)])
Btw, you have a redundant subtraction: (n-2)%2==0 is exactly the same as n % 2 == 0
I'm new to Python, which is why I'm having trouble on a problem which others might find easy.
Background to this problem: Euler Project, question 2. The problem essentially asks us to add all the even terms in the Fibonacci sequence, so long that each term is under 4,000,000. I decided to do the problem a little differently than what many solutions online show, by calculating the nth Fibonacci term from a closed formula. For now, suppose this function is called Fibonacci(n).
What I'd essentially like to do is loop through an unknown amount of integers that represent the indexes of the Fibonacci set (i.e., 1, 2, 3, 4... etc) and plug each value into Fibonacci(n). If the result has no remainder when divided by 2, then add this Fibonacci number to some value initially set at 0.
Here's what I have so far:
def Fibonacci(n):
return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
i=0
FibSum = 0
nFib = 0
while (nFib <= 10):
nFib = Fibonacci(i)
if(nFib%2==0):
FibSum += nFib
i += 1
print FibSum
(Yes, as you can see, I'm constraining the Fibonacci sequence to end at 10 as opposed to 4,000,000; this is done merely for testing's sake.)
Now, here's my problem: when I run this code, I get 2.0 instead of 10.0 (2 and 8 are the two Fibonacci numbers that should be added together).
How come? My guess is that the loop stops after it gets to the third Fibonacci number (2) and doesn't continue beyond that. Does anyone see something wrong with my code?
Please comment if you have any further questions. Thanks in advance.
Solution provided by Gal Dreiman is fine but, conversion with in function is more better, below is your revised code:
def Fibonacci(n):
return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))
You have a floating point problem (which you can read on here)- the returned value 'nFib' is not an integer and not a rounded value. I ran your code and added print for this value in every iteration and got:
0.0
1.0
1.0
2.0
3.0000000000000004
5.000000000000001
8.000000000000002
13.000000000000002
The solution for this is to modify your code as the following:
nFib = int(Fibonacci(i))
After that I got the output: 10
The problem is with nFib%2==0 comparison. Here you try to compare the float LHS with integer 0. So either modify the if loop as below or modify the return as return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))).
>>> def Fibonacci(n):
... return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
...
>>> i=0
>>> FibSum = 0
>>> nFib = 0
>>> while (nFib <= 10):
... nFib = Fibonacci(i)
... if(int(nFib%2)==0):
... FibSum += nFib
... i += 1
...
>>> print FibSum
10.0