Using while loops and variables - python

I'm trying to write a collatz program from the 'Automate the Boring Stuff with Python book', but have ran into some problems. I'm using python 3.5.2. Here's the project outline:
Write a function named collatz() that has one parameter named number. If number is even, then collatz() should print number // 2 and return this value. If number is odd, then collatz() should print and return 3 * number + 1. Then write a program that lets the user type in an integer and that keeps calling collatz() on that number until the function returns the value 1.
My code:
def collatz(number):
if number % 2 == 0: #its even
print(number // 2)
return number // 2
elif number % 2 == 1: #its odd
print(3*number+1)
return 3*number+1
print('Type an integer: ')
num=int(input())
while(True):
if collatz(num) == 1:
break
# Or even simpler:
# while(collatz(num) != 1):
# pass
The output gives me an infinite loop:
Type an integer:
10
5
5
5
5
5
5
5
5
...
But when I break it down and use a variable to store the return value, it works:
while(True):
num=collatz(num)
if num == 1:
break
Output:
Type an integer:
5
16
8
4
2
1
Why is it? I don't understand why the first program doesn't work. Both are similar but I just chose to test the return value directly in my original program instead of using variables.
I'd appreciate any help, Thanks.

Your code:
while(True):
if collatz(num) == 1:
break
didn't work because everytime collatz gets called it gets called with the same value of num and as a result returns the same number again and again. That number is not 1, so you have an infinite loop.
When you do num = collatz(num), the value of num is changed the first time the function is called. The new value is then passed to the second time the function is called, and so on. So eventually you reach a point when the value of num becomes 1 and exit the loop.

Related

Keep asking for numbers and find the average when user enters -1

number = 0
number_list = []
while number != -1:
number = int(input('Enter a number'))
number_list.append(number)
else:
print(sum(number_list)/ len(number_list))
EDIT: Have found a simpler way to get the average of the list but if for example I enter '2' '3' '4' my program calculates the average to be 2 not 3. Unsure of where it's going wrong! Sorry for the confusion
Trying out your code, I did a bit of simplification and also utilized an if statement to break out of the while loop in order to give a timely average. Following is the snippet of code for your evaluation.
number_list = []
def average(mylist):
return sum(mylist)/len(mylist)
while True:
number = int(input('Enter a number: '))
if number == -1:
break
number_list.append(number)
print(average(number_list));
Some points to note.
Instead of associating the else statement with the while loop, I revised the while loop utilizing the Boolean constant "True" and then tested for the value of "-1" in order to break out of the loop.
In the average function, I renamed the list variable to "mylist" so as to not confuse anyone who might analyze the code as list is a word that has significance in Python.
Finally, the return of the average was added to the end of the function. If a return statement is not included in a function, a value of "None" will be returned by a function, which is most likely why you received the error.
Following was a test run from the terminal.
#Dev:~/Python_Programs/Average$ python3 Average.py
Enter a number: 10
Enter a number: 22
Enter a number: 40
Enter a number: -1
24.0
Give that a try and see if it meets the spirit of your project.
converts the resulting list to Type: None
No, it doesn't. You get a ValueError with int() when it cannot parse what is passed.
You can try-except that. And you can just use while True.
Also, your average function doesn't output anything, but if it did, you need to call it with a parameter, not only print the function object...
ex.
from statistics import fmean
def average(data):
return fmean(data)
number_list = []
while True:
x = input('Enter a number')
try:
val = int(x)
if val == -1:
break
number_list.append(val)
except:
break
print(average(number_list))
edit
my program calculates the average to be 2 not 3
Your calculation includes the -1 appended to the list , so you are running 8 / 4 == 2
You don't need to save all the numbers themselves, just save the sum and count.
You should check if the input is a number before trying to convert it to int
total_sum = 0
count = 0
while True:
number = input("Enter a number: ")
if number == '-1':
break
elif not number.isnumeric() and not (number[0] == "-" and number[1:].isnumeric()):
print("Please enter numbers only")
continue
total_sum += int(number)
count += 1
print(total_sum / count)

Collatz from automate the boring stuff

I know there are multiple posts on this question. But I could not post my code in any other way except by asking a question. Can someone please help me understand how I can stop n from being input into the collatz function each time the global scope executes.
Write a function named collatz() that has one parameter named number.
If number is even, then collatz() should print number // 2 and return this value.
If number is odd, then collatz() should print and return 3 * number + 1.
Then write a program that lets the user type in an integer and that keeps calling collatz() on that number
until the function returns the value 1.
(Amazingly enough, this sequence actually works for any integer—sooner or later, using this sequence,
you’ll arrive at 1! Even mathematicians aren’t sure why.
Your program is exploring what’s called the Collatz sequence, sometimes called “the simplest impossible math problem.”)#
Remember to convert the return value from input() to an integer with the int() function; otherwise, it will be a string value.
desired output
3
10
5
16
8
4
2
1
Input Validation
Add try and except statements to the previous project to detect whether the user types in a noninteger string.
Normally, the int() function will raise a ValueError error if it is passed a noninteger string, as in int('puppy').
In the except clause, print a message to the user saying they must enter an integer.
def collatz(number):
if number%2==0:
number=number//2
print(number)
elif number%2==1:
number=3*number+1
print(number)
print('Enter number: ')
n=int(input())
while n!=1:
collatz(n)
You‘ve created an infinite loop, since your „n“ doesn‘t change within the loop and „n!=1“ is never met as long as the user doesn’t input “1” in the beginning.
Try this:
def collatz(number):
if number % 2 == 0:
number = number // 2
else:
number = 3 * number + 1
print(number)
return number
n = int(input("Enter number: "))
while n != 1:
n = collatz(n)

creating a python program which ask the user for a number - even odd

I am new to python and I am taking a summer online class to learn python.
Unfortunately, our professor doesn't really do much. We had an assignment that wanted us to make a program (python) which asks the user for a number and it determines whether that number is even or odd. The program needs to keep asking the user for the input until the user hit zero. Well, I actually turned in a code that doesn't work and I got a 100% on my assignment. Needless to say our professor is lazy and really doesn't help much. For my own knowledge I want to know the correct way to do this!!! Here is what I have/had. I am so embarrassed because I know if probably very easy!
counter = 1
num = 1
while num != 0:
counter = counter + 1
num=int(input("Enter number:"))
while num % 2 == 0:
print ("Even", num)
else:
print ("Odd", num)
There are a couple of problems with your code:
You never use counter, even though you defined it.
You have an unnecessary nested while loop. If the number the user inputs is even, then you're code will continue to run the while loop forever.
You are incorrectly using the else clause that is available with while loops. See this post for more details.
Here is the corrected code:
while True:
# Get a number from the user.
number = int(input('enter a number: '))
# If the number is zero, then break from the while loop
# so the program can end.
if number == 0:
break
# Test if the number given is even. If so, let the
# user know the number was even.
if number % 2 == 0:
print('The number', number, 'is even')
# Otherwise, we know the number is odd. Let the user know this.
else:
print('The number', number, 'is odd')
Note that I opted above to use an infinite loop, test if the user input is zero inside of the loop, and then break, rather than testing for this condition in the loop head. In my opinion this is cleaner, but both are functionally equivalent.
You already have the part that continues until the user quits with a 0 entry. Inside that loop, all you need is a simple if:
while num != 0:
num=int(input("Enter number:"))
if num % 2 == 0:
print ("Even", num)
else:
print ("Odd", num)
I left out the counter increment; I'm not sure why that's in the program, since you never use it.
Use input() and If its only number specific input you can use int(input()) or use an If/else statement to check
Your code wasn't indented and you need to use if condition with else and not while
counter = 1
num = 1
while num != 0:
counter = counter + 1
num = int(input("Enter number:"))
if num % 2 == 0:
print ("Even", num)
else:
print ("Odd", num)
Sample Run
Enter number:1
Odd 1
Enter number:2
Even 2
Enter number:3
Odd 3
Enter number:4
Even 4
Enter number:5
Odd 5
Enter number:6
Even 6
Enter number:0
Even 0

Collatz sequence ends at 4

I am writing a Collatz sequence program using the practice projects from chapter 3 of Automate the boring stuff with python.
The program outline is:
Write a function named collatz() that has one parameter named number.
If number is even, then collatz() should print number // 2 and return
this value. If number is odd, then collatz() should print and return
3 * number + 1.
Then write a program that lets the user type in an integer and that
keeps calling collatz() on that number until the function returns the
value 1.
My code runs however it stops on 4 rather than 1. For every number I have tried so far the output goes past 1 back to 4.
example output:
6,3,10,5,16,8,4,2,1,4
I am using python 3.4.2
def collatz(number):
if number % 2 == 0:
number = number //2
print(number)
return number
elif number % 2 == 1:
number = 3 * number + 1
print(number)
return number
print ("pick a number:")
while True:
try:
number = int(input())
while number != 1:
number = collatz(number)
collatz(number)
break
except ValueError:
print("Error: Please enter a valid integer")
print("Magic! You are down to 1.")
The problem is that you call collatz() once more after the loop finishes with 1. Just remove that line, and it works fine.
Also if you move the "pick a number" to the input function, you can avoid the new line after the question and are asked again every time, if you input an invalid value.
Additionally you should also check if the number is greater than or equal to 1, to avoid endless loops. The code to do all that would look like that:
while True:
try:
number = int(input("pick a number: "))
if number < 1:
print("Error: Please enter a integer greater than or equal to 1 ")
continue
while number != 1:
number = collatz(number)
# removed the additional call to collatz
break
except ValueError:
print("Error: Please enter a valid integer")
print("Magic! You are down to 1.")
def collatz(number):
number = number // 2 if number % 2 == 0 else 3 * number + 1
print(number)
return number
number = int(input("Pick a Number\n"))
while number != 1:
number = collatz(number)
print("Magic! You are down to 1.")

How to compare inputted numbers without storing them in list

Note: This is not my homework. Python is not taught in my college so i am doing it my myself from MITOCW.
So far i have covered while loop, input & print
Q) Write a program that asks the to input 10 integers, and then prints the largest odd number that was entered. If no odd number was entered it should print a message to the effect
How can i compare those 10 number without storing them in some list or something else? Coz i haven't covered that as if yet.
print "Enter 10 numbers: "
countingnumber=10
while countingnumber<=10:
number=raw_input():
if number % 2 == 0:
print "This is odd"
countingnumber=countingnumber+1
else:
print "This is even. Enter the odd number again"
i think the program will look something like this. But this has some unknown error & How can i compare all the numbers to get the largest odd number without storing those 10 numbers in the list.
print "Enter 10 numbers: "
countingNumber = 1
maxNumber = 0
while countingNumber<=10:
number=int(raw_input())
if (number % 2 == 0):
countingNumber = countingNumber+1
if (maxNumber < number):
maxNumber = number
else:
print "This is even. Enter the odd number again"
print "The max odd number is:", maxNumber
you can just define a maxnum variable and save the max in it! also you must use int(raw_input()) instead raw_input()
print "Enter 10 numbers: "
maxnum=0
for i in range(10):
number=int(raw_input())
if number%2 == 0:
print "This is odd"
if number>maxnum:
maxnum=number
else:
print "This is even. Enter the odd number again"
print "max odd is :{0}".format(maxnum)
DEMO:
Enter 10 numbers:
2
This is odd
4
This is odd
6
This is odd
8
This is odd
12
This is odd
14
This is odd
16
This is odd
100
This is odd
2
This is odd
4
This is odd
max odd is :100
Whenever I do input, I like to make sure I don't leave room for human error giving me bugs.
Because I put in extra checks I break code into a lot of separate function. This also gives code the quality of being non-coupled. ie) You can reuse it in other programs!!
def input_number():
while true:
input = raw_input("Enter Value: ")
if not input.isdigit():
print("Please enter numbers only!")
else:
return int(input)
Designing the input function in this fashion gives the code no opportunity to crash. We can now use it in a function to get odd numbers!
def input_odd_number():
while true:
input = input_number()
if input % 2 == 0:
print("Please enter odd numbers only!")
else:
return input
Now we can finally move onto the main code. We know we need ten numbers so lets make a for loop. We also now we need to hold onto the largest odd number, so lets make a variable to hold that value
def largest_odd(count = 10): // its always nice to make variables dynamic. The default is 10, but you can change it when calling!
max_odd = input_odd_number() // get the first odd number
for i in range(count - 1): // we already found the first one, so we need 1 less
new_odd = input_odd_number()
if new_odd > max_odd:
max_odd = new_odd
print("The largest odd value in '{}' inputs was: {}".format(count, max_odd)
In your solution are multiple flaws.
A syntax error: The colon in number=raw_input():.
raw_input returns a string and you have to cast it to an int.
Your while loop just runs one time, because you start with 10 and compare 10 <= 10. On the next iteration it will be 11 <= 10 and finishes.
Also you have mixed odd an even. even_number % 2 gives 0 and odd_number % 2 gives 1.
To get the biggest value you only need a additional variable to store it (See biggest_number in my solution). Just test if this variable is smaller then the entered.
You ask again if the number is odd, but you should take every number and test only against odd numbers.
A working solution is:
print "Enter 10 numbers"
count = 0
max_numbers = 10
biggest_number = None
while count < max_numbers:
number=int(raw_input("Enter number {0}/{1}: ".format(count + 1, max_numbers)))
if number % 2 == 1:
if biggest_number is None or number > biggest_number:
biggest_number = number
count += 1
if biggest_number is None:
print "You don't entered a odd number"
else:
print "The biggest odd number is {0}".format(biggest_number)
If you wonder what the format is doing after the string take a look in the docs. In short: It replaces {0} with the first statement in format, {1} with the second and so on.
here is the correct code for that:
print "Enter 10 numbers: "
countingnumber=1
MAX=-1
while countingnumber<=10:
number=int(raw_input())
if number%2==1:
if number>MAX:
MAX=number
if MAX==-1:
print "There Weren't Any Odd Numbers"
else:
print MAX
here are some notes about your errors:
1- you should cast the raw input into integer using int() function and the column after calling a function is not needed and therefor a syntax error
2- your while loop only iterates once because you initial counting number is 10 and after one iteration it would be bigger than 10 and the while body will be skipped.
3-an even number is a number that has no reminder when divided by 2 but you wrote it exactly opposite.
4- you don't need to print anything in the while loop, you should either print the biggest odd number or print "There Weren't Any Odd Numbers".
5- an additional variable is needed for saving the maximum odd number which is MAX.
Last note: in the code provided above you can combine the two ifs in the while loop in to one loop using 'and' but since you said you are a beginner I wrote it that way.

Categories