Python printing NONE, not storing variable due to except statement [duplicate] - python

This question already has answers here:
Recursive function does not return specified value
(2 answers)
Closed last month.
Issue is when I test my error handling, entering the unexpected inputs multiple times and then proceeding to enter the acceptable number of lines to bet on the return is recived as "None" the variable seems to not stay stored or is somehow over written. Any Ideas?
I would place the other half of the code but am forced to type everything due to company policies. I apologize for any inconvenience, I thank everyone for ther time in viewing this post.
MAX_LINES = 3
def get_number_of_lines():
try:
while True:
lines = ("Enter the number of lines to be on (1-" + str(MAX_LINES) + ")? ")
if lines.isdigit:
lines = int(lines)
if 1 <= lines <= MAX_LINES:
break
else:
print("Enter a valid number of lines.")
return lines
except ValueError:
print("Please enter a number. ")
get_number_of_lines()
def main():
lines = get_number_of_lines()
print(lines)
Expected the number entered 1-3 to be printed from the return line even if moved from and to the except statment.

Add return before get_number_of_lines(). Otherwise your function will return None.
print("Please enter a number")
return get_number_of_lines()

Related

why is the return of the program not good?

I'm new to python and there's a video on Youtube that I watched. I do the exact same code as he but mine doesn't work and I don' understand why.
Here's the code:
MAX_LINES = 3
def deposit():
while True:
amount = input("What would you like to deposit? $")
if amount.isdigit():
amount = int(amount)
if amount > 0:
break
else:
print("Amount must be greater than 0. ")
else:
print("Please enter a number. ")
return amount
def get_number_of_lines():
while True:
lines = input("Enter the number of lines to bet on (1-" + str(MAX_LINES) + ")? ")
if lines.isdigit():
lines = int(lines)
if 1 <= lines <= MAX_LINES:
break
else:
print("Please enter a valid number of lines. ")
else:
print("Please enter a number. ")
return lines
There are 3 problems.
Unindent amount does not match previous indent. I have no idea what does that mean
"return" can be used only within a function. As far as I'm concerned I'm using it in the function, copied the first function then pasted it into the second function and somehow it doesn't work
"lines" is not defined. What dou you mean it's not defined, I define it in the first line of the function
https://www.youtube.com/watch?v=th4OBktqK1I
This video's code what I'm trying to do
I appreciate any help!
I just simply don't understand why it works in one and not the other
You have one space too much in front of while True in function get_number_of_lines().
Yes used in functions to return value
Because function don't get inside while loop (because of indent problem), lines is never defined, probably this was the problem.
So try fix indent and run again

Python: detecting a input error and how to give a solution to it [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 2 years ago.
I am a beginner in python and made a couple of programs, one of the same things I see, is that when ever I make a code like this
do = int(input("Enter number >"))
I accidentally type a letter, I want to be able to give like a wrong input message and try again, but python would always detect the difference in variable container.
You can catch ValueError:
success = False
while not success:
try:
do = int(input("Enter number >"))
success = True
except ValueError:
print("Wrong input, please try again")
I would suggest having a validation function. You can then use this function in other Python programs in the future.
def validate_int(inp):
try:
int(inp)
return True
except Exception:
print('Invalid input')
return False
This function will return true or false depending on whether a number has been entered.
You can then call the function like this:
inp = input('Enter number >')
while validate_int(inp) == False:
inp = input('Enter number >')

I don't understand why digit not return but "local variable 'total' referenced before assignment" instead [duplicate]

This question already has answers here:
local variable 'servers' referenced before assignment
(3 answers)
Asking the user for input until they give a valid response
(22 answers)
Closed 4 years ago.
I want write a method that asks a user to input a digit, but if the user also inputs a string it needs to ask the user to input again until the correct data is input.
-------code that shows error-------------
def get_total():
try:
total = int(input("How many people you got in total: "))
except:
print("Your data is invalid, please try again.")
get_total()
return total
x = get_total()
print(x)
If you type 5 directly, it will print 5.
However if you type "s" first and then 5, it will throw this error:
"local variable 'total' referenced before assignment"
Can anyone could please tell me why?
If I correct the code like this, it works just fine
------code that works fine-----------------
def get_total():
try:
total = int(input("How many people you got in total: "))
return total
except:
print("Your data is invalid, please try again.")
return get_total()
x = get_total()
print(x)
So why does this happen?
The problem is that when in the code
total = int(input("How many people you got in total: "))
the input is not a number and int throws an exception the local variable total has not been assigned.
In the except part of the first version you are calling get_total recursively but this doesn't set the total variable, just returns you the result (that is ignored).
When (after this successful recursive call) you end up in your return statement the total variable is still unbound and therefore you get an exception.
The key point to understand is that calling get_total recursively is not a "goto". If you want a loop write a loop (e.g. using while), if you want recursion the use recursion.
The reason is that if you enter 5 in first try it assigns total the value of 5 and then returns it
However if you enter the value "s" the except block gets run and it goes back to the function call . Then you enter the value 5 the return statment in the second function call returns 5 and it exits the except block in the first function call.
Then it runs the return statement however the variable total doesnt exist only the value 5 exists
correct code is
def get_total():
try:
total = int(input("How many people you got in total: "))
except:
print("Your data is invalid, please try again.")
total = get_total()
return total
Hope it helps :)
The error code should be modified as:
def get_total():
try:
total = int(input("How many people you got in total: "))
except ValueError:
print("Your data is invalid, please try again.")
total = get_total() # assign return value back to total
return total
You don't receive the returned value from the function when you called within function, so when it encounters return total, Python throws UnboundLocalError.
A better way is to use an infinite loop like following:
def get_total():
while True:
try:
total = int(input("How many people you got in total: "))
return total
except ValueError:
print("Your data is invalid, please try again.")
Note that it's not advised to handle all exceptions once (like except:). Always name the exception with except keyword (ValueError in this case).
I think this code is also correct:
def get_total():
while True: # prompt's the user until a correct input is given(break)
try:
total = int(input("How many people you got in total: "))
break # if the input for total is int, program will break from the loop. if not, program will print an error message and this loop will execute again
except:
print("Your data is invalid, please try again.")
return total
x = get_total()
print(x)
hope it helps

Error Tapping a section of code

I have a while statement which works well and I have a whole section of code that asks the user to input how many names they have which will then ask them for a name that amount of times and then each time a name will be entered.
I need the section of the names entered to be error tapped but I don't know how to do it, as I have a while statement and I may need to put another while statement in, although I have error tapped the section for amount of names in numbers.
Also there is code further on with a dictionary and sorts but I need help with the one section of error tapping started at while currentnum part
print("Please enter each name when asked without any spaces.") #The program will post this
print("Please enter each of your names individually also.") #Program will again post this
names = [] #This is the value of names which will be changed depending on the input
currentnum = 0 #Currentnum value is 0
while True: #While loop as it will revert to the start if question answered incorrectly
try:
numofnames = int(input("How many names do you have? "))
except ValueError: #if the input is not an integer or a whole number it will
print("Sorry that was not a valid input please retry")
continue #it will loop back and ask the question again as it says that the unput was not valid
else:
break #If the input is correct then the loop will break and continue to the next section of the program
while currentnum < numofnames: #This means that while currentnum is smaller than input for numofnames it will continue to ask question. This is another loop
currentnum = currentnum + 1 # every time the question is asked it means that currentnum gets 1 added to it and will continue to ask untill it is the same as the input for numofnames
name = str(input("Enter your name: ")) #Name asked to be entered in string
name = name.upper() #This changes all letters to upper case no matter what so there is no error for upper and lower case or a bigger dictionary showing lower and upper case values.
names.append(name)
Yep. The easiest way to describe what you're doing is to use the .isalpha attribute in an if statement. First you will have to def your while loop
Like the following:
def Loop():
name_input_complete = False
while name_input_complete != True:
string = input("Please input :")
string = str(string)
if string.isalpha():
name_input_complete = True
else:
print("Please do not use numbers and spaces")
Loop()
Loop()
Baisically you have to define the loop and then run it. The if statement(which is the part you should add to your loop) then checks if there is nothing other than letters. If true, your done with error trapping and the loop is exited. The program continues outside the loop. If not then the while is repeated because the Loop() function is called again.
Your code looks very good to me. I dont see what input can the user put that could cause an error, since most data in python can be stringed AND names can be pretty much anything!. If you could comment exactly what error could be caused i might be able to help you

Function running differently in separate instances-python [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 7 years ago.
I have written this program that takes a file called Sonnets and firstly, changes all the roman numerals in the sonnets to numbers, copies that to a new file, then asks the user for number input and shows them the sonnet corresponding to their number (if between 1 and 7).
For numbers outside 1 and 7, I would display appropriate error messages, giving specific directions on what they inputted and what they need to input again.
I wrote all of my functions separately, and everything runs when I put them together EXCEPT for the "except" part in function serve_poem(). It gave me the correct error message when I ran the function separately, however, now it just gives me the automatic error message instead of the specific message I encoded.
I posted my whole code below, because I figure that something in one of the other functions is messing with it(???) because it ran fine on its own.
def change_romans_to_numbers(s):
if s == "I.":
return("1.")
elif s == "II.":
return("2.")
elif s == "III.":
return("3.")
elif s == "IV.":
return("4.")
elif s == "V.":
return("5.")
elif s == "VI.":
return("6.")
elif s == "VII.":
return("7.")
else:
return s
def serve_poem():
sonnet=open(r"C:\Users\Emily\Documents\sonnets.txt", "r")
x=int(input("Please enter a number 1-7:"))
s=sonnet.readlines()
s=list(s)
try:
if x==1:
up=int(2+14*(x-1))
lower=int(2+14*(x-1)+14)
for i in range (up,lower):
print(s[i])
if 2<=x<=7:
up=int((2+14*(1-1))+(19*(x-1)))
lower=int((2+14*(1-1)+14)+(19*(x-1)))
for i in range (up,lower):
print(s[i])
if x<0:
print("You entered a negative number. Please enter a number between 1 and 7:")
serve_poem()
if x==0:
print("You entered 0. Please enter a number between 1 and 7:")
serve_poem()
if x>7:
print("You entered a number greater than 7. Please enter a number between 1 and 7:")
serve_poem()
except ValueError:
print("Error: Value Error. You did not enter a number at all! Please re-enter a number:")
serve_poem()
def writing_romans_to_numbers():
sonnet=open(r"C:\Users\Emily\Documents\sonnets.txt", "r")
sonnet_fixed=open(r"C:\Users\Emily\Documents\sonnets-fixed.txt", "w")
for line in sonnet:
new=change_romans_to_numbers(line.strip())
sonnet_fixed.write(new + '\n')
def main():
writing_romans_to_numbers()
serve_poem()
main()
Here is my error message (if user inputs q):
File "C:/Users/Emily/.spyder2-py3/temp.py", line 28, in serve_poem
x=int(input("Please enter a number 1-7:"))
ValueError: invalid literal for int() with base 10: 'q'
Your problem is that you aren't wrapping this line in the try...except block:
x=int(input("Please enter a number 1-7:"))
This line will raise an exception if given non-numeric input, but this exception will not handled by your try...except block. You would only need to put that one line in a try...except block, if that line passes it will be guaranteed to be numeric input, so your comparisons should work.
However, as Martjin said, that isn't the best approach.

Categories

Resources