Input from user to print out a certain instance variable in python - 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)

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.

How to create and print the contents of a class?

I am creating a class structure in python for a city, that stores the name, country, population and language for a city, all of which are input by the user. The information shall then be printed.
I think that I may be successful in storing the information within the class structure (although this may be wrong as well), but I am unsuccessful in printing the information. Currently, I am receiving the error that int object is not subscriptable.
class User():
def _init_(self, username, password, email, numOfLogins):
User.username = username
User.password = password
User.email = email
User.numOfLogins = numOfLogins
#User Record Array Creation
def createUserArray(num , User):
UserArray = []
for x in range(num):
UserArray.append(User)
return UserArray
#User Record Array Population
def populateUserArray(num, UserArray):
for x in range(len(userArray)):
UserArray[x].username = str(input("Enter username."))
UserArray[x].password = str(input("Enter password."))
UserArray[x].email = str(input("Enter email address."))
UserArray[x].numOfLogins = int(input("Enter number of logins."))
return UserArray
#User Record Array Display
def displayUserArray(UserArray, num):
for x in range(len(userArray)):
print(UserArray[x].username, UserArray[x].password, UserArray[x].email, str(UserArray[x].numOfLogins))
#Top Level Program
numOfUsers = 3
userArray = createUserArray(numOfUsers, User)
userArray = populateUserArray(numOfUsers, userArray)
displayUserArray(numOfUsers, userArray)
The contents of the class should all be displayed at the end of the program, but at the minute my program crashes due to the error - int object is not subscriptable.
you can always implement the method : __str__(self) of an object , and then when you just print it with :
your_obj = User(...)
print your_obj
your __str__(self) will be called and you can return from it whatever you want to print.
for example:
def __self__(self):
return `this class has the following attributes: %s %s %s %s` % (self.username,self.password,self.email ,self.numOfLogins )
and this what will get print, i think it is more efficient and well coded to work like that and not creating a function that print each class attribute separately.
The cause of your error is quite simple and obvious: you defined the function as displayUserArray(UserArray, num) but call it with displayUserArray(numOfUsers, userArray) - IOW you pass the arguments in the wrong order.
This being said, almost all your code is wrong, you obviously don't get the difference between a class and instance and how to use a class to create instances. I strongly suggest you read at least the official tutorial, and check a couple other tutorial and/or example code on the topic of classes and instances.

How to access a class object and its attributes from user input?

I just started programming and I decided to use Python for my first attempts at coding, and I am now practicing with classes and objects.
I apologize if the question I am about to ask has been asked before, but I can't seem to find answers anywhere, so here it goes.
I have a file that contains a class. Below the full code I have written :
#class file
#class prodotti refers to "register" with products in stock and their prices
class Prodotti(): #class Prodotti() contains products from register and their relative specs
def __init__(self, nome="", #name of product
prezzo=0, #product price
quantità=0,): #stock quantity of product
self.nome=nome
self.prezzo=prezzo
self.quantità=quantità
def newproduct(self): #method appends new product and its specs to the end of this file
name=input("Inserire nuovo prodotto: ")
f=open("cassa3.py", "a")
f.write(name + "=Prodotti(nome='" + name + "', ")
price=input("Inserire prezzo prodotto: ")
f.write("prezzo=" + price + ", quantità=0)\n")
f.close()
def tellprice(self): #method should return price of object
inp=input("Di quale prodotto vuoi conoscere il prezzo? ") #asks user which product they want to know the price of
if inp=Prodotti():
print(inp.prezzo)
#class objects
#user can insert new products that are saved below
tortino=Prodotti(nome="Tortino al cioccolato", prezzo=3.4, quantità=0)
muffincioccolato =Prodotti(nome="Muffin al cioccolato", prezzo=1.8, quantità=0)
cupcake=Prodotti(nome='cupcake', prezzo=2, quantità=0)
In another file, saved in the same directory, I have the main program:
from cassa3 import Prodotti #file cassa3.py in same directory as this file
if __name__=="__main__":
P=Prodotti()
P.tellprice()
As you may tell from the code above, what I want method tellprice() to do is to ask the user what product they want to know the price of.
However, I just don't know how to make the user input correspond to a class object, so that I can access its attributes.
Can someone explain how i could manage to do that?
Thanks in advance.
Before you will be able to solve this issue, you will need to fix the design problem you have.
Your comment says # class Prodotti() contains products from register and their relative specs but it is not quite true. This class contains a single product with its name, price and quantity.
You will need to define another class (perhaps Register) that will actually store a list (or dictionary if product names are unique for efficient lookup, or whatever) of products (instances of Prodotti).
The tellprice method currently makes no sense. It simply creates a new instance of Prodotti and the if condition will never be True.
Also, it is highly suggested to use English names in code.
Consider the below example as a general guide:
class Product:
def __init__(self, name, price, quantity):
self.name = name
self.price = price
self.quantity = quantity
# (... some other methods ... )
class Register:
def __init__(self, products):
# this will store the products in a dictionary with products names as keys
# and Product instances as values for an efficient look up by tell_price
self.products = {product.name: product for product in products}
def tell_price(self):
name = input('Which product would you like to know the price of?')
# this will raise KeyError if user inputs a non-existing product name
# and should be caught, or use .get(...) instead
return self.products[name].price
apple = Product('apple', 1, 10)
banana = Product('banana', 2, 2)
register = Register([apple, banana])
print(register.tell_price())
# Which product would you like to know the price of?
>> apple
# 1
I wouldn't make your tellprice include user input.
def tellprice(self): #method should return price of object
return self.price
Then in main (this is significantly simplified):
inp = input("Di quale prodotto vuoi conoscere il prezzo? ")
print(inp.tellprice)
Obviously this assumes they put in the correct product name, so some way of indicating to the user that they're incorrect might be useful

Writing dictionary output to file - Python

I have a small program to track monthly balances. This worked fine as is, and then I added in the section to write to a .txt file at the bottom. I did some searching but can't figure out a way to make it work. Basically I want to keep appending to this test.txt file. Every time I enter a new month/account/balance I want that appended to the file.
The alternative is to append to the test.txt file after 'exit', so it doesn't do it every loop. Not sure which way is more efficient
***EDIT****
This updated code now creates test.txt file but the file is blank after each loop
Secondary question - I have heard this would be better off using a Class for this, but I haven't any idea how that would look. If someone wants to demonstrate that would be awesome. This isn't homework, this is strictly learning on my own time.
Any ideas? Thanks
# create program to track monthly account balances
savings = []
def add_accounts(date, account, balance):
savings.append({'date': date, 'account': account, 'balance':
balance})
def print_accounts():
print(savings)
while True:
date = input('Enter the date, type exit to exit program: ')
if date == 'exit':
break
account = input('Enter the account: ')
balance = int(input('Enter the balance: '))
add_accounts(date, account, balance)
print_accounts()
with open('test.txt', 'a') as f:
for row in savings():
print (row)
f.write(str(savings[-1]))
file.close()
The problem with your original code is that print_accounts() doesn't return anything, yet you attempt to perform operations on its (nonexistent) return value.
Here is a version of your program made using classes, and with a few corrections:
class Account:
def __init__(self, id, date, balance):
self.id = id
self.date = date
self.balance = balance
def getString(self):
return self.id + "," + self.date + "," + str(self.balance)
savings = []
def add_account(date, account, balance):
savings.append(Account(date, account, balance))
def print_accounts():
for account in savings:
print(account.getString())
while True:
date = input("Enter the date, type exit to exit program: ")
if date.lower() == "exit":
break
else:
account = input('Enter the account: ')
balance = int(input('Enter the balance: '))
add_account(date, account, balance)
print_accounts()
with open("test.txt", "w") as file:
for account in savings:
file.write(account.getString() + "\n")
Some explanation regarding the class: The Account class has 3 fields: id, date, and balance. These fields are defined in the constructor (__init__()). The class also has a method, getString(), which I use to get the string representation of each instance.
Over all, the following changes have been made:
Create an Account class, which serves as the template for the object which holds the data of each account.
Use a loop to print accounts and write them to the file.
Turn date into lowercase before checking to see if it is equal to "exit". This is a minor change but a good habit to have.
Removed f.close(), as it is unnecessary when using a with open() statement.
Created a custom string representation of each instance of Account, consistent with what you would otherwise get.
That last one is achieved via defining the getString method in the account class. There is nothing special about it, it is merely what we use to get the string representation.
A better but quite more advanced way to achieve that is by overriding the __str__ and __repr__ methods of the base object. These are essentially hidden functions that every class has, but which python defines for us. The purpose of these two specific ones is to give string representations of objects. The default code for them doesn't produce anything meaningful:
<__main__.Account object at 0x0000000003D79A58>
However, by overriding them, we can use str() on instances of Account, and we will get a string representation in the exact format we want. The modified class will look like so:
class Account:
def __init__(self, id, date, balance):
self.id = id
self.date = date
self.balance = balance
def __repr__(self):
return self.id + "," + self.date + "," + str(self.balance)
def __str__(self):
return self.__repr__()
This also eliminates the need to loop through savings when writing to the file:
with open("test.txt", "w") as file:
for account in savings:
file.write(account.getString() + "\n")
Turns into:
with open("test.txt", "w") as file:
file.write(str(savings))
This wouldn't have worked before, as str() would have given us the gibberish data you saw earlier. However, now that we have overridden the methods, it works just fine.
Try this code (use -1 to exit):
savings = []
def add_accounts(date, account, balance):
savings.append({'date': date, 'account': account, 'balance':
balance})
def print_accounts():
print(savings)
while True:
date = input('Enter the date, type exit to exit program: ')
if date == -1:
break
account = input('Enter the account: ')
balance = int(input('Enter the balance: '))
add_accounts(date, account, balance)
print_accounts()
with open('test.txt', 'a') as f:
for row in savings:
print (row)
f.write(str(savings[-1]))
f.close()

Can't get python to read/display my variable

I have been working on this one program for hours now and I am still having no luck. I am trying to create a "search engine" where you can look products with a SKU number.
class SKU:
def __init__(self, name, product):
self.name = name
self.product = product
def displaySKU(self):
print "Sku Number : ", self.name, ", Product: ", self.product
sku90100 = SKU("90100", "10310, 00310")
sku90101 = SKU("90101", "10024, 00024")
sku90102 = SKU("90102", "10023")
sku90103 = SKU("90103", "10025")
sku90104 = SKU("90104", "10410")
search = input("Please type SKU Number")
if search in range(90100, 90106):
"sku",search.displaySKU
My problem is that I can't seem to get display the SKU information; I have tried removing, changing, and adding characters to the variables without success. I may have missed something thou, but all I now is that nothing that I try works. Please help me figure this out, and thank you for taking the time to read my question.
Instead of storing each product as its own variable, use a dict:
skus = {}
skus[90100] = SKU("90100", "10310, 00310")
skus[90101] = SKU("90101", "10024, 00024")
skus[90102] = SKU("90102", "10023")
skus[90103] = SKU("90103", "10025")
skus[90104] = SKU("90104", "10410")
Then you can check membership using in, and call the .displaySKU() method to print:
if search in skus:
skus[search].displaySKU()
Lastly, for Python 2, it's preferred to use raw_input instead of input. raw_input gives you a string though, so you want to convert that to an int to match your skus keys:
search = int(raw_input("Please type SKU Number"))

Categories