Unbound local error when writing nested codes - python-3.x

I’m trying to tweak the subfile on my python but it keeps showing me an unboundlocalerror on the a variable (Min_Alpha) which was referenced earlier on. I am confused by this as if I run the alpha command I get no errors though when I run the beta command I get this error. Any help would be much appreciated.
def main():
print("Welcome to the Beta Distribution Software")
print(" ")
playerschoice = input("Do you want to use this software ? Yes/No : ")
if (playerschoice == "yes" or playerschoice =="Yes" or playerschoice == "YES"):
Body_function_01()
else:
end_program()
def Body_function_01():
users_choice = input("What constant would you like to vary ? Alpha/Beta: ")
if (users_choice == "Alpha" or users_choice == "alpha"):
Max_Alpha = float(input("Enter the Maximum Alpha Value: "))
Min_Alpha = float(input("Enter the Minimum Alpha Value: "))
Alpha_increment = float(input("Enter Alpha Increment Value: "))
Beta_constant = float(input("Enter constant Beta value"))
else:
Body_function_02()
if (Min_Alpha >= 0):
print("Minimum Alpha value is within an acceptable range")
elif (Min_Alpha < 0):
print("Minimum value of alpha is too low ")
print ("Try again")
if ((Max_Alpha - Min_Alpha) > Alpha_increment):
print("The Alpha Increment is within an acceptable range")
elif ((Max_Alpha - Min_Alpha) < Alpha_increment):
print("The Alpha increment is too high")
print("Try again")
if (Max_Alpha > Min_Alpha):
print("The Maximum value of alpha is within an acceptable range")
elif (Max_Alpha < Min_Alpha):
print("The maximum value of alpha is too high")
print("Try again")
def Body_function_02():
users_choice = input("What constant would you like to vary ? Alpha/Beta: ")
if (users_choice == "Beta" or users_choice == "beta"):
Max_Beta = float(input("Enter the Maximum Beta Value: "))
Min_Beta = float(input("Enter the Minimum Beta Value: "))
Beta_increment = float(input("Enter Beta Increment Value: "))
Alpha_constraint = float(input("Enter constant Alpha value: "))
else:
print("Try again")
if (Min_Beta >= 0):
print("Minimum Beta value is within an acceptable range")
elif (Min_Beta < 0):
print("Minimum value of Beta is too low ")
print ("Try again")
if ((Max_Beta - Min_Beta) > Beta_increment):
print("The Beta Increment is within an acceptable range")
elif ((Max_Beta - Min_Beta) < Beta_increment):
print("The Beta increment is too high")
print("Try again")
if (Max_Beta > Min_Beta):
print("The Maximum value of Beta is within an acceptable range")
elif (Max_Beta < Min_Beta):
print("The maximum value of Beta is too high")
print("Try again")
def end_program():
print(" ")
input("Press any key to leave")
sys.exit()
main()
Body_function_01()
Body_function_02()
end_program().
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-25-c662d0a92b77> in <module>
111
112
--> 113 main()
114 Body_function_01()
115 Body_function_02()
<ipython-input-25-c662d0a92b77> in main()
16 playerschoice = input("Do you want to use this software ? Yes/No : ")
17 if (playerschoice == "yes" or playerschoice =="Yes" or playerschoice == "YES"):
---> 18 Body_function_01()
19
20 else:
<ipython-input-25-c662d0a92b77> in Body_function_01()
33 Body_function_02()
34
---> 35 if (Min_Alpha >= 0):
36 print("Minimum Alpha value is within an acceptable range")
37 elif (Min_Alpha < 0):
UnboundLocalError: local variable 'Min_Alpha' referenced before assignment

I think the problem is that Min_Alpha is initialised in this if:
users_choice = input("What constant would you like to vary ? Alpha/Beta: ")
if (users_choice == "Alpha" or users_choice == "alpha"):
Max_Alpha = float(input("Enter the Maximum Alpha Value: "))
Min_Alpha = float(input("Enter the Minimum Alpha Value: "))
Alpha_increment = float(input("Enter Alpha Increment Value: "))
Beta_constant = float(input("Enter constant Beta value"))
Which mins it will be initialised only if user choices Alpha/alpha. For any other choice the variable will not be initialised and it will be unbounded when you compare it to 0. Not sure what is the expected behaviour but i think you should return on the else case in both Body_function_01 and Body_function_02 functions.

Related

Number Guessing game Computer Playing

I have created this game. User is giving a number from 1 to 100. Computer is trying to guess it. User is giving hint to computer to go lower or go higher. I am open for any feedback.
Thank you in advance.
import os
import random
os.system('clear')
user = int(input("Please enter a number between 1-100: "))
print("Your Number is: " + str(user))
comp_list = list(range(1,101))
comp_selection = random.choice(comp_list)
count = 0
def game(num, a = 1, b = 100):
global count
print("I have chosen " + str(num) + "\nShould I go Higher or Lower or Correct? ")
user = input("Your Selection: ")
if user == "L":
count = count + 1
low_game(a, num)
elif user == "H":
count = count + 1
high_game(num, b)
else:
print("I have guessed correctly in " + str(count) + " tries")
def low_game(old_low, new_High):
x = new_High
new_comp_list = list(range(old_low, x))
new_comp_selection = random.choice(new_comp_list)
game(new_comp_selection, old_low, x)
def high_game(new_low, old_high):
x = new_low + 1
new_comp_list = list(range(x, old_high))
new_comp_selection = random.choice(new_comp_list)
game(new_comp_selection,x, old_high)
game(comp_selection)
I agree, you have over complicated the game with recursive functons.
Here is a much simplified game with penalties for player who does not answer correctly
or falsifies the answer:)
import sys, random
wins = 0
loss = 0
while 1:
user = input('Please enter a number between 1-100: (return or x = quit) > ' )
if user in [ '', 'x' ]:
break
elif user.isnumeric():
user = int( user )
if user < 1 or user > 100:
sys.stdout.write( 'Number must be between 1 and 100!!\n' )
else:
low, high, count = 1, 100, 0
while 1:
p = random.randint( low, high )
count += 1
while 1:
answer = input( f'Is your number {p}? Y/N > ').upper()
if answer in [ 'Y','N' ]:
break
else:
sys.stderr.write( 'Answer must be Y or N\n' )
if answer == 'N':
if p != user:
if input( f'Is my number (H)igher or (L)ower? > ').upper() == 'H':
if user < p:
high = p - 1
else:
sys.stderr.write( f'Wrong!! Your number was lower. You loss\n' )
loss =+ 1
break
else:
if user > p:
low = p + 1
else:
sys.stderr.write( f'Wrong!! Your number higher. You loss\n' )
loss =+ 1
break
else:
sys.stderr.write( f'Cheat!! Your number is {user}!! You loss\n')
loss =+ 1
break
else:
if user == p:
sys.stdout.write( f'I guessed Correctly in {count} guesses\n' )
wins += 1
else:
sys.stderr.write( f'Cheat!! This is not your number. You loss\n' )
loss =+ 1
break
print( f'Computer won = {wins} : You lost = {loss}' )
Happy coding.
You have really overly complicated the problem. The basic process flow is to have the computer guess a number within a fixed range of possible numbers. If the guess is incorrect, the user tells the computer how to adjust the list by either taking the guessed number as the low end or the high end of the guessing range. So to accomplish this, I would do the following:
from random import randint
# Function to request input and verify input type is valid
def getInput(prompt, respType= None):
while True:
resp = input(prompt)
if respType == str or respType == None:
break
else:
try:
resp = respType(resp)
break
except ValueError:
print('Invalid input, please try again')
return resp
def GuessingGame():
MAX_GUESSES = 10 # Arbritray Fixed Number of Guesses
# The Game Preamble
print('Welcome to the Game\nIn this game you will be asked to provide a number between 1 and 100 inclusive')
print('The Computer will attempt to guess your number in ten or fewer guesses, for each guess you will respond by telling the computer: ')
print('either:\n High - indicating the computer should guess higher\n Low - indicating the computer should guess lower, or')
print(' Yes - indicating the computer guessed correctly.')
# The Game
resp = getInput('Would You Like To Play?, Respond Yes/No ')
while True:
secret_number = None
if resp.lower()[0] == 'n':
return
guess_count = 0
guess_range = [0, 100]
secret_number = getInput('Enter an Integer between 1 and 100 inclusive', respType= int)
print(f'Your secret number is {secret_number}')
while guess_count <= MAX_GUESSES:
guess = randint(guess_range[0], guess_range[1]+1)
guess_count += 1
resp =getInput(f'The computer Guesses {guess} is this correct? (High?Low/Yes) ')
if resp.lower()[0] == 'y':
break
else:
if resp.lower()[0] == 'l':
guess_range[1] = guess - 1
else:
guess_range[0] = guess + 1
if guess == secret_number:
print (f'The Computer has Won by Guessing your secret number {secret_number}')
else:
print(f'The Computer failed to guess your secret number {secret_number}')
resp = getInput('Would You Like To Play Again?, Respond Yes/No ')

Code Not Compiling- Unable to figure out Issue

I have been stumped on this for days now and I can seem to figure out what the problem is. I am able to run all of it fine except when I select option 1 on the console menu. I will be able to make through the first inputs and then I get an error every time. Also for some reason when another option is selected, it does not jump to that option, it just starts going the password generator code instead. Any help would be appreciated. Still fairly new to all this.
import math
import sys
import random
import datetime
import string
import secrets
from datetime import date
while 1:
print("\nWelcome to the application that will solve your everday problems!")
print("\nPlease Select an Option from the List Below:")
print("1: To Generate a New Secure Password ")
print("2: To Calculate and Format a Percentage ")
print("3: To Receive the amount of days until Jul 4th, 2025 ")
print("4: To Calculate the Leg of Triangle by using the Law of Cosines ")
print("5: To Calculate the Volume of a Right Circular Cylinder ")
print("6: To Exit the Program ")
choice = int(input("Please enter your Selected Option: "))
if choice == 6:
print("\nThank you for coming, Have a Great Day!")
break
elif choice == 1:
def input_length(message):
while True:
try: #check if input is integer
length = int(input(message))
except ValueError:
print("Not an integer! Try again.")
continue
if length < 5: #check if password's length is greater then 5
print("Too short password!")
continue
else:
return length
def input_yes_no(message):
while True:
option = input(message).lower()
if option not in ('y', 'n'): #check if user entered y/n (or Y/N)
print("Enter y or n !")
else:
return option
def get_options():
while True:
use_upper_case = input_yes_no("Use upper case? [y/n]: ")
use_lower_case = input_yes_no("Use lower case? [y/n]: ")
use_numbers = input_yes_no("Use numbers? [y/n]: ")
use_special_characters = input_yes_no("Use special characters? [y/n]: ")
options = (use_upper_case, use_lower_case, use_numbers, use_special_characters)
if all(option == 'n' for option in options): #check if all options are 'n'
print("Choose some options!")
elif all(option == 'n' for option in options[:-1]) and options[-1] == 'y':
print("Password can not contain only special characters")
return options
def generate_alphabet(use_upper_case, use_lower_case, use_numbers, use_special_characters):
alphabet = ''
if use_upper_case == 'y' and use_lower_case == 'y':
alphabet = string.ascii_letters
elif use_upper_case == 'y' and use_lower_case == 'n':
alphabet = string.ascii_uppercase
elif use_upper_case == 'n' and use_lower_case == 'y':
alphabet = string.ascii_lowercase
if use_numbers == 'y':
alphabet += string.digits
if use_special_characters == 'y':
alphabet += string.punctuation
def generate_password(alphabet, password_length, options):
use_upper_case = options[0]
use_lower_case = options[1]
use_numbers = options[2]
use_special_characters = options[3]
while True:
password = ''.join(secrets.choice(alphabet) for i in range(password_length))
if use_upper_case == 'y':
if not any(c.isupper() for c in password):
continue
if use_lower_case == 'y':
if not any(c.islower() for c in password):
continue
if use_numbers == 'y':
if not sum(c.isdigit() for c in password) >= 2:
continue
if use_special_characters == 'y':
if not any(c in string.punctuation for c in password):
continue
break
def main():
password_length = input_length("Enter the length of the password: ")
options = get_options()
alphabet = generate_alphabet(*options)
password = generate_password(alphabet, password_length, options)
print("Your password is: ", password)
if __name__ == "__main__":
main()
elif choice == 2:
Num = float(input("Please Enter the Numerator: "))
Denom = float(input("Please Enter the Denomenator: "))
Deci = int(input("Please Enter the Number of Decimal Places You Would Like: "))
Val = Num/Denom*100
Val = round(Val, Deci)
print("\nThe Percentage of the numbers you entered is", Val, "%")
elif choice == 3:
Today = datetime.date.today()
Future = date(2025, 7, 25)
Diff = Future - Today
print("\nTotal numbers of days till July 4th, 2025 is:", Diff.days)
elif choice == 4:
A = int(input("Please Enter angle A: "))
B = int(input("Please enter angle B: "))
Angle = int(input("Please Enter the Angle of the Triangle: "))
c = A*A + B*B - 2*A*B*math.cos(math.pi/180*Angle)
print("\nThe Leg of the Triangle is:", round(c))
elif choice == 5:
Radius = int(input("Please Enter the Radius of the Cylinder: "))
Height = int(input("Please Enter the Height of the Cylinder: "))
Volume = (math.pi*Radius*Radius)*Height
print("\nThe Volume of the Cylinder is:", Volume)

Python3: How to loop my dice roller program back to the start

Writing my first solo program with no help from teacher or group, a simple code that can act as a D&D dice roller for any type or number of dice a user requires.
I've been working on it for about four hours, and I'm stuck on the last thing I want to do which is loop it back to the beginning instead of just ending when a user doesn't reroll the already chosen dice, I'd like it so it starts again from the top so the player can input a new dice value and number of rolls generated without closing the program and rerunning it.
import random
try:
min = 1
max = int(input("Enter the highest value of dice to be rolled: "))
except:
print("Your input was invalid, program rolled a d20 by default")
min = 1
max = 20
again = True
number_of_dice = int(input("Enter number of dice to roll: "))
for i in range(number_of_dice - 1):
print(random.randint(min, max))
while again:
print(random.randint(min, max))
reroll = input("Roll again? (y/n): ")
if reroll.lower() == "y" or reroll.lower() == "yes":
for i in range(number_of_dice - 1):
print(random.randint(min, max))
else:
print("Thank you")
break
You might try something like:
import random
while True:
try:
min = 1
max = int(input("Enter the highest value of dice to be rolled or 0 to exit: "))
except:
print("Your input was invalid, program rolled a d20 by default")
min = 1
max = 20
if max == 0:
break
if max < 0:
continue
again = True
number_of_dice = int(input("Enter number of dice to roll: "))
for i in range(number_of_dice - 1):
print(random.randint(min, max))
while again:
print(random.randint(min, max))
reroll = input("Roll again? (y/n): ")
if reroll.lower() == "y" or reroll.lower() == "yes":
for i in range(number_of_dice - 1):
print(random.randint(min, max))
else:
print("Thank you")
break
Also, I would suggest renaming "min" and "max" as they are reserved keywords

Create a function to test a value between two ranges

I want to create a function within this code to kick the user back if the input values are outside of the input ranges, so if the first number with the second number doesn't exceed the high range or fall below the low rang with any of the calculations, if it does it would return with an error message and prompt to try again.
while True:
try:
number1 = int(input('Enter your Lower Range:'))
if number1 < -100 or number1 > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
number2 = int(input('Enter your Higher Range: '))
if number2 < -100 or number2 > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
a = int(input('Enter your first number: '))
if a < -100 or a > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
b = int(input('Enter your second number: '))
if b < -100 or b > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
print('{} + {} = '.format(a, b))
print(a + b)
print('{} - {} = '.format(a, b))
print(a - b)
print('{} * {} = '.format(a, b))
print(a * b)
print('{} / {} = '.format(a, b))
print(a / b)
restart = input("Would you like to restart this program?")
if restart == "yes" or restart == "y":
main()
if restart == "n" or restart == "no":
print ("Script terminating. Goodbye.")
print ("Thanks for using my calculator!")
main()
If you need this into a method, you can try the following:
def read_number(text, lower=-100, higher=100):
while True:
number = int(input(text))
if number < lower or number > higher:
print("Invalid integer. The number must be between {} and {}.".format(lower, higher)
pass
else:
return number
The method read_number() above get the input and returns it only on condition, so you can use it directly to a variable:
def main():
number1 = read_number('Enter your Lower Range: ')
number2 = read_number('Enter your Higher Range: ')
a = read_number('Enter your first number: ')
b = read_number('Enter your second number: ')
# do something ...
I don't know if is it you want. If not, try to explain it with more clarity.
However, I hope has helped you.
I've tried my best to design a function. I hope this helps:
def my_calculator():
while True:
try:
number1 = int(input('Enter your Lower Range:'))
if number1 < -100 or number1 > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
number2 = int(input('Enter your Higher Range: '))
if number2 < -100 or number2 > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
a = int(input('Enter your first number: '))
if a < -100 or a > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
while True:
try:
b = int(input('Enter your second number: '))
if b < -100 or b > 100:
raise ValueError
break
except ValueError:
print("Invalid integer. The number must be between -100 and 100.")
print('{} + {} = '.format(a, b))
addition = a + b
print(addition)
print('{} - {} = '.format(a, b))
diff = a - b
print(diff)
print('{} * {} = '.format(a, b))
prod = a * b
print(prod)
quo = None
try:
quo = a / b
except ZeroDivisionError as ze:
print("Division by zero not allowed; Please retry.")
my_calculator()
print('{} / {} = '.format(a, b))
print(quo) if quo else print()
results = [addition, diff, prod, quo]
try:
if not all(-100 < i < 100 for i in results):
raise ValueError
except ValueError as ve:
print("Some of the results of calculation exceed 100 or are less than -100."
"The results must be between -100 and 100. Please retry.")
my_calculator()
restart = input("Would you like to restart this program?")
if restart == "yes" or restart == "y":
my_calculator()
if restart == "n" or restart == "no":
print("Script terminating. Goodbye.")
print("Thanks for using my calculator!")
if __name__ == "__main__":
my_calculator()

Python while loop through program not working

import random
replay = 1
while replay == 1:
replay = replay - 1
target = random.randint(1, 100)
guess = int(input("Guess the number 1-100: "))
count = 0
score = 0
while count == 0:
score = score + 1
if guess < target:
print ("The number is higher. Try again.")
guess = int(input("Guess the number 1-100: "))
elif guess > target:
print ("The number is lower. Try again.")
guess = int(input("Guess the number 1-100: "))
elif guess == target:
print ("You guessed Correctly!")
print ("Your score was:", score)
again = str(input("Play again? (yes or no)"))
if again == "yes" or "YES":
replay = replay + 1
elif again == "no" or "NO":
break
This is my code, except it doesn't do what I want it to do. After you guess the correct number, it doesn't see to properly loop through the game again when you say yes or no. It just goes through the final if statement again.
Why won't it go through the entire program again?
Your code will always be evaluated to true
if again == "yes" or "YES":
Change it to:
if again.lower() == "yes":
Or
if again in ("YES", "yes", "y",..)
When it is true, you need to break from you second loop:
if again.lower() == "yes":
replay = replay + 1
break
When it is false, don't break but exit the program using:
exit()
Since replay is only used to exit your code, you don't need it if you use exit().
Code would then be:
import random
while True:
target = random.randint(1, 100)
guess = int(input("Guess the number 1-100: "))
score = 0
while True:
score = score + 1
if guess < target:
print ("The number is higher. Try again.")
guess = int(input("Guess the number 1-100: "))
elif guess > target:
print ("The number is lower. Try again.")
guess = int(input("Guess the number 1-100: "))
elif guess == target:
print ("You guessed Correctly!")
print ("Your score was:", score)
again = str(input("Play again? (yes or no)"))
if again.lower() == "yes":
break
elif again.lower() == "no":
exit()

Resources