I am working on a python program with for loops, dictionary, and items. I have an array from a class that supposedly has the items for the dictionaries however each time I run the code I get an error and I have change my code several time and I cant get it to output the right result or to even run properly. In contrast I can't change anything above my for loops and was wondering if i should input a dictionary. However it is stated that the dictionary should be in the DepartmentManager in the departments{} array. Therefore, i would like some help in trying to make my for loop run correctly without an error.
Here are the instructions for the first for loop:
Create a for in loop to loop over the items in the dictionary stored in the departments attribute of the DepartmentManager object
Here is the 2nd for loop instructions:
Create another for in loop inside the first loop. This loop will be used to print out the assets that belong to the Department if the asset value is less than $2,000
class Department:
def __init__(self, departmentSupervisor):
self.departmentSupervisor = departmentSupervisor
self.departmentAssets =[]
class DepartmentAsset:
def __init__(self, assetName, quantity, expectedLifeSpan, AssetValue):
self.assetName = assetName
self.quantity = quantity
self.expectedLifeSpan = expectedLifeSpan
self.AssetValue = AssetValue
class DepartmentManager:
def __init__(self):
self.departments = {}
deptManager = DepartmentManager()
mktDept = Department("Jamie Doe")
maktDeptAsset1 = DepartmentAsset ("desk", 5000, 2, 10)
maktDeptAsset2 = DepartmentAsset ("computer", 1500, 5, 5)
mktDept.departmentAssets.append(maktDeptAsset1)
mktDept.departmentAssets.append(maktDeptAsset2)
financeDept = Department("Ryan Doe")
financemaktDeptAsset1 = DepartmentAsset ("chair", 500, 2, 10)
financemaktDeptAsset2 = DepartmentAsset ("calculator", 500, 3, 5)
financeDept.departmentAssets.append(financemaktDeptAsset1)
financeDept.departmentAssets.append(financemaktDeptAsset2)
deptManager.departments["marketing"] = mktDept
deptManager.departments["financing"] = financeDept
for key, value in deptManager.departments():
print(mktDept.departmentSupervisor + "is in charge of the fowwling " +
departmentAsset.getkey() + " department and the following assets less than $2000." )
for mktDept in deptManager.departments["Marketing"]:
print (mktDept.departmentAssets.quantity + " " +
mktDept.departmentAssets.assetName + "at $" +
mktDept.departmentAssets.AssetValue + " each. This asset is expected to last for " +
mktDept.departmentAssets.expectedLifeSpan + "to the values stored in the DepartmentAsset belonging to the Department")
TypeError: 'dict' object is not callable
**This is the error I keep getting at the end of my code or something similar to this
Instead of
for key, value in deptManager.departments():
you want
for key, value in deptManager.departments.items():
Related
I tried to create a student class object, and collect some data and show it:
class Student:
subjects = []
grades = []
d = {}
def __init__(self, name, id):
self.name = name
self.id = id
def addGrade(self, subject, grade):
self.subjects.append(subject)
self.grades.append(grade)
def showGrades(self):
self.d = dict(zip(self.subjects, self.grades))
for subject in self.d:
return subject + ' : ' + str(self.d[subject])
when I try add to values:
stu =Student('Zaki', 23)
stu.addGrade('Math',90)
stu.addGrade('Physicis',95)
stu.addGrade('English',100)
print(stu.showGrades())
the output turns to be
Math : 90
and it ignores the other values!
When you call return subject + ' : ' + str(self.d[subject]) in showGrades you exit the function, you can't use return in a loop. You should instead parse and format the output to your liking and then use return outside of the loop.
The specific problem that you are having is that you are putting an (unconditional) return inside the for loop (so it returns on the first iteration of the loop), rather than for example, building a list and returning that list after the loop.
However, separate from this, your code is also modifying the class variables, and you will get a surprise if you create another instance stu2 = Student(...) and find that this second student already has subjects and grades.
What you need to do to fix this second problem is to make subjects and grades into instance variables instead - and initialise them in __init__. You could do similarly with your class variable d, but it looks like it is probably only for use inside showGrades and would probably be best just replaced with a local variable in that method (function).
Putting these together, you could have something like this:
class Student:
def __init__(self, name, id):
self.name = name
self.id = id
self.subjects = []
self.grades = []
def addGrade(self, subject, grade):
self.subjects.append(subject)
self.grades.append(grade)
def showGrades(self):
d = dict(zip(self.subjects, self.grades))
grades = []
for subject in d:
grades.append(subject + ' : ' + str(d[subject]))
return grades
stu =Student('Zaki', 23)
stu.addGrade('Math',90)
stu.addGrade('Physics',95)
stu.addGrade('English',100)
print(stu.showGrades()) # ['Math : 90', 'Physics : 95', 'English : 100']
stu2 = Student("Juan", 24)
print(stu2.showGrades()) # []
You expect that return subject + ' : ' + str(self.d[subject]) in showGrades run three times, but when it reaches the first return, it leaves the loop. So, change your showGrades code to:
def showGrades(self):
self.d = dict(zip(self.subjects, self.grades))
ret = []
for subject in self.d:
ret.append(subject + ' : ' + str(self.d[subject]))
return ret # this will return list containing [subject : grade]
Output:
['Math : 90', 'Physicis : 95', 'English : 100']
I have a simple class that stores simple data. The class is as follows.
class DataFormater:
def __init__(self, N, P, K, price):
self.N = N
self.P = P
self.K = K
self.price = price
The code that calls this class is
from DataFormater import DataFormater
#global variables
ObjectList = [0,1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50]
ObjectListCounter = 0
# main
print "enter you N-P-K values, followed by a coma, then the price"
print "example ----> 5 5 5 %50 "
print "return as many values as you want to sort, then enter, 'done!' when done."
while True:
RawData = raw_input()
if RawData == 'done!':
break
else:
ObjectList[ObjectListCounter] = DataFormater
ObjectList[ObjectListCounter].N = int(RawData[0])
# very simple test way of putting first indice in ObjectList[ObjectListCounter].N
ObjectListCounter += 1
print ObjectList[0].N
print ObjectList[1].N
My idea is that ObjectList[0] would create that object '1' that I could call with 1.N
But, when I call these, it seems that I have overwritten the previous instances.
this is what prints...
return as many values as you want to sort, then enter, 'done!' when done.
12
1
done!
1
1
Thanks so much! And I know that my post is messy, I don't exactly know how to make it more "pretty"
So, it looks like you are assigning the actual class (instead of an instance of the class) in your loop. Where you do this:
ObjectList[ObjectListCounter] = DataFormater
I think what you actually want is this
ObjectList[ObjectListCounter] = DataFormater(...insert args here....)
EDIT to address the comments:
Your class init method looks like this:
def __init__(self, N, P, K, price):
That means that to create an instance of your class, it would look like this:
my_formater = DataFormater(1, 2, 3, 4)
You would then be able to access my_formater.N which would have a value of 1.
What you are trying to do instead is access a CLASS level attribute, DataFormater.N. This is generally used in situations where you have a constant variable that does not change between instances of the class. For example:
class DataFormater():
CONSTANT_THING = 'my thing that is always the same for every instance'
You would then be able to access that variable directly from the class, like this:
DataFormater.CONSTANT_THING
I hope that clears things up.
I'm trying to write a program that would ask for a students name, a couple other numerical values, and assign them to groups, via their numerical value, to have all groups as close to equal as possible (by taking the the highest next value in the list, and assigning it to the next group and so on).
However, I'd need to save their number to some variable, as well as their name, to then print out the group's list.
For this I'd need a variable that changes everytime the loop goes through to add another student. I'd also need to sort these number, and then somehow call back the name they corrispond to after they've been sorted into groups, and I'm not sure how to do any of these. Is there any way for this to be done, would I have to use another language?
This is the code I have so far:
from easygui import *
times = 0
name = 0
s_yn = ynbox("Would you like to enter a student?")
while s_yn == 1:
msg = "Student's Information"
title = "House Sorting Program"
fieldNames = ["Name", "Grade","Athleticism (1-10)","Intellect (1-10)","Adherance to school rules (1-10)"]
fieldValues = []
fieldValues = multenterbox(msg,title, fieldNames)
times = times + 1
ath = fieldValues[2]
int_ = fieldValues[3]
adh = fieldValues[4]
ath = int(ath)
int_ = int(int_)
adh = int(adh)
total = ath+int_+adh
s_yn = ynbox("Would you like to enter a student?")
I believe it would be nice to create a Student class that holds all variables associated with a student. Then you could add each student to a list which you could sort by the values you want and divide to how many groups you want.
from easygui import *
from operator import attrgetter
class Student(object):
def __init__(self, name, grade, athleticism, intellect, adherance):
self.name = name
self.grade = int(grade)
self.athleticism = int(athleticism)
self.intellect = int(intellect)
self.adherance = int(adherance)
self.total = self.athleticism + self.intellect + self.adherance
def __str__(self): # When converting an instance of this class to a string it'll return the string below.
return "Name: %s, Grade: %s, Athleticism (1-10): %s, Intellect (1-10): %s, Adherance to school rules (1-10): %s"\
% (self.name, self.grade, self.athleticism, self.intellect, self.adherance)
student_group = []
while ynbox("Would you like to enter a student?"): # Returns 'True' or 'False' so it'll loop every time the user press 'yes'.
message = "Student's Information"
title = "House Sorting Program"
field_names = ["Name", "Grade", "Athleticism (1-10)", "Intellect (1-10)", "Adherance to school rules (1-10)"]
field_values = multenterbox(message, title, field_names)
student = Student(*field_values) # Unpack all elements in the list 'field_values' to the initializer.
student_group.append(student) # Add the student to the group 'student_group'.
# When the user has put in all the students we sort our group by 'total' (or any other value you want to sort by).
sorted_group = sorted(student_group, key=attrgetter("total"), reverse=True)
# Just as an example I divided the students into 3 groups based on their total.
best_students = sorted_group[:len(sorted_group) // 3]
average_students = sorted_group[len(sorted_group) // 3:2 * len(sorted_group) // 3]
worst_students = sorted_group[2 * len(sorted_group) // 3::]
I'm stumped on a python problem. I'm writing a program that receives a command from Scratch (MIT) and then should create a new object, in this case named PiLight. The object only need to be created when the command is received so it doesn't have to loop, just be able to executed repeatedly and have the number increment each time it is executed.A list will not work for me due to the requirements of the program and talking between Scratch. I'm trying to figure out a way for the constructor, once initialized, to print out a statement something like
class Newpilight:
def __init__(self):
print "Pilight" + pilnumber + " created"
pilnumber should be 1 for 1st object, 2 for 2nd, etc
From there I need the creation of the object to change the number in the name of the object as well
PiLight(PiLnumber) = Newpilight()
I tried messing around with for loops but just ended up making more of a mess
Use number generator as class variable
from itertools import count
class NewPilight(object):
nums = count()
def __init__(self):
self.num = self.nums.next()
print "Pilight {self.num} created".format(self=self)
Then using in code:
>>> pl1 = NewPilight()
Pilight 0 created
>>> pl2 = NewPilight()
Pilight 1 created
>>> pl3 = NewPilight()
Pilight 2 created
>>> pl3.num
2
The trick is to have the nums (what is actually a generator of numbers, not list of numbers) as class property and not property of class instance. This way it is globally shared by all class instances.
class NewPilight:
def __init__(self, number):
self.number = number
print "Pilight" + number + " created"
for x in range(5):
NewPilight(x)
if you need to keep objects:
all_pilights = []
for x in range(5):
all_pilights.append( NewPilight(x) )
and now you have access to objects as
print all_pilights[0].number
print all_pilights[1].number
print all_pilights[2].number
class NewPiLight(object):
global_pilnumber = 0 # Since this is on the class definition, it is static
def __init__(self):
print "Pilight %s created" % NewPiLight.global_pilnumber
self.pilnumber = NewPiLight.global_pilnumber # Set the variable for this instance
NewPiLight.global_pilnumber += 1 # This increments the static variable
I am currently trying to calculate the average of a list created by a method in a class. Firstly all information is passed to a Class that records/returns the data passed through from the main function. The issue is what do I pass in from the main function to firstly retrieve the self._marks list and then manipulate it in order for the average to be returned. Also am I using the correct code for the calculateAverageMark section? Thanks in advance
Here is the code:
class Student :
def __init__(self, id):
self._studentId = id
self._marks = []
##
# Converts the student to a string .
# #return The string representation .
#
# Sets the student's ID.
# #param newId is the student's new ID.
#
def setStudentId(self, id):
self._studentId = id
##
# Gets the student's ID.
# #return the student's ID
#
def getStudentId(self, newId):
return self._newId
##
# Appends a mark to the marks list
#
def addMark(self, mark):
self._marks.append(mark)
def __repr__(self) :
# Build a string starting with the student ID
# followed by the details of each mark .
s = "Student ID :" + self._studentId + " "
if len(self._marks) == 0 :
s += " <none \n>"
else :
for mark in self._marks :
s += " Course Module: " + mark.getModule() + " Raw Mark: " + str(mark.getRawMark())
return s
##
# Method to calculate the students average mark
#
def calculateAverageMark(self):
totalMarks = 0
count = 0
for mark in self._marks :
if mark == 0 :
count = count
else :
count = count + 1
totalMarks = totalMarks + mark
average = totalMarks / count
return average
Your current code is incorrect because you divide by count in every iteration (and before count is actually the number of marks). Calculating the average is very easy with a list of values:
def calculateAverageMark(self):
if self._marks: # avoid error on empty list
return sum(self._marks) / float(len(self._marks))
You don't need to pass anything in; all instance attributes are available via self. Unless you have specifically been told to exclude zero scores from the average, you should count them.