How to use variable from constructor inside of methode? - python

Hi guys hope u are doing well, i'm new with python :)
so i have two issues the first how can i use the variable name from the init to my function game() which it use two args (those args whose make it realy difficult for me !) as u can see in code bellow:
# FUNCTION.py
class penGame():
def __init__(self):
print("Welcome to Pendu Game")
self.name = input("Enter your name: ") # IMPORT THIS VARIABLE FROM HERE
def game(self, letter, rword):
letter = letter.lower()
if letter in rword:
for Id, Value in enumerate(rword):
if Value == letter:
donnee.default_liste[Id] = letter
else:
name2 = self.name # it deosn't work i got 1 missing arg when i run the code from MAIN.py
print(f"try again {name} it's wrong ")
print("-".join(donnee.default_liste))
The second issue is i need to use the same variable (name) from init in another module which is my main module and i couldn't use it cause i tried to create an object from class penGame() like:
myObject = penGame()
name2 = myObject.name
then use the name2 inside of the if condition as u can see bellow but it doesn't work properly cause it run the init again which is not what i want actualy !
any idea how can i did it plz?
#MAIN.py
import donnee
from fonctions import penGame
random_word = random.choice(donnee.liste_words) # creation of random word from liste_words
penGame() #call the constructor
while donnee.counter < donnee.score:
letter = input("Enter the letter: ")
if penGame.check(letter):
print("You cant use more one letter or numbers, try again !")
else:
penGame.game(letter, random_word) # as u can see that's the reason cause i supposed to send 3 args instead of two ! but i only need those two !!?
if penGame.check_liste():
myObject = penGame() # that's cause runing the init everytime !!
name2 = myObject.name
print(f"congratulation {name2} you've guessed the word, your score is: {donnee.choice-donnee.counter} point.")
break
if penGame.loser():
print(f"the word was {random_word.upper()} you have done your chances good luck next time.")
donnee.counter += 1
Thank u in advance hope u help me with that and excuse my english if it wasn't that good :) :)

1.Error
You're calling the methods on the class penGame, not on a instance of penGame.
This causes your missing argument error because the method needs an instance of the class (the self parameter) but don't get one.
Instead use your variable (from the second solution):
if mygame.check(letter):
print("You cant use more one letter or numbers, try again !")
else:
mygame.game(letter, random_word)
...
Replace penGame with mygame also in the other calls.
Error
Save the result of the call in a variable and you won't need to recreate it.
mygame = penGame() # call the constructor
This line can then be removed:
myObject = penGame() # that causes the init to run again because it creates a new instance!

Related

Input from user to print out a certain instance variable in python

I have created a class with programs:
class Program:
def __init__(self,channel,start, end, name, viewers, percentage):
self.channel = channel
self.start = start
self.end = end
self.name = name
self.viewers = viewers
Channel 1, start:16.00 end:17.45 viewers: 100 name: Matinee:The kiss on the cross
Channel 1, start:17.45 end:17.50 viewers: 45 name: The stock market today
Channel 2, start:16.45 end:17.50 viewers: 30 name: News
Channel 4, start:17.25 end:17.50 viewers: 10 name: Home building
Channel 5, start:15.45 end:16.50 viewers: 28 name: Reality
I also have created a nested list with the programs:
[[1,16:00, 17,45, 100, 'Matinee: The kiss on the cross'],[1,17:45, 17,50, 45,'The stock market today'],[2,16:45, 17,50, 30,'News'], [4,17:25, 17,50, 10,'Home building'],[5,15:45, 16,50, 28,'Reality']
Now we want the user to be able to write the name of a program:
News
The result should be:
News 19.45-17.50 has 30 viewers
I thought about how you could incorporate a method to avoid the program from crashing if the input is invalid/ not an instance variable
I have tried this:
Check_input():
print('Enter the name of the desired program:')
while True: #Continue asking for valid input.
try:
name = input('>')
if name == #is an instance?
return name
else:
print('Enter a program that is included in the schedule:') #input out of range
except ValueError:
print('Write a word!') #Word or letter as input
print('Try again')
I wonder if I should separate all the program-names from the nested list and check if the user enters a name in the list as input? (Maybe by creating a for-loop to iterate over?)
I also have a question regarding how to print out the selected program when the user enters the correct name? I understand how to rearrange them into the correct order to create the sentence. However, I don't know how to access the correct program in the "memory"
Do you have any suggestions how to combat the problem?
All help is much appreciated!
I wonder if I should separate all the program-names from the nested list and check if the user enters a name in the list as input? (Maybe by creating a for-loop to iterate over?)
Well if all your programs have a unique name then the easiest approach would probably be to store them in a dictionary instead of a nested list like:
programs = {
"News": Program("2", "16:45", "17:50", "News", "30", "60"),
"Reality": <Initialize Program class object for this program>,
...
}
Then you could just use the get dictionary method (it allows you to return a specific value if the key does not exist) to see if the asked program exists:
name = input('>')
program = programs.get(name, None)
if program:
print(program)
else:
# raise an exception or handle however you prefer
And if your programs don't have a unique name then you will have to iterate over the list. In which case I would probably return a list of all existing objects that have that name. A for loop would work just fine, but I would switch the nested list with a list of Program objects since you already have the class.
I also have a question regarding how to print out the selected program when the user enters the correct name? I understand how to rearrange them into the correct order to create the sentence. However, I don't know how to access the correct program in the "memory" Do you have any suggestions how to combat the problem.
I would say that the most elegant solution is to override the __str__ method of your Program class so that you can just call print(program) and write out the right output. For example:
class Program:
def __init__(self,channel,start, end, name, viewers, percentage):
self.channel = channel
self.start = start
self.end = end
self.name = name
self.viewers = viewers
def __str__(self):
return self.name + " " + self.start + "-" + self.end + " has " + self.viewers + " viewers"
should print out
News 19.45-17.50 has 30 viewers
when you call it like:
program = programs.get(name, None)
if program:
print(program)

Menu for a turn based game

Our teacher has assigned us an assignment for doing a turned based game.
This only included name.strip() but this does not prompt player to input unique name:
def start():
print("\nNew game started...Setting up Player 1's team...\n")
for total_characters in range (1,4):
name = input('Enter a unique name for unit #'+str(total_characters)+'==> ')
if not name.strip():
print('Cant be blank name,please provide a unique name')
return start()
else:
role_selection()
def role_selection():
for total_characters in range (1):
role = input('Select unit #'+str(total_characters)+' type: (W)arrior, (T)anker, or Wi(Z)ard ==> ')
total_characters+=1
if role.upper() == 'W':
pass
elif role.upper() == 'T':
pass
elif role.upper() == 'Z':
pass
else:
print("I don't understand what are you typing.")
return role_selection()
There are things that doesn't make sense :
You have the exact same function twice :
def set_up(team_size)
def set_up(name)
You are doing :
for total_units in range(team_size):
[...]
invalid = True
[...]
while invalid: # Infinite loop
set_up() # What's this function ?
As you can see from the comments in the code above, you never set invalid to False, leading to the infinite loop.
Note: My recommendation is that you should check out some tutorial on python before moving on coding a complex project, because your homework is not that easy.
Edit :
From the new code you've posted, you could do something like this :
def new_game():
names = []
for unit_id in range(1,4):
print(f'Enter a unique name for unit #{unit_id} ->')
empty = True
while empty:
name = input('>')
if name == "":
continue
empty = False
if name in names:
print('Unit name must be unique.')
else:
print('Name looks good!')
names.append(name)
python menu
At first glance, this stood out to me:
if not name.strip():
print('Unit name could not be blank.')
invalid = True
Remember in python the indentation matters. You are setting invalid to True regardless of the if condition. Further down you have a while loop that checks it.
The other if conditions have invalid=True inside the condition. Plus you don't have invalid=False anywhere as far as I see, so you'll get an error if you don't declare it somewhere so it's always on the path before the while.
this doesn't seem like a specific problem, more an ask for general guidance for going about this kind of problem?
One thing to note is that your above script only uses functions (which store behaviour) whilst really for something like the turn based game, you need to store behaviour (attacks etc) and information (how much health is left etc).
I won't write the script for you, but here's an example of how you might define an rpg like entity, capable of attacking, being attacked by another entity etc:
class Entity:
"""Abstract class for any combat creature"""
def __init__(self, name, health):
self.name = name
self.health = health
self.is_alive = True
def attack(self, other):
dmg = random.randint(7, 12)
other.be_attacked(dmg)
def be_attacked(self, dmg):
self.health = self.health - dmg
if self.health <= 0:
self.die()
def die(self):
self.is_alive = False
def check_life(self):
return self.is_alive
You can then initialise a bunch of these to make up the 'team' you where talking about:
one_person = Entity('Lee', 34)
another_person = Entity('Someone Else', 21)
etc. Hope that helps a bit. Good luck with your project and have fun!

How to print actual name of variable class type in function?

I'm trying to return variable name, but i keep getting this:
<classes.man.man object at (some numbers (as example:0x03BDCA50))>
Below is my code:
from classes.man import man
def competition(guy1, guy2, counter1=0, counter2=0):
.......................
some *ok* manipulations
.......................
if counter1>counter2:
return guy1
bob = man(172, 'green')
bib = man(190, 'brown')
print(competition(bob , bib ))
Epilogue
If anyone want to, explain please what I can write instead of __class__ in example below to get variable name.
def __repr__(self):
return self.__class__.__name__
Anyway, thank you for all of your support
There are different ways to approach your problem.
The simplest I can fathom is if you can change the class man, make it accept an optional name in its __init__ and store it in the instance. This should look like this:
class man:
def __init__(number, color, name="John Doe"):
self.name = name
# rest of your code here
That way in your function you could just do with:
return guy1.name
Additionnally, if you want to go an extra step, you could define a __str__ method in your class man so that when you pass it to str() or print(), it shows the name instead:
# Inside class man
def __str__(self):
return self.name
That way your function could just do:
return guy1
And when you print the return value of your function it actually prints the name.
If you cannot alter class man, here is an extremely convoluted and costly suggestion, that could probably break depending on context:
import inspect
def competition(guy1, guy2, counter1=0, counter2=0):
guy1_name = ""
guy2_name = ""
for name, value in inspect.stack()[-1].frame.f_locals.items():
if value is guy1:
guy1_name = name
elif value is guy2:
guy2_name = name
if counter1 > counter2:
return guy1_name
elif counter2 > counter2:
return guy1_name
else:
return "Noone"
Valentin's answer - the first part of it at least (adding a name attribute to man) - is of course the proper, obvious solution.
Now wrt/ the second part (the inspect.stack hack), it's brittle at best - the "variables names" we're interested in might not necessarily be defined in the first parent frame, and FWIW they could as well just come from a dict etc...
Also, it's definitly not the competition() function's responsability to care about this (don't mix domain layer with presentation layer, thanks), and it's totally useless since the caller code can easily solve this part by itself:
def competition(guy1, guy2, counter1=0, counter2=0):
.......................
some *ok* manipulations
.......................
if counter1>counter2:
return guy1
def main():
bob = man(172, 'green')
bib = man(190, 'brown')
winner = competition(bob, bib)
if winner is bob:
print("bob wins")
elif winner is bib:
print("bib wins")
else:
print("tie!")
Python prints the location of class objects in memory if they are passed to the print() function as default. If you want a prettier output for a class you need to define the __repr__(self) function for that class which should return a string that is printed if an object is passed to print(). Then you can just return guy1
__repr__ is the method that defines the name in your case.
By default it gives you the object type information. If you want to print more apt name then you should override the __repr__ method
Check below code for instance
class class_with_overrided_repr:
def __repr__(self):
return "class_with_overrided_repr"
class class_without_overrided_repr:
pass
x = class_with_overrided_repr()
print x # class_with_overrided_repr
x = class_without_overrided_repr()
print x # <__main__.class_without_overrided_repr instance at 0x7f06002aa368>
Let me know if this what you want?

Writing to text file error

Hi I am working on a program to store some files to a text document that can be reloaded when necessary. Below is the beginning of the code however when run I receive a trace back error stating "recipe_title is not defined" when I thought I had defined it as the name of the text file. Please help show me what I have done wrong.
import sys
opt=0
def choice1():
print("WORKED")
def choice2():
Recipe_Name = input("Please enter a recipe name: ")
Recipe_List = open(recipe_title.txt,"w")
Recipe_List.write(recipe_title+"\n")
def ingredient_input_loop(recipe_title, ):
Recipefile = open(recipe_title,"w")
if(ingredient== "end" or "End" or "END" or "EnD" or "eNd" or "enD" or "ENd" or "eND"):
Recipe.write(recipe_title)
recipe_title.txt is your file name and not a variable. Therefore you should add quotes
Recipe_List = open('recipe_title.txt',"w")
or if the recipe_title is really a variable:
Recipe_List = open('{}.txt'.format(recipe_title),"w") # now you can open brocolli.txt for example
General feedback about your code:
Variable names should not have Uppercase characters. This should only
be used for Class names.
Checking if for all the combinations of 'end' can be written to if ingredient.lower() == "end":

I don't understand code behaviour

I have the folowing code:
from random import randint
from medical_room import *
from Library import *
from basement import *
from End import *
class start_Game(object):
def __init__(self):
print "You landed on planet and see three rooms."
print "You approach and see that you need to enter password..."
self.door=raw_input("Pick number of door>>>")
self.password=('%d')%(randint(1,9))
self.entered_password=int(raw_input("Enter password of one digit>>>"))
self.ROOMs={'1':Medical_room,'2':Library,'3':basement,'4':End}
while True:
# break
room=self.ROOMs[self.door]
# print room()
self.door=room()
a=start_Game()
When asked about door number I pick '1' and class Medical_room is launched (code of class is below):
class Medical_room(object):
def __init__(self):
self.play()
def play(self):
print "Medical_room plays"
return '2'
But I can't switch to Library class since get error:
room=self.ROOMs[self.door]
KeyError: <medical_room.Medical_room object at 0x0000000002906978>
For me everything is ok, but Python doesn't like my 'great logic'. Please help.
Before the loop runs, self.door is a string. On the first iteration of the loop, you set self.door as a reference to an object on the first iteration. On the second iteration, you try to use that object as a key on self.ROOMS, but that dictionary has only strings for keys.
You need to set self.door to the string returned by play, I believe:
while True:
room=self.ROOMs[self.door]
self.door=room().play()
However, this doesn't allow you to choose a new door in each room (unless you change the definition of play).

Categories