There is two classes - Company and Project. Company object has property projects as list, that should indicate list of Project instances that is added to the company
Here is realization of classes and methods to add projects to the company:
class Company(object):
def __init__(self, companyname):
self.companyname = companyname
self.projects = list()
def show_projects(self):
print(f"Company projects: {self.projects}")
def add_project(self, name):
return self.projects.append(Project(name))
class Project(object):
def __init__(self, name):
self.name = name
But when I try to initialize company, then project and add it to company, add add_project returns not project.name, but object itself, so i.e. output of this:
firm = Company("New")
first = Project("first")
print(first.name)
firm.add_project(first.name)
firm.show_projects()
will be:
first
Company projects: [<__main__.Project object at 0x00A54170>]
Why is it passing not name, but object itself? Can't find out what is missing here.
firm.projects is a list so in show_projects when you print it it will be a list of objects. One solution would be to modify show_projects to format the list into a comma separated string first:
def show_projects(self):
formatted_projects = ','.join([p.name for p in self.projects])
print(f"Company projects: {formatted_projects}")
Related
I'm new to python and as I was doing an assignment for class, I got stuck using init method.
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
Customer('308','John').addorder((1,2,3,4))
print(Customer('308','John'))
The output is an empty list [].
I want the output to be [1,2,3,4]
What am I doing wrong here?
The issue is that you have two Customer objects. I.e. your print line:
print(Customer('308','John'))
Is creating a new Customer object with a number of '308' and a name of 'John'. It's completely unrelated to the customer on the previous line.
To fix this, you should assign your first object to a variable (think of it like a handle, that lets you access the object), and then print that:
john = Customer('308','John')
john.addorder((1,2,3,4))
print(john)
You're creating two instances of the class
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
customer = Customer('308','John')
customer.addorder((1,2,3,4))
print(customer)
Keep in mind that each time you "call" a class, you instantiate a new object (this is why in many languages other than Python, this actually requires the keyword new). So, in your example, you're instantiating two different objects (that don't share their properties). Instead, you should save them in a variable:
customer = Customer("308", "John")
customer.addorder((1, 2, 3, 4))
print(customer)
Here is an example code of what I am trying to do. My end goal is creating a JSON object for class real estate agent, but I am struggling because I don't know what to do about self.housesSold.
class realEstateAgent:
def __init__(self, name, salary, houses):
self.name = name
self.sal = salary
self.housesSold = #a list of **HOUSE** objects
class houseSold:
def __init__(openPrice, closePrice, closeDate):
self.openPrice = openPrice
self.closePrice = closePrice
self.closeDate = closeDate
You mention that housesSold is a list. In your last comment, it appears that it's not the case and it is actually an object.
However, in both cases, printing the object (or the list of objects) will not get you anywhere unless you edit the __str__ or __repr__ method of the corresponding class. Instead you should try to get the attributes of that object (because you care mainly about them).
For example if housesSold is an object, then try this:
housesSold = data.housesSold
print(housesSold.openPrice) #get the price
If it's a list, then try this :
housesSold = data.housesSold
print(housesSold[0].openPrice) #get the price of the first house
I was expecting the object items inside other python objects are isolated.
However, the following code shows my expected result is wrong. It seems python uses a central item_list for all Group items. How can I fix this?
class Item:
name = ''
def __init__(self, name):
self.name = name
class Group:
item_list = []
def __init__(self, item):
self.item_list.append(item)
g2 = Group(Item('bb1'))
g2.item_list.append(Item('bb2'))
group_list = []
group_list.append(Group(Item('aaa')))
group_list.append(g2)
group_list.append(Group(Item('ccc')))
print('len = ', len(group_list[-1].item_list))
print('bb2 = ', group_list[1].item_list[1].name)
Result
len = 4
bb2 = bb1
Version
python3 --version
Python 3.5.2
Well, first of all we should make a difference between class attributes and instance attributes. A class attribute (like item_list) belongs to the class itself (in this case "Group"), so it will be accessible by calling Group.item_list. On the other hand, you can define a item_list for every instance of Group by defining self.item_list = [] inside the Group class constructor (__init__).
The Group.item_list array will be unique for the whole class, and thus will be suitable to store things that you want to share across instances (such as g2).
The self.item_list array (that will be different for each instance of Group) will hold values exclusively for the instance itself, so each Group will have its own item_list.
I think you are aiming for the second approach (instance variables) so you should move the definition of item_list = [] inside the class constructor.
The result should look like this:
class Item:
def __init__(self, name):
self.name = name
class Group:
def __init__(self, item):
self.item_list = []
self.item_list.append(item)
item1 = Item("itemName")
group1 = Group(item1)
# This should print an array containing the *item1* instance
print(group1.item_list)
print(group1.item_list[0] == item1)
Variables that are declared outside of the __init__ method (in this case item_list) are shared between all instances of a class (called class variables), which is why your expected result is wrong.
On the other hand, variables inside the __init__ only belong to the given instance of that class.
Your using class variables, which are similar C++ static variables inside classes (i.e. that variable is shared by ALL class instances). You need to put it inside the __init__ (constructor) to make it so each class creates its own version:
class Item:
def __init__(self, name):
self.name = name
class Group:
def __init__(self, item):
self.item_list = []
self.item_list.append(item)
# Though typically you would also have a function like this:
def add_item(self, item):
self.item_list.append(item)
g2 = Group(Item('bb1'))
g2.item_list.append(Item('bb2'))
group_list = []
group_list.append(Group(Item('aaa')))
group_list.append(g2)
group_list.append(Group(Item('ccc')))
print('len = ', len(group_list[-1].item_list))
print('bb2 = ', group_list[1].item_list[1].name)
Instance vs class attributes is covered in other answers. I want to add that you can avoid having shared instance variables by using an immutable type (e.g. tuple) instead of a mutable type (e.g. list) for class attributes. Like that they won't be shared among instances while still allowing you to define class attributes.
class Item:
name = ''
def __init__(self, name):
self.name = name
class Group:
item_list = tuple()
def __init__(self, item):
self.item_list += (item,)
Im writing a basic program in Python.
In the program, there is an array called abc. The array contains the following data:
birthdate and name.
Instead of using:
abc[1]
I want to create sub function, like:
abc.name()
That will return the value of abc[1]
How can i create a function like this (with dot)? Thanks!!
You will want to use a class like this:
class abc():
def __init__(self, birthday, name):
self.__birthday = birthday
self.__name = name
def birthday(self):
return self.__birthday
def name(self):
return self.__name
Now just create abc
person = abc('5/04/1984', 'Nick Stone')
And get the data like so:
bday = person.birthday()
name = person.name()
As said, you can't add such 'function' to your value, it's necessary to create a class definition if you need to use .dot notation. Basic example:
class abc():
# constructor, initializing object state
def __init__(self,item):
self.item=item
# here you define name and body of your function
def name(self):
# return just second item from our "item" value (string, array, list, etc.)
return self.item[1]
Now, you can create object of class abc and call it's 'name function':
> myData=abc('123')
> myData.name()
'2'
> myData=abc(['birth','name'])
> myData.name()
'name'
For a program that creates a timetable for a doctor(specialist) I want to use certain attributes of an object created by a different class to be used in the class that makes the timetable for the doctor.
class makePatient(object):
def __init__(self,name,room):
self.name = name
self.room = room
def getPatient(self):
print(self.name)
print(self.room)
class makeSpecialist(object):
def __init__(self,name,specialization,timetable):
self.name = name
self.specialization = specialization
self.timetable = timetable
def getSpecialist(self):
print(self.name)
print(self.specialization)
print(self.timetable)
class makeAgenda(object):
def addAgenda(self):
self.timetable.append()
#I want to append the name of the patient I have defined here.
print(self.timetable)
patient1 = makePatient("Michael","101")
specialist1 = makeSpecialist("Dr. John","Hematology",[])
What do I do now, to make sure that the name "Michael" gets added to the list [] of specialist Dr. John?
Thanks in advance, I will provide further details if necessary!
I think another approach would be better; you can put the whole makePatient object into the timetable for the specialist:
specialist1 = makeSpecialist("Dr. John", "Hematology", [patient1])
Now you can access the names and other attributes of the patients in a specialist's timetable:
for patient in specialist1.timetable:
print(patient.name)
You can also define a __repr__ method to tell Python how to display an object, rather than the current getPatient:
class makePatient(object):
# ...
def __repr__(self):
return "{0} (room {1})".format(self.name, self.room)
Now when you print the whole timetable:
>>> print(specialist1.timetable)
You get the necessary information:
[Michael (room 101)]
Note also that the classes should probably be called, simply, Patient, Specialist and Agenda; the make is implied.
Finally, you will get errors in makeAgenda.addAgenda as, without an __init__, self.timetable doesn't exist for a makeAgenda object, and an empty append() doesn't do anything anyway.
Classes are often used to represent entities and operations allowed on them, include constructing, or making, new instances of them. Therefore, your classes would be better named simplyPatient, Specialist, andAgenda. The name of the method that constructs a new instance of any class in Python is always__init__().
That said, after creating aPatientand aSpecialistyou could then add patient instances to the specialist's timetable/agenda by passing it to aSpecialistmethod specifically designed for that purpose. In other words, a Specialist "has-a" Agenda instance namedtimetableand to which patients can be added via an appropriately namedadd_to_timetable()method.
Here's what I mean -- note I've modified your code to follow PEP 8 -- Style Guide for Python Code guidelines which I also suggest that you follow:
class Agenda(object):
def __init__(self):
self.events = []
def append(self, event):
self.events.append(event)
class Patient(object):
def __init__(self, name, room):
self.name = name
self.room = room
def get_patient(self):
print(self.name)
print(self.room)
class Specialist(object):
def __init__(self, name, specialization):
self.name = name
self.specialization = specialization
self.timetable = Agenda()
def add_to_timetable(self, patient):
self.timetable.append(patient)
def get_specialist(self):
print(self.name)
print(self.specialization)
print(self.timetable)
specialist1 = Specialist("Dr. John", "Hematology")
patient1 = Patient("Michael", "101")
specialist1.add_to_timetable(patient1)
I'm not too sure what you're trying to accomplish here with method that just print values or with the makeAgenda class, but here's how you can get Michael in Dr. John's list:
specialist1.timetable.append(patient1.name)