input variable inside of a function output outside of function - python

I'm pretty new to coding and I'm making an adventure "game" to help me learn. The player has a bit of dialogue to get through and a decision to make, which leads to different choices, two of which ask for their name. I can't seem to make the player_name variable appear in the next function, it just stays blank. I just want it as a global variable where I can continue to use it throughout the game.
player_name = ("")
def path_2():
print("I found you lying in the hallway.")
print("Maybe I should have left you there...")
player_name = input("What is your name? : ")
return player_name
def path_1():
print("It's a pleasure to meet you.")
print ("My name is Azazel. I am the warden of this place.")
print ("I found you lying in the hallway,")
print ("bleeding profusely from you head there.")
print ("")
player_name = input("What is your name? : ")
return player_name
def quest():
print(("This is a long story ")+str(player_name)+(" you'll have to be patient."))
enter()

When you're doing player_name = input("What is your name? : "), you're re-defining player_name in the scope of your function, so it's no longer pointing to the global variable, what you could do is:
def path_2():
print("I found you lying in the hallway.")
print("Maybe I should have left you there...")
global player_name
player_name = input("What is your name? : ")
Notice that you don't need to return player name, because you're modifying the global variable.

use global keyword before using the same variable in a function

You have a couple of concepts here that you'll need to sharpen up on to make this work. The first is the scope of a variable. The second is parameters and return values of functions. Briefly (you should research this more), the variables you create in a function are not visible outside that function. If you return a value, then you can catch it from the calling location. Using global variables is possible, but usually not the best approach. Consider:
def introduce():
player_name = input("tell me your name: ")
print("welcome, {}".format(player_name))
return player_name
def creepy_dialogue(p_name, item):
print("What are you doing with that {}, {}?".format(item, p_name))
# start the story and get name
name = introduce()
weapon = "knife"
creepy_dialogue(name, weapon)

Related

Creating a Python game, working with returns in-between multiple modules

No matter how many times I google variations of my question, I cannot seem to find a solution. I am a beginner programmer, trying to build a game that randomly generates events as you progress through the stages. The problem I am running into are return statements, and passing the values between different modules. Each method for each file are inside of classes. They are all static methods, and calling these methods is not my problem. It is transferring the value of the variables. I'm not sure where I am going wrong, whether it is how I am structuring it, or if I just don't understand how these return statements work.
This is the first File I am starting from. Print statements will be filled out after everything functions properly.
def story():
print("---Intro Story Text here--- ... we will need your name, Traveler. What might it be?")
user_prompt = Introduction.PlayerIntroduction
name = user_prompt.player_info(1)
print(f"Welcome {name}!")
print(f"----After name is received, more story... how old might you be, {name}?")
age = user_prompt.player_info(2)
This is the file I am trying to get the values from. File: Introduction, Class: PlayerIntroduction
#staticmethod
def player_info(funct_select):
if funct_select == 1:
name = PlayerIntroduction.get_player_name()
player_name = name
elif funct_select == 2:
age = PlayerIntroduction.get_player_age()
player_age = age
return player_name, player_age
#staticmethod
def get_player_name():
print("\n\n\nWhat is your name?")
players_name = input("Name: ")
while True:
print(f"Your name is {players_name}?")
name_response = input("Yes/No: ")
if name_response == "Yes" or name_response == "yes":
name = "Traveler " + players_name
break
elif name_response == "No" or name_response == "no":
print("Let's fix that.")
PlayerIntroduction.get_player_name()
else:
print("Please respond with 'Yes' or 'No'.")
return name
#staticmethod
def get_player_age():
print("\n\n\nHow old are you?")
age = input("Age: ")
while True:
print(f"Your age is {age}?")
age_response = input("Yes/No: ")
if age_response == "Yes" or age_response == "yes":
break
elif age_response == "No" or age_response == "no":
print("Let's fix that.")
PlayerIntroduction.get_player_age()
else:
print("Please respond with 'Yes' or 'No'.")
return age
I would like to use the values for "name" and "age" throughout multiple modules/multiple methods within my program. But in order to get those values, I need to assign a variable to the function call.. Resulting in prompting the user to re-enter their name/age at later stages in the game. My idea to combat this was in the first method of this module, creating a conditional statement "if 'example' == 1: 'run the name prompt' and elif == 2: run age prompt, thinking the initial run with the arguments defined would run these prompts, store the values into the variables (name, age), and finally pass the values to the new variables that are NOT assigned to the function call (p_name, p_age), avoiding triggering the user prompt over and over. Ultimately, this failed, and as the code sits now I am getting:
UnboundLocalError: local variable 'player_age' referenced before assignment
Why is this? The only instance 'player_age' is called that is reachable at this point is in the return statement, indented in-line with the conditional statement. The code should read (If I understand incorrectly, please explain) from top to bottom, executing in that order. The 'if' condition is met, so it should run that. If I were to define 'player_name' and 'player_age' as null at the top of this method to avoid this error, then every time I would need to reference these values initially entered by the user, they would be re-assigned to 'null', negating everything I am trying to do.
Thank you all for your patience, I tried to explain what I was doing and my thought process the best I could. Any feedback, criticism, and flaws within my code or this post are GREATLY appreciated. Everything helps me become a better programmer!! (:

Using a while loop to output a list after user input

I'm new to python and im attempting for my program to output a the variable "movie genre" vertically once a user enters their name. I plan to use a while loop but keep hitting the error "movie_genre". And perplexed as to how to proceed.
def main():
#Movie list
movie_genre = ["Action", ["Horror"], ["Adventure"], ["Musical"], ["Comedy"], ["Sci-Fi"], ["Drama"], ["Romance"], ["Thriller"]]
name = ''
#We introduce the program to the user
print ("Hello my name is Frank, the theatre clerk!")
#Asks the user to input their name
print ("May I please know who i have the pleasure of speaking with?")
#User submits name
name = input("")
#Returns user name + prompt
print(name + ", pleasure to make your acquaintance!")
while name:
#Asks the user for what genre they want to watch
i = name ("What are we interested in watching today?")
for x in zip (*movie_genre):
print (x)
You didn't show error message but if this is your original indentations then problem is that you create movie_genre inside function - so it is local variable which exists only inside function, but rest of code is outside function and it can't access it. You should move all code inside function or you should keep all code outside function.
I will keep all outside function - so I can remove it.
There are other mistakes and few elements which you could fix
You could keep genders withou inner [] and then you don't need zip(*...)
movie_genre = ["Action", "Horror", "Adventure", "Musical", "Comedy", "Sci-Fi", "Drama", "Romance", "Thriller"]
for genre in movie_genre:
print(genre)
You use name in strange way in i = name(..) - name is a string and you can't use it like a function. Maybe you needed input() to ask for selected genre - selected = input(...) - but I would do this after displaying genres.
I also don't know what you want to do with while name. This will run loop forever because you doesn't change name inside loop. Maybe you need something different - ie. maybe you want to repeate loop until user select correct gender - `while selected not in movie_genre:
Full example
#Movie list
movie_genre = ["Action", "Horror", "Adventure", "Musical", "Comedy", "Sci-Fi", "Drama", "Romance", "Thriller"]
name = ''
#We introduce the program to the user
print("Hello my name is Frank, the theatre clerk!")
#Asks the user to input their name
print("May I please know who i have the pleasure of speaking with?")
#User submits name
name = input()
#Returns user name + prompt
print(name + ", pleasure to make your acquaintance!")
# --- select genre ---
selected = "" # default value before loop
while selected not in movie_genre: # repeate until user select genre
for genre in movie_genre:
print(genre)
#Asks the user for what genre they want to watch
selected = input("What are we interested in watching today?")
movie_genre isn't defined in the same scope as where you are trying to use it.
This can be fixed in a variety of ways, either indent all of your code so it is under the same scope as the main function, and then call that function using main()
Or
A simpler fix is to just move the definition of movie_genre closer to where you will use it:
movie_genre = [["Action"], ["Horror"], ["Adventure"], ["Musical"], ["Comedy"], ["Sci-Fi"], ["Drama"], ["Romance"], ["Thriller"]]
if name:
#Asks the user for what genre they want to watch
print("What are we interested in watching today?")
for x in zip(*movie_genre):
print(x)

Calling a variable from one function to the other (Python)

I'll start by saying that I did look up answers to this question and unfortunately, I just couldn't understand them or they didn't seem to work for me. This is of course down to me rather than the people who answered the question, so I do apologise in advance.
So pretty much I'm trying to call a variable that is assigned by the user from one function to the other, I'll give an example:
def function_one():
a = input("What is your name?")
return a
def function_two():
print("Nice to meet you, "a)
function_one()
function_two()
This of course does not work and I'm sure that is down to my own stupidity, I wasn't sure why at first because I saw other people saying to simply return the variable, which I did!
I also tried calling the variable from the other function, for example:
def function_two()
a = function_one()
but I realised that was pretty stupid since I'm just assigning that function as a, so it's not going to work.
I'd appreciate some insight, I know these are not the kind of questions you'd expect but yeah... I'm clueless.
I think what you want to do is take user input, store it in a variable, then greet the user using that variable:
def ask_for_users_name():
name = input("What is your name?")
return name
def greet_user(name):
print("Nice to meet you, " + name)
users_name = ask_for_users_name()
greet_user(users_name)
One important thing to note is that I had to concatenated the name with the string "Nice to meet you, " using the + operator.
Edit:
To answer to the question in the comments, you could do something like this in that case:
def ask_for_user_info():
name = input("What is your name?")
age = input("What is your age?")
return name, age
user_name, user_age = ask_for_user_info()
Best practice is to make functions that only do one thing, for many reasons, one is that the name of the function normally replaces any need for inline comments:
def ask_for_user_name():
name = input("What is your name?")
return name
def ask_for_user_age():
age = input("What is your age?")
return age
In the case of the ask_for_user_info() method, it isn't immediately clear what exactly it is doing from the name.
Edit 2:
You could then use those two functions like this, in either order:
age = ask_for_user_age()
name = ask_for_user_name()
or
name = ask_for_user_name()
or
age = ask_for_user_name()
you do have it. this should work.
def function_two():
a = function_one()
print('hi {}'.format(a))
then
>>>function_two()
Another way is to use this:
def ask_for_users_name():
name = input("What is your name?")
greet_user(name)
def greet_user(user_name):
print("Nice to meet you,"+user_name)
ask_for_users_name()
You merely call ask_for_users_name() at the end.
Edit:
greet_user_() is a void function, which means it does not return anything. In this case, all it does is receive input passed to it and prints it. If you want to perform other operations, you can pass it additional parameters, or keep it the way it is.
Version 1:
def ask_for_users_name():
name = input("What is your name?")
age = int(input("What is your age? "))
print("Your age is ", age)
greet_user(name)
def greet_user(user_name):
print("Nice to meet you,"+user_name)
ask_for_users_name()
In version 1, we are still utilizing greet_user() to just print one thing, and performing another print operation in ask_for_users_name().
Version 2:
def ask_for_users_name():
name = input("What is your name?")
age = int(input("What is your age? "))
greet_user(name, age)
def greet_user(user_name, user_age):
print("Nice to meet you,"+user_name)
print("Your age is", user_age)
ask_for_users_name()
In version 2, we are passing both age and name to greet_user(), which in turn prints out the passed variables. I hope this helps.

Validating an input with a function in Python

I'm really new to Python and I'm mainly just messing around. I'm trying to put together a function that validates a user input (in my case, to check wether the user writes either James or Peter. This is probably a very newbie question, but I was just wondering if my code is a good way to accomplish this function.
Thanks for any help.
namelist = "Peter", "James"
def nameinput():
global name
name = raw_input("Write a name. ")
def checkname(x):
while name not in namelist:
print "Try again"
nameinput()
else:
print "Good,", name
checkname(nameinput())
if name == "Peter":
print "This is a text for Peter"
elif name == "James":
print "This is a text for James"
No; there is no reason to use global variables here. Pass data around to the functions that need it.
def nameinput():
return raw_input("Write a name. ")
def checkname(name):
namelist = ["Peter", "James"]
while name not in namelist:
print "Try again"
name = nameinput()
else:
print "Good,", name
return name
name = checkname(nameinput())
Using global variables is generally frowned upon (it can really do stupid stuff if you don't always know what you are doing), so don't start doing so that early.
You could easily avoid that by returning the name from nameinput.
Also, you already have the name list. Do the following in the end:
if name in namelist:
print("This is a text for " + name)

Append Python returns instead of overwriting

I'm teaching myself Python and writing a simple GPA calculator. I have very little programming experience prior other than a college Java course, so bear with my code.
The premise is, the code will ask if you want to add a course to the list. If you do, it runs a function asking you the class name. Every time you add a class it'll ask if you want to add another. If you don't, it'll spit out a list of the classes you've added and then ask you to enter in the grades. I didn't get the grading part done yet. I don't think that will be too hard.
The problem is you can add a bunch of classes and it will only spit out the last one you entered. I'm assuming the issue is in askAgain(): classList = addClasses() because it keeps overwriting, but I'm not sure how to avoid a global variable (since they're bad?) and still keep this from overwriting itself. I seem to draw a blank when trying to figure out how to call something once to intialize it and not run it again. I've also read that conditional variables are bad, so I'm not sure what's best practice here. thanks
def main():
askAgain()
return 0
def askAgain():
while True:
addOrNot = raw_input("Add a class? [y/n]: ")
if addOrNot == "Y" or addOrNot == "y":
classList = addClasses() #This is probably where my issue is.
else:
try:
editClassGradeSelection = mainMenu(classList)
addGrades(editClassGradeSelection, classList)
except:
print("Hey you didn't add any classes yet.")
def addClasses():
try:
if classList in locals():
print("debug msg - classList exists")
except:
classList = []
classList.append(raw_input("Add class to the list: "))
return classList
def mainMenu(classList):
print("Here are the classes you've added: ")
counter = 0
for classes in classList:
print((str(counter+1)) + ". " + (str(classList[counter])) + "\n")
counter = counter + 1
while True:
editGrade = raw_input("Enter the number for the class grade to edit: ")
if int(editGrade) > len(classList) or int(editGrade) < 1:
print("Enter a proper number in the range listed.")
else:
break
return editGrade
def addGrades(editClassGradeSelection, classList):
print("debug stuff for now: ")
print((str(editClassGradeSelection)))
print((str(classList[:])))
if __name__ == '__main__':
main()
Although this snippet makes sure classlist is defined:
try:
if classList in locals():
print("debug msg - classList exists")
except:
classList = []
classlist is a local variable, hence everytime you run that function, classlist will be [], which probably explains why you can't ever display more than one. The classlist you assign it to gets reassigned to the one element of classlist (addClasses scope) every time this line is called:
classList = addClasses() #This is probably where my issue is.

Categories

Resources