how to get attribute information through another attribute in a class - python

I have a class like this:
class School:
instances = []
def __init__(self, name, number, hour, income):
self.__class__.instances.append(weakref.proxy(self))
self.name = name
self.number = number
self.hour = hour
self.income = income
And an instance like this:
n1 = School('Namjoo', 114, 50, 30)
how can I extract the name attribute by having 114, 50 or 30?
I can't use a dictionary as not all the data stays unique

If you want to find the name of any class instances that have a particular value set for another attribute, you can walk the instances list and check the listed object attributes. For example:
print([x.name for x in School.instances if x.number == 114 or x.hour == 50 or x.income == 30])
# ['Namjoo']

Related

one child class method is calling another child class of same parent in python

Main objective is to create a "Stock_by_Material" method which will iterate over the amount of each item of a given material that is in stock. the script should add up to 10 cotton Polo shirts.
class Clothing:
stock={ 'name': [],'material' :[], 'amount':[]}
def __init__(self,name):
material = ""
self.name = name
def add_item(self, name, material, amount):
Clothing.stock['name'].append(self.name)
Clothing.stock['material'].append(self.material)
Clothing.stock['amount'].append(amount)
def Stock_by_Material(self, material):
count=0
n=0
for item in Clothing.stock['material']:
if item == material:
count += Clothing.stock['amount'][n]
n+=1
return count
class shirt(Clothing):
material="Cotton"
class pants(Clothing):
material="Cotton"
polo = shirt("Polo")
sweatpants = pants("Sweatpants")
polo.add_item(polo.name, polo.material, 4)
sweatpants.add_item(sweatpants.name, sweatpants.material, 6)
current_stock = polo.Stock_by_Material("Cotton")
print(current_stock
Though the program above is giving the desired result i.e current _stock = 10.
As this code is written by someone else, I just filled some blanks...I am not able to understand why this person called Stock_by Material method on only "polo"...why not "clothing.Stock_by_material."
and why just calling "polo" is adding both "polo" and "sweatpants"

How to set up constructor for class with attribute initialized to empty list?

I have to create the following class, but I am unsure of how to set up my constructor.
A GradeRecords object has the following attributes:
term : a string representing the current semester;
grades : a list object containing tuples, where the first entry of each tuple is a string representing the code of the class, the second entry of each tuple is the grade out of 100, and the third entry is the number of credits for this course. grades can be initialized as an empty list.
num_courses : an int which contains the number of courses in the record.
This can be initialized as 0.
You are not allowed to add more attributes.
Furthermore, a GradeRecords object has the following methods:
an initialization method which takes as input the current term and initializes the three attributes;
add_course, a method which takes a string representing the course code, an int for the grade out of 100 and the number of credits. The method adds a new tuple to grades.
My code give me the error:
g1 = GradeRecords("Fall 2021")
TypeError: __init__() missing 1 required positional argument: 'new_tuple'
Thank you!
class GradeRecords:
grades = []
num_courses = 0
def __init__(self, term, new_tuple):
self.term = term
#create a list from the input new_tuple
self.grades.append(new_tuple)
GradeRecords.num_courses += len(self.grades)
def add_course(self, course_code, grade_100, num_credits):
new_tuple = (course_code, grade_100, num_credits)
self.grades.append(new_tuple)
return grades
The __init__ of your class has two arguments : term and new_tuple.
When you make an instance of your class as g1 = GradeRecords("Fall 2021"), you give a value for term (="Fall 2021") but the object is waiting for a new_tuple as well.
So to make it works, you should give a tuple as a second argument like :
g1 = GradeRecords("Fall 2021", ("Maths", 90, 10))
However, in my opinion, the class might also be written this way :
class GradeRecords:
def __init__(self, term):
self.grades = []
self.num_courses = 0
self.term = term
def add_course(self, course_code, grade_100, num_credits):
self.grades.append((course_code, grade_100, num_credits))
self.num_courses += len(self.grades)
return self.grades
And we can use it like so :
>>> g1 = GradeRecords('Fall 2021')
>>> g1.add_course("Maths", 90, 10)
[("Maths", 90, 10)]
>>> g1.add_course("Physics", 80, 9)
[('Maths', 90, 10), ('Physics', 80, 9)]
Your __init__ expects 2 arguments while only 1 is passed to it, so you can add a default value to new_tuple if nothing is passed and can be called as g1 = GradeRecords("Fall 2021"). If you want it to be initialised to something else then it can be called as g1 = GradeRecords("Fall 2021", ("Course", "<Grade>", "<Credits>"))
class GradeRecords:
grades = []
num_courses = 0
def __init__(self, term, new_tuple=("",0,0)):
self.term = term
#create a list from the input new_tuple
self.grades.append(new_tuple)
self.num_courses += len(self.grades)
def add_course(self, course_code, grade_100, num_credits):
new_tuple = (course_code, grade_100, num_credits)
self.grades.append(new_tuple)
return grades

Modifying parent class attribute from child class method

I have two classes, one parent called Organization and one child called Employee. Organization has an attribute called org_size which I want to be able to increment when I call my add_employee method that belongs to the Employee class.
class Organization( object ):
def __init__(self, org_name):
self.org_name = org_name
self.org_size = 0
self.org_revenue = 0
self.num_placements = 0
def get_org_size(self):
return self.org_size
class Employee( Organization ):
def __init__(self, employee_name, comission_rate):
self.employee_name = employee_name
self.comission_rate = comission_rate
self.total_comission = 0
def add_employee(employee_name, comission_rate):
employee = Employee(employee_name, comission_rate)
self.org_size += 1
return employee
team = Organization("My Sales Team")
emp = Employee("Bob", 15)
Regardless if I call team.org_size or team.get_org_size(), I get an answer of 0, instead of the expected 1, as I want to increment org_size as part of calling the add_employee() method. I tried adding a super() to Employee but then whenever I called add_employee it caused issues with requiring the org_name argument from Organization.
What do I need to do with Employee class in order to modify attributes in Organization?
The relationship between Organization and Employee is a "HAS A" relationship, not an "IS A" relationship. An Employee is not a KIND OF an organization, she is a MEMBER of an organization.
class Organization():
def __init__(self, org_name):
self.org_name = org_name
self.org_size = 0
self.org_revenue = 0
self.num_placements = 0
self.employees = []
def add_employee(self, employee_name, comission_rate):
employee = Employee(employee_name, comission_rate)
self.employees.append(employee)
return employee
def get_org_size(self):
return len(self.employees)
class Employee():
def __init__(self, employee_name, comission_rate):
self.employee_name = employee_name
self.comission_rate = comission_rate
self.total_comission = 0
team = Organization("My Sales Team")
bob = team.add_employee("Bob", 15)

Get attributes of class item from string associated with class item

I have a niche problem. I create a class classA, with attributes name and number. Once a class item is created, its name is stored as a string in a list, namesList. Later in the code, namesList prints and the user can enter a string input. If that input matches a string in namesList, I want the program to print the number attribute associated with that class item. How should I do this?
ClassA is just a class. You tried to reference it in the last line which leads to an error. Instead of doing that appending the object to the list would be better because then you can individually get the value back from the object while searching in the array.
namesList = []
class classA:
def __init__(self, name, number):
self.name = name
self.number = number
namesList.append(self)
def getNumber(self):
return self.number
def getName(self):
return self.name
example = 'c'
classA(example, 5)
userChoice = input('Which name do you need the number for?')
for name in namesList:
if name.getName() == userChoice:
nameIndex = namesList.index(name)
print(nameIndex)
print('The current price for', name.getNumber())
I think what you're trying to do is this:
namesList = []
class classA:
def __init__(self, name, number):
self.name = name
self.number = number
namesList.append(self.name)
example_Class = classA('example', 5)
userChoice = input('Which name do you need the number for?')
for name in namesList:
if name == userChoice:
print('The number is', example_Class.number)
You have to set classA('example', 5) equal to a variable example_Class and then if you want to access the number value stored it's just example_Class.number
EDIT
This code ought to work regardless of how many class items there are:
class Iterator(type):
def __iter__(cls):
return iter(cls.namesList)
class ClassA(metaclass=Iterator):
namesList = []
def __init__(self, name, number):
self.name = name
self.number = number
self.namesList.append(self)
example_Class1 = ClassA('one', 8)
example_Class2 = ClassA('two', 7)
example_Class3 = ClassA('three', 6)
userChoice = input('Which name do you need the number for?')
for class_name in ClassA:
if class_name.name == userChoice:
print('The number is', class_name.number)

Python: Can't copy pygame surface objects

I have a class:
class personInfo:
def __init__(self,name,age,height,hairColour,face):
self.name = name
self.age = age
self.height = height
self.hairColour = hairColour
self.face = face
I have several images here that I load in using the pygame module.
yellowFace = pygame.image.load("happy.png")
blueFace = pygame.image.load("sad.png")
redFace = pygame.image.load("angry.png")
I created an array that holds instances of that class. Here I am populating it.
personArray = []
while len(array) != 10:
personArray.append(personClass("John",32,6,"Blond",yellowFace))
I would like to store the actual variables of that class (name, age height,hairColour, etc) in a variable I will call "personStorage". However, I can't have that var be mutatable since I need to access that var's values and change them. Doing this can't change the values of any instances inside the personArray. How would I do this?
EDIT:
I also can't seem to be able to Copy this class because I get a type error that says: "can't pickle pygame.surface objects" since I have a value of a surface object within that class.
If I understood what you're trying to do :
class PersonInfo:
def __init__(self,name,age,height,hairColour):
self.name = name
self.age = age
self.height = height
self.hairColour = hairColour
def toList(self):
return [self.name, self.age, self.height, self.hairColour]
By the way, class names' first letter is always uppercase.
EDIT : To achieve what you're trying to do :
old = PersonInfo("old", 1, 2, "blue")
new = PersonInfo(*old.toList())
new.name = "new"
print(old.name) #'old'
Use the copy module:
The function copy() shallow copy operation on arbitrary Python objects.
import copy
class PersonInfo:
def __init__(self, name, age, height, hair_colour):
self.name = name
self.age = age
self.height = height
self.hairColour = hair_colour
personArray = []
for x in range(20, 24):
personArray.append(PersonInfo("John", x, 6, "Brown"))
personStorage = copy.copy(personArray[2])
personStorage.name = "Ana"
print("\rpersonArray[2].name is %s\n"
"\rpersonStorage.name is %s"
% (personArray[2].name, personStorage.name))
I have created setters and getters to get the data.Also you can create a copy of the instance that holds the data.
from copy import deepcopy
class PersonInfo:
def __init__(self,name,age,height,hairColour):
self.name = name
self.age = age
self.height = height
self.hairColour = hairColour
x = PersonInfo("Mario",34,1.70,"blue")
print(x.height) # prints 1.70
x1 = deepcopy(x)
print(x1.age)

Categories