I am making a text-based game on python using the class system to keep track of main character changes (like its name). I am writing the main code for the game outside of the Main Character Class- inside of the main function.
I am struggling because I need to update self.character_name inside the Main Character class to an input from the user inside the main function. I am unsure how to do this, I have the code written below- however it is not updating the name inside Main Character class. How can I rewrite this?
I'm also worried that I will have this problem when trying to update pets, characters_known. However, I do not seem to have this problem with updating Health or XP....
class Main_Character():
def __init__(self):
self.health=100
self.exp=0
self.level=0
self.character_name=""
self.characters_known={None}
self.pets={None}
self.progression_tracker=0
def __str__(self):
return "Name: "+ str(self.character_name)+" | "+ "Health:"+ str(self.health) + " | " +"XP:"+ str(self.exp) + " | "+ "Level:"+ str(self.level)+" | "+"Pets:"+str(self.pets)
def Char_Name(self,name):
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
else:
self.character_name=name
def Char_Level_Experience(self,exp,b):
self.exp+=exp
b=2
if exp<=0:
exp=1
ans = 1
level=0
while ans<exp:
ans *= b
level += 1
if ans == exp:
self.level=level
print("You have reached level", self.level)
else:
level = int(log(exp, 2))
level = min(level, exp)
if level>=0:
self.level=level
else:
level=0
def healing(self,heal):
if self.health+heal>=100:
self.health=100
else:
self.health+=heal
def other_answers(answer):
if answer=='quit':
raise SystemExit
if answer=='pets':
print("Pets owned:", Main_Character().pets)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
elif Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
if answer=='characters':
print("Characters met:", Main_Character().characters_known)
user_decision=input("Would you like to continue where you left off? Type 'yes' to continue, or 'no' to go back to main menu:")
if user_decision=='yes':
if Main_Character().progression_tracker==0:
main()
if Main_Character().progression_tracker==1:
choice1()
if user_decision=='no':
main()
else:
other_answers(user_decision)
def start_check():
print("If you understand the game, type 'go' to continue- if not, type 'more information' to receive more information about how to play the game")
begin_game=input("")
if begin_game=="go":
choice1()
if begin_game=='more information':
print("\n","The object of the game is to gain XP [experience points] without dying")
start_check()
else:
other_answers(begin_game)
def choice1():
Main_Character().progression_tracker=1
print("You are a knight in the Kings Guard- the King has asked to meet with you about a very special mission")
print("What would you like to do?")
print(" 1.Go Directly to King","\n", "2. Finish your dinner")
choice=input("1 or 2?")
if choice=="1":
Main_Character().Char_Level_Experience(1,2)
elif choice=="2":
Main_Character().Char_Level_Experience(.5,2)
else:
other_answers(choice)
print(Main_Character())
def main():
print("Welcome!")
unfiltered_name=input("Please enter the name of your character:")
Main_Character().Char_Name(unfiltered_name)
print("Welcome,", Main_Character().character_name,"!", "Here are your current stats!")
print(Main_Character())
start_check()
You haven't quite understood how classes and instances work.
Calling the class is what you do when you need a new character. Every time you call Main_Character(), you get a whole new instance - with the default values as set in __init__. If you had characters for each of your friends, you would call it one time for each one. You then would need to keep each of those instances in a variable, so you can reference them again each time.
So, for instance:
my_character = Main_Character()
unfiltered_name=input("Please enter the name of your character:")
my_character.Char_Name(unfiltered_name)
print("Welcome,", my_character.character_name,"!", "Here are your current stats!")
print(my_character)
You create a new character each time you call Main_Character. Instead, you should call it once:
the_character = Main_Character()
...
the_character.name = "..."
Related
I'm a beginner in Python and I'm writing a code for a school project and ran into an early bug.
For some reason my if function won't run.
import time #imports computer time to program(buit in function)
count= 0
print(" Gymship") # center this
print("--------------------------------------") # this should go across the whole screen
print("Input a level to view the description or InputSign up to begin signing up for a card")
print("--------------------------------------------------------------------------")
print("Bronze")
time.sleep(1) # this wil pause the program for 1 second(for effect)
print("Silver")
time.sleep(1)
print("Gold")
time.sleep(1)
print("Platinum")
time.sleep(2)
print("-----------------------------------------------") # this should go across the whole screen
print("Sign up")
print(" ")
input()
if input == "Bronze":
print("Bronze")
print("--------------------------------------------")
print("You acquire a bronze card when you use two or less gym services")
print("2 Hours limit in the gym")
print("-------------------------------------")
print(input("Back to return to menu screen"))
count = count + 1
This is not correct:
input()
if input == "Bronze":
The way input() works is by returning a value. The name input refers to the function itself, so the function input will never equal the text "Bronze" unless you explicitly do something bad, like input = "Bronze" (it's bad because if you overwrite input, you'll no longer be able to access that function).
Instead, you should be using the returned value:
usr_input = input()
if usr_input == "Bronze":
Also, the line print(input("Back to return to menu screen")) is unnecessarily complicated; the print() will print whatever was returned by input(), but input() will display the "Back to return to menu screen" prompt without wrapping it in an if statement. So, input("Back to return to menu screen") is all you need. If you keep it the way you have it, if someone typed some text and then hit enter, the text would display again, because the print() is printing whatever that text was that the user typed.
You first need to assign a variable to the input and then check if the variable is equal to "Bronze"
Right now you are taking the input, but are not storing it anywhere. So the fixed code would be
user_input = input()
if user_input == "Bronze":
I am working on a bank account program where the user logs in with a four digit number (pin).
I want to find a way to access a specific object with all its attributes at runtime after the right pin has been entered.
class Konto(object):
def __init__(self, account_holder, balance , pin):
self.account_holder = account_holder
self.balance = balance
self.pin = pin
I have three different objects defined in a list
kontoList = []
kontoList.append(Konto("Person1", 143541, 1223)),
kontoList.append(Konto("Person2", 6230, 1234)),
kontoList.append(Konto("Person3", 4578, 4321))
The last attribute is the Pin that is entered by the user. When the program checks the pin is '1234' for example it displays a menu where you can get the current balance, account holder etc. In this case it would be 6230 (balance) and Person2 (account holder). So here is some code:
pin = input("PIN: ")
for konto in kontoList:
if konto.pin == pin:
print("Valid PIN")
continue
else:
print("not valid")
break
while True:
print("1: Withdrawal \n"
"2: Deposit \n"
"3: Transfer \n"
"4: Current Balance \n"
"5: Account Holder \n"
"6: Quit \n")`
choice = input("Your Choice: ")
Is there any way to access the specific object during runtime and then go on to work with it? I've looked up getattr() but it does not seem useful in this situation.
You could simply create a list of pins, then check whether the pin you're checking is contained in that list:
kontoPinList = [konto.pin for konto in kontoList]
and then you would check whether your pin is in the kontoPinList with:
pin in kontoPinList
EDIT: If you want to keep working with the konto you do the following:
for konto in kontoList:
if konto.pin == pin:
#do something with the konto here
EDIT nr.2: If you wish to now call functions on the konto, such as account_holder(), you just do account_holder(konto) and that should work.
The reason my first response was to write a getPin() function is because while this will not solve your problem, it is a good idea to "protect" your variables by deciding how you want to return them. (it's more of a java thing than a python thing)
However, as you pointed out, it is a useless function if all you're interested in is simply returning konto.pin .
You could try something like this:
kontos_with_pin = filter((lambda k: k.pin == pin), kontoList)
if len(kontos_with_pin) == 1:
relevant_konto = kontos_with_pin[0]
# Do something with relevant_konto
else:
# handle case where there is no konto with that pin, or more than one, etc.
im doing a little project for myself to understand the function, if statement in python. i want to call the "name" inside the user function and use it in jungle function.
def user():
global name
name = raw_input("Whats your name?")
def jungle():
print name, "Please, Select your Enemy"
print '\n'.join(jungle_enemy)
enemy = raw_input('> ')
if enemy == "1":
print "The Lion Will eat you alive."
game_over()
exit_countdown()
elif enemy == "2":
print "The Jaguar will tear you apart."
game_over()
exit_countdown()
elif enemy == "3":
print "The Snake will eat you whole."
game_over()
exit_countdown()
else:
try_again("Are You Noob? \nNone of the Choice!")
jungle()
when i run this code. it gives me an error.
NameError : global name 'name' is not define.
Global variables are a bad idea in general. Better pass the variable to whoever needs it:
def user():
return raw_input("Whats your name?")
def jungle(name):
print name, "Please, Select your Enemy"
# etc.
and then call the functions like this
username = user()
jungle(username)
If you have to use global names, you need to use the global statement in all the functions that use that variable - so you need to add global name at the start of jungle(). But don't do that. See where global variables have taken JavaScript - you don't want to do that in Python.
I am reading the book "Python Programming for the Absolute Beginner (3rd edition)". I am in the chapter introducing custom modules and I believe this may be an error in the coding in the book, because I have checked it 5 or 6 times and matched it exactly.
First we have a custom module games.py
class Player(object):
""" A player for a game. """
def __init__(self, name, score = 0):
self.name = name
self.score = score
def __str__(self):
rep = self.name + ":\t" + str(self.score)
return rep
def ask_yes_no(question):
""" Ask a yes or no question. """
response = None
while response not in ("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
""" Ask for a number within a range """
response = None
while response not in range (low, high):
response = int(input(question))
return response
if __name__ == "__main__":
print("You ran this module directly (and did not 'import' it).")
input("\n\nPress the enter key to exit.")
And now the SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
So this is exactly how the code appears in the book. When I run the program I get the error IndentationError at for i in range(num):. I expected this would happen so I changed it and removed 1 tab or 4 spaces in front of each line from for i in range(num) to again = games.ask_yes_no("\nDo you want to play again? (y/n): ").
After this the output is "Welcome to the world's simplest game!" and that's it.
I was wondering if someone could let me know why this is happening?
Also, the import games module, is recognized in Eclipse after I added the path to PYTHONPATH.
I actually have this book myself. And yes, it is a typo. Here is how to fix it:
# SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
All I did was indent num 4 spaces and lined it up with the first for-loop.
You have an infinite loop here:
again = None
while again != "n":
players = []
If this is exactly the way it's printed in the book, the book does have an error.
You've got these two lines:
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
The second one is more indented than the first. That's only legal if the first one is a block-introducer like a for or while or if. Since it's not, this is an IndentationError. And that's exactly what Python is telling you.
(It's possible that you've copied things wrong. It's also possible that you're mixing tabs and spaces, so it actually looks right in your editor, but it looks wrong to Python. But if neither of those is true, the book is wrong.)
So, you attempted to fix it by dedenting everything from that for loop on.
But when you do that, only one line is still left under the while loop:
while again != "n":
players = []
There's nothing that can possibly change again to "n", so this will just spin forever, doing nothing, and not moving on to the rest of the program.
So, what you probably want to do is to indent the num = … line to the same level as the for i… line, so both of them (and all the stuff after) ends up inside the while loop.
I'm trying to make a text-based game in Python, however, code could get out of hand pretty quickly if I can't do one thing on one line.
First, the source code:
from sys import exit
prompt = "> "
inventory = []
def menu():
while True:
print "Enter \"start game\" to start playing."
print "Enter \"password\" to skip to the level you want."
print "Enter \"exit\" to exit the game."
choice = raw_input(prompt)
if choice == "start game":
shell()
elif choice == "password":
password()
elif choice == "exit":
exit(0)
else:
print "Input invalid. Try again."
def password():
print "Enter a password."
password = raw_input(prompt)
if password == "go back":
print "Going to menu..."
else:
print "Wrong password. You are trying to cheat by (pointlessly) guess passwords."
dead("cheating")
def shell(location="default", item ="nothing"):
if location == "default" and item == "nothing":
print "Starting game..."
# starter_room (disabled until room is actually made)
elif location != "default" and item != "nothing":
print "You picked up %s." % item
inventory.append(item)
location()
elif location != "default" and item == "nothing":
print "You enter the room."
location()
else:
print "Error: Closing game."
def location():
print "Nothing to see here."
# Placeholder location so the script won't spout errors.
def dead(reason):
print "You died of %s." % reason
exit(0)
print "Welcome."
menu()
First, an explanation on how my game basically works.
The game has a 'shell' (where input is done) which receives information from and sends information to the different 'rooms' in the game, and it stores the inventory. It can receive two arguments, the location and an eventual item to be added to the inventory. However, line 40-42 (the first elif block in 'shell') and line 43-45 (the last elif block in 'shell') are supposed to go back to whatever location the location was (line 42 and 45, to be exact). I've tried "%s() % location" but that doesn't work, it seems to only work when printing things or something.
Is there any way to do this? If not, even writing an engine for this game would be a nightmare. Or I'd have to make an entirely different engine, which I think would be a way better approach in such a case.
Sorry if I made any mistakes, first question/post ever.
elif location != "default" and item != "nothing":
print "You picked up %s." % item
inventory.append(item)
location()
elif location != "default" and item == "nothing":
print "You enter the room."
location()
I guess you want to call a function having its name. For that you need a reference to the module or class inside which it was defined:
module = some_module # where the function is defined
function = getattr(module, location) # get the reference to the function
function() # call the function
If the function is defined in the current module:
function = globals()[location]
function() # call the function
If I correctly understand what you want is something like this : player will enter a location name and you want to call the related method. "%s"()%location will not work, a string (that is what is "%s" is not callable).
Let's try an OOP way :
class Maze:
def __init__(self):
# do what you need to initialize your maze
def bathroom(self):
#go to the bathroom
def kitchen(self):
# go to the kitchen
def shell(self, location="", item=""):
if location == "" and item == "":
print "Starting game..."
# starter_room (disabled until room is actually made)
elif location and item:
print "You picked up %s." % item
inventory.append(item)
getattr(self, location)()
elif location and item == "":
print "You enter the room."
getattr(self, location)()
else:
print "Error: Closing game."
maze = Maze()
while True: # or whatever you want as stop condition
location = raw_input("enter your location :")
item = raw_input("enter your location :")
maze.shell(location=location, item=item)
I think you can use the getattr() method.
Example : You want to call method "helloword()" from module "test", you would then do :
methodYouWantToCall = getattr(test, "helloworld")
caller = methodYouWantToCall()
Hope it gives you a clue.