Here is my approach to simulate a goto sequence. Is there a more eloquent way?
PS: the idea with storing the variable in a class variable was just for fun (because of the .(format()) accessing story.
n=0
while n==0:
print("Whats your height?")
height=input()
print("Whats your age?")
age=input()
class loop:
h=height
a=age
print("Your height is {answer.h}".format(answer=loop()))
print("Would you like to continue?")
answer=input()
if answer=="yes":
++n
print("alright ONE MORE TIME!")
else:
print("see you")
Solution
class Person():
def __init__(self,name, height, age):
self.name = name
self.height = height
self.age = age
while True:
name = input("What's your name?\n")
height = input("What's your height?\n")
age = input("What's your age?\n")
user = Person(name, height, age)
print(f"\nHello {(user.name).title()}, your height is {user.height} and you are" \
f" {user.age} years old!")
answer = input("\nWould you like to continue?('yes' or 'no')\n")
if answer == 'yes':
print("alright ONE MORE TIME!")
continue
else:
print("See you!")
break
This is how I would go about this, although there is no reason to have a class here for what you are trying to accomplish, but since you had it in there I'm assuming you were using it as practice, so I threw in a class here as well.
Edit
Ah you mentioned the class was for fun, not claiming I used class in the best fashion here but it's an improvement for the way you attempted, would definitely look over proper utilization of class.
Related
I'am new to python, and i decided to make a simple quiz game.
The idea is:
Your base health is 100, every wrong answered question is -25 hp.
If hp equals 0 you lose.
And here lies the problem. I don't know how to pass the variable from function to a second function (in this case, every question in quiz is a different function)
The problem is that in every function, hp resets to its basic number (100).
Sorry if i poorly described my problem but im not very fluent in english.
Already tried to make a function that contains ,,hp = 100", making it global etc. Also tried various stuff with ,,return".
hp = 100
def test1():
test = input("yes no")
if test == "yes":
print("this is hp test")
print(hp - 25) # should be 100 - 25 = 75
test2()
if test == "no":
print("ok")
input("dead end")
def test2():
test2 = input("yes no")
if test2 == "yes":
print("this is second hp test")
print(hp - 25) # should be 75 - 25 = 50
if test2 == "no":
print("ok")
input("another dead end")
input("start")
test1()
I am not really sure what your trying to achieve here.
But i would suggest using a class that will allow you to have better control over your variables.
class Game:
def __init__(self):
self.hp = 100
def takeInput(self):
self.current = input()
self.computeScore()
def computeScore(self):
if self.input ==="Something":
self.hp -= 25
if self.checkValidScore():
self.takeInput()
else:
print "game over"
def checkValidScore(self):
return self.hp < 0
The statement print(hp - 25) simply prints the value of hp minus 25. It does not actually modify the value of hp. You probably want:
hp = hp - 25
print(hp)
Use global inside each function declartion
hp = 100
def test1():
global hp # do this in each of your functions
test = input("yes no")
if test == "yes":
print("this is hp test")
hp -= 25 # which is equivalent to hp = hp - 25
print(hp) # here just print the updated variable
test2()
Keep in mind that using global variables is not considered a good practice because it might make your code very hard to debug. You can read more about it here.
Not sure what you want to achieve. If it keeps that simple you could also go in the following direction...
def test1(hp):
test = input("yes no")
stop_msg = None
if test == "yes":
print("not ok")
hp -= 25
elif test == "no":
print("ok")
stop_msg = "dead end"
else:
raise Exception("Expected input to be 'yes' or 'no'.")
return hp, stop_msg
def test2(hp):
test = input("yes no")
stop_msg = None
if test == "yes":
print("'yes' sucks")
hp -= 25
elif test == "no":
print("ok")
stop_msg = "another dead end"
else:
raise Exception("Expected input to be 'yes' or 'no'.")
return hp, stop_msg
def run_game(hp=100):
print("start...")
tests = [test1, test2]
for test in tests:
hp, stop_msg = test(hp)
print("hp: {}".format(hp))
if stop_msg:
print(stop_msg)
return
if __name__ == "__main__":
run_game()
Remarks:
If you want to implement a more complex decision tree, you could use any simple tree representation.
If you have always the same structure within testX functions, introduce one function with parameters for questions, answer, etc.
I'm currently writing up a simple program to manage a car yard for a rental company, i've gotten to the end with no real issues until now. To illustrate what I mean i'll posted my code and then my issue.
# class for Car_Yard
class CarYard():
def __init__(self, listOfCars):
self.availableCars = listOfCars
def carYardCarsAvailable(self):
print("Available Cars: ")
for car in self.availableCars:
print(car)
def carYardRentCar(self, rentCar):
if rentCar in self.availableCars:
print("Congratulations on renting your new car, here\'s the keys")
self.availableCars.remove(rentCar)
else:
print("We currently don't have that car in our yard")
def carYardReturnCar(self, rentCarReturn):
self.availableCars.append(rentCarReturn)
print("You have returned the car. Thank You!")
# class for Buyer and his/hers actions
class Buyer():
def buyerRentCar(self):
print("Which car would you like to rent out?" )
self.car = input()
return self.car
def buyerReturnCar(self):
print("Which car would you like to return? ")
self.car = input()
return self.car
# create objects from class and pass a list of cars to the car yard
carYard = CarYard (['Mazda','Holden','Ford','Porsche','Honda','VW','Toyota','Kia'])
buyer = Buyer
# infinite loop
while True:
print()
print("Enter 1 to see our wide range of cars")
print("Enter 2 to rent a car")
print("Enter 3 to return a car")
print("Enter 4 to leave the rental yard")
print()
userInput = int(input())
if userInput is 1:
carYard.carYardCarsAvailable()
elif userInput is 2:
rentCar = buyer.buyerReturnCar
carYard.carYardRentCar(rentCar)
elif userInput is 3:
rentCarReturn = buyer.buyerReturnCar
carYard.carYardReturnCar(rentCarReturn)
elif userInput is 4:
quit()
The issue that i'm having is when I run my code and enter 2 it automatically skips to the line "we currently don't have that car in our yard" and when I enter 3 is says "You have returned the car. Thank you!".
I'm trying to figure out why my code is not called the Buyer class to request for the input. Any suggestions on what I might be missing?
You shouldn't use is like that. The is operator tests whether 2 objects are the same, which is not the same as testing whether their values are equal. What you actually want is an equality test (e.g. userInput == 1).
Anyway, the source of your problem is that you're passing around methods instead of the values that are returned by those methods. For instance this may work better:
buyer = Buyer()
...
elif userInput == 2:
rentCar = buyer.buyerReturnCar()
carYard.carYardRentCar(rentCar)
By passing buyer.buyerRentCar you're passing a method to carYardRentCar, and naturally it's not able to match that method against anything in the list of cars. What you want is to pass a string that is returned by carYardRentCar(). This will cause that method to get invoked, asking the user for input, and then the result of that will get passed along, which is what you want
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.
Through some educational materials I've been tasked to use the below structure (the classes) for a text adventure game and am required to add a simple combat system for battle between a hero and an enemy.
Currently I am able to have an enemy created in each room and move between the start room(corridor) to the bathroom and back, but at this point I'm stuck. I can't determine where I should be creating my 'hero' or how I'd communicate the changes I'd need to make to the health attributes etc.
If I could structure the code in another way, I would be able to complete the game, but as it is there is a gap in my understanding of how to enable various sections of code communicate with each other.
Thanks,
Dave
# text based adventure game
import random
import time
from sys import exit
class Game(object):
def __init__(self, room_map):
self.room_map = room_map
def play(self):
current_room = self.room_map.opening_room()
while True:
next_room_name = current_room.enter()
current_room = self.room_map.next_room(next_room_name)
class Character(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
class Hero(Character):
def __init__(self, name):
super(Hero, self).__init__(name, 10, 2)
def __str__(self):
rep = "You, " + self.name + ", have " + str(self.health) + " health and " + \
str(self.attack) + " attack."
return rep
class Enemy(Character):
ENEMIES = ["Troll", "Witch", "Ogre", "Jeremy Corbyn"]
def __init__(self):
super(Enemy, self).__init__(random.choice(self.ENEMIES),
random.randint(4, 6), random.randint(2, 4))
def __str__(self):
rep = "The " + self.name + " has " + str(self.health) + \
" health, and " + str(self.attack) + " attack."
return rep
class Room(object):
def __init__(self):
self.commands = ["yes", "no"]
self.rooms = ["\'corridor\'", "\'bathroom\'", "\'bedroom\'"]
self.enemy = Enemy()
def command_list(self):
print("Commands: ", ", ".join(self.commands))
def enter_room_question(self):
print("Which room would you like to enter?")
print("Rooms:", ", ".join(self.rooms))
def leave_room_question(self):
print("Do you want to leave this room?")
print("Commands:", ", ".join(self.commands))
class Bathroom(Room):
def enter(self):
print("You enter the bathroom. But, wait! There is an", \
self.enemy.name, "!")
print(self.enemy)
print("You are in the bathroom. Need to take a dump? ")
self.command_list()
response = input("> ")
while response not in self.commands:
print("Sorry I didn't recognise that answer")
print("You are in the bathroom. Need to take a dump?")
self.command_list()
response = input("> ")
if response == "yes":
print("Not while I'm here!")
return "death"
elif response == "no":
print("Good.")
self.leave_room_question()
response = input("> ")
if response == "yes":
return "corridor"
else:
return "death"
class Bedroom(Room):
def enter(self):
pass
class Landing(Room):
def enter(self):
pass
class Corridor(Room):
def enter(self):
print("You are standing in the corridor. There are two rooms available to enter.")
self.enter_room_question()
response = input("> ")
if response == "corridor":
print("You're already here silly.")
else:
return response
class Death(Room):
QUIPS = ["Off to the man in sky. You are dead",
"You died, no-one cried.",
"Lolz. You're dead!"]
def enter(self):
time.sleep(1)
print(random.choice(Death.QUIPS))
exit()
class Map(object):
ROOMS = {"corridor": Corridor(),
"bathroom": Bathroom(),
"death": Death(),
"landing": Landing(),
"bedroom": Bedroom()}
def __init__(self, start_room):
self.start_room = start_room
self.hero = hero
def next_room(self, room_name):
return Map.ROOMS.get(room_name)
def opening_room(self):
return self.next_room(self.start_room)
a_hero = Hero("Dave")
a_map = Map("corridor")
a_game = Game(a_map, a_hero)
a_game.play()
If I were you, I would set out a game schema. You could find out asking yourself questions like this:
What are the really important entities?
In your case, as you have done, I would consider Character, Enemy, Room and Map, inheriting when it would be appropiate, like Character-> Hero and Enemy, and several types of room from Room as Bathroom, Corridor, ...
If I were you a consider using a data structure to represent the Map. For example, if you are considering do a text game adventure, you could think in different rooms as different states in your game. If you are in the bathroom, you could be attacked by an enemy and if you are in the bedroom, you can retrieve your hitpoints (life) so these places can be thought as different states.
As an example, you would an array for group all your different rooms (states)
rooms = ["bedroom", "bathroom", "corridor", "kitchen", "living_room"]
and other rooms that you can think about.
(there is probably a better example, more efficient and so on, so this example is to help you about not giving up when you gets stuck about an problem.
According to this example, if you use an array, you can assign a value to each room (equal to each position in the array)
Moreover, you will need to know the hero's position, so you could assign a random value to it using rand(). You can read links below for more information:
random docs python
stackoverflow answer
At last, you also would find useful to compare the hero's position, which would have a random assigned value previously with every position of your array or rooms
In this cases, you could use a if... elif.. elif... to compare those values and do something according to the room where your hero would be.
I hope this answer will be useful for you.
Let me know if you have any doubt about my answer.
Cheers
the question i have sounds complicated but i'm sure its simple. i want my code to remember if the player is male or female and take them down different paths. so males have one story and females have another.
while True:
sex = raw_input ("> ")
if sex.lower() not in ('male', 'female'):
print("What? Try again")
continue
else:
break
if sex.lower() == "male":
print("'Okay Mr %s get ready for the test, it won't be easy'")% name
elif sex.lower() == "female":
print("'Well Ms %s i hope youre ready for the test'")% name
def male_questions():
# all the questions for men
def female_questions():
# all the questions for women
while True:
sex = raw_input ("> ")
if sex.lower() not in ('male', 'female'):
print("What? Try again")
continue
else:
break
if sex.lower() == "male":
print("'Okay Mr %s get ready for the test, it won't be easy'")% name
male_questions()
elif sex.lower() == "female":
print("'Well Ms %s i hope youre ready for the test'")% name
female_questions()
Note that this is a poor implementation of a finite state machine. The link may be able to help you build a much (MUCH) better one.
Also possible (without a state machine) if all you need to do is vary the question:
class Question(object):
def __init__(self, male_q, female_q):
"""Question("Do you have a beard? ", "Purses or wallets? ")"""
self.male = male_q
self.female = female_q
questions = [Question("foo","bar"), Questions("spam","eggs"), ...]
for num,question in enumerate(questions, 1):
print("{}. {}".format(num, question.__dict__.get(sex, "male")))