Implementing a python class - python-3.x

I am working on a personal project and I am having trouble implementing this following part.
Implementing a Menu Class.
This class will make use of MenuItem objects.
This class represents the restaurant menu which contains 4 different categories of menu item diners can order from.
This class will have a single class(or static) variable:
Menu_Item_types: a list containing 4 strings representing the 4 possible types of menu items.: Drink, appetizer, entree, dessert.
This class will use the following instance attribute:
List item
self.menuItemDrinkList: list of all drink list
self.menuItemAppetizerList: list of all appetizer list
self.menuItemEntreeList: a list of all entree list
self.menuItemDessertList: a list of all the dessert list
Below is the menuItem object
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self.name = name
self.types = types
self.price = price
self.description = description
def setName(self, name):
self.name = name
def getName(self):
return self.name
def setTypes(self, types):
self.types = types
def getTypes(self):
return self.types
def setPrice(self, price):
self.price = price
def getPrice(self):
return self.price
def setDescription(self, description):
self.description = description
def getDescription(self):
return self.description
def __str__(self):
return "{} ({}): ${}, {}".format(self.name, self.types, self.price, self.description)

If I understand you correctly you are looking for setters and getters properties. Here is the way how you do it in Python.
You can learn more about properties here:
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self._name = name
self._types = types
self._price = price
self._description = description
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
#property
def types(self):
return self._types
#types.setter
def types(self, types):
self._types = types
#property
def price(self):
return self._price
#price.setter
def price(self, price):
self._price = price
#property
def description(self):
return self._description
#description.setter
def description(self, description):
self._description = description
def __str__(self):
return "{} ({}): ${}, {}".format(
self._name, self._types, self._price, self._description
)
menu_item = MenuItem("pizza", "entry", 10)
print(menu_item)
menu_item.price = 20
menu_item.description = "Delicious"
print(menu_item)
output:
pizza (entry): $10, None
pizza (entry): $20, Delicious
Please notice:
In python you don't call properties with getXxx or setXxx, you just use regular names and decoreate methods with #property and #xxx.setter
You should have #property before #setter.
Setter must start with the property name
In order to escape recursion, name your internal
attributes with _ (_name). If you will not do it you will have a
"RecursionError: maximum recursion depth exceeded in comparison"
because setter will call itself in the loop.

Related

#property - method calling logic

Here is the code:
class Duck():
def __init__(self,input_name):
self.__name = input_name
#property
def name(self):
print('inside the getter')
return self.__name
#name.setter
def name(self):
print('inside the setter')
self.__name = input_name
fowl = Duck("Howard")
So, "dot" is the connection between object and method. That's to say, type fowl.name will get "Howard", because the object called name and returned self.__name.
My question is if I type fowl.name = "cat", why I won't get anything from #property, getter. And how the program knew it's a setter? Because I used "="?

QuerySet django . How to write a function correctly to make tests pass

how returns in tree_downwards the root organization with the requested org_id and all its children at any nesting level and returns in tree_upwords the root organization with the requested org_id and all its parents at any nesting level to make tests pas???
I will only be able to return either the parents or the organization itself
models.py
class OrganizationQuerySet(models.QuerySet):
def tree_downwards(self, root_id):
"""
:type root_org_id: int
"""
return self.filter(???)
def tree_upwards(self, child_id):
"""
:type child_org_id: int
"""
return self.filter(???)
class Organization(models.Model):
objects = OrganizationQuerySet.as_manager()
name = models.CharField(max_length=1000, blank=False, null=False)
parent = models.ForeignKey(
"self", null=True, blank=True, on_delete=models.PROTECT
)
class Meta:
ordering = ["name"]
verbose_name = "organization"
def __str__(self):
return self.name
tests.py
def test_get_tree_downwards_cluster(make_organization):
org_1 = make_organization()
org_2 = make_organization(parent=org_1)
children = Organization.objects.tree_downwards(org_1.id)
assert org_1 in children
assert org_2 in children
def test_get_parents_chain(make_organization):
org_1 = make_organization()
org_2 = make_organization(parent=org_1)
org_3 = make_organization(parent=org_2)
parents = Organization.objects.tree_upwards(org_3.id)
assert org_1 in parents
assert org_2 in parents
assert org_3 in parents
Does it have to be a QuerySet? I would implement it as follows:
from django.db import models
class Organization(models.Model):
name = models.CharField(max_length=1000, blank=False, null=False)
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT, related_name='children')
class Meta:
ordering = {'name'}
verbose_name = 'organization'
def __str__(self):
return self.name
#property
def tree_upward(self):
result = [self]
if self.parent:
result += self.parent.tree_upward
return result
#property
def tree_downward(self):
result = [self]
for child in self.children.all():
result += child.tree_downward
return result
In the answer from #physicalattraction you get a very nice interface for the Organization model. If you really need to return a QuerySet, you could "cast" the list into a QuerySet like this:
class Organization(models.Model):
# other code
#classmethod
def _cast_to_queryset(cls,list):
'''method to cast list of objects into queryset'''
castlist = [rec.id for rec in list]
queryset = cls.objects.filter(id__in=castlist)
return queryset
#property
def tree_upward(self):
result = [self]
if self.parent:
result += self.parent.tree_upward
return Organization._cast_to_queryset(result) # <-- cast to queryset
#property
def tree_downward(self):
result = [self]
for child in self.children.all():
result += child.tree_downward
return Organization._cast_to_queryset(result) # <-- cast to queryset
I think this would work nicely and retain the nice interface that #physicalattraction set up for you in his answer.

Python: for multiple properties use one getter and setter method

I have created a class that has multiple properties. I want to use one function for the getter method and the second one for the setter method.
class person:
def __init__(self, fname, lname, city, state):
# make all attributes as private
self._fname = fname
self._lname = lname
self._city = city
self._state = state
#property # get method
def fname(self):
return self._fname
#fname.setter # set method
def fname(self,fname):
self._fname = fname
#property
def lname(self):
return self._lname
#lname.setter
def lname(self,lname):
self._lname = lname
#property
def city(self):
return self._city
#city.setter
def city(self, city):
self._city = city
#property
def state(self):
return self._state
#state.setter
def state(self, state):
self._state = state
How to use all properties for one get methods and one set method?
e.g.:
def get(self):
return self._attr
def set(self,value):
self._attr = value
class person:
def __set_name__(self, name):
self.name = name
def __get__(self, obj, type=None) -> object:
return obj.__dict__.get(self.name)
def __set__(self, obj, value) -> None:
obj.__dict__[self.name] = value
my_value = person
my_values.fname = 'Shivam'
my_values.lname = 'Gupta'
print(my_values.fname) #--> Shivam
print(my_values.lname) #--> Gupta

Class object doesn't inherit other class attribute

have 3 classes: Patient, Patients and Hospital.
class Patient:
def __init__(self, ID, name, age, sex, alergies):
self.ID = ID
self.name = name
self.age = age
self.sex = sex
self.alergies = alergies
def Is_old(self):
if self.age >= 60:
return True
else:
return False
def Add_patient(self, P):
pass
class Patients():
def __init__(self):
self.dict = {} # where key is a patient ID, value is an Patient object
class Hospital(Patients):
def __init__(self, name):
self.name = name
def Get_oldPatients(self):
old_patients = []
for key, value in self.dict.items(): # where an error appears
if Patient.Is_old():
old_patients.append(value)
return old_patients
an error appears
AttributeError: 'Hospital' object has no attribute 'dict'
Hospital class inherit from Patients so should have the same attribs like Patients, any idea where is the problem?

How can I return all values inside of a class variable?

I'm writing a text adventure game in Python and I'm curious on how I can go about listing all the items inside of the Room class
I'm very new to Python and have very limited practice.
# Declaring items and assigning them rooms
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.items = []
self.items_in_room = ''
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.items.append(item)
def list_items_in_room(self):
for item in self.items:
self.items_in_room += item
', '.split(self.items)
return self.items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __str__(self):
return f'{self.name} - {self.description}' + '\n' + "-" * 40
I'm expecting Room.list_items_in_room to list all the items in the room in a comma separated string.
I have re-arranged your code and also changed the function list_items_in_room. Also, have changed the __str__ function to __repr__ and removed the '-' * 40 (I couldn't understand why that's there).
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.__items = []
# __ so that it's not modifiable without getter and setter functions
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.__items.append(item)
def list_items_in_room(self):
return self.__items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __repr__(self):
return f'{self.name} - {self.description}'
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
print(room['garden'].list_items_in_room())
Output:
[Dingus - This really dings., Flippers - Webbed in nature.]

Resources