i have to write a hailstone program in python
you pick a number, if it's even then half it, and if it's odd then multiply it by 3 and add 1 to it. it says to continue this pattern until the number becomes 1.
the program will need methods for the following:
accepting user input
when printing the sequence, the program should loop until the number 1.
print a count for the number of times the loop had to run to make the sequence.
here's a sample run:
prompt (input)
Enter a positive integer (1-1000). To quit, enter -1: 20
20 10 5 16 8 4 2 1
The loop executed 8 times.
Enter a positive integer (1-1000). To quit, enter -1: 30
30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
The loop executed 19 times.
Enter a positive integer (1-1000). To quit, enter -1: -1
Thank you for playing Hailstone.
right now i have this:
count = 0
def hailstone(n):
if n > 0
print(n)
if n > 1:
if n % 2 == 0:
hailstone(n / 2)
else:
hailstone((n * 3) + 1)
count = count + 1
i don't know what to do after this
Try to think in a modular way, make two functions: check_number() and user_call(). Check_number will verify if the current number in the loop is odd or even and the user_call() just wraps it to count how many times the loop did iterate.
I found the exercise in a great book called Automate Boring Stuff with Python, you have to check it out, if you don't know it already.
Here's my code. Try to use what serves you the best.
from sys import exit
def check_number(number):
if number % 2 ==0:
print(number // 2)
return(number // 2)
else:
print(number*3+1)
return number*3+1
def user_call(number):
count = 0
while number != 1:
count += 1
number = check_number(number)
return count
if __name__ == "__main__":
try:
number = int(input('Give a number \n'))
count = user_call(number)
print('count ',count)
except Exception as e:
exit()
you can use global
visit https://www.programiz.com/python-programming/global-keyword to learn more
import sys
res = []
def hailstone(number):
global res
if number > 1:
if number % 2 == 0:
res.append( number // 2 )
hailstone(res[len(res)-1])
else:
res.append(number * 3 + 1)
hailstone(res[len(res)-1])
return res
number = int(input('Enter a positive integer. To quit, enter -1: '))
if number <= 0 or number == 0:
print('Thank you for playing Hailstone.')
sys.exit()
else:
answers = hailstone(number)
for answer in answers:
print(answer)
print('The loop executed {} times.'.format(len(answers) + 1))
I used recursion to solve the problem.
Heres my code:
Edit: All criteria met
count = 0
list_num = []
def input_check():
number = int(input("Enter a positive integer (1-1000). To quit, enter -1: "))
if number >= 1 and number <= 1000:
hailstone_game(number)
elif number == -1:
return
else:
print("Please type in a number between 1-1000")
input_check()
def hailstone_game(number):
global count
while number != 1:
count += 1
list_num.append(number)
if number % 2 == 0:
return hailstone_game(int(number/2))
else:
return hailstone_game(int(number*3+1))
list_num.append(1) # cheap uncreative way to add the one
print(*list_num, sep=" ")
print(f"The loop executed {count} times.")
return
input_check()
Additional stuff that could be done:
- Catching non-integer inputs using try / except
Keep in mind when programming it is a good habit to keep different functions of your code separate, by defining functions for each set of 'commands'. This leads to more readable and easier to maintain code. Of course in this situation it doesn't matter as the code is short.
Your recursive function is missing a base/terminating condition so it goes into an infinite loop.
resultArray = [] #list
def hailstone(n):
if n <= 0: # Base Condition
return
if n > 0:
resultArray.append(n)
if n > 1:
if n % 2 == 0:
hailstone(int(n/2))
else:
hailstone((n * 3) + 1)
# function call
hailstone(20)
print(len(resultArray), resultArray)
Output
8 [20, 10, 5, 16, 8, 4, 2, 1]
Here's a recursive approach for the problem.
count=0
def hailstone(n):
global count
count+=1
if n==1:
print(n)
else:
if n%2==0:
print(n)
hailstone(int(n/2))
else:
print(n)
hailstone(3*n+1)
hailstone(21)
print(f"Loop executed {count} times")
Related
experts.
I'm trying to define a function (collatz) that:
Asks for a number. If it is even it prints number // 2, if it odd it prints 3 * number + 1. (OK)
The result, whatever it is, must enter a loop until the result is 1. (NOK)
So, i´m not figure out because the result is not used and is in an infinite loop. Any suggestion?
def collatz():
number = int(input('Enter the number: '))
x = number % 2
while number != 1:
if x == 0:
print(f'{number // 2}')
else:
print(f'{3 * number + 1}')
number = number
print(f'{collatz()}')
You need to actually assign the result back to number.
As well:
The divisibility check needs to be in the loop.
The outer print() is not needed.
The f-strings are redundant. print() converts its arguments to string automatically.
def collatz():
number = int(input('Enter the number: '))
while number != 1:
if number % 2 == 0:
number //= 2 # Short for "number = number // 2"
else:
number = 3*number + 1
print(number)
collatz()
Example run:
Enter the number: 3
10
5
16
8
4
2
1
is there a way to keep the counter going without counting the negatives and only to stop when the input is zero?
count = 0
total = 0
n = input()
while n != '0':
count = count + 1
total = total + int(n) ** 2
n = input()
print(total)
Here is an example of execution result.
Input: -1 10 8 4 2 0
Output: 184
Since you want only number to enter the loop you can use isnumeric() built in function to check that.
You need if() : break here.
num = input()
...
while(isnumeric(num)):
...
if(num == "0"):
break;
The response you wait for is:
ignore negative number
count positive numbers
stop when input is 0
count = 0
total = 0
n = int(input())
while (n != 0):
count += 1
if (n > 0):
total = total + n**2
num = int(input())
print(total)
Your code was already OK except that you did not cast the number n into int and you did not test n to take away negative values.
Execution:
When you enter -1 10 8 4 2 0, it should show 184
You can parse your Input to an integer (number) and check if it's larger than zero:
count = 0
total = 0
num = int(input())
while number != 0:
if number < 0:
continue
count += 1
total = total + num**2
num = int(input())
print(total)
The difference between pass, continue, break and return are:
pass = ignore me an just go on, usefull when you create a function that has no purpose yet
continue = ignore everything else in the loop and start a new loop
break = break the loop
return = end of a function - a return statement can be used to give an output to a function but also as a way to break out of the function like the break statement does in loops.
My task is to:
"Write a program that will keep asking the user for some numbers.
If the user hits enter/return without typing anything, the program stops and prints the average of all the numbers that were given. The average should be given to 2 decimal places.
If at any point a 0 is entered, that should not be included in the calculation of the average"
I've been trying for a while, but I can't figure out how to make the programs act on anything I instruct when the user hits 'enter' or for it to ignore the 0.
This is my current code:
count = 0
sum = 0
number = 1
while number >= 0:
number = int(input())
if number == '\n':
print ('hey')
break
if number > 0:
sum = sum + number
count= count + 1
elif number == 0:
count= count + 1
number += 1
avg = str((sum/count))
print('Average is {:.2f}'.format(avg))
You're very close! Almost all of it is perfect!
Here is some more pythonic code, that works.
I've put comments explaining changes:
count = 0
sum = 0
# no longer need to say number = 1
while True: # no need to check for input number >= 0 here
number = input()
if number = '': # user just hit enter key, input left blank
print('hey')
break
if number != 0:
sum += int(number) # same as sum = sum + number
count += 1 # same as count = count + 1
# if number is 0, we don't do anything!
print(f'Average is {count/sum:.2f}') # same as '... {:.2f} ...'.format(count/sum)
Why your code didn't work:
When a user just presses enter instead of typing a number, the input() function doesn't return '\n', rather it returns ''.
I really hope this helps you learn!
Try this:
amount = 0 # Number of non-zero numbers input
nums = 0 # Sum of numbers input
while True:
number = input()
if not number: # Breaks out if nothing is entered
break
if int(number) != 0: # Only add to the variables if the number input is not 0
nums+=int(number)
amount += 1
print(round(nums/amount,2)) # Print out the average rounded to 2 digits
Input:
1
2
3
4
Output:
2.5
Or you can use numpy:
import numpy as np
n = []
while True:
number = input()
if not number: # Breaks out if nothing is entered
break
if int(number) != 0: # Only add to the variables if the number input is not 0
n.append(int(number))
print(round(np.average(n),2)) # Print out the average rounded to 2 digits
A list can store information of the values, number of values and the order of the values.
Try this:
numbers = []
while True:
num = input('Enter number:')
if num == '':
print('Average is', round(sum(numbers)/len(numbers), 2)) # print
numbers = [] # reset
if num != '0' and num != '': numbers.append(int(num)) # add to list
Benefit of this code, it does not break out and runs continuously.
Beginner question here.
I have just attempted an exercise from Automate the boring stuff. I've completed the question in the format suggested by first defining a function as below:
"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."
and then using that same function, meeting those minimal constraints, to write a programme that meets the following requirements:
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.
I've managed to generate a sequence of numbers ending with one, following the above rules, but my program prints each number in the sequence three times. Is anyone able to explain why this might be?
Thanks so much for your help
def collatz(number):
if int(number) % 2 == 0:
print(int(number)//2)
return int(number)//2
else:
print(3 * int(number) + 1)
return 3 * int(number) + 1
collatz(5)
print('Enter a number')
entry = input()
while collatz(entry) != 1:
collatz(entry)
entry = collatz(entry)
Your loop should look like this:
entry = input()
while entry != 1:
entry = collatz(entry)
You are calling the function 3 times and you have a print call in the function.
Only call the function once and I would remove the print statements from the collatz method and just print in the calling loop, e.g.:
In []:
def collatz(number):
if number % 2 == 0:
return number//2
return 3*number + 1
entry = int(input("Enter a number: "))
print(entry)
while entry != 1:
entry = collatz(entry)
print(entry)
Out[]:
Enter a number: 10
10
5
16
8
4
2
1
You can try:
def collatz(number):
if number == 0:
return 'Try again with an integer other than 0'
elif number == 1:
return 1
elif number % 2 == 0:
n = number // 2
print(n)
elif number % 2 == 1:
n = 3 * number + 1
print(n)
while n != 1:
n = collatz(n)
return n
return n
The last statement return n in line 15 is optional.
I've started the book "Automate The Boring Stuff" by Al Sweigart.
At the end of Chapter 3, the author suggests creating a Collatz Sequence in Python as a practice exercise. (the practice exercise suggests I use a the print function and return statement)
When I use a print() function in my code, it works great and I get all the evaluated values I want to see on the screen:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
print(n)
else:
n = n * 3 + 1
print(n)
collatz(user)
Question:
How come when I want to use the return statement, the while loop only runs once?
For example, passing the integer 3 into my function with the return statement only gives me the return value of 3 and 10:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
return n
else:
n = n * 3 + 1
return n
result = collatz(user)
print(result)
return exits the function and, therefore terminates your while loop.
Perhaps you meant to use yield instead:
print("This is The Collatz Sequence")
user = int(input("Enter a number: "))
def collatz(n):
print(n)
while n != 1:
if n % 2 == 0:
n = n // 2
yield(n)
else:
n = n * 3 + 1
yield(n)
print(list(collatz(user)))
Output:
This is The Collatz Sequence
Enter a number: 3
3
[10, 5, 16, 8, 4, 2, 1]
Yield is logically similar to a return but the function is not terminated until a defined return or the end of the function is reached. When the yield statement is executed, the generator function is suspended and the value of the yield expression is returned to the caller. Once the caller finishes (and assumably uses the value that was sent) execution returns to the generator function right after the yield statement.
In your code you don't re-feed the new value back into your equation. Try separating your while loop from the collatz module. I have an example of this below:
def collatz(number):
if number % 2 == 0:
return number // 2
elif number % 2 == 1:
return 3 * number + 1
chosenInt = int(input('Enter an integer greater than 1: '))
print(chosenInt)
while chosenInt != 1:
chosenInt = collatz(chosenInt)
print(chosenInt)
def collatz(number):
if (number%2 == 0):
return print(number//2);
else:
return (print(number*3+1));
inputNumber = input("Enter a number greater than 1:");
result = collatz(int(inputNumber));
while result != 1:
result = collatz(result);
I am getting a typeError with it! Don't know why?