Recursive function printing all values twice - python

When I run my code the output is correct, it's just printing out two of each value.
Can somebody enlighten me on what is going wrong?
number = int(input("Enter any number: "))
tfcheck = True
def reducer(number):
if (number % 2) == 0:
number = int(number/2)
else:
number = number * 3 + 1
print(number)
return number
while tfcheck:
if reducer(number) == 1:
tfcheck = False
break
else:
number = reducer(number)
reducer(number)
This code should divide a user inputted number down to 1 and display each step, this is a sample output of what I'm getting if I put in 3:
10
10
5
5
16
16
8
8
4
4
2
2
1
1
Cant see where I'm going wrong with it

reducer prints the number. In your while loop, you call reducer twice:
while tfcheck:
if reducer(number) == 1: # Call once
tfcheck = False
break
else:
number = reducer(number) # Call again
Thus, the number will get printed twice. To fix this, you can just call reducer once and store its result in a temporary variable.
while tfcheck:
reduced = reducer(number) # Call once
if reduced == 1:
tfcheck = False
# break # No need to break since you set tfcheck = False
else:
number = reduced # Do not call again

Iterative Approach:
Solution provided in the question prints the number inside the function and since in the while loop reducer is called twice with same value as it executes else statement unless the return value is 1.
Therefore solution to this problem would be simply printing the number in else statement of while loop.
number = int(input("Enter any number: "))
tfcheck = True
def reducer(number):
if (number % 2) == 0:
number = int(number/2)
else:
number = number * 3 + 1
return number
while tfcheck:
if reducer(number) == 1:
tfcheck = False
break
else:
number = reducer(number)
print(number)
print(reducer(number))
Recursive Approach:
A better approach would be using this method as it eliminates repetitive function call, while loop along with if-else statements can be eliminated. Also you will be able to understand the code better.
Yes it is true Python has recursion limit, if the use case is exceeding the limit then go for Iterative method. But for most cases the limit will not be crossed.
def reducer(number):
if number==1:
return 1
if (number % 2) == 0:
number = int(number/2)
else:
number = number * 3 + 1
print(number)
reducer(number)
reducer(int(input("Enter any number: ")))

Related

Program must ask the user for an even integer max six times, if not it ends

The program ask the user for an even integer. If he asks for it 6 times, the program ends. If the number is even, it returns it. My code so far:
i = 0
for i in range(6):
num = int(input("Num: "))
if num % 2 == 0:
print(num)
else:
num = int(input("Num: "))
i+=1
if i == 6:
break
My program doesn't end after user gives 6 not even numbers, how can i fix this?
You don't need to check for i == 6 yourself, this is done automatically by the for loop.
But you need to break out of the loop when an even number is entered.
for i in range(6):
num = int(input("Num: "))
if num % 2 == 0:
print("Success!")
break
else:
print("Failure")
The else: block of a loop is executed if the loop reaches its normal conclusion instead of exiting due to break.
for i in range(6):
num = int(input("Num: "))
if num % 2 == 0:
print(liczba)
break
This will do what you want, without all the extra lines you had.

Collatz Sequence - Trying to fix a printed 'None' value

Complete beginner here, I'm currently reading through "Automate the Boring Stuff With Python" by Al Sweigert. I'm running into an issue where my program is returning a None value and I can't figure out how to change that.
I understand that at some point collatz(number) doesn't have a value, therefor None is returned- but I don't understand how to fix it. The book hasn't touched on yield yet. I've tried using return instead of print within the function, but I haven't been able to fix it.
def collatz(number):
while number != 1:
if number % 2 == 0:
number = number // 2
print(number)
elif number % 2 == 1:
number = 3 * number + 1
print(number)
print('Enter number:')
try:
number = int(input())
print(collatz(number))
except ValueError:
print ('Please enter an integer.')
As #chepner proposed you need to remove the print statement which is enclosing your collatz(number) call. The correct code would look like
def collatz(number):
while number != 1:
if number % 2 == 0:
number = number // 2
print(number)
elif number % 2 == 1:
number = 3 * number + 1
print(number)
print('Enter number:')
try:
number = int(input())
collatz(number)
except ValueError:
print ('Please enter an integer.')

Automate the Boring Stuff with Python The Collatz Sequence assignment repet

I know there are a lot of posts on this assignment and they all have great information, however, I am trying to take my assignment to the next level. I have written the code for the sequence, I have written the try and except functions and have added the continues so the program will keep asking for a positive integer till it gets a number. now I would like the whole program to repeat indefinitely, and I will then write a (Q)uit option. I tried making the question ask into a global scope but that was wrong, can someone please give me a hint and I will keep working on it. here is my code;
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
elif number % 2 == 1:
result = 3 * number + 1
return result
while True:
try:
n = int(input("Give me a positive number: "))
if n <= 0:
continue
break
except ValueError:
continue
while n != 1:
n = collatz(int(n))
An example of repeating indefinitely is as follows.
def collatz(number):
" No element of Collatz can be simplified to this one liner "
return 3 * number + 1 if number % 2 else number // 2
while True:
# Will loop indefinitely until q is entered
try:
n = input("Give me a positive number: ")
# String returned from input
if n.lower() == "q": # check for quit (i.e. q)
break
else:
n = int(n) # assume int, so convert (will jump to exception if not)
while n > 1: # loops and prints through collatz sequence
n = collatz(n)
print(n)
except ValueError:
continue
Pretty much all you need to do is move the second while loop into the first and add a "quit" option, though I've done some additional things here to simplify your code and give more feedback to the user.
def collatz(number):
if number % 2 == 0:
# Removed "print" here - should be done in the calling scope
return number // 2
else: # Removed "elif" - You already know "number" is not divisible by two
return 3 * number + 1
while True:
s = input("Give me a positive number, or 'q' to quit: ")
if s == 'q':
print('Quit')
break
try:
# Put as little code as possible in a "try" block
n = int(s)
except ValueError:
print("Invalid number, try again")
continue
if n <= 0:
print("Number must be greater than 0")
continue
print(n)
while n != 1:
n = collatz(n)
print(n)
Example run:
Give me a positive number, or 'q' to quit: a
Invalid number, try again
Give me a positive number, or 'q' to quit: 0
Number must be greater than 0
Give me a positive number, or 'q' to quit: 2
2
1
Give me a positive number, or 'q' to quit: 3
3
10
5
16
8
4
2
1
Give me a positive number, or 'q' to quit: q
Quit
Thank you the suggestions are great!! Here is my finished code;
def collatz(number):
while number != 1:
if number % 2 == 0:
number = number // 2
print(number)
else:
number = 3 * number + 1
print(number)
while True:
try:
n = input("Give me a positive number or (q)uit: ")
if n == "q":
print('Quit')
break
n = int(n)
except ValueError:
continue
collatz (n)

Python Program to check if a number is armstrong or not is not working, what am I doing wrong?

n=int(input("Enter a Number: "))
x=0
y=0
z=0
while(n>0):
x=n%10
y=x**3
z=z+y
n=n//10
print (z)
#The z here is the same value which I enter, yet it doesn't work.
#If I enter 407 as n, z becomes (4^3)+(0^3)+(7^3) which is 407
if (z==n):
#But even when 407==407, it just wont print the bottom statement
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
#it prints that it isn't an Armstrong number
After the while loop, n already became 4//10 which is 0, so it'll never equal z which is 407.
You will want to keep a copy of the original input for comparison.
As a general advice, use a debugger or at least print() your objects to see where the assignments went wrong.
Without using any built-in method
Armstrong number is 371 because 3**3 + 7**3 + 1**3 = 371. according this rule 123 is not Armstrong number because 1**3 + 2**3 + 3**3 is not equal to 123
def count_digit(n):
count = 0
while n > 0:
count += 1
n //= 10
return count
def is_armstrong(n):
given = n
result = 0
digit = count_digit(n)
while n > 0:
reminder = n % 10
result += reminder ** digit
n //= 10
return given == result
is_armstrong(371)
>> True
is_armstrong(123)
>> False
You can take in your initial number as a string so we can more easily convert it to a list. We can then map to create that list of ints. After we can use list comprehension to raise all int in that list to the power that is the len of our list. If the sum of this list equals our input, then we have an Armstrong number.
n = input('Enter a number: ')
nums = list(map(int, n))
raised = [i**len(nums) for i in nums]
if sum(raised) == int(n):
print('The number is Armstrong')
else:
print('The number is not Armstrong')
Expanded list comprehension:
raised = []
for i in nums:
i = i**len(nums)
raised.append(i)
print(raised)
Alternate for map:
nums = []
for i in n:
i = int(i)
nums.append(int(i))
I corrected your code:
n = int(input("Enter a Number: "))
x = 0
y = 0
z = 0
num = n
while n > 0:
x = n % 10
y = x**len(str(num))
z = z+y
n = n//10
print(z)
if (z == num):
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
But you can still do it in many ways better. Look at the code of vash_the_stampede and ggorlen.
Or:
def isArmstrong(n):
print(f"{n} is {'' if int(n) == sum(int(i)**len(n) for i in n) else 'not '}an Armstrong number")
isArmstrong(input("Please enter a number: "))
Definition: a number n is an Armstrong number if the sum of each digit in n taken to the power of the total digits in n is equal to n.
It's important to keep track of the original number n, because it'll be needed to compare against the result of z (your variable representing the sum). Since you're mutating n in your while loop, there's no grounds for comparison against your original input, so if (z==n): isn't working like you expect. Save n in another variable, say, original, before reducing it to 0.
Additionally, your code has arbitrarily chosen 3 as the number of digits in the number. For your function to work correctly for any number, you'll need a way to count its digits. One way is to convert the number to a string and take the length.
I strongly recommend using descriptive variable names which reduces the chance of confusing yourself and others. It's only apparent that z represents your sum and x your remainder by virtue of reading through the code. If the code was any longer or more complex, it could be a nightmare to make sense of.
Lastly, Python is not a particularly flexible language from a style standpoint. I recommend adhering to the style guide as best as possible to keep your code readable.
Here's a working example:
def armstrong(n):
total = 0
original = n
digits = len(str(n))
while n > 0:
total += (n % 10) ** digits
n //= 10
return total == original
if __name__ == "__main__":
while 1:
print(armstrong(int(input("Enter a Number: "))))
Output:
Enter a Number: 407
True
Enter a Number: 1234
False
Enter a Number: 23
False
Enter a Number: 8
True
Enter a Number: 371
True
Try it!
total=0
def Armstrong(n):
m=list(n)
global total
for i in m:
total+=pow(int(i),len(n))
if total==int(n):
print ("it is Armstrong number")
else:
print("it is not Armstrong number")
Armstrong(input("enter your number"))
print(total)

how to solve this factorial

I've managed to get factors in a list but I can't finish because I'm doing something wrong in the end, the count variable is not updating with the products.
I want to solve it without using the factorial function.
Question:
Write a program which can compute the factorial of a given number.
The results should be printed in a comma-separated sequence on a single line.
Suppose the following input is supplied to the program:
8
Then, the output should be:
40320
Hints:
In case of input data being supplied to the question, it should be assumed to be a console input.
user = int(input("Input a number: "))
factors = []
while user > 0:
n = user * (user - 1)
if user == 1:
factors.append(1)
break
else:
factors.append(user)
user -= 1
count = 0 # this should be updating but it's not
for f in range(factors[0]): # I'm not sure if this is the correct range
counting = factors[f] * factors[f + 1] # I'm not sure about this either
count = count + counting
f = f + 1
Just change the last part of your program to:
result = 1
for f in factors:
result *= f
print result
Finding the factorial of a number is simple. I'm no python expert, and it could probably be written simpler but,
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
I think #erip may be right in the comment section.
num = int(input("Input a number: "))
factorial = 1
for i in range(2,num+1): # range isn't inclusive
factorial*=i

Categories

Resources