Function and loop debugging [duplicate] - python

This question already has answers here:
Loop until a specific user input is received in Python [duplicate]
(3 answers)
Closed 4 years ago.
This is code I wrote, it runs perfectly and so does the function this code is from except for one part, when it comes to the part where I ask the user if they want to try again, if they select no then it stops which is what is suppose to happen. On the other hand, if they say yes ‘y’ they will get another exact same prompt 'Would you like to try again? (y/n) '. You can say y 100 times and nothing will happen, my goal is for the code to go back and call the function from the start. I have tried a break if the user says ‘y’ to try and get out of the loop etc but it did not work and I now have no idea…
Additionally, as you can see, I have correct digits which compares to see if the user guessed number is in the generated list, that part I have no problem with. Now with the correct locations, I am not sure how to do that, the goal is to check is both the number and location is the name in both lists.
import random
play = True
turnsleft = 1
#this is a function that is in charge of generating a random password
def generatePassword():
generatePassword = [] #create an empty list
for i in range(1,6):
generatePassword.append(random.randint(1,9))
return generatePassword
'''this is a function that prompts the userfor their guess
the input will be comprimised of 5 different variables to store
the different numbers which will then all be added to the list of user number'''
def getUserGuess():
getUserGuess = [] #create an empty list
v1,v2,v3,v4,v5 = input("Please take a guess of the password by entering 5 numbers(comma between each): ").split(",")
v1,v2,v3,v4,v5 = int(v1), int(v2), int(v3), int(v4), int(v5)
for i in(v1,v2,v3,v4,v5):
getUserGuess.append(i)
return getUserGuess
#this function will compare the cpu generated password to the user inputed numbers list
def reportResult(generatePassword,getUserGuess):
correctdigits = 0
correctlocations = 0
global turnsleft #use the play variable initiated outside the funtion
global play #use the play variable initiated outside the funtion
while play is True:
if getUserGuess == generatePassword:
print("Congradulations! You have guessed the right password.")
elif turnsleft == 0:
print("You will never guess my password! It was " +str(generatePassword()))
playagain = input("Would you like to play again? (y/n) ")
if playagain == 'n':
play = False
else:
turnsleft-= 1
for e in getUserGuess():
if e in generatePassword():
correctdigits+= 1
for e in getUserGuess():
if e in generatePassword():
correctlocations+= 1
print(str(turnsleft) +" guesses left.")
print(str(correctdigits) +" of 5 correct digits.")
print(str(correctlocations) +" of 5 correct locations.")
return reportResult
while play is True:
reportResult(generatePassword,getUserGuess)

I believe you simply need to set 'turnsleft' to some value greater than 0 in when 'turnsleft' is 0.
For example:
elif turnsleft == 0:
print("You will never guess my password! It was " +str(generatePassword()))
turnsleft = 2 #<-- Reset turns here!
playagain = input("Would you like to play again? (y/n) ")
if playagain == 'n':
play = False
This will allow you to 'start a new game' with the turns set to some value. But it also introduces new problems. Perhaps you should write a resetGame() that will edit all the variables it needs to to truly start from scratch.

Related

How to display an integer many times

I'd like to create a function that add 2 to an integer as much as we want. It would look like that:
>>> n = 3
>>> add_two(n)
Would you like to add a two to n ? Yes
The new n is 5
Would you like to add a two to n ? Yes
the new n is 7
Would you like to add a two to n ? No
Can anyone help me please ? I don't how I can print the sentence without recalling the function.
The idea is to use a while loop within your function that continues to add two each time you tell it to. Otherwise, it exits.
Given that knowledge, I'd suggest trying it yourself first but I'll provide a solution below that you can compare yours against.
That solution could be as simple as:
while input("Would you like to add a two to n ?") == "Yes":
n += 2
print(f"the new n is {n}")
But, since I rarely miss an opportunity to improve on code, I'll provide a more sophisticated solution as well, with the following differences:
It prints the starting number before anything else;
It allows an arbitrary number to be added, defaulting to two if none provided;
The output text is slightly more human-friendly;
It requires a yes or no answer (actually anything starting with upper or lower-case y or n will do, everything else is ignored and the question is re-asked).
def add_two(number, delta = 2):
print(f"The initial number is {number}")
# Loop forever, relying on break to finish adding.
while True:
# Ensure responses are yes or no only (first letter, any case).
response = ""
while response not in ["y", "n"]:
response = input(f"Would you like to add {delta} to the number? ")[:1].lower()
# Finish up if 'no' selected.
if response == "n":
break
# Otherwise, add value, print it, and continue.
number += delta
print(f"The new number is {number}")
# Incredibly basic/deficient test harness :-)
add_two(2)
You can use looping in your add_two() function. So, your function can print the sentence without recalling the function.
The above answer describes in detail what to do and why, if you're looking for very simple beginner-type code that covers your requirements, try this:
n = 3
while True:
inp = input("Would you like to add 2 to n? Enter 'yes'/'no'. To exit, type 'end' ")
if inp == "yes":
n = n + 2
elif inp == "no":
None
elif inp == "end": # if the user wants to exit the loop
break
else:
print("Error in input") # simple input error handling
print("The new n is: ", n)
You can wrap it in a function. The function breaks once the yes condition is not met
def addd(n):
while n:
inp = input('would like to add 2 to n:' )
if inp.lower() == 'yes':
n = n + 2
print(f'The new n is {n}')
else:
return
addd(10)

Validating User Input in Python [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 3 years ago.
"""
GuessNumber.py - This program allows a user to guess a number
between 1 and 10.
Input: User guesses numbers until they get it right.
Output: Tells users if they are right or wrong.
"""
import random
number = random.randint(1, 10)
# Prime the loop.
keepGoing = input("Do you want to guess a number? Enter Y or N ")
# Validate input.
# Enter loop if they want to play.
while keepGoing == "Y":
# Get user's guess.
stringNumber = input("I'm thinking of a number. .\n Try to guess by entering a number between 1 and 10 ")
userNumber = int(stringNumber)
# Validate input.
# Test to see if the user guessed correctly.
if userNumber == number:
keepGoing = "N"
print("You are a genius. That's correct!")
else:
keepGoing = input("That's not correct. Do you want to guess again? Enter Y or N ")
# Validate input.
If the user guesses correctly, the program congratulates the user, and then the loop that controls guessing numbers exits; otherwise the program asks the user if he or she wants to guess again. If the user enters "Y", he or she can guess again. If the user enters "N", the loop exits. You can see that the "Y" or "N" is the sentinel value that controls the loop. I need to ass a code that validates "y" and "n"
keepGoing.upper() == "Y" would check lower and upper case inputs.
You shouldn't need to validate N/n
import random
number=random.randint(1,10)
keepGoing=raw_input("DO you want to guess a number:\n ")
keepGoing=keepGoing[0].upper()
while keepGoing=='Y':
stringNumber=int(raw_input("I'm thinking of a number. .\n Try to guess by entering a number between 1 and 10:\n "))
if (stringNumber==number):
print("You are a genius. That's correct!")
break
else:
keepGoing=raw_input("DO you want to guess a number")
keepGoing=keepGoing[0].upper()

How do I have python run (if statements) based on the users input.?

I am not doing anything particularly complicated I am simply messing with import random and having the user type roll to roll a six sided die. I have gotten this far.
import random
roll = random.randint(1,6)
input("Type roll to roll the dice!\n")
# This is where I have my issue pass this line I'm trying things out, unsuccessfully.
if (userInput) == (roll)
print("\n" + str(roll))
else:
input("\nPress enter to exit.")
I don't want the program to print the str(roll) if the use presses enter, I'd rather it exit the program if no input is given. So how do I write the code to do particular thing based of user input when using the if statement. If user input is 'roll" then print("str(roll))?
You need to capture the user input in a variable. Currently, the return value of input(…) is being thrown away. Instead, store it in userInput:
userInput = input("Type roll to roll the dice!\n")
The if requires a colon at the end in order to start the block:
if someCondition:
# ^
If you want to compare the user input against the string 'roll', then you need to specify that as a string, and not as a (non-existent) variable:
if userInput == 'roll':
You also don’t need parentheses around the values
In order to check for just an enter press, check against the empty string:
elif userInput == '':
print('User pressed enter without entering stuff')
You should roll inside the condition, not before, so you don’t generate a random number although it’s not requested.
So in total, it could look like this:
import random
userInput = input('Type roll to roll the dice!\n')
if userInput == 'roll':
roll = random.randint(1,6)
print('You rolled: ', roll)
elif userInput == '':
print('Exit')

Python: while (True != True) loop

I started learning to code this week so I'm playing around with small programs that I'm creating to try to get a better understanding of how it work.
One of the programs I made is a Pig Latin translator that loops until the user exits. The program works but the logic isn't making any sense to me.
pyg = "ay" #Pig Latin words end with ay.
def translate(): #Creating a function.
original = input("Enter a word: ").lower() #Ask for input then convert to lower.
if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
first = original[0] #Assigns the first letter of the string to first.
latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
print(latin)
else:
print("You did not enter a valid word, please try again.")
translate() #If you did not enter valid word, then call function again until you do.
translate() #Don't forget to actually call the function after you define it.
#Set run to False.
#Can be set to True if while (run != True) is set to while (run == True).
run = False
#Defining cont(). Ask for imput and error handling.
def cont():
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
run = True
elif loop == "n" :
run = False
print("Thank you for using this program, have a nice day!")
exit()
else :
print("You did not enter a valid response, please try again.")
cont()
cont()
#Infinite loop as long as run is not equal to True.
while (run != True) :
translate()
cont()
My question is, why does this program work? I set run to False and I set the loop to run as long as run != True. No problem there, however when I defined cont(), I set run to take on the value True if the user inputs "y". True != True should be False (if I understand correctly) and the loop should end, but instead it is working as I wanted it to.
Is this a coding mistake that I've made or am I just thinking about this the wrong way? Thank you in advance.
Edit: Thank you very much to everyone that answered. I hadn't learned about local and global variables yet.
To expand on what others have already stated, run on these lines
if loop == "y" :
run = True
elif loop == "n" :
run = False
are not referring to the same run defined by
#Can be set to True if while (run != True) is set to while (run == True).
run = False
run in the cont function is a local variable to your function, not the globaly defined run.
There are a couple (at least) ways to fix this. The preferred (imo) way to do it is have cont return a new value to be assigned to run. That would look like
#Defining cont(). Ask for imput and error handling.
def cont(_run):
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
return _run
elif loop == "n" :
return not _run
else :
print("You did not enter a valid response, please try again.")
return cont(_run)
...
#Infinite loop as long as run is not equal to True.
while (run != True) :
translate()
run = cont(run)
The other (less preferred) way would be to use the global run variable inside of your cont function. This is achieved using the global keyword.
That would look like this:
#Defining cont(). Ask for imput and error handling.
def cont():
global run
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
run = True
elif loop == "n" :
run = False
print("Thank you for using this program, have a nice day!")
exit()
else :
print("You did not enter a valid response, please try again.")
cont()
** Couple side notes
In my first example I return _run when the value is y and not _run when the value is n. This allows you to change you initial run value to be True, and change the while condition without having to change the cont function itself.
You don't need to actually change the run value at all if you use the global and the user enters n since you exit before the function returns.
You might be better off changing your if conditional checks to
if loop in ("yes", "y"):
if loop in ("no", "n"):
since lots of people don't read full instructions :)
The run inside the cont function is a local variable. Changing its value has no effect on the global variable that the while loop refers to.
I think this is probably because of the scope of your run variable; because you're not returning run from your cont function. I believe what your != True check sees is always going to be False outside of that function, though obviously you can successfully end the program within the function.
The problem is that the run variable defined in cont() is not the same as the run variable defined in the global scope. (If you aren't sure what I mean by that you might want to look at https://docs.python.org/3.4/tutorial/classes.html#python-scopes-and-namespaces. Perhaps a better approach for your code would be to have cont() return True or False. It is also more intuitive and readable to use True for when you want to continue. Here's how I would rewrite it.
pyg = "ay" #Pig Latin words end with ay.
def translate(): #Creating a function.
original = input("Enter a word: ").lower() #Ask for input then convert to lower.
if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
first = original[0] #Assigns the first letter of the string to first.
latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
print(latin)
else:
print("You did not enter a valid word, please try again.")
translate() #If you did not enter valid word, then call function again until you do.
#Defining cont(). Ask for imput and error handling.
def cont():
while True:
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y":
return True
elif loop == "n":
print("Thank you for using this program, have a nice day!")
return False
else :
print("You did not enter a valid response, please try again.")
translate()
while cont():
translate()

using exceptions and writing data to files in python 3

here what I need to do:
Your program must raise an exception if the user chooses any item not on the menu
presented. Along with raising an exception, write the code to handle this exception.
Ask the user for a value to convert.Your program must raise and exception, and handle the exception, if an input
errors occurs
Perform the conversion and write the original value, the original unit, the
converted value, and the converted unit to an output file named
conversions.txt.
Repeat steps a and b 10 times (in a loop).
heres my code:
#imports
import os
# global variables
mile_choice = 1
gallon_choice = 2
pound_choice = 3
inch_choice = 4
fah_choice = 5
quit_choice = 6
mainfile = open('conversions.txt', 'w')
# intro and global name variable
name = input ('what is your name? ')
print()
print('hello',name,', today we will be doing\
some standard to metric conversions.')
#define main function
def main():
choice = 0
while choice != quit_choice:
display_menu()
print()
choice = int(input('Please enter a number 1 - 6 : '))\
if choice == mile_choice:
print()
miletokm()
elif choice == gallon_choice:
print()
galtolit()
elif choice == pound_choice:
print()
poundstokg()
elif choice == inch_choice:
print()
inchtocm()
elif choice == fah_choice:
print()
fahtocel()
elif choice == quit_choice:
print()
print('Exiting the program.')
#define functions
def display_menu():
print()
print(' Menu ')
print()
print('Press 1 for Miles to Kilometers')
print()
print('Press 2 for Gallons to Liters')
print()
print('Press 3 for Pounds to Kilograms')
print()
print('Press 4 for Inches to Centimeters')
print()
print('Press 5 for Fahrenhiet to Celisus')
print()
print('To exit please enter 6 ')
def miletokm():
invalid_attempts = 0
#while loop for invalid input limited to 3
while invalid_attempts < 3 and invalid_attempts >= 0:
print()
mile = float(input('how many miles would you\
like to convert to kilometers? '))
mainfile.write(str(mile) + '\n')
# if statement to determine weather to proceed with conversation
# valid input = conversion
# invalid input = return with + 1 to invalid_attempt count
if mile >= 0 :
print()
mile_conv = mile * 1.6
print('that would be:', format(mile_conv, '.2f'), 'kilometers.')
print()
mainfile.write(str(mile_conv) + '\n')
return mile
else:
print()
print ('invalid input')
print()
invalid_attempts += 1
I left out the other conversion def. to help keep it shorter.
I am having problems with the exception part first and for most.
I have tried various things but I cant figure out how to write out the code correctly
I know how to define a value error for a number entered outside of the menu range
I don't understand how to write the units along with the data entered to the file.
The way I Have it now, it is not writing any information to mainfile.
I also feel like my code is very sloppy written. I have no idea because my professor refuses to help me.
I know that's alot to run through but i really have no where else to turn. I don't understand how I should structure the code and how to effectively accomplish what I need done.
what I have read covers the basis of this but I have no examples to look at other than very simple simple examples that deal with strictly one thing.
You could try something like... (from http://docs.python.org/2/tutorial/errors.html#exceptions)
>>> while True:
... try:
... x = int(raw_input("Please enter a number: "))
... break
... except ValueError:
... print "Oops! That was no valid number. Try again..."
...
You're on the right track. First thing that you need to do is to handle better the value for choice that the user gives you. Check what happens if they give you 9 or 'foo'.
Next, you should do the same for every value received in your functions that convert units. For that, you use try/except as #bitfish showed you (except that you use input instead of raw_input).
close the files you open (mainfile.close())
doing this elif choice == quit_choice: inside of this while choice != quit_choice makes no sense
use '\n' to skip lines (print('\n') is the same than print() two times
there are many ways to solve such a problem, white the experience you'll acquire you'll find more elegant ones, but this one is already ok.

Categories

Resources