Reputation: 61
I need to write a code that counts down, decreasing with 2 steps until it reaches zero, where it then counts up again with 1 step between each integer.
As an example , if I define a function updown(n)
and write updown(7)
, it should give:
6 4 2 0 1 2 3 4 5 6 7
Here is my attempt:
def updown(n,m):
while n>=1:
print(n-1)
n=n-m
while n<=7:
print(n)
n=n+1
It takes m steps down, in my case m=2
. When I run the code I get
6 4 2 0 -1 0 1 2 3 4 5 6 7
As you can see, a negative integer appear and that is wrong. Also, I have n<=7 in the code, which I know is wrong. It should be valid for any n I insert and use that value as an upper limit.
I'm stuck and don't know what to do. It should be a recursive code and no built-in functions shall be used. The reason is that I want to understand the basics and continue from there, without any shortcuts.
Upvotes: 3
Views: 7149
Reputation: 1223
That hardcoded 7
in your example is the same parameter n
, so you should be using that instead. And you can "reset" or begin the second loop from 0
(hardcoded).
def updown(n,m):
aux = n # Don't modify n
while aux > 1: # Use aux instead of n
# Also, `>=` changed for `>`
# so `0` is not counted in this loop
print(aux - 1)
aux = aux - m
aux = 0 # aux reseted
while aux <= n: # See how n take place for 7
print(aux)
aux = aux + 1
But, for that specific task is more common to use the range function and the for loop instead of the while
loop and the using of manual counter. To give you an idea (and let you redefine your function as "homework"),...
Here is a for
loop using the range
function to print the numbers from 0
to 7
one by one:
for i in range(8):
print(i)
And here is a for
loop using the range
function to print the numbers from 6
to 2
two by two:
for i in range(6, 0, -2):
print(i)
Finally, you could use the chain method from itertools to do the same action for each iteration of many loops, as your case, where you want to simply print a number in each loop. This way, you have not to repeat that print statement (or in a future, repeat that processing block).
Here is an example chaining the two for
loops exposed:
from itertools import chain
for i in chain(range(6, 2, -2), range(8)):
print(i) # Processor block
Upvotes: 1
Reputation: 1789
A recursive way to do the same
def updown(n,m = 2):
if n % 2 == 0:
updownhelper(-n,n,m)
else:
updownhelper(-(n-1),n,m)
def updownhelper(a ,n,b = 2):
if a < 0:
print(str(-a))
updownhelper(a+b,n,b)
elif a == n:
print(a)
elif a >= 0:
b = 1
print(str(a))
updownhelper(a+b,n,b)
updown(6)
Upvotes: 2
Reputation: 21466
You dont need any while loop,
You can use range
like this,
>>> range(6,-2,-2) + range(1,8)
[6, 4, 2, 0, 1, 2, 3, 4, 5, 6, 7]
Function:
def updown(n, m):
return range(n -1, -1 * m, -2) + range(1,n+1)
Output:
[6, 4, 2, 0, 1, 2, 3, 4, 5, 6, 7]
range(start, stop[, step])
This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised).
Upvotes: 2
Reputation: 152725
I'm not sure why the first printed value should be 6 so the solution might be wrong but if you want your output try:
def updown(n,m):
start = n
#n -= 1
# or if you want the first number that is divisible by m:
n = m * (n // m) # Floor division ignores decimal places so this is the first number divisible by m
while n >= m:
print(n)
n -= m
while n <= start:
print(n)
n += 1
updown(7, 2)
The problem with your solution was that you printed before you subtracted so the value was actually smaller than the one printed, so you printed a negative value in the second while loop. You need to reconsider the termination condition if you print and then change the value (what I have done). Or change the order of print and operation.
Upvotes: 1
Reputation: 23524
First of all you call updown(7, 2)
it decreases to 1: 7, 5, 3, 1
then it runs again because statement while 1 >= 1
is True
so it decreases one more time.
The second problem it that when you decrease it output print(n - 1)
not print(n)
I believe your solution is that.
def updown(n, m):
while n >= m:
print(n)
n = n - m
while n <= 7:
print(n)
n = n + 1
However if you want to start with even number the solution is that:
def updown(n, m):
if n % 2 != 0:
n = n - 1
while n >= m:
print(n)
n = n - m
while n <= 7:
print(n)
n = n + 1
Upvotes: 0
Reputation: 477210
I think that by using n-1
, you will make things more complicated than they should be.
Simply first calculate the largest even number that is smaller than the given number:
n2 = n-(n%2)
or more general (for m
):
nm = n-(n%m)
Next use range
:
for i in range(nm,-1,-m):
print(i)
and finally print all number from 0
and including n
:
for i in range(n+1):
print(i)
or putting it all together:
def updown(n,m):
nm = n-(n%m)
for i in range(nm,-1,-m):
print(i)
for i in range(n+1):
print(i)
From my own experience, it is rather un-pythonic to modify variables. Python aims to be a bit declarative: you use for
loops if a variable can have different values to iterate over it.
Upvotes: 1