Name error when trying to print an object of a class - list

I'm new to python and need some help. My code is below. I'm trying to get the formatted table from a list of user details inputted but keep getting error stating 'NameError: name 'games' is not defined' Not sure what I am doing wrong to get it to print, please help.
class game():
def _init_(self,name,platform,genre,no_of_players,online_functionality):
self.name = name
self.platform = platform
self.genre = genre
self.no_of_players = no_of_players
self.online_functionality = online_functionality
def __repr__(self):
print()
print("%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality"))
print("---------------------------------------------------------------------------------")
print("%-10s%-10s%-10s%-10s%-10s%" %(games.name,games.platform,games.genre,games.no_of_players,games.online_functionality))
print()
def __str__(self):
print()
print("%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality"))
print("------------------------------------------------------------------------")
print("%-10s%-10s%-10s%-10s%-10s%" %(games.name,games.platform,games.genre,games.no_of_players,games.online_functionality))#formats and aligns columns
print()
def get_game_from_user():
gameList =[]
games = game()
games.name= input("Enter name of game: ")
games.platform= input("Enter Platform (e.g. XBox, PlayStation, PC etc: ")
games.genre = input("Genre (e.g. Sport, Shooter, Simulation etc.): ")
games.no_of_players= int(input("Enter number of players: "))
games.online_functionality= input("Enter if it has online functionality or not : ")
gameList.append(games)
print(gameList)

First Problem:
Use self inside your class to access to your object not games. change these:
games.name, games.platform , games.genre, ...
and other stuffs like them to these:
self.name, self.platform , self.genre, ...
Second problem:
in your code is that you must return what you want inside the __str__ and __repr__ not print them:
def __repr__(self):
result = ""
result += "%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality\n")
result += "---------------------------------------------------------------------------------\n"
result += "%-10s%-10s%-10s%-10s%-10s" %(self.name,self.platform,self.genre,self.no_of_players,self.online_functionality)
result += "\n"
return result
source: python data model

Related

Accessing parent class method error

I am trying to learn super implementation in Python and I have tried various help threads on SO but I am not able to implement the following code:
class Person:
def __init__(self, first, last, age):
self.firstname = first
self.lastname = last
self.age = age
def __str__(self):
return self.firstname + " " + self.lastname + ", " + str(self.age)
class Employee(Person):
def __init__(self, first, last, age, staffnum):
super(Employee, self).__init__(first, last, age)
self.staffnumber = staffnum
def __str__(self):
return super(Employee, self).__str__() + ", " + self.staffnumber
x = Person("Marge", "Simpson", 36)
y = Employee("Homer", "Simpson", 28, "1007")
print(x)
print(y)
What is wrong with this syntax in above code?
return super(Employee, self).__str__() + ", " + self.staffnumber
In Python 2.7 there are leftovers of the old hierarchy. Not all classes inherit from object, which is the default in Python 3. If you do not explicitly inherit object Python will use old style objects, which fail with Super which depends on this.
All you need to do is explicitly make sure all your objects eventually inherit object:
class Person(object):
In Python 3 this is 'fixed'.
An alternative is to forego super in favor of using the methods as class methods, which will work with both types of objects:
Person.__init__(self,first,last,age)
Person.__str__(self)

Manipulating instances of a class change the whole class

So I'm struggling. I've seen quite a few posts on this topic, but after a couple hours struggling with the problem, I can't figure this out. Here are a few snippets of code I have. I'd like to be able to change one instance of the class without the other being changed as well, and I'm coming up short
class voter:
def __init__(self, iPositon, jPosition, affiliation):
self.affiliation = affiliation
self.iPositon = iPositon
self.jPosition = jPosition
class district:
def __init__(self, *listOfVotersPassed):
# super(district, self).__init__()
self.listOfVoters = []
for x in listOfVotersPassed:
self.listOfVoters.append(x)
class city:
def __init__(self, *listOfDistrictsPassed):
self.listOfDistricts = []
for x in listOfDistrictsPassed:
self.listOfDistricts.append(x)
def main():
# I have a list of class district that I pass to city()
startCity = city(*startCityList)
solutionCity = city(*solutionCityList)
print solutionCity.listOfDistricts[0].listOfVoters[0].affiliation # Democrat
print startCity.listOfDistricts[0].listOfVoters[0].affiliation # Democrat
solutionCity.listOfDistricts[0].listOfVoters[0].affiliation = "Republican"
print solutionCity.listOfDistricts[0].listOfVoters[0].affiliation # Republican
print startCity.listOfDistricts[0].listOfVoters[0].affiliation # Republican
if __name__ == "__main__":
main()
edit.
So I was asked about how I created the instance(s) of city. I have a file I'm reading in, each has either R or D in each line.
file = open(fileName)
# import contents
startVoterList = []
solutionVoterList = []
for line in file:
for house in line:
if " " in house:
pass
elif "\n" in house:
pass
else:
startVoterList.append(house)
solutionVoterList.append(house)
I also updated the classes, now each is in the following format. No changes besides the "(object)" after each class className.
class voter(object):
def __init__(self, iPositon, jPosition, affiliation):
self.affiliation = affiliation
self.iPositon = iPositon
self.jPosition = jPosition

Computed fields Odoo9

I'm creating a module for student management in "Odoo9", in a part of that module I want to compute the average mark that a student get in a subject like "maths".I'm tryingto achieve that using this code, but I have a problem computing the "Avg-Maths" immediately after filling "Maths-1" and "Maths-2", it can only be computed after saving the student profile.Can someone help me please realizing the issue here? and how can I fix this?
#student class
class student_student(models.Model):
'
'
'
result_ids = fields.One2many("schoolresults.detail", "student_id", "School Results")
'
'
'
class schoolresults_detail(models.Model):
_name = "schoolresults.detail"
_description = "Student's results."
student_id = fields.Many2one("student.student", "Student", ondelete="cascade")
subject_id = fields.Many2one("schoolresults.subject", "Subject")
result_manual = fields.Float("Result")
result = fields.Float(compute='_compute_value',store=True)
manual = fields.Boolean(compute='_is_manual', default=False)
#api.one
#api.depends('manual')
def _is_manual(self):
self.manual = self.subject_id.my_id
#api.one
#api.depends('result_manual','subject_id','subject_id.my_id')
def _compute_value(self):
self.ensure_one()
results = self.env['schoolresults.detail'].search([])
total = 0
for data in results:
total += data.result_manual
for data in results:
#if the subject is the average of others
if data.subject_id.my_id:
data.result = total
class schoolresults_subject(models.Model):
_name = "schoolresults.subject"
_description = "Student's subjects."
my_id = fields.Integer(default=0)
name = fields.Char("Subject")
Add student_id.result_ids.result_manual to your depends list on _compute_value. That should trigger a recomputation.
i think after calculating the value you should assign it to your result field
#api.one
def _compute_method(self):
# compute average for this record
self.result = calclated_value
but i don't see that you assign the value to the result field ?!! sot try to assign it that should do it

Replace all elements of a two-item list with elements from another list

I'm learning about classes in Python and decided to create one just to practice but I'm having problems when displaying the instance's attributes in a specific way:
from abc import ABCMeta, abstractmethod
class Salad(object):
__metaclass__ = ABCMeta
seasoning = ["salt", "vinegar", "olive oil"] # default seasoning
def __init__(self, name, type, difficulty_level, ingredients):
self.name = name
self.type = type
self.difficulty_level = difficulty_level
self.ingredients = ingredients
def prepare(self, extra_actions=None):
self.actions = ["Cut", "Wash"]
for i in extra_actions.split():
self.actions.append(i)
for num, action in enumerate(self.actions, 1):
print str(num) + ". " + action
def serve(self):
return "Serve with rice and meat or fish."
# now begins the tricky part:
def getSaladattrs(self):
attrs = [[k, v] for k, v in self.__dict__.iteritems() if not k.startswith("actions")] # I don't want self.actions
sortedattrs = [attrs[2],attrs[1], attrs[3], attrs[0]]
# sorted the list to get this order: Name, Type, Difficulty Level, Ingredients
keys_prettify = ["Name", "Type", "Difficulty Level", "Ingredients"]
for i in range(len(keys_prettify)):
for key in sortedattrs:
sortedattrs.replace(key[i], keys_prettify[i])
# this didn't work
#abstractmethod
def absmethod(self):
pass
class VeggieSalad(Salad):
seasoning = ["Salt", "Black Pepper"]
def serve(self):
return "Serve with sweet potatoes."
vegsalad = VeggieSalad("Veggie", "Vegetarian","Easy", ["lettuce", "carrots", "tomato", "onions"])
Basically, I'd like to get this output when calling vegsalad.getSaladattrs():
Name: Veggie
Type: Vegetarian
Difficulty Level: Easy
Ingredients: Carrots, Lettuce, Tomato, Onions
instead of this (which is what I get if I simply tell python to display the keys and values using a for loop):
name: Veggie
type: Vegetarian
difficulty_level: Easy
ingredients: lettuce, carrots, tomato, onions
Thanks in advance!
Your list of attributes and values seems to be of the form:
[['name', 'Veggie'], ['type', 'Vegetarian'], ['difficulty_level', 'Easy'], ['Ingredients', 'Carrots, Lettuce, Tomato, Onions' ]]
So the following should produce the output you want:
for e in attrs:
if '_' in e[0]:
print e[0][:e[0].find('_')].capitalize() + ' ' \
+ e[0][e[0].find('_') + 1:].capitalize() + ': ' + e[1]
else:
print e[0].capitalize() + ': ' + e[1]

How can I sort my Django model using complex data from a second model?

I have 3 django models (simplified for this example):
class Fighter (models.Model):
name = models.CharField(max_length=100)
weight_class = models.ForeignKey(WeightClass, related_name="fighter_weight_class")
class Bout (models.Model):
fighter_1 = models.ForeignKey(Fighter, related_name="bout_fighter_1")
fighter_2 = models.ForeignKey(Fighter, related_name="bout_fighter_2")
winner = models.ForeignKey(Fighter, related_name="bout_winner", blank=True,
null=True, help_text='Leave blank for draw.')
date = models.DateField()
cancelled = models.BooleanField()
class WeightClass (models.Model):
name = models.CharField(max_length=100)
I would like to be able to list the Fighters by their stats. I created these
functions (which work) to calculate their wins, losses, and draws:
def get_bouts_with_fighter (fighter):
return Bout.objects.filter(fighter_1 = fighter) | \
Bout.objects.filter(fighter_2 = fighter)
def get_fighter_wins (fighter):
return Bout.objects.filter(winner=fighter)
def get_bouts_fought_not_won (fighter):
return get_bouts_with_fighter(fighter) \
.exclude(cancelled=True) \
.exclude(date__gt = datetime.datetime.now())
def get_fighter_losses (fighter):
return get_bouts_fought_not_won(fighter)\
.exclude(winner=fighter)\
.exclude(winner=None)
def get_fighter_draws (fighter):
return get_bouts_fought_not_won(fighter)\
.filter(winner=None)
But now, when comes to sorting the output for the view, I'm having two problems:
The "sort" is neither correct nor consistent.
During the sort, I'm losing the fighter's name
Here is the current code (the output is correct if no sorting is performed):
def list(request, sort=None):
class WeightGroup:
"""
Internal class to keep data organized by weight class.
"""
weight_class = None
fighters = None
def win_sort (self):
wins = []
winners = []
for fighter in self.fighters:
wins.append((fighter.id, get_fighter_wins(fighter)),)
for win in (sorted(wins, key=lambda f: f[1], reverse=True)):
winners.append(Fighter.objects.filter(id=win[0])) #build winner list by score
self.fighters = winners
def loss_sort (self):
#TO DO:
pass
def draw_sort (self):
#TO DO:
pass
title = 'Fighters'
weight_groups = []
for weight_class in WeightClass.objects.all():
weight_group = WeightGroup()
weight_group.weight_class = weight_class
weight_group.fighters = Fighter.objects.filter(weight_class=weight_class)
weight_groups.append(weight_group)
if sort in ['wins', 'losses', 'draws']:
title += ', sorted by ' + sort
for weight_group in weight_groups:
if (sort == 'wins'): weight_group.win_sort()
if (sort == 'losses'): weight_group.loss_sort()
if (sort == 'draws'): weight_group.draw_sort()
return render_to_response ('fighters/list.html',{
'title': title,
'weight_groups':weight_groups
})
Any suggestions how I can get this to work will be appreciated!
I've managed to solve both problems:
I was appending the collection of wins, not the "length" of that list.
I needed to change this:
wins.append((fighter.id, get_fighter_wins(fighter)),)
to:
wins.append((fighter.id, len(get_fighter_wins(fighter))),)
I was constructing a list of querysets, not a list of objects.
I needed to change this:
winners.append(Fighter.objects.filter(id=win[0]))
to:
winners.append(Fighter.objects.get(id=win[0]))
(Cheers to my friend Attila who explained the second issue to me.)
BTW, my final code doesn't use three separate functions. Instead I did this:
.
.
.
class WeightGroup:
.
.
.
def sort (self, sort_function):
scores = []
scorers = []
for fighter in self.fighters:
scores.append((fighter.id, len(sort_function(fighter))),)
for score in (sorted(scores, key=lambda f: f[1], reverse=True)):
scorers.append(Fighter.objects.get(id=score[0]))
self.fighters = scorers
.
.
.
if sort in ['wins', 'losses', 'draws']:
title += ', sorted by ' + sort
for weight_group in weight_groups:
if (sort == 'wins'): weight_group.sort(get_fighter_wins)
if (sort == 'losses'): weight_group.sort(get_fighter_losses)
if (sort == 'draws'): weight_group.sort(get_fighter_draws)
.
.
.