How can I improve this loop? - python

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.

Related

Number guessing game will not print the right phrase

I am extremely new to python and this is one of the first things I have tried. There are 3 criteria that I want this game to meet. First is to use the number 0-10 and guess the number 3 which it does correctly. Next is 0-25 when 11 is chosen. This also works correctly.
However this last part has been giving me trouble. When picking from 0-50, it should guess 1 which it does. It should also print the "I'm out of guesses" line when another input is placed as it cannot go higher than one now. What am I doing wrong here?
import random
import math
smaller = int(input("Enter the smaller number: "))
larger = int(input("Enter the larger number: "))
maxTry = math.log(larger - smaller)
count = 0
guess = int((smaller+larger)/2)
while count != maxTry:
count += 1
guess = int((smaller+larger)/2)
print("Your number is ", guess)
help = input("Enter =, <, or >: ")
if help == ">":
smaller = guess +1
elif help == "<":
larger = guess -1
elif help == "=":
print("Hooray, I've got it in", count, "tries")
break
elif count == maxTry:
print("I'm out of guesses, and you cheated")
break
Your maxTry is a log so it is not an integer, therefore it can never be equal to count.
You can either use an int for maxTry (cast it to int maxTry = int(math.log(larger - smaller))) or compute it with something different than log that will return an int.
Alternatively, your condition could be count > maxTry instead of equal. It would actually be a bit better conceptually.
Note: you should not use capital letters in variable names in python but all lowercase with _ max_try. It is only a convention though so won't affect your program directly. You can find more info on conventions in the PEP8 documentation

Unexpected outcomes in if and elif statements

I created a number guessing game and its code is as follows but the problem is that when I input the number which is warm (look at the code)(for eg 70) and then the warmer number(say 69) and then finally the secret number(i.e. 65) instead of showing 'you won!!:)' it again asks the user to input value but if I directly input the secret number or input the secret number followed in any manner accept this one it works fine. I'm new to python so please help in as easy manner as possible.
guesses = 0
number = 65
while guesses < 30:
guess = int(input())
close = abs(number - guess)
if guess == number:
print("You won!!:)")
break
elif close < 10:
print("Warm")
guesses += 1
guess = int(input())
if abs(guess - number) < close:
print("Warmer")
guess = int(input())
guesses += 1
elif close > 10:
print("Cold")
guesses +=1
if abs(guess - number) < close:
print("Colder")
guesses += 1
Remove the guess = int(input()) from under the if abs(guess-number) < close:. The problem was that after input() is called there, it is called again at the beginning of the loop on its way to be checked for equality.
guesses = 0
number = 65
while guesses<30:
guess = int(input())
close = abs(number - guess)
if guess == number:
print("You won!!:)")
break
elif close<10:
print("Warm")
guesses += 1
guess = int(input())
if abs(guess-number) < close:
print("Warmer")
guesses += 1
elif close>10:
print("Cold")
guesses +=1
guess = int(input())
if abs(guess-number)<close:
print("Colder")
guesses += 1
It's like that because you ask for a number after print("Warmer") and you do nothing with this guess - you do not check if it's correct or not. The iteration of loop finishes and it starts again asking for a new guess.
Remove guess = int(input()) from
print("Warmer")
guess = int(input())
guesses += 1
and it should work just fine.
remove guess = int(input()) . on line number #15
it's a repeated call for input, because you are calling it on line number #4 which makes it ask for input than give you the result.
The others have pointed out the cause for your specific problem.
I would like to recommend that you should try to avoid code duplication in general. Besides calling input() multiple times, you also increment guesses at multiple places.
This is so important, it has a cool acronym: DRY, which stands for "Don't Repeat Yourself".
Code duplication causes your code to be harder to maintain, because you have to apply the same change in multiple places. DRY code, on the other hand, is usually more readable and easier to maintain.
Think about how to rewrite your code to reduce code duplication.

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

Why Does my loop not work after the third time

This is my code, The computer is supposed to guess a number between 1 and 100. The computer's guesses should either decrease or increase by half of the previous guess. The third time through the loop going only higher it breaks, or if I use higher after saying lower it breaks. Both ways, it will stop adding its guesses and divide the previous guess by two, instead of adding the previous guess divided by two to the previous guess. i.e instead of 50 + (50/2) = 75 my code does 50/2 = 25. So where it breaks on higher is at 87, instead of adding half of the previous guess, which would be six, it divides 87 by 2 equaling 43. (I have now edited this question, and the code and everything should work besides where I need help. Thank you)
pcguess = 50
useranswer = 50
print("Wanna see a magic trick?")
print("Please think of a random number between 1 and 100.")
print("Now that you have written down your number")
print("I will guess it in ten guesses or less.")
a = print("My first guess is", pcguess)
tries = 0
while tries < 100000:
newguess = pcguess//2
b = input("Was that your number?")
if b == "no":
tries += 1
c = input("Is your number higher or lower than my guess?")
if c == "lower":
print("Then my next guess is:")
print(useranswer - newguess )
useranswer = pcguess - newguess
pcguess = newguess
tries += 1
elif c == "higher":
print("Then my next guess is:")
print(useranswer + newguess)
useranswer = pcguess + newguess
pcguess = newguess
tries += 1
if b == "yes":
print("I got it in", tries, "tries!")
break
You need to narrow down the possible range of numbers based on the user's "higher"/"lower" responses. So you should store the lower and upper bounds as variables, and adjust them as you get responses. Something like this:
lower = 0
upper = 100
while lower < upper:
guess = (lower+upper)//2
print("My guess is ", guess)
# Find out if the correct answer is higher or lower than this guess
if the correct answer is higher:
lower = guess + 1 # This gives a new lower bound
if the correct answer is lower:
upper = guess - 1 # This gives a new upper bound
The first thing I would change in your code is your where you increment your tries variable. In your current while loop, you are incrementing once every time you execute your while loop and then again after whichever if statement gets executed. This means that every iteration, your number of tries goes up by 2 instead of 1. So why don't you just increment tries once at the beginning of your loop instead?
Second, the reason your useranswer variable doesn't become what you expect is simply because you are updating it wrong. For example
if c == "lower":
print("Then my next guess is:")
print(useranswer - newguess )
useranswer = pcguess - newguess # WRONG
pcguess = newguess
since you are updating useranswer, it should be useranswer = useranswer + newguess or more succinctly useranswer += newguess
Do this for the other if statement as well (where your guess is higher than what the computer is guessing)
Thirdly. This is more a matter of styling but your while loop condition should be more accurate (i.e. since you are telling the user that you will guess their number in 10 tries or less, does your loop condition really need to have tries < 100000?

Ending a while loop with a specific input

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.

Categories