Ending a while loop with a specific input - python

I have attempted to search for similar problems, but have come up short. I'm attempting to get a while loop to stop upon the input 'done'. No matter what I do or how I format it, it either won't stop the loop, or it prints the value I have assigned to 'done'. If I run it without an assignment it throws a 'NameError: name 'done' is not defined'. If I assign a value to it, it won't end the loop. I am not asking for code optimization or help with anything else, but I would truly appreciate it if someone could explain why this is happening.
Counter1 = 0
Counter2 = 0
Counter3 = 0
Counter4 = 0
n = 0
while True: #Begins a loop that runs until manually ended.
n = input("Enter desired scores, and type done when complete: ")
if n == "done": #Closes the loop if given this input.
break
else:
n = int(n) #changes input to an integer
if n >= 0 and n <= 25: #increments the counters depending on the input
Counter1 = Counter1 + 1
elif n > 25 and n <= 50:
Counter2 = Counter2 + 1
elif n > 50 and n <= 75:
Counter3 = Counter3 + 1
else:
Counter4 = Counter4 + 1

You're using Python 2. input immediately tries to convert your input into a Python type, which is dangerous and causes problems like the one you are experiencing. Use raw_input instead.
In other words, when you type "done", input tries to eval* it, comes up with a non-existent variable named "done", and bails out complaining. If you use raw_input instead, it will give you a string, which you can properly cast into a different type as desired, or as in your case, leave it alone since a string is what you want.
* This is about JavaScript but eval appears in many programming languages.

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)

A program that uses while loop to find average of numbers inputted, and uses a break statement to exit the loop

I would like to write a program that uses a while loop to repeatedly prompt the user for numbers and adds the numbers to a running total. When a blank line is entered, the program should print the average of all the numbers entered. I also would like to use a break statement to exit the while loop.
My Incorrect Work:
y = "\n"
total = 0
k = 0
while True:
x = input("Enter your number here: ")
x = float(x)
total = total + float(x)
k = k + 1
if type(x) != int:
print(total/k)
break
Be aware that the function input() will always outputs a string, so type(input()) != int will always be true.
Try using try-except function, when there is ValueError (example unable to convert blank/letters to float), the exception will be raised and break the loop:
total = 0
k = 0
while True:
x = input("Enter your number here: ")
try:
total += float(x)
k += 1
except ValueError:
if k > 0: #to avoid division by zero
print("Average: ", total/k)
break
Output:
Enter your number here: 3
Enter your number here: 4
Enter your number here: 5
Enter your number here:
Average: 4.0
Bearing in mind the comments already made, here is one such way to perform your task and finishing up when a blank entry is encountered.
total = 0.0
k = 0.0
while True:
x = input("Enter your number here: ")
if (x == " "): # Check for a blank line entry here before attempting to convert to float
print("Average is:", (total/k))
break
x = float(x)
total = total + float(x)
k = k + 1
As noted in the comments, one should check for the blank line entry prior to attempting to convert the entry.
You are immediately casting the value of x that is inputted to a float. So,
if type(x) != int
always is true, meaning the loop breaks after one iteration every time.
Others have already solved your problem in different ways, but I think that explaining our thinking might also be useful.
Currently, your program is not checking correclty the exit condition (empty line is entered instead of a number). When a new line is entered, your program should do one of the two possible scenarios:
when an empty line is entered: print result & exit (break)
else (assume a number is entered): add number to total
No third option is specified, so for now, let's assume that every line will either be an empty line or a number. Will expand it later.
After you decided what to do, the actions should just be easily wrapped in a while True: block - so it should be:
initialize_variables_total_and_count
while True:
read_line
decide_what_to_do:
# in case line was a number
convert_line_to_float
add_float_to_total
increment_count
other_case:
# empty line was entered
calculate_and_print
break
With only two options, you only need to decide once what to do. You can swap around the cases by deciding which condition to check for (and that also results in the other being the "default" behavior for other cases).
It's simpler to check for the line being empty with if line_entered == "":. In this case, any non-empty line is treated like a number, and if it were not one, the float() function will error out and your program crashes.
Checking if a string (the entered line) can be converted to a float is a bit harder. There is just no built-in for that in python, but there is a trick: you can try to convert it to a float, and if that works, it was convertible, and if that errors, it was not. There are other ways too, but this is the simplest - see this question on the topic.
In this case, every number will be added to the total, and every non-number (including the empty line, but also random strings like "asdf") will cause the program to calculate the total and stop.
You can avoid putting both cases into an if-else block by using break or continue. (technicly, you never need to use break or continue, all programs can be written without them. In this case, you could have a boolean variable, named run for example, write while run: and instead of break, do run = False). You can use the fact that both break and continue end the loop early to avoid placing the second case inside an else-block and still have the same behavior (as break and continue already causes skipping the rest of the loop body).
So an example implementation: (testing for == "", not using unstructured control flow)
total = 0
count = 0
run = True
while run:
line = input("Enter your number here: ")
if line == "":
print(total / count)
run = False
else:
total += float(line)
count += 1
I also renamed k to count, x to line and used in-place addition operators.
Another implementation, with break, testing for float with try/except (and re-using that for the entire control flow):
total = 0
count = 0
while True:
line = input("Enter your number here: ")
try:
# order matters here. If the first line errors out, the second won't happen so the count will only be inremented if it was indeed a float
total += float(line)
count += 1
except:
print(f"Average is: {total / count}")
break
Here I removed the run variable, and used a format string to print a bit fancier.
And an example using both continue and break:
total = 0
count = 0
while True:
line = input("Enter your number here: ")
if line != "":
total += float(line)
count += 1
continue
print(f"Average is: {total / count}")
break
You can fancy it a bit with adding more error handling - use three cases:
user entered empty line: print & exit
user entered a number: add to total
user entered something else: ignore line, but tell user what to do
I only provide one example implementation for this, but as you can see, it can be implemented in many ways.
total = 0
count = 0
# good practice to tell the user what to do
print("Average calcuator. Enter numbers one per line to calulate average of, enter empty line to print result & exit!")
while True:
line = input("Enter your number here: ")
if line == "":
print(f"Average is: {total / count}")
break
else:
try:
total += float(line)
count += 1
except ValueError:
print("You should enter a number or an empty line to calculate & exit!")

Running into issues with looping the calculation of # of digits in a number

My assignment requires me to take in an input, determine how many digits are in said input, then spit it back out. we are not allowed to use string conversion in order to determine the length of the input. I've managed to get that to work properly. My issue is that I'm supposed to have it repeat in a loop until a sentinel is reached. Here's my code so far.
print("This program determines the number of digits in a number.")
print("Enter a number, or 0 to quit.")
count = 0
num = 1
final = 0
num = int(input("Enter a number: "))
while num != 0:
num = num //10
count += 1
print("There are", count, "digits in", num)
I'm also seeming to have trouble with having my input integer print properly, but it might just be my ignorance there. I've cut out what my attempts at looping it were, as they all seemed to just break the code even more. Any help is welcome, even criticism! Thank you in advance!
Firstly, that is a strange way to get the digits in the number. There's no need to modify the actual number. Just cast the int back to a string and get the length (don't just keep the original string, it could have spaces or something in it which would throw off the count). That is the number of digits.
Secondly, you can do all the work in the loop. There's no need for setup variables, incrementing, a second loop, or anything like that. The key insight is the loop should run forever until you break out of it, so you can just use "while True:" for the loop, and break if the user inputs "0".
print("This program determines the number of digits in a number.")
print("Enter a number, or 0 to quit.")
def find_digits(num):
count = 0
while num != 0:
num = num //10
count += 1
return count
count += 1
# loop forever
while True:
# hang onto the original input
text_input = input("Enter a number: ")
# cast to int - this will throw an exception if the input isn't int-able
# you may want to catch that
num = int(text_input)
# the number of digits is the length of the int as a string
num_digits = find_digits(num)
if num == 0:
print("Goodbye.")
# "break" manually ends the loop
break
# if we got to this point, they didn't input 0 and the input was a number, so
# print our response
print(f"There are {num_digits} digits in {num}.")
The problem with printing the input integer correctly is, that you first save it in the num variable and then constantly change it in your while loop. So the original input is lost of course and in the end it always prints the 0, that ends up in num after the while loop finishes.
You can easily fix it, by saving the input value to another variable, that you don't touch in the loop.
print("This program determines the number of digits in a number.")
print("Enter a number, or 0 to quit.")
count = 0
num = int(input("Enter a number: "))
numcopy = num
while numcopy != 0:
numcopy = numcopy // 10
count += 1
print("There are", count, "digits in", num)
Counting is better done with Python builtin functions.
len(str(num))
will give you number of digits in your number.

Creating a game where the computer guesses a value through inputs of <,> or =

I am trying to create a game where i think of a number in my head. And then the computer guesses the number through me telling it if its guess is too low or high.
This is what I've come up with but i am pretty lost tbh.
maxguess = 100
minguess = 1
count = 0
print("Think of a number between {} and {}".format(minguess,maxguess))
def midpoint(maxguess, minguess) :
z = ((maxguess + minguess)/2)
def guessing(x) :
print("Is you number greater (>) , equal (=) ,or less (<) than" ,z,)
print("please answer <,=, or >! >")
x = input()
if x == (">") :
minpoint = z
count += 1
continue
elif x == ("<") :
maxpoint = z
count += 1
continue
elif x == ("=") :
print ("I have guessed it!")
count += 1
break
print("I needed {} steps!".format(count))
Purposely not a complete solution, but some hints for you:
I'd recommend avoiding the global variables like count, maxguess, and minguess. Instead, make a function that holds all these variables.
Change your midpoint function to return z instead, then call it inside your guessing function.
Your continue and break functions would need to be inside a for or while loop. Since you aren't sure how many iterations you need to guess the number, I think a while loop would make sense here
Your functions are never run. On a style point, bring all your 'main' statements down to the bottom so they're together. After the prompt to think of a number, you need to call the guessing() function. When you call it, you should pass the minguess and maxguess values to it.
I can see what you're trying to do with the if...elif statements, but they need to be in a while True: block. So should the three statements preceding them so the script repeatedly asks for new advice from you.
Either bring the content of the midpoint() function into guessing() or make it return the value of z.
You also offer the user a choice of '>1' but don't handle it - and you don't need it as far as I can tell.
You never use minpoint or maxpoint - and you dont need them. Call the midpoint function instead and pass it the appropriate values, e.g., if '>', z = midpoint(z, maxguess).
Also, you're going to spend forever trying to get it to guess as you are using floats. Make sure everything is an integer.
Finally, you should add some code to manage input that isn't expected, i.e., not '<', '>' or '='.
Good luck!
minguess=1
maxguess=100
z=50
count=0
print("Think of a number between 1 and 100")
condition = True
while condition:
z=((maxguess + minguess)//2)
print("Is your number greater (>) , equal (=) ,or less (<) than" ,z,)
print("Please answer <,=, or >! >")
x = input()
if x == (">"):
minguess=z
count += 1
elif x == ("<") :
maxguess=z
count += 1
elif x == ("=") :
print ("I have guessed it!")
count += 1
condition=False

How can I improve this loop?

Once again, i'm still getting the hang of python. I made a program that has the user guess a 'magic number', randomly generated by the computer. After 5 incorrect tries, it provides a hint in the form of an addition problem using two randomly generated variables whose sum is equal to the magic number.
This is the code:
def moot():
count = 0
# magicNumber is the randomly generated number from 1 to 100 that must be guessed
magicNumber = random.randint(1,100)
var1 = 0
var2 = 0
guess = eval(input('Enter a number: '))
# This loop sets random values for var1 and var2 that sum up to the magicNumber
while var1 + var2 != var:
var2 = random.randint(1,100)
var3 = random.randint(1,100)
# an addition problem is made from var1 and var2 to be used as a hint later
hint = 'Try adding '+ str(var1)+ ' and '+ str(var2)+'\n'
# withinRange checks to see if the users guess is (valid) within the range of 1 to 100
# if not, asks for another number until a valid one is provided
withinRange = True if (guess <= 100 and guess >= 1) else False
while not withinRange:
count = count + 1
guess = eval(input('Number is invalid.Enter a number between 1 and 100: '))
withinRange = True if (guess <= 100 and guess >= 1) else False
# rng tells the user if his guess is too high or low
rng = 'low' if guess < magicNumber else 'high'
# the following loop repeatedly asks for input until the user enteres the majicNumber
while magicNumber != guess:
count = count + 1
print('\nThats incorrect. Your number is too',rng,end='\n')
# after 5 incorrect guesses the program prints out the addition problem that
# was made using var1 and var2
if count > 5:
print(hint)
guess = eval(input('Guess: '))
withinRange = True if (guess <= 100 and guess >= 1) else False
while not withinRange:
count = count + 1
guess = eval(input('Nope, has to be between 1 and 100. Try again: '))
withinRange = True if (guess <= 100 and guess >= 1) else False
rng = 'low' if guess < magicNumber else 'high'
print('\nYou entered the right number!')
print('Number:',magicNumber)
print('range of last guess was too',rng)
print('Number of guesses:',count + 1)
Last time, I was told that I didn't provide enough information about my program. And I hope I didn't over do it with the comments. This is my goal/question/inquiry/objective: I want to add some line of code into the program to have it terminate after 7 tries.
What the program does now is accept guesses over and over until the right one is reached. But I want to add some code that kills it after the 'count' variable reaches 6. The count variable goes up each time a guess is entered. Regardless of whether it is correct or not.
Any suggestion would be awesomely appreciated, Thanks in advance wizards!
There are a lot of problems with the code.
Please don't use eval() to convert a string to an integer. int() does this without the security risks of eval.
In your while loop you compare var1 and var2 with var. What is var? You didn't define it anywhere. I guess you meant magicNumber. Then in the loop you set var2 and var3. Why var3. You don't use it. And least, the best way to get the two numbers for the addition would be to get one number with the maximum of magicNumber and just calculate the second number.
True if (guess <= 100 and guess >= 1) else False could be written as
True if 1 <= guess <= 100 else False
Get rid of the duplicate code in the loop and outside of the loop. You might want to add other functions e.g. a function just for getting the input from the user and to do some basic checks.

Categories