How to retrieve a class object inside the dictionary in python? - python

I have added a employee class object inside a dictionary successfully .But i am not able to get back the value from the same dictionary? Below are the code and output.
source code:
# decalre a dict
employee_collection = {}
# Class object to store employee's details
class employee:
# Constructor
def __init__(self,name,age):
self.name = name
self.age = age
# Display the object values
def print_property(self):
print(f"name is {self.name} and age is {str(self.age)}")
# loop to add multiple employee details
for x in range(1, 6):
obj= employee("xxx", 28+x)
employee_collection.update({x : obj})
# extract the employee detail from and print the vaue to user
for x in employee_collection:
# print(x.name)
print(x)
print(employee_collection)
output :
1
2
3
4
5
{1: <__main__.employee object at 0x0327F610>, 2: <__main__.employee object at 0x03550C70>, 3: <__main__.employee object at 0x03550580>, 4: <__main__.employee object at 0x035503B8>, 5: <__main__.employee object at 0x03550FB8>}
My question is:
How to print the name and age using loop in main method?

Two methods. The dict is storing the instance of each employee (which should be Employee btw).
You can either print the properties of the instance, or change what happens when you try to print an object.
The former:
for key, e in employee_collection.items():
print(f'{x} {e.name} {e.age}')
The latter:
class Employee:
...
def __str__(self):
return f'{self.name} {self.age}'
for e in employee_collection.values():
print(e)

To iterate through a dictionary you can use its keys(), values() or items(). Since you want both the key (x) and the value (employee) you want to use items() which returns all dictionary key-value pairs as so-called tuple in a list:
for x, employee in employee_collection.items():
print(f'Number: {x}, Name: {employee.name}, age: {employee.age}') # this is printing a format-string

Related

How to set a property of a property by name in python?

I have a piece of code where I have an object B that has another object A as a property, and I would like the user to be able to set the properties of either object by name. How can I let the user set attributes of either A or B?
The following code illustrates what I am trying to do:
>>> class A:
... def __init__(self):
... self.asd = 123
>>> class B:
... def __init__(self, a):
... self.a = a
>>> a=A()
>>> b=B(a)
>>> b.a.asd
123
>>> setattr(b, 'a.asd', 1000)
>>> b.a.asd
123 # I would like this to be 1000
I would like to only prompt the user for the property name and value.
I am prompting the user with this code:
prop = input("Property name to set: ")
try:
print(f"Current value of property {prop}: {getattr(B, prop)}")
value = input("Property value to set: ")
setattr(B, prop, value)
except AttributeError:
print(f"Object {B} has no property named {prop}. See {dir(B)}")
Edit: question solved, but I cannot accept my own answer for 2 days
setattr(getattr(b, 'a'), 'asd', 1000)
There is no way to traverse objects using the property name in setattr(). So to simulate this behaviour, you can split the property name on . and use getattr() to select the object you want to set the property on. This way, you only need to prompt the user for the property name and value.
prop = input("Property name to set: ")
obj_to_set = B
try:
for i in prop.split(".")[:-1]:
obj_to_set = getattr(obj_to_set, i)
prop_name = prop.split(".")[-1]
print(f"Current value of property {prop_name}: {getattr(obj_to_set, prop_name)}")
value = input("Property value to set: ")
setattr(obj_to_set, prop_name, value)
except AttributeError:
print(f"Object {obj_to_set} has no property named {prop}. See {dir(obj_to_set)}")

How can I check if an attribute of a class exists in array?

I want to know if it is possible to check if an array of a class has a specific instance of an attribute, and return True if it does. In other words, does an instance of a class attribute exist in an array of that class?
In my example, I have an array of class Team. The class Team has an attribute, name. I want to check if a Team instance with a specific name exists by iterating over an array of Team instances.
Class Team:
class Team:
def __init__(self):
self.name = name # (String)
[Invalid] This is the how I wanted to write the function:
# team_name is a String variable
# teams is an array of the Team class
def team_name_taken(team_name, teams):
if team_name in teams.name:
return True
else:
return False
I know this doesn't work, but is it possible to iterate over the same attribute within an array in this fashion?
[Valid] Regarding the goal of my code, I have the following code that works properly:
def team_name_taken(team_name, teams):
for team in teams:
if team_name == team.name:
return True
return False
I know that this works, I was just wondering if there was another way to do it, similar to the invalid way I represented above.
What you could do is the following:
def team_name_taken(team_name, teams):
team_names = [team.name for team in teams]
if team_name in team_names:
return True
else:
return False
This will generate a list with the items of the list being all team names. Once you have done that you can do if team_name in team_names: and get the desired outcome.
If on the other hand you just want to make it a oneliner you could do this:
def team_name_taken(team_name, teams):
return len([ team for team in teams if team.name == team_name ]) >= 1
This will make a list then check if the len() of the list is 1 (or bigger) and if that is the case return True else False.
The following class definition allows name from the user to be assigned to the Team.name attribute and forces it to be a str object:
class Team(object):
def __init__(self, name):
self.name = str(name)
Here is an example list of Team instances:
teams = [Team(x) for x in range(10)]
You can do what I think you want with some one-liners:
Using another list comprehension to find out if any of the names equal '3':
any([team.name == '3' for team in teams])
Or if you really want to use a function you can use the following:
any(map(lambda obj: obj.name == '3', teams))

Class with dictionary not getting initialized [duplicate]

This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 5 years ago.
I have a simple class with a string and a dictionary. When I make multiple objects of the class, apparently the dictionary does not get initialized properly. Dictionaries of all objects contains the entry for last object created. The code is:
# a simple class with a string and a dictionary:
class Myclass:
name = ""
valuedict = {}
# a list for objects:
mylist = []
# create 3 objects:
for i in range(3):
mc = Myclass()
mc.name = str(i)
mc.valuedict['name'] = str(i)
mylist.append(mc)
# disply objects in list:
for item in mylist:
print("-----------------")
print("name = ", item.name)
print("name in dict = ", item.valuedict['name'])
The output is:
-----------------
name = 0
name in dict = 2
-----------------
name = 1
name in dict = 2
-----------------
name = 2
name in dict = 2
The name strings are 0, 1 and 2 as expected but name in dictionary is 2 in all 3 objects. Where is the problem and how can it be solved? Thanks for your help.
Currently, valuedict is a class object. I believe what you're going for is to have separate instances, in which case you'll need a constructor (called __init__ in Python).
The corrected class code is as follows (self refers to the instance of the class)
class Myclass:
def __init__(self):
self.name = ""
self.valuedict = {}
So why isn't name acting the same way? In the first for loop, you're defining name, where you're accessing a key of valuedict, which doesn't exist, so you take the "next best thing", the class variable. name doesn't have this problem, as you're initializing it. A better explanation of this can be found here.

Accessing method variables of one class in another python class

I have started learning Object Oriented concepts in python. I have got this sample code below:
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
class School(object):
students = []
def __init__(self, name):
self.name = name
def add_student(self, student):
self.students.append(student)
def show_students(self):
print("{0} Student Roster".format(self.name))
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
my_school = School("Quora University")
first_student = Student("Rongan Li", 20)
second_student = Student("Jason Kane", 20)
my_school.add_student(first_student)
my_school.add_student(second_student)
my_school.show_students()
Question:
In the def show_students method of School class how they are accessing the construct variables of class student without instance of that class?
first_student = Student("Rongan Li", 20)
second_student = Student("Jason Kane", 20)
These lines create object of student class ,first_student which has name 'Rongan Li' and age '20'.
second_student which has name 'Jason Kane' and age '20'
Now, you add these 2 objects to the list.
my_school.add_student(first_student)
my_school.add_student(second_student)
Now, when you iterate in the list
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
's' goes to first element of list, and since it is an object of class Student , 's' becomes object of student class. Now, since 's' is first element in the list and on first place you added 'Rongal Li' and 20 . So, s has 2 properties name and age. When you do s.name , it prints 'Rongal Li' and s.age prints 20
Then it goes to next element and same process is repeated.
in the method show_students there's a for loop :
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
it loops over the list of students added by method add so inside the loop the variable "s" represent an instance of student class so s.name is a legit way of accessing an instance variable by using an instance of the class
The students are added to School.students list via the add_student method.
my_school.add_student(first_student)
my_school.add_student(second_student)
These two lines add two references to the School.students list in my_school. So now the list has two references pointing at first_student and second_student.
You can think of the list in my_school at this point as
students = [Pointer to first_student, Pointer to second_student]
When you call my_school.show_students(), my_school.students list (the list above) is accessed and through the references to first_student and second_student in the list, you access the original first_student object and second_student object and can then retrieve their properties.

Searching a list to see if there is a match python

Basically this is within a class which appends objects of another class to list self. There are 200 objects in list self. So basically if I call self[1] I will get ['John',['Alex', 'Rob']. Basically 'john' refers to self.firstname and the other names refer to there group members. For example the below will print the firstnames and groupmembers of each object for all 200 objects
for line in self:
print line.firstname
for line in self:
print line.groupmembers
Now I have to create something that goes through all the names and checks the names. So basically if John has Alex and Rob as members then there has to be another object with a first name Alex and another object with a firstname Rob. So say there is no object with firstname Alex I want to print 'mismatch'. This is what I have so far but its not doing what its intended to do.
def name(self):
firstnames = []
for item in self:
firstnames.append(item.firstname)
for item1 in self:
for i in item1.groupmembers:
if i not in hello:
print 'mismatch'
Okay so first off, line and self are bad variable names.
self should only be used within a class to be used as a way to call or use its own variables.
Secondly, you say each value in this self list contains values like ['John',['Alex', 'Rob'], but then you go on to use it like a class object... and frankly that don't do make none sense.
So to remedy this, I'm going to assume its done with class objects. I would also rename self to something like school, and instead of calling an element of self; line, which yields no information to the reader.. call it a student!
I'm going to assume your class would start looking like this:
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
Then if you have a list of people you can loop through them like so..
>>>school = [Student("foo", ["bar", "that guy"]),
Student("bar", ["foo", "that guy"])]
>>>for student in school:
print student.firstname
print student.groupmembers
foo
["bar", "that guy"]
bar
["foo", "that guy"]
Then to check it a students group members are in school you can add a function to the Student class
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
def group_present(self, school):
# This is how you would get all the names of kids in school without list comprehension
attendance = []
for student in school:
attendance.append(student.firstname)
# this is with list comprehension
attendance = [ student.firstname for student in school]
#compare group members with attendance
#note that I write student_name, not student
## helps point out that it is a string not a class
for student_name in self.groupmembers:
if not student_name in attendance:
print "Group member '{}' is missing :o!! GASP!".format(student_name)
In idle:
>>> school[0].group_present(school)
Group member 'that guy' is missing :o!! GASP!
Hope that helps!
I am not sure if i understand exactly but maybe you can use contains
self[1].__contains__('Alex')
this should return true in case of existence or false otherwise.

Categories

Resources