Keep all values added by a method in a separate variable - python-3.x

I want to create a method that adds a row to my variable. What I currently have is the following
class Album :
def __init__(self,nbr,nbr_songs):
self.header = 'Album ' + str(nbr) + ' (' + str(nbr_songs) + ' songs)')
def add(self,song,n):
self.line = song
self.nbre = n # This is the count of how many song there is
def __str__(self):
s = self.header
s += '\n' + "{:02}".format(self.nbre) + ': ' + str(self.line)
return s
The output wanted is the following
Album 1 (3 songs)
01: White_Wedding - Billy_Idol - 00:04:12
02: Stand_And_Deliver - Adam_&_The_Ants - 00:03:33
03: You_Spin_Me_Around - Dead_Or_Alive - 00:03:14
The issue is that when I add the three songs to an Album one after the other, it returns the following.
Album 1 (3 songs)
01: You_Spin_Me_Around - Dead_Or_Alive - 00:03:14
I know that my code is missing something but I can't figure out what.

This is by no means a perfect solution but I think it would be a definite improvement to create a separate Song class and maybe even an Artist one too, and have a list of songs in your Album class:
class Song:
def __init__(self, title, artists, duration, album, track_number):
self.title = title
self.artists = artists
self.duration = duration
self.album = album
self.track_number = track_number
def __str__(self):
return f'{self.track_number:02}: {self.title} - {self.artists} - {self.duration}'
class Album:
def __init__(self, number):
self.number = number
self.songs = []
def add_song(self, title, artists, duration):
track_number = len(self.songs) + 1
song = Song(title, artists, duration, self, track_number)
self.songs.append(song)
def __str__(self):
header = f'Album {self.number} ({len(self.songs)} songs)'
str_list = [header]
for song in self.songs:
str_list.append(str(song))
return '\n'.join(str_list)
album = Album(1)
album.add_song('White_Wedding', 'Billy_Idol', '00:04:12')
album.add_song('Stand_And_Deliver', 'Adam_&_The_Ants', '00:03:33')
album.add_song('You_Spin_Me_Around', 'Dead_Or_Alive', '00:03:14')
print(album)
Output:
Album 1 (3 songs)
01: White_Wedding - Billy_Idol - 00:04:12
02: Stand_And_Deliver - Adam_&_The_Ants - 00:03:33
03: You_Spin_Me_Around - Dead_Or_Alive - 00:03:14

Related

Get the string of two upper levels in foraign relations

Good Morning,
How to get the value Entity.name about ProjectsComments row.
Top model :
class Entities(models.Model):
code = models.CharField(verbose_name='Código', max_length=10, blank=False, unique=True,
help_text='Codigo de entidad.')
name = models.CharField(max_length=150, verbose_name='Nombre', unique=True,
help_text='Nombre de la entidad.')
def __str__(self):
return self.name
def toJSON(self):
item = model_to_dict(self)
return item
Second Level:
class Projects(models.Model):
entity = models.ForeignKey(Entities, on_delete=models.DO_NOTHING, verbose_name="Entidad")
def __str__(self):
return f'{self.entity}' + ' \ ' + f'{self.code}' + ' \ ' + f'{self.name}' # + ' \ ' + f'{self.phase}'
def toJSON(self):
item = model_to_dict(self)
item['entity'] = self.entity.toJSON()
return item
Third Level
class ProjectsComments(models.Model):
project = models.ForeignKey(Projects, on_delete=models.DO_NOTHING, default=0, verbose_name='Proyecto',
help_text='Proyecto')
def __str__(self):
return f'{self.date}' + f' ' + f'#' + f'{self.user}' + f'# ' + f'{self.comment}'
def toJSON(self):
item = model_to_dict(self)
item['project'] = self.project.toJSON()
item['entity'] = Entities.objects.get(pk = )
item['user'] = self.user.toJSON()
return item
I would need that from projectscommentsListView get the value of ProjectsComments__Projects__Entity.name
I have tried get into ProjectsComments.toJSON() with :
item['entity'] = Entities.objects.get(pk = )
AND
item['entity'] = self.entity.toJSON()
I do not know anymore.
You can get the entity from your project since they are related
item['entity'] = self.project.entity.toJSON()
No need for another query.

How can I alter/expand the following python code to also calculate mg (miligram?)

I want to expand the following code in order to calculate the miligrams too. Can someone tell me how to?
class weight:
__metric = {"g" : 1,
"kg" : 1000,
}
def __init__(self, value, unit = "g"):
self.value = value
self.unit = unit
def convert_to_gram(self):
return self.value * weight._metric[self.unit]
def __add__(self,other):
x = self.convert_to_gram() + other.convert_to_gram()
return weight + (x/weight._metric[self.unit], self.unit)
def __str__(self):
return "{} {}".format (self.value, self.unit)
class weight:
def __init__(self, value, unit = "g"):
"""
This method is initialized when the object is created
"""
self.value = value
self.unit = unit
# The value of kg is 0.001 (1E-3) because your logic multiplies the input value. So mg must be 1/1E-3 = 1000
self._metric = {"g" : 1,
"kg" : 0.001,
"mg" : 1000
}
def convert_to_gram(self):
"""
This method converts a self.value to g, kg or mg based on self.unit
"""
return self.value * self._metric[self.unit]
def __add__(self, other):
"""
The __add__ method is a 'magic' (dunder) method which gets called when we add two numbers using the + operator.
this method calls convert_to_gram() methods from this class object and from 'other' class object as well
it then returns the sum of both convertion results from the two objects
"""
x = self.convert_to_gram() + other.convert_to_gram()
return (x/self._metric[self.unit], self.unit)
def __str__(self):
return "{} {}".format (self.value, self.unit)
w1 = weight(100, 'mg') # create object w1
w2 = weight(50, 'mg') # create object w2
# call convert_to_gram() to convert 100 to mg and save the result in result_w1
result_w1 = w1.convert_to_gram()
print(result_w1)
# call convert_to_gram() to convert 50 to mg and save the result in result_w2
result_w2 = w2.convert_to_gram()
print(result_w2)
print(w1 + w2)
Gives:
100000
50000
(150.0, 'mg')

Issue with displaying quantity button in proper position in Python

I am building a page using Python, it has 2 frames, one frame is to display the products and when we click upon the product it should perform a mouseclickevent and should display in second frame. Along with the product name it should display quantity with + and - option to increment and decrement.
I am using pycharm professional 2017.3.2
This is my code:
def OnDoubleClick(event):
a = tree.selection()[0]
price = tree.item(a, "values")
amt = price[1]
print("amt is :",amt)
t1=0
v1 = IntVar(receiptbox, value='1')
def onMinus():
if (v1.get()>0):
v1.set(v1.get() - 1)
btn1 = Button(receiptbox, justify=CENTER, text="-
",command=onMinus,bg="#33ccff")
receiptbox.insert(END, "\n")
btn1.pack(side=LEFT,anchor=E)
e1 = Entry(receiptbox, justify=CENTER, textvariable=v1, width=4, state="readonly")
e1.pack(side=LEFT,anchor=E)
def onPlus():
v1.set(v1.get() + 1)
# receiptbox.delete("1.0", END)
if(v1.get()>1):
receiptbox.delete("1.0", END)
# v1.set(v1.get() + 1)
var = v1.get()
price = tree.item(a, "values")
amt1 = (price[1])
# amt2 = int(amt1)
# t1 = float(amt1) * (var)
receiptbox.insert(END, tree.item(a, "text") + " Sub Total: "+str(float(amt1) * (var)))
receiptbox.insert(END,"\n")
btn2 = Button(receiptbox, justify=CENTER, text="+", command=onPlus,bg="#33ccff")
btn2.pack(side=LEFT,anchor=E)
receiptbox.insert(END,"\n")
if (v1.get()==1):
total = (v1.get() * amt)
print("Total is :"+str(total))
receiptbox.insert(END, tree.item(a, "text") + " Sub Total: " + str(total))
receiptbox.insert(END, "\n")
receiptbox.insert(END, "\n\n")
I am able to display the list of product and mouseclick is working fine. Products are listed from the database. The issue is with the quantity button. Its not coming in the proper position. I mean it should display in the same row along with the product name.

Loop initilized attributes inside an `class` definition body

How to Loop initilized attributes inside an class definition body?
Supposed a class:
class WakeUp:
def __init__(self,date,time):
self.date = str(date)
self.time = str(time)
self.brush_teeth = brushteeth
.
.
def get_wakeup_activities(self):
return 'date: ' + self.date + 'time' + self.time. + 'brush_teeth', + self.brush_teeth
I intend to avoid the verbose typing, expect to refactor the method as:
def get_wakeup_activities(self):
act_list = ()
for attr in attrs:
act_list.append(attr)
return 'date: %s time:%s brush_teeth: %s' %tuple(act_list)
When the method is called, outputs
date:2017-10-17 time:11:50:27 ...
or more abstract:
def get_wakeup_activities(self):
wakeup_dict = {k:v for k, v in self.attrs}
return wakeup_dict
While command to call:
today_wakeup = Wakeup
today_wakeup.get_wakeup_activities()
Outputs:
{date:2017-10-17, time:11:50:27,....}
class WakeUp:
def __init__(self,date,time, brushteeth):
self.date = str(date)
self.time = str(time)
self.brush_teeth = brushteeth
def get_wakeup_activities(self):
return self.__dict__
today_wakeup = WakeUp('today', '8am', 'YES!')
print(today_wakeup.get_wakeup_activities())

Python OOP, cannot overwrite instances

I want to make 2 instances with same name like,
a = SomeClass(someAttr1)
a = SomeClass(someAttr2)
so that the new one should overwrite the previous one.
I also tried this:
a = SomeClass(someAttr1)
a = None
a = SomeClass(someAttr2)
I tried this but it doesn't overwrite the previous instance and adds it in itself, is there any way to do it?
Here is the code:
### Do not change the Location or Campus classes. ###
### Location class is the same as in lecture. ###
class Location(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, deltaX, deltaY):
return Location(self.x + deltaX, self.y + deltaY)
def getX(self):
return self.x
def getY(self):
return self.y
def dist_from(self, other):
xDist = self.x - other.x
yDist = self.y - other.y
return (xDist ** 2 + yDist ** 2) ** 0.5
def __eq__(self, other):
return (self.x == other.x and self.y == other.y)
def __str__(self):
return '<' + str(self.x) + ',' + str(self.y) + '>'
class Campus(object):
def __init__(self, center_loc):
self.center_loc = center_loc
def __str__(self):
return str(self.center_loc)
class MITCampus(Campus):
""" A MITCampus is a Campus that contains tents """
tents_list = []
def __init__(self, center_loc, tent_loc=Location(0, 0)):
""" Assumes center_loc and tent_loc are Location objects
Initializes a new Campus centered at location center_loc
with a tent at location tent_loc """
# Your code here
Campus.__init__(self, center_loc)
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)
def add_tent(self, new_tent_loc):
""" Assumes new_tent_loc is a Location
Adds new_tent_loc to the campus only if the tent is at least 0.5 distance
away from all other tents already there. Campus is unchanged otherwise.
Returns True if it could add the tent, False otherwise. """
# Your code here
new_tent_flag = True
for loc in self.tents_list:
if loc == new_tent_loc or new_tent_loc.dist_from(loc) < 0.5:
new_tent_flag = False
if new_tent_flag:
self.tents_list.append(new_tent_loc)
return True
else:
return False
def get_tents(self):
""" Returns a list of all tents on the campus. The list should contain
the string representation of the Location of a tent. The list should
be sorted by the x coordinate of the location. """
# Your code here
new_list_sorted = sorted(self.tents_list, key=lambda tent: tent.getX())
str_list = []
for x in new_list_sorted:
str_list.append(x.__str__())
return str_list
Test Cases:
Test: 0
c = MITCampus(Location(1,2))
print(c.add_tent(Location(1,2)))
print(c.add_tent(Location(0,0)))
print(c.add_tent(Location(2,3)))
print(c.add_tent(Location(2,3)))
print(c.get_tents())
Output:
True
False
True
False
['<0,0>', '<1,2>', '<2,3>']
Test: 1
init campus with default tent loc
c = MITCampus(Location(-1,-2))
print(sorted(c.get_tents()))
Output:
['<0,0>','<0,0>', '<1,2>', '<2,3>']
Expected Output:
['<0,0>']
As can be seen that the second instance should overwrite the previous one but instead it is adding it. Is the problem in the code? and how to solve it?
Ok,
Your tents_list attribute is a class atribute, so even when your c object is overwrited the tents_list attribute stays the same.
It's better to make your tents_list an object argument so the tents_list attribute is overwrited too.
def __init__(self, center_loc, tent_loc=Location(0, 0)):
Campus.__init__(self, center_loc)
self.tents_list = [] # <--- Add this
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)
The object is overwritten but you defined tents_list as a class variable so all of the instances of MITCampus share this list.
So any new instance will add to that list and that seems to you as not "overwritten".
If you want that "overwriting" behavior, move the tents_list into the __init__ method as self.tents_list. Only then it will be unique for each instance.

Resources