I don't understand code behaviour - python

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).

Related

Finding class via string

import random
class Game():
def __init__(self, username, gameId):
self.users = []
self.users.append(str(username))
self.gameId = gameId
def new_user(self, username):
self.users.append(str(username))
def remove_user(self, username):
try:
self.users.remove(username)
except:
print("[-] User not found!")
def generate_gameId():
gameId = ""
letters = 5
while(letters>0):
gameId += chr(random.randint(65, 90))
letters-=1
return(gameId)
lobby = []
for i in range(2):
lobby.append(generate_gameId())
lobby[i] = Game("Test", lobby[i])
lobby[i].new_user("Test123")
lobby[i].remove_user("Test123")
This is my code for a simple networking game, I will have multiple Game classes at the same time, but I need to find the specific object of a specific gameId. The gameId is randomly generated. Each time a user wants to join the lobby he has to enter the gameId to enter.
How would you achieve something like this? Am I doing it wrong?
There are some things that can be refactored in your code:
In the constructor of your Game class, there's no need for a username parameter, since there's already a new_user method:
class Game():
def __init__(self, gameId):
# Just create the list of users
self.users = []
self.gameId = gameId
# ...
lobby = []
for i in range(2):
lobby.append(generate_gameId())
lobby[i] = Game(lobby[i])
# Use the `new_user` method to create a Test
lobby[i].new_user("Test")
lobby[i].new_user("Test123")
lobby[i].remove_user("Test123")
You're storing the ids in an integer list. You should use a dictionary given that a game will have an unique id:
lobby = {}
for i in range(2):
game_id = generate_gameId()
game = Game(game_id)
# Create a entry in the dictionary
lobby[game_id] = game
game.new_user("Test")
game.new_user("Test123")
game.remove_user("Test123")
Then, you can access the list of games and their ids:
for game_id, game in lobby.items():
print(f'The game {game_id} has the following users:')
for user in game.users:
print(user)
print()
The other guys said everything I was going to say so I deleted most of my post, but here's some other things you could improve on if you want:
You are not looking up a "Class" here. You're looking up an instance of a class, otherwise known as an object. The word "class" in programming always means "The definition of an object". Classes can be instantiated to make objects AKA instances. A good analogy is that a "class" is the blueprints for making a car, while the instance/object would be the car itself that was made using the blueprints(the class).
Don't combine naming conventions. You're combining camel case and snake case which is never a good idea, choose one or the other (python is usually snake case). Specifically, generate_gameId() should be generate_game_id(). This just makes it easier to write code without making spelling mistakes.

Printing variable which was taken from other class in other page

I tried to explain my problem as much as I could.
I can edit if you need.
class calculating:
def __init__(self,username,password,url):
self.username=username
self.password=password
self.url=url
def connectingTowebsite(self):
r=request.get("self.url")
# I achived number1 and number 2 by connectingTowebsite
return number1,number2
def sum(self):
number3,number4=self.connectingTowebsite()
# There are some calculating process here
number5=(numbers3+numbers4)
return number5
def addingtodatabase(self,divisionnumber):
# Then user send a number and methods' jobs are over
number6=(self.sum() / divisionnumber)
sql_query=("INSERT INTO SOMETHÄ°NG.....")
values=number6
return number6
# Now I want to use the number6 in a class in another page.
#this is another python file\secondpage.py
from firstpage import calculating
import sys`
from PyQt5.QtWidgets import QApplication, QMainWindow
class showingvalues(QMainWindow):
def __init__(self):
super().__init__()
# I have some codes here for my window and login process
# and a textedit to show the variables from firstpage\calculating
def calculate(self,divisionnumber):
result=calculating("myUsername","myPassword","myUrl").addingtodatabase(divisionnumber)
return result
def calculateSaveAndShow(self):
# User enter a divisionnumber
# Number1 and Number2 which have already taken from website by request
self.calculate("a division number from user") # I am using PyQt5 to get that.
Then all process over.
Dates has been inserted into database
I want to show the value which has been just saved on textedit on my application window
What is the best way to do that ?
I would store number6 as a property in your first class then you can just access it directly in your second class.
so in your addingtodatabas method:
self.number6 = number6
Then in showingvalues class you have access to it as:
number6 = calculating.number6
It seems that functions are already returning the values, you just need to assign it to a local variable.
Change self.calculate("a division number from user") to:
number6 = self.calculate("a division number from user")

How to use variable from constructor inside of methode?

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!

Program pauses and waits for user to hit return before finishing function

There is a while loop which constantly allows user input using the raw_input keyword, that input is then passed to a function called commands() which then routes the input to the command that the user specified. In this instance, Whenever I call function movement in my code, it makes the user press enter in the function and won't process the data until the user does hit enter.
Furthermore, it appears the program is returning part of code in function movement() back to the commands() function and thus is gives me the following glitch:
target leo2
Successful lock on Leo2
launch
Your mobile suit shifts as you begin moving towards Leo2 at coordinates [300, 100, 100]Invalid command
Type 'commands' for a list of valid commands
Distance from suit is: 200
As you can see, in the middle of the function it is trying to run the main whileloop from the main module, but it then goes back to running the function in the middle. Why does this occur, and how can I fix it?
My code:
Gundam2.py
import math
class Mobilesuits:
#class global variables/methods here
instances = [] #grid cords here
names=[]
def __init__(self,armor,speed,name,description,cockpit_description,\
radar_range, coordinates):
Mobilesuits.instances.append(self)
Mobilesuits.names.append(name)
self.armor=armor
self.speed=speed
self.name=name
self.description=description
self.cockpit_description=cockpit_description
self.radar_range=radar_range
self.coordinates=coordinates
#Intrinsically links mobile suits objects to their names.
#I want to be able to access each object directly through the name
def update_names(self):
Mobilesuit_names_instances_dictionary={}
for i in range(len(Mobilesuits.instances)):
Mobilesuit_names_instances_dictionary[Mobilesuits.names[i]] =Mobilesuits.instances[i]
return Mobilesuit_names_instances_dictionary
def can_detect(self, other):
for own_coord, other_coord in zip(self.coordinates, other.coordinates):
if abs(own_coord - other_coord) > self.radar_range:
return False
return True
def radar(self):
for other in Mobilesuits.instances:
if other is not self and self.can_detect(other):
print "%s detected at %s" % (other.description, other.coordinates)
def movement(self, target, official_target, currentmobilesuit):
print("Your mobile suit shifts as you begin moving towards %s at coordinates %s" %(target,official_target.coordinates))
distance = (currentmobilesuit.coordinates[0] - official_target.coordinates[0],\
currentmobilesuit.coordinates[1] - official_target.coordinates[1], \
currentmobilesuit.coordinates[2]-official_target.coordinates[2])
calculation=0
for i in distance:
calculation += abs(i)
print("Distance from suit is: %s" % (calculation))
#Make speed calculation based on distance away and speed of suit
#Errors:
#target without a suit gives error
maingundam.py
from Gundam2 import Mobilesuits
import thread
import time
#Main Variable/Object declarations:
Leo1=Mobilesuits(100,100,"Leo1","leo desc","dockpit desc",100,[100,100,100])
Leo2=Mobilesuits(100,100,"Leo2","leo desc","dockpit desc",100,[300,100,100])
Leo3=Mobilesuits(100,100,"Leo3","leo desc","dockpit desc",100,[100,150,100])
currentmobilesuit=Leo1
mobile_suit_names_list=currentmobilesuit.update_names()
#Main Function declarations
def commands(user_input,currentmobilesuit, mobile_suit_names_list):
#radar
if user_input == "radar":
currentmobilesuit.radar()
#Commands overview
elif user_input == "commands":
print("Command list:\nradar\ntarget (object)")
#Target objects
elif user_input.startswith("target"):
try:
global target
target=user_input.split()[1].title()
if mobile_suit_names_list[target]:
global official_target
official_target=mobile_suit_names_list[target]
print("Successful lock on %s" % (target))
except:
print("space object '%s' not detected" %(target))
elif user_input=="launch":
# try:
if official_target:
thread.start_new_thread(currentmobilesuit.movement, (target, official_target, currentmobilesuit))
# except:
# print("No target is selected")
#command not found
else:
print("Invalid command\nType 'commands' for a list of valid commands")
def active_delay(action, delay):
time.sleep(delay)
action()
#Main execution: paused
while True:
mobile_suit_names_list=currentmobilesuit.update_names()
commands(raw_input(),currentmobilesuit,mobile_suit_names_list)
Your second problem is that, if your user just hits Return, the return from raw_input is an empty string "", which is not handled by command(). You could fix this by adding the lines:
elif user_input == "":
pass
Your first problem is due to the way raw_input works; it always waits for user input followed by Return and is not designed for being used for continuous control input. This is trickier to fix. You might be better using a library designed for this sort of thing (continuous keyboard control), like pygame.

When a function in a class returns a value, where is it returned to?

I've been learning about Classes and I got my code to work, but I'm just wondering where does the returned value go?
code:
from sys import exit
from random import randint
class Game(object):
def __init__(self, start):
self.pie = [ 'pie test']
self.start = start
def play(self):
next_room_name = self.start
while True:
print "\n--------"
room = getattr(self, next_room_name)
next_room_name = room()
def rooom(self):
print "Test worked. good job"
return "piez"
def piez(self):
print "pie room"
exit(1)
a_game = Game("rooom")
a_game.play()
For example, in the code above I return "piez" in rooom() and it now takes me to the piez(self) function. However, where did the return value go to take me there?
Did it return "piez" outside the class and re-enter the class with the new value? Did it return the string "piez" to init(self, start) ? Did I just return the value to the previous function, play(self)?
Other than that, everything is working fine, but I just don't understand how I arrived at the piez(self) function, simply by returning "piez" in the previous function. In the past I jumped around functions just by typing in the name of it with (), but this way I'm returning a string and not sure how I'm jumping around.
Here's my observation:
1.) Instantiate class Game("Rooom") to a_game
2.) from a_game we call the play() function
3.) "Rooom" is sent to init and assigned to self.start
4.) play(self) starts and uses intialized function self.start and sets to next_room_name
5.) Loop starts. Next function is grabbed from next_room_name and assigned to room
6.) next_room_name is assigned to room() . Suddenly jump to rooom(self)
7.) We arrived at rooom(self) and return "piez"
8.) ?? Piez is returned somewhere... and we are now at piez(self)
Can someone help me fill in the gaps? It's driving me crazy. I hope I'm making sense... I've just been closely trying to understand this for an hour now, and even after breaking it down I seem to be misunderstanding something.
You have slight confusion here:
5.) Loop starts. Next function is grabbed from next_room_name and assigned to room
6.) next_room_name is assigned to room() . Suddenly jump to rooom(self)
The return value of any statement is assigned to the left hand side of the equal sign, if the equal sign exists.
When you write
x = hello()
This means:
"Call hello and store any return value in x"
So it should be
"The return value of the function called by room() is stored in next_room_name"
Hopefully this clarifies it for you.

Categories