Printing object attributes based on user input in Python 3x - python

First of all I'd like to say im a Python beginner (or programming beginner for that matter) and I'm trying to figure out how to print attributes from a object based on user input.
This is the code I have so far:
class Customer:
"De klasse customer"
def __init__(self, naam, adres, woonplaats, email):
self.naam = naam
self.adres = adres
self.woonplaats = woonplaats
self.email = email
input1 = input ("Enter the object name")
print(input1.naam) ## ** << This is what i like to know**
a = Customer('Name1', 'address', 'Utrecht', 'Email1#hotmail.com')
b = Customer('Name2', 'Bonestaak', 'Maarssen', 'Bijjaapishetaltijdraakhotmail.com')
So I basically want this: print(a.naam) to work, but the 'a' must be entered by a user.
Did some searching but no success so far.

You can use the locals function:
>>> a = {1:'abc'}
>>> obj = raw_input('Obj?> ')
Obj?> a
>>> print locals()[obj][1]
abc
>>>
This is however an highly insecure construct (there are other things in locals!)
A cleaner way would be to:
customers = {
'a' : Customer('Name1', 'address', 'Utrecht', 'Email1#hotmail.com')
'b' : Customer('Name2', 'Bonestaak', 'Maarssen', 'Bijjaapishetaltijdraakhotmail.com')
}
customer = raw_input('Customer? > ')
print customers[customer].naam
You'll need to handle KeyError properly though!

Related

Calling a function from a class in main

I seem to be making a stupid mistake that I cant find. Im simply trying to call my functions from my record class and having an invalid syntax error despite looking at sample code and trying to emulate the syntax.
Ive tried following tutorials and calling the function in every which way so the problem may not be in the calling of the function but something else I feel.
class definitions
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
def addrecord(self,x,y,z):
x = input('Enter telephone number')
y = input('Enter lastname')
z = input('Enter firstname')
phonebook.append(record(x,y,z))
return
def deleterecord(self,x):
phonebook[x-1].pop
return
Main
phonebook = record[]
addrecord(515,'fin','matt')
print(phonebook[0].firstname)
deleterecord(1)
print(phonebook[0].firstname)
If all this works I expect the output to be
"matt"
"null"
There are a number of problems with your code:
you are defining phonebook otuside of the class
in deleterecord you should call phonebook.pop(x).
there should be two classes that handle the phonebook and records, and the record could be modeled using a namedtuple.
there are syntax errors like calling record[] which is not valid Python.
Alternative implementation:
from collections import namedtuple
PhoneRecord = namedtuple("PhoneRecord", ['firstname', 'lastname', 'telephone'])
class PhoneBook:
def __init__(self):
self._phonebook = []
def addrecord(self, record):
self._phonebook.append(record)
return self._phonebook.index(record)
def deleterecord(self, i):
self._phonebook.pop(i)
phonebook = PhoneBook()
record_index = phonebook.addrecord(PhoneRecord(firstname="matt", lastname="snow", telephone="25512521"))
print(phonebook._phonebook)
phonebook.deleterecord(record_index)
print(phonebook._phonebook)
which will yield in the console:
[PhoneRecord(firstname='matt', lastname='snow', telephone='25512521')]
[]
The simplified version of your question is, given code
records = []
records.append("matt")
print(records[0])
del records[0]
print(records[0])
why don't I get the following output
"matt"
None
Instead, you get an IndexError exception.
The reason is that you are accessing an element beyond the size of the list, and Python handles this by raising an exception rather than returning None.

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.

Variable within an instance of a class does not take a new value when it is assigned.

So, I'm working on a command line RPG for the sake of filling time, and re-stretching my Python muscles as I've been out of practice for a couple of years. I used to code in a really functional manner but I'm trying to get my head around object-orientated programming.
Preamble aside, I have an issue where after creating an instance of a class, my class variable is no longer being defined. I've made 2 versions of this which I'll use to demonstrate since I'm finding it hard to articulate.
Below I created a "character" class which I intended to use as a basis for both player characters and npcs. In the first draft I was updating this class, before realising it was going to affect subclasses, when I really just wanted it as a template. Either way, this particular code block worked; it adds the values of 2 dictionaries together, then assigns them to character.characterStats. It then prints them as per displayStats().
from collections import Counter
class character:
def __init__(self, *args, **kwargs):
pass
def __setattr__(self, name, value):
pass
characterRace = ''
characterStats = {}
charLocation = ''
charName = ''
class race:
def __init__(self):
pass
baseStatsDict = {
'Strength' : 5,
'Agility' : 5,
'Toughness' : 5,
'Intelligence' : 5 }
humanStatsDict = {
'Strength' : 1,
'Agility' : 1,
'Toughness' : 1,
'Intelligence' : 1 }
def displayRace():
print("Race: ", character.characterRace, "\n")
def displayStats():
for stat, value in character.characterStats.items():
print(stat, "=", value)
print("\n")
def raceSelection():
playerInput = input("I am a ")
playerInput
playerLower = playerInput.lower()
while "human" not in playerLower:
if "human" in playerLower:
character.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
character.characterRace = 'Human'
break
playerInput = input()
playerInput
playerLower = playerInput.lower()
playerChar = character()
raceSelection()
displayRace()
displayStats()
And this was the output:
Race: Human
Strength = 6
Agility = 6
Toughness = 6
Intelligence = 6
This however is the new code when I tried to tidy it up and turn the class into the template it was meant to be, and started using the class instance playerChar which for whatever reason can't assign the new value to playerChar.characterStats. playerChar.displayStats() prints the characterRace and characterStats variables as empty, even though they are assigned when the player enters the value human.
from collections import Counter
class character:
characterRace = ''
characterStats = {}
def __init__(self):
pass
def displayRace(self):
print("Race: ", self.characterRace, "\n")
def displayStats(self):
for stat, value in self.characterStats.items():
print(stat, "=", value)
print("\n")
class race:
def __init__(self):
pass
baseStatsDict = {
'Strength' : 5,
'Agility' : 5,
'Toughness' : 5,
'Intelligence' : 5 }
humanStatsDict = {
'Strength' : 1,
'Agility' : 1,
'Toughness' : 1,
'Intelligence' : 1 }
def raceSelection():
playerInput = input("I am a ")
playerInput
playerLower = playerInput.lower()
while "human" not in playerLower:
if "human" in playerLower:
playerChar.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
playerChar.characterRace = 'Human'
break
playerInput = input()
playerInput
playerLower = playerInput.lower()
playerChar = character()
raceSelection()
playerChar.displayRace()
playerChar.displayStats()
So this will output:
Race:
\n
\n
\n
So I know it's able to draw from the class race dictionaries and add their contents together as from the previous code. If I try and print the player.x characteristics it won't throw any errors so it recognises they exist. If anyone could explain to me what's going wrong and why in this new iteration, I'd be very grateful.
EDIT: So a friend and I have tried passing the class as an argument of raceSelection(), we've tried printing a string after each call/update of a variable and we've tried entering a string into the variable, printing it, then redefining the variable with a new string.
Input:
class character:
charRace = ''
charStats = {}
charLocation = ''
charName = ''
charString = "Cole said define a string."
Within the if statements:
if "human" in playerLower:
print("Oh, you're just a really ugly human.")
playerChar.charStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
playerChar.charRace = 'Ugly Human'
print("playerChar.charString = ", playerChar.charString)
playerChar.charString = "Redefine."
print("playerChar.charString = ", playerChar.charString)
break
Output:
Oh, you're just a really ugly human.
playerChar.charString = Cole said define a string.
playerChar.charString = Cole said define a string.
Race:
It should not be character.characterStats.items(), but self.characterStats.items(). Similarly for all other values that belong to one, specific character.
Using the name of the class assigns a value that belongs to the class, and is the same for all objects you create. Lookup instance vs class attributes.
So, after trying to move the variables in and out of __init__, trying setattr(), trying to pass any sort of argument through the class just so it had some data, trying to run the instance of the class through a function, none of those solutions came to work in the end.
The solution turned out to be to create a subclass of character and manipulate that instead. I figured this would be alright as well since the player character will mutate throughout gameplay, and will never see further subclasses of itself.

Python Attribute Error - Type Object has no Attribute

I am writing some code for a project at school. I am reading in a List that I have created as a text file with 5 attributes. This is my class object code:
class studentclass(object):
def __init__(self,firstname,lastname,classno,correct,mydate):
self.firstname = firstname
self.lastname = lastname
self.classno = classno
self.correct = correct
self.mydate = mydate
Later in the program I am using this code to read in the data, sort it and perform some calculations:
myList = [studentclass]
totalnoofrecords = 0
counter = 0
for counter in range(0,totalnoofrecords):
firstname = myList.firstname[counter]
lastname = myList.lastname[counter]
classno = myList.classno[counter]
correct = myList.correct[counter]
mydate = myList.mydate[counter]
newname = myList.firstname[counter +1]
if newname == firstname:
grade = grade + studentclass.correct(counter +1)
nummberofattempts = 2
newname2 = studentclass.firstname(counter +2)
if newname2 == firstname:
grade = grade + studentclass.correct(counter +2)
nummberofattempts = 3
mean = grade / numberofattempts
print ("num ",counter ,"=", myList[counter])
But it does not work. I get the following error message:
AttributeError: 'list' object has no attribute 'firstname'
The error message points to this line of the code:
firstname = myList.firstname[counter]
Hoping that someone call help me please. Thanks
In your code you are referencing mylist.firstname. What is mylist? It's a list. Does it have a firstname attribute? The error is telling you that it doesn't, and looking at the code you aren't adding that attribute to the list.
Each element of the list has that attribute, however. Perhaps you meant to get the firstname attribute of one of the elements of the list. Maybe the following, perhaps?
for counter in range(0,totalnoofrecords):
firstname = myList[counter].firstname
lastname = myList[counter].lastname
...
In python, when you get an error like "object X has no attribute Y", you can usually rely on that being a true statement. So, ask youself "why does X not have that attribute?". It's usually either a) you forgot to define that attribute, b) you misspelled the attribute or you misspelled X, or c) X isn't what you think it is.
You have several issues. As Alex S. pointed out, your myList is a List, and specifically it is a list with one element: a class constructor.
I think what you want is something like:
# assumption: you have textlines,
# which is an array of lines of the form firstname,lastname,blah
myList = [studentclass(*(args.split(",")) for args in textlines]
And then do myList[counter].firstname to get the (counter-th) firstname value

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