Passing multiple args into expanded if-else statements - python

I'm trying to pass multiple args. The first function creates the variables for age and gender. The second function redirects the arg based on gender. The 'num' variable should choose get_Male or get_Female and run through if-else statement until it finds equality. I'm new to python and it might be something simple. I just need to understand why the num variable doesn't pass. This is what I have so far...
A_Age = 0
B_Age = 4
C_Age = 8
D_Age = 15
E_Age = 25
F_Age = 38
G_Age = 48
H_Age = 60
def main():
#print('I am Rae...')
with open("output.txt", "r") as f:
gender = f.readline().split(":")[-1].strip()
age = f.readline().split(":")[-1].strip().split('-')[0]
print(gender) # Male
print(age) # 25-32
num = age
gen = gender
get_Gender(gen, num)
def get_Gender(gen, num):
#print('I am Rza...')
if gen == 'Male':
print('The gender is male.')
get_Male(gen, num)
else:
print('The gender is female.')
get_Male(gen, num)
return(gen, num)
def get_Male(gen, num):
#print('I am Gza...')
if gen == 'Male' and num == A_Age:
print('Unintentional Injuries')
elif num == B_Age:
print('Neoplasms')
elif num == C_Age:
print('Teenage injuries')
elif num == D_Age:
print('School fights')
elif num == E_Age:
print('High Blood Pressure')
elif num == F_Age:
print('Hypertension')
elif num == G_Age:
print("Heart Disease")
elif num == H_Age:
print('old age')
return
get_Female(gen, num)
return(gen, num)
def get_Female(gen, num):
#print('I am meth...')
if gen == 'Female' and num == A_Age:
print('Unintentional Injuries')
elif num == B_Age:
print('Neoplasms')
elif num == C_Age:
print('Teenage injuries')
elif num == D_Age:
print('School fights')
elif num == E_Age:
print('High Blood Pressure')
elif num == F_Age:
print('Hypertension')
elif num == G_Age:
print("Heart Disease")
elif num == H_Age:
print('old age')
return(gen, num)
main()

There are several ways you can make this code more straightforward and readable, which make it easier to understand how your code works.
First, you don't need nested if-else statements. You can use elif, which only gets evaluated if the previous if or elif evaluated to False. NB: A dictionary would simplify this function even further. I'll leave that up to you to discover.
Second, your functions get_Male and get_Female generally implement the same behavior, independent of the value of gen. Realizing this, we can consolidate these two functions into one and remove the gen parameter entirely.
Your functions get_Male and get_Female could look like this:
def print_symptom(num): # Previously `get_Male` and `get_Female`
if num == A_AGE:
print('Unintentional Injuries')
elif num == B_AGE:
print('Neoplasms')
elif num == C_AGE:
print('Teenage injuries')
elif num == D_AGE:
print('School fights')
elif num == E_AGE:
print('High Blood Pressure')
elif num == F_AGE:
print('Hypertension')
elif num == G_AGE:
print("Heart Disease")
elif num == H_AGE:
print('old age')
You don't need to return gen and num since you don't use them anywhere else. The same goes for your get_Gender function (see next code block).
Since we removed the gen parameter from print_symptoms, we need to check that gen is either 'Male' or 'Female' in the function that will call print_symptoms:
def get_gender(gen, num):
if gen == 'Male':
print('The gender is male.')
elif gen == 'Female': # Previously checked in `get_Female`
print('The gender is female.')
else:
print('Invalid gender. Exiting.')
return
print_symptom(gen, num)
Hopefully, these changes make it easier to understand what's going on in your code. Some other notes:
Check out this PEP which specifies naming conventions.
In general, functions should be defined before other functions which call them. That way, when you read a file from top to bottom, you know what a function does before you encounter it within another function.
A cleaned-up version of your code could look like this:
A_AGE = 0
B_AGE = 4
C_AGE = 8
D_AGE = 15
E_AGE = 25
F_AGE = 38
G_AGE = 48
H_AGE = 60
def print_symptom(num):
if num == A_AGE:
print('Unintentional Injuries')
elif num == B_AGE:
print('Neoplasms')
elif num == C_AGE:
print('Teenage injuries')
elif num == D_AGE:
print('School fights')
elif num == E_AGE:
print('High Blood Pressure')
elif num == F_AGE:
print('Hypertension')
elif num == G_AGE:
print("Heart Disease")
elif num == H_AGE:
print('old age')
def get_gender(gen, num):
if gen == 'Male':
print('The gender is male.')
elif gen == 'Female':
print('The gender is female.')
else:
print('Invalid gender. Exiting.')
return
print_symptom(num)
def main():
with open("output.txt", "r") as f:
gender = f.readline().split(":")[-1].strip()
age = f.readline().split(":")[-1].strip().split('-')[0]
print(gender) # Male
print(age) # 25-32
get_gender(gender, age)
main()

First, if I'm understanding your question correctly, the reason that your code isn't looking at both gender and age is because in get_Gender(), you check for gender but run get_Male() regardless of whether of what value you have for gen. The problem is specifically in this part:
def get_Gender(gen, num):
#print('I am Rza...')
if gen == 'Male':
print('The gender is male.')
get_Male(gen, num)
else:
print('The gender is female.')
get_Male(gen, num) #<---- I think this should be get_Female()
return(gen, num)
Another change that will make it easier to troubleshoot code like this: don't nest a bunch of if else statements like that. Instead, you can use "elif", which will only run if the prior if-statement resolved to False. Here is an example of how you can update your code:
def get_Male(gen, num):
if gen == 'Male' and num == A_Age:
print('Unintentional Injuries')
elif num == B_Age:
print('Neoplasms')
elif num == C_Age:
print('Teenage injuries')
elif num == D_Age:
print('School fights')
elif num == E_Age:
print('High Blood Pressure')
elif num == F_Age:
print('Hypertension')
elif num == G_Age:
print("Heart Disease")
elif num == H_Age:
print('old age')
return(gen, num)

Couple of things:
You can use the sentence elif instead of else and then if
You can use a dictionary to perform a kind of switch operation of other languages. I'd do something as follows:
switch = {
0: 'Unintentional Injuries',
4: 'Neoplasms',
8: 'Teenage injuries',
15: 'School fights',
25: 'High Blood Pressure',
38: 'Hypertension',
48: 'Heart Disease'.
60: 'old age'
}
disease = switch[num]
print(disease)

Related

Why this isn't working, it's giving me an this error ('bool' object is not subscriptable)

here is the code, it's a car parking system:
import time
parking_slots = []
start = []
for i in range(6):
start.append(0)
for i in range(6):
parking_slots.append(False)
while True:
print("1.view empty\n2.add\n3.remove\n4.save\n5.load\n6.exit")
choice = int(input())
if choice == 1:
print("Empty slots are: ")
for slot in range(6):
if parking_slots[slot] == 0:
print(slot, end=" - ")
print("")
if choice == 2:
index = int(input("Enter the index of the slot: "))
if start[index] == 0:
start[index] = int(time.time())
parking_slots[index] = True
else:
print("this slot is already token, please choose another one")
if choice == 3:
index = int(input("Enter the index of the slot: "))
print("Your bill is", int(time.time()) - start[index])
parking_slots[index] = False
start[index] = 0
if choice == 4:
open("cps.txt", "w").write("")
for i in start:
open("cps.txt", "a").write(str(i) + "\n")
if choice == 5:
file = open("cps.txt", "r").readlines()
start = [float(x.strip("\n")) for x in file]
for x in range(6):
if start[x] == 0:
parking_slots = False
else:
parking_slots = True
if choice == 6:
break
the error is when I enter choice 1, it tells me bool object is not subscriptable
When choice == 5 you do
for x in range(6):
if start[x] == 0:
parking_slots = False
else:
parking_slots = True
which replaces the list that was contained in parking_slots with a plain boolean, which gives you that error when you later try to index it. Probably here you meant
for x in range(6):
if start[x] == 0:
parking_slots[x] = False
else:
parking_slots[x] = True

Python print day name of week from number

I'm creating a program which I have to put a number and when I run the program, the solution should be the day for that number. But I don't know how to do. The program I did was this:
num = 4
if(num = 1)
print('Monday')
elif(num = 2)
print('Tuesday')
elif(num = 3)
print('Wednesday')
elif(num = 4)
print('Thursday')
elif(num = 5)
print('Friday')
elif(num = 6)
print('Sunday')
elif(num = 7)
print('Saturday')
elif(num < 1)
print('Put a number between 1 and 7')
else(num > 7)
print('Put a number between 1 and 7')
In python, for statements like if, for, etc. You have to add : at the end of it.
And for comparing (for equal) you have to use == and not =
num = 4
if(num == 1):
print('Monday')
elif num == 2:
print('Tuesday')
.....
You can compare without parenthesis and it will work too.
num = 0
while num <= 7:
num += 1
if num == 1:
print('Monday')
elif num == 2:
print('Tuesday')
elif num == 3:
print('Wednesday')
elif num == 4:
print('Thursday')
elif num == 5:
print('Friday')
elif num == 6:
print('Saturday')
elif num == 7:
print('Sunday')

Giving one hint for each of the tries (guessing number game)

I am making a game which requires the user to enter a number. They get four tries, and if they get the number wrong, they get a hint.
How can I try to give only one hint for each of the four tries the user has to get the number right? For example, after the user gets the first try wrong, I would like the program to display the even_or_odd hint.
from random import randrange
new_number = randrange(1, 101)
class Hints:
def __init__(self, new_number):
self.new_number = new_number
def even_or_odd(self):
if self.new_number % 2 == 0:
print('Hint. The number is even.')
else:
print('Hint. The number is odd.')
def multiple3to5(self):
for x in range(3, 6):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of {x}', end = ' ' )
def multiple6to10(self):
for x in range(6, 11):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of x {x}', end = ' ')
print('Guess a number beteen 1 and 100.')
hint = Hints(new_number)
for x in range(1, 5):
is_answer_given = False
while not is_answer_given:
try:
user_input = int(input(f'Attempt {x}: '))
is_answer_given = True
except ValueError:
print('Please enter a numerical value.')
if user_input == new_number and x == 1: #hint after first attempt
print('You win!')
break
else:
print('Incorrect!')
hint.even_or_odd()
if user_input == new_number and x == 2: #hint after second attempt
print('You win!')
break
else:
print('Incorrect!')
hint.multiple3to5()
if user_input == new_number and x == 3: #hint after third attempt
print('You win!')
break
else:
print('Incorrect!')
hint.multiple6to10()
if x == 4:
print('You are out of attempts!')
print(f'The number was {new_number}')
break
You should make one if statement that checks for the correct answer. In the else statement you can use if - elif statements to check for the attempt number.
if user_input == new_number:
print('You win!')
break
else:
print('Incorrect!')
if x == 1:
hint.even_or_odd()
elif x == 2:
hint.multiple3to5()
elif x == 3:
hint.multiple6to10()
else:
print('You are out of attempts!')
print(f'The number was {new_number}')
The reason you see multiple hints on attempt is that for multiple if statements their condition is not true, so their 'else' block is run
Here is a neat trick:
from random import randrange
new_number = randrange(1, 101)
class Hints:
def __init__(self, new_number):
self.new_number = new_number
self.choices = {
1: self.even_or_odd,
2: self.multiple3to5,
3: self.multiple6to10
}
def run(self,key):
action = self.choices.get(key)
action()
def even_or_odd(self):
if self.new_number % 2 == 0:
print('Hint. The number is even.')
else:
print('Hint. The number is odd.')
def multiple3to5(self):
for x in range(3, 6):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of {x}', end = ' ' )
else:
print("Well, Not a multple of 3 or 5")
def multiple6to10(self):
for x in range(6, 11):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of x {x}', end = ' ')
else:
print("Well, Not a multple of 6 or 10")
print('Guess a number beteen 1 and 100.')
hint = Hints(new_number)
print(new_number)
i = 3
win = False
while i >= 1 :
is_answer_given = False
while not is_answer_given:
try:
user_input = int(input(f'Attempt {i}: '))
is_answer_given = True
except ValueError:
print('Please enter a numerical value.')
if user_input == new_number:
print('You win!, Number is: {new_number}')
win = True
break
hint.run(i)
i -= 1
if not win:
print("You lost!")
print(f"Number is {new_number}")

Access a function variable from outside the function in python

I have a python function and would like to retrieve a value from outside the function. How can achieve that without to use global variable. I had an idea, if functions in python are objects then this could be a right solution?
def check_difficulty():
if (difficulty == 1):
check_difficulty.tries = 10
elif (difficulty == 2):
check_difficulty.tries = 5
elif (difficulty == 3):
check_difficulty.tries = 3
try:
difficulty = int(input("Choose your difficulty: "))
check_difficulty()
except ValueError:
difficulty = int(input("Type a valid number: "))
check_difficulty()
while check_difficulty.tries > 0:
I am new to python so excuse me...
def check_difficulty(difficulty):
if (difficulty == 1):
return 10
elif (difficulty == 2):
return 5
elif (difficulty == 3):
return 3
tries = 0
while tries > 0:
difficulty = int(input("Choose your difficulty: "))
tries = check_difficulty(difficulty)
tries = tries - 1
if you use a while loop and put everything inside in a structured way, a function will not be needed.
You can change this to a class to get your tries:
class MyClass:
def __init__(self):
self.tries = 0
def check_difficulty(self, difficulty):
if (difficulty == 1):
self.tries = 10
elif (difficulty == 2):
self.tries = 5
elif (difficulty == 3):
self.tries = 3
ch = MyClass()
try:
difficulty = int(input("Choose your difficulty: "))
ch.check_difficulty(difficulty)
except ValueError:
difficulty = int(input("Type a valid number: "))
ch.check_difficulty(difficulty)
ch.tries
# 5
If you want the question answered within the construct of your current code simply put your try, except before the function. You can call a function anywhere in the code it doesn't ave to be after the function is created . So something like this:
try:
difficulty = int(input("Choose your difficulty: "))
check_difficulty()
except ValueError:
difficulty = int(input("Type a valid number: "))
check_difficulty()
def check_difficulty():
if (difficulty == 1):
check_difficulty.tries = 10
elif (difficulty == 2):
check_difficulty.tries = 5
elif (difficulty == 3):
check_difficulty.tries = 3
while check_difficulty.tries > 0:
however, I would have to agree with the other answers and just kind of put everything together within the same loop and you won't have to worry about this. I created a guessing game recently that actually had something similar to this. Here is the difficulty portion of that code:
def guessing_game():
again = ''
# Define guesses/lives
while True:
try:
guesses_left = int(input('How many guess would you like(up to 4)?: '))
if 1 > guesses_left or guesses_left > 4:
print('You must choose between 1 and 4 for your guess amount. Try again.')
continue
break
except:
print('You must enter a valid number between 1 and 4. Try again.')
# Define difficulty based on guesses_left
difficulty = ''
if guesses_left == 1:
difficulty = 'Hard Mode'
elif guesses_left == 2:
difficulty = 'Medium Mode'
elif guesses_left == 3:
difficulty = 'Easy Mode'
elif guesses_left == 4:
difficulty = 'Super Easy Mode'
print('You are playing on ' + difficulty + ' with ' + str(guesses_left) + ' guesses.')
#code continues under this line to finish#

Python 2.7 Slot Machine if statement issue

import random
numbers = []
wheel1 = 0
wheel2 = 0
wheel3 = 0
winnings = int(0)
balance = int(50)
def generator(balance):
number1 = random.random()
number2 = random.random()
number3 = random.random()
if number1 < 0.05:
wheel1 = "Cherry"
elif number1 < 0.15:
wheel1 = "Diamond"
elif number1 < 0.30:
wheel1 = "Hearts"
elif number1 < 0.65:
wheel1 = "Spade"
elif number1 < 1:
wheel1 = "Monkey"
if number2 < 0.05:
wheel2 = "Cherry"
elif number2 < 0.15:
wheel2 = "Diamond"
elif number2 < 0.30:
wheel2 = "Hearts"
elif number2 < 0.65:
wheel2 = "Spade"
elif number2 < 1:
wheel2 = "Monkey"
if number3 < 0.05:
wheel3 = "Cherry"
elif number3 < 0.15:
wheel3 = "Diamond"
elif number3 < 0.30:
wheel3 = "Hearts"
elif number3 < 0.65:
wheel3 = "Spade"
elif number3 < 1:
wheel3 = "Monkey"
return wheel1
return wheel2
return wheel3
def win(generator,balance):
generator(balance)
if wheel1 =="Monkey"and wheel2 == "Monkey"and wheel3 == "Monkey":
print "JACKPOT!"
winnings = int(50)
balance + winnings
print 'JACKPOT!'
else:
print 'noice'
winnings = int(10)
balance + winnings
print 'noice'
return balance
print "Welcome to the International Slot Machine"
print ""
print "Balance: $",balance
print ''
spinyn = (raw_input("Would you like to spin? $5 per spin. Enter y or n:\n"))
while True:
if spinyn == "y":
break
elif spinyn == "n":
print "Final Balance: $",balance
print "Thank you for using the International Slot Machine"
raise SystemExit
else:
spinyn = raw_input('\033[31mPlease enter only y or n.\033[0m\n')
spin = (raw_input("Press enter to spin for $5:\n"))
while True:
if spin == '':
balance = balance - 5
if balance <= 0:
print ""
print "Final Balance: $",balance
print "You have run out of money, the game has now ended."
raise SystemExit
print ""
print "\033[34mResult:\033[0m"
print "\033[34m-------\033[0m"
balance = generator(balance)
print ""
print win(generator,balance)
print "New balance:$",balance
print ""
spinagain = (raw_input("Would you like to spin again? Press enter to spin again, type anything to exit.\n"))
while True:
if spinagain == "":
break
else:
print "Final Balance: $",balance
print "Thank you for using the International Slot Machine"
raise SystemExit
else:
spin = (raw_input("Please press enter to spin.\n"))
I appreciate any suggestions about the method of selecting a random symbol, but please withhold as there is only one question I have. My question is: In the win function, how do I make it recognise the 3 wheel outputs. I've done what I thought would work however it does not, even when I land on 3 monkeys.
Any other suggestions are welcome. But please keep in mind that is the most important.
Thank you very much in advance.
The problem that you have here is that your concept of scope needs a little help.
This answer is a really good start.
To make a short example of your code, let's just do this:
def generator(balance):
wheel_1 = 'Monkey'
wheel_2 = 'Diamond'
wheel_3 = 'Heart'
return wheel_1, wheel_2, wheel_3
def win(generator):
print wheel_1, wheel_2, wheel_3
win(generator)
What you'll get here is a NameError, because wheel_1 (and 2 & 3) don't actually exist within the win function. They only exist within the generator function. So what you need to do is get the values from the generator function, and put them somewhere that 'win' can see. You can actually do this pretty easily, since we're already returning the values from the generator function:
# Note: generator was removed as a parameter.
# We don't need it here, because if Python
# can't find the name `generator` it will look
# in the enclosing scope and find the function
# `generator` there.
def win():
# What we want to do is *call* `generator` and
# assign the results to some variables that *are*
# in `win`'s scope
wheel_1, wheel_2, wheel_3 = generator()
print wheel_1, wheel_2, wheel_3
As you mentioned, you can definitely improve some things in your current code. You've noticed inside your generator function there's code that looks almost exactly the same. When you look at code and you get that feeling, that's what's called a "code smell". That's what happens when your (sub)conscious mind sees some code that it knows could be improved. In this particular case there's a principle called DRY - Don't Repeat Yourself.
You can replace your existing code with the following:
def spin_one():
number = random.random()
if number < 0.05:
result = 'Cherry'
elif number < 0.15:
result = 'Diamond'
elif number < 0.30:
result = 'Hearts'
elif number < 0.65:
result = 'Spade'
else:
result = 'Monkey'
return result
def generator():
return spin_one(), spin_one(), spin_one()
And what I might even do is remove the generator call altogether and simply do this:
if all((spin_one() == 'Monkey' for _ in xrange(3))):
You can read the docs on all.
Though, if you want to have more than just win a lot and win a little, then you'd need to keep the values:
wheels = [spin_one() for _ in xrange(3)]
Then you can do:
if all(wheel == 'Monkey' for wheel in wheels):
# Alternatively, wheels.count('Monkey') == 3
print 'Jackpot'
elif wheels.count('Hearts') == 2:
print 'Win'
elif all(wheel == 'Lemon' for wheel in wheels):
print 'You lose'
And any other kind of winning you might want to add.
Prompt
I don't think this is either better or worse than your current prompt approach, but I used to use it all the time in my C++ course.
def prompt():
choice = raw_input('(Y)es or (N)o: ').lower()
if choice == 'y':
return True
elif choice == 'n':
return False
else:
print '**ERROR** Please input "y" or "n"'
return prompt()
It's a nice, simple way to get a handle on recursion :)

Categories