How do I assign a function to a variable? - python

I'm creating a text game so here is the point where I got stuck at:
def characters():
def assassin():
dmg = 150
health = 500
print "Do you want to become an assassin ?"
choice = raw_input("> ")
if choice in ["Yes", "yes", "YES"]:
print "So you said %s about becoming an assassin" % choice
choice = assassin() # Error
else:
print "Templar detected!"
So I wanted to set the choice variable to the assassin() function and then I wanted to copy the properties of the assassin() function to the choice variable but all I get is error that says " assassin is not defined.".
So, how can I do that ?

You have two problems:
if choice == "Yes" or "yes" or "YES": doesn't do what you think it does.
In Python, x or y always returns True or False based on the values of x and y.
The Python intepreter inteprets that line different to how it would be intepreted in English.
It means the same as this if (choice == "Yes") or ("yes") or ("YES").
As a non-empty string has the Boolean value True, this is the same as if (choice == "Yes") or True or True. The first part of that - (choice == "Yes") or True has True as an argument to the or, so it (and therefore the whole line) will always be True.
The second problem is that you are misunderstanding how functions work.
Firstly, neither of these functions do anything. A function is a way of giving a name to some code, which makes your program shorter if you are calling it more than once.
Secondly, variables in a function definition (and functions defined inside others) aren't accessible outside the function. That is why the variable assassin isn't located outside the definition of the characters function.

The assassin function doesn't do anything other than assigning the variables dmg and health some values.

Related

How do I make my Python program redefine a variable based on a response?

So, I've made code for a Choose Your Own Adventure game, or at least the start of one, and I need to know how I can get my code to change a variable's definition based off of an input() response. Here's my code:
import time
import winsound
PlayerAttributes = None
dream_item = None
print("ADVENTURE")
time.sleep(1)
print("Programmed and Developed by:")
print("Gabe 'GabeCodes' Chavez")
time.sleep(2)
print("We meet our heroes.")
print("Alice: The trained explorer doesn't give up hope.")
print("Although she isn't the strongest, she is the smartest person in the crew.")
print("")
time.sleep(6)
print("Sean: The fun loveable Irishman. He is quick on his feet, but not so much")
print("in the classroom. He has an innate sense of direction.")
print("")
time.sleep(6)
print("Mark: While he is strong, he is very ill-tempered and easy to aggravate.")
print("He tends to sleepwalk and has an inexplicable fear of elephants.")
print("")
time.sleep(6)
print("Amy: Amy is one of the kindest. Not just in the crew, but as an overall person.")
print("She is great with medicine and doesn't fear Mark's anger. They actually make a great balance,
and a cute couple.")
print("")
time.sleep(6)
print("Choose your Character... ")
PlayerChoice = input()
if PlayerChoice == "Alice" or "alice":
PlayerAttributes == "smart" and "fast"
dream_item == "golden totem"
elif PlayerChoice == "Sean" or "sean":
PlayerAttributes == "clumsy" and "fast"
dream_item == "little green eyeball"
elif PlayerChoice == "Mark" or "mark":
PlayerAttributes == "strong" and "smart"
dream_item == "tiny box"
elif PlayerChoice == "Amy" or "amy":
PlayerAttributes == "kind" and "healer"
dream_item == "dark iced coffee"
print("You wake with a start. You see your door, window, and dresser.")
time.sleep(2)
print("'What was I dreaming?' you thought. 'There was a", dream_item, "or something.")
If you want to compare a single value to multiple values, using this kind of syntax will fail:
if my_animal is "cat" or "horse":
my_operation()
This is for several reasons.
The first is that operator precedence interprets the statement as:
if (my_animal is "cat") or "horse":
my_operation()
...and regardless of the truthiness of (my_animal is "cat"), "horse" by itself (or any string, scalar, non-empty sequence) will be evaluated as True.
The second reason this syntax fails is that the is operator checks that two object are the same object in memory, not equivalent values.
So to correct this you could say:
if my_animal == "cat" or my_animal == "horse":
my_operation()
If you have a lot of animals to check, this becomes cumbersome.
In that case I would recommend:
valid_animals = ["cat", "fish", "horse", "dog"]
if my_animal in valid_animals:
my_operation()
In the case where you're checking against different capitalization, I recommend converting the string to either all upper or lower case:
if character_name.lower() == 'alice':
character_action()
Lastly, where you say things like PlayerAttributes == "clumsy" and "fast", you're way off base there.
First, == is comparison, not assignment.
So fix that and open up a python interpreter and evaluate that statement by itself. E.g.,
>>> PlayerAttributes = "clumsy" and "fast"
>>> print(PlayerAttributes)
You'll get True because like we said above, strings are "truthy" and True and True evaluates to True.
If you want to assign multiple values to a single variable, you need to use a list, tuple, or some other sequence.
PlayerAttributes = ["clumsy", "fast"] # that's a list
To assign a value you need to use a single equal sign "=" and not doubles "==". The doubles are a comparison operator.
A few suggestions:
Choose a different naming convention for your variables (consult PEP8)
Consider using classes for Player and PlayerAttributes
Use an "else" in your conditional in case the user enters something unexpected
Ok, I realized that I made the program too complex for both the language and my knowledge in coding, so I simplified it alot. Here's the code:
import time
import winsound
gender = ["boy", "girl", "Boy", "Girl"]
##It's simpler now. No set names, rooms, or big choices
print("Are you a boy or girl?")
genderChoice = input("Insert here -> ")
name = input("What is your name?")
if gender = "boy" or gender = "Boy":
friend = input("Your roommate walks in looking worried. Her name is...")
elif gender = "girl" or gender = "Girl"
##almost the same thing, just with the genders switched

Struggling with loops and statements

So I've almost finished a calculator but after giving the results, I want it to ask if I'm still gonna use it.
At the beginning of the code I have this loop to make it start again unless I typed 'n'.
# LOOP TO MAKE IT STAY ON
import sys
from colorama import init
from colorama import Fore, Back, Style
init()
while True:
Then the rest of the code which is finished goes on.
Then, at the end, I've tried this:
answer = input()
def badanswer():
if answer != "y" or "n":
return True
else:
return False
while badanswer is True:
print ("Wrong answer")
answer = input(("Wanna keep using the calculator? y/n "))
if badanswer is False:
if answer == "y":
continue
else:
break
sys.exit()
Somehow when I test it I type a random letter (not y or n) and the program continues... What I am missing here? I'm pretty new to python so forgive my mistakes! Thanks.
One problem is the
if answer != "y" or "n":
"or" is a logical operator, and does not allow you to "double" a != comparison like you are trying to do. The actual meaning of this statement is if answer is not "y", or if "n", and "n", like any nonempty string, is always True in boolean context.
You want
if answer not in ("y", "n"):
You also need to actually call badanswer() by adding the parentheses.
There's also no reason to add the if True to the loop condition — while badanswer() does the same thing.
badanswer is a function, not a boolean. You need to call the function and get its return value, like so: if badanswer() is True
However, your logic for exiting the program is needlessly contrived. You don't need the badanswer function at all. Just get the input from the user and check whether it is 'y' or 'n'.
while True: # loop for exit prompt
answer = input("Wanna keep using the calculator? y/n ").lower()
# using .lower() to permit 'Y' and 'N' as well
if answer == "n":
sys.exit()
elif answer == "y":
break
# exits from the 'exit prompt' loop,
# returns to the outside calculator loop
else:
print("Bad answer!")
Note: As mentioned in the comments, sys.exit() is a pretty cutthroat way to exit your program. You can do it more gracefully by modifying a variable that is checked by the outer calculator loop; e.g., initialize a variable keep_running = True, run the main loop with while keep_running: (...) and if the user requests to exit from the calculator, set keep_running = False so that the main loop exits.

If statement not working properly inside a while loop [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Why does non-equality check of one variable against many values always return true?
(3 answers)
Closed 3 years ago.
So I'm doing a calculator in python, I have the code for it inside a while loop and a prompt to ask the user if they want to restart the program (that's what the while loop is for) but it does not seem to work properly, am I missing something? I'm kinda new to programming so maybe there is something blatantly wrong that I just don't see. (I did not add the full code but I did import the necessary libraries ("sys" and "math"))
var1 = True
while var1 == True:
op = eval(input("\n Your operation: "))
print(f"\n The result would be: {op}")
var2 = input("\n Would you like to do another operation? If so type yes: ")
if var2 != "yes" or "Yes" or "YES" or "y" or "Y" or "1":
print("\n Ok then, exiting... \n")
sys.exit()
So if the user types, for example, "yes" in the prompt, it should restart the program, but it executes the if statement anyways and closes the program even though the condition for it doesn't apply.
I have tried adding an "else" statement like this:
if var2 != ... :
sys.exit()
else:
print("Restarting...")
But it doesn't seem to work either.
I've also tried doing it the other way around, that is instead of checking if it does not match, check if it does match. Like this:
if var2 == ... :
print("Restarting...")
else:
sys.exit()
But that just gets stuck in the while loop and does not close the program.
I just don't see what's wrong in the code.
The correct way of doing it would be:
if var2.lower() not in ("yes", "1"):
print("Ok then, exiting...")
sys.exit()
You’re logic is backwards you need to exit if it ISNT yes also instead of using or (plus you’re using it incorrectly) use in and instead of typing all the different variations of Yes use star.lower():
var1 = True
while var1 == True:
op = eval(input("\n Your operation: "))
print(f"\n The result would be: {op}")
var2 = input("\n Would you like to do another operation? If so type yes: ")
if var2.lower() not in ("yes", "1"):
print("\n Ok then, exiting... \n")
sys.exit()

Python, not following if statements [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 6 years ago.
I'm trying to create a text bases dungeon game. Just for fun and practice but I'm having a problem with Python not following my if blocks. The weird thing is that it worked when I first typed it out, but a day later it's not. It's treating as if all conditions are true.
choosing_race = True
while choosing_race == True:
print("options: Human, Elf, Dwarf")
p['race'] = input("Choose Race: ",)
print(p['race'], choosing_race)
if p['race'] == "Elf" or "elf":
print()
print("Elves are nimble, both in body and mind, but their form is frail. They gain Bonuses to Intelligence and Dexterity and a Penalty to Constitution")
print()
confirm_race = input("Are you an Elf? ",)
if confirm_race == "yes" or "Yes":
p['int_mod_r'] = 2
p['dex_mod_r'] = 2
p['con_mod_r'] = -2
choosing_race = False
elif confirm_race == "no" or "No":
print()
print("ok, select a different race")
else:
print()
print("Could not confirm, try again")
The p[race] input shows fine, but I can type anything (example duck) and it acts as if I typed elf. When I ask to confirm_race it's always returning yes. I assume I must have put a typo in there, but I can't find it. I redid all my indenting but still no luck. I'm going to try to restructure with functions and maybe that will help. In the mean time I'd love to know what went wrong here so I can prevent it in the future. Thanks. (I'm using Python 3, on my Nexus 5 phone is case that matters)
You are not getting the behavior you expect from lines like
if p['race'] == "Elf" or "elf":
In this case, "elf" evaluates to true every time. You want to instead write
if p['race'] == "Elf" or p['race'] == "elf":
or more concisely
if p['race'] in ["Elf", "elf"]:
or
if p['race'].upper() == "ELF":

Trying to return a True variable from a nested chain of functions (in Python)...

I'm trying to write part of an adventure game program in Python, and though I have most of it down, I'm stuck at trying to return a value declared as "True" at the end of one branch in the function chain. Basically, this is a fight against a monster, which you can win if you choose the right options. If you win, you obtain the bow that he was guarding. Here is the code of the fight:
#The first line imports all the text displayed in the game, saved in gametext.py
#For purposes of clarity, all text has been saved to variables imported by the file.
#Any variable that is not "HaveBow", "why" or declared by a raw_input() is actually text.
from gametext import *
def BG_fight():
print BowGuardIntro
print InitOptions
BGfirstmove = raw_input('> ')
if BGfirstmove == "1":
spearfight()
elif BGfirstmove == "2":
dead(BGUnarmed1)
else:
dead(BGUnarmed2)
def spearfight():
print GotSpear
print SpearFight
spearact = raw_input("> ")
if spearact == "1":
blindfight()
elif spearact == "2":
dead(SeeChest)
elif spearact == "3":
dead(SeeArms)
else:
dead(NoUseSpear)
def blindfight():
print BlindFight
followblow = raw_input("> ")
if followblow == "1":
print Victory
HaveBow = True
return HaveBow
elif followblow == "2":
dead(BlindArms)
else:
dead(BlindNoKill)
def dead(why):
print why
exit(0)
BG_fight()
(If people are interested, I can also produce the contents of the gametext file, though I would rather not as it is lengthy and has nothing to do with the problem I'm having)
As you can see, only one branch there offers the winning condition (which would give the HaveBow = True value that I want to return), and it is nested two functions deep and part of an if-statement. What I want to know is how I return that "HaveBow = True" value back outside the function chain, so it can be used in other parts of the game? If I try to code:
HaveBow = blindfight()
print HaveBow
at the end of the code and try to run it, it just makes me repeat that part of the game twice, before declaring "True". Same goes if I try BG_fight() instead of blindfight(). But I don't want that; I just want the "True" for "HaveBow" so I can use the condition "HaveBow = True" in other parts of the game.
In short, my question is whether or not it's possible to return a value from a nested function chain without repeating the code of that chain, and if so, how?
Thanks.
You can only return a value, not a name and a value. In other words, you cannot "return HaveBow = True"; all you can do is return True. There's no way to return a value and at the same time assign it to a variable that exists outside the function. If you want to assign the value, you need to do it outside the function.
From what you say, it sounds like you want HaveBow to be a global variable that you can use anywhere in your program. In that case, you can change your code in blindfight to do:
if followblow == "1":
global HaveBow
print Victory
HaveBow = True
Note that in this case you do not need to return the True value -- you just directly assign it to a global variable.
Ultimately there are better ways to structure your code, but those issues are out of the scope of this question. For the moment, I would suggest that, if you have global state like HaveBow that you want to be able to use "anywhere else in the game", you should make those global variables using global as I showed in my example. As you progress learning more programming, you will gradually learn why using global variables is not usually the best idea, but for the purposes of this program it is the simplest solution.

Categories