Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I need to create a class student and then assign him or her a subject (maths, science, etc.) and then the grade by subject.
Basically, I have created a class student with name, gender,etc. Then I need to add more than one subject.
But i dont understand how one student object can get more than one subject and probably a greade per subject.
class student:
def __init__(self,name,age,gender,subject):
self.name = name
self.age = age
self.gender = gender
self.subject = subject
def __str__(self):
return ('{},{},{},{}'.format(self.name,self.age,self.gender,self.subject))
new = student('Alan',17,'M','Science')
Please if someone can help me to clarify a little bit I appreciate.
thanks
From your question, I gather that you have already worked with entity relations (ERDs), which is why you are thinking in terms of associations -- which is good. I'm assuming this is homework, so I don't want to give away too much. However, the code below should get you started.
from typing import List, Dict
class CollegeClass:
def __init__(self, class_code: str, name: str):
self.class_code = class_code #type: str
self.name = name
def __str__(self):
return f"{self.class_code}, {self.name}"
def __repr__(self):
return str(self)
class Student:
def __init__(self):
self.current_classes = dict() # type: Dict[str, CollegeClass]
def enroll(self, college_class: CollegeClass):
if college_class.class_code in self.current_classes:
print("The student is already taking the class.")
return
self.current_classes[college_class.class_code] = college_class
if __name__ == '__main__':
math = CollegeClass("mth101", "Intro to Math")
english = CollegeClass("eng201", "Intro to Fiction")
eric_praline = Student()
eric_praline.enroll(math)
eric_praline.enroll(english)
for _, cls in eric_praline.current_classes.items():
print(cls)
There are many ways to accomplish this task. One solution is to not specify the subject when creating the student. Instead, you would create the student object and then add subjects to it.
For example:
student = Student(name="John Smith")
for subject_name in ("Math", "Science", "Literature"):
student.add_subject(subject_name)
That gives you a new student who has three subjects. The add_subject method might look something like this:
class Student(object):
def __init__(self, name, age, gender):
...
self.subjects = {}
...
def add_subject(self, name):
self.subjects[name] = Subject(name)
To assign grades you would do something like this, perhaps
student.add_grade("Math", "A")
student.add_grade("Science", "B")
student.add_grade("Literature", "C")
add_grade would then take the grade name, look up the subject object from self.subjects, and call a method on that subject object to add the grade.
For example:
def add_grade(self, subject_name, grade):
subject = self.subjects[subject_name]
subject.add_grade(grade)
Your class Subject could be something very simple:
class Subject(self):
def __init__(self, name):
self.name = name
self.grade = None
def add_grade(self, grade):
self.grade = grade
Note: the above assumes you want a single grade per subject. If you want multiple grades, you can change self.grade to be self.grades and have it be a list.
Class Student represents just a type of people
Object of class Student represents a particular student, e.g. John Smith
Class Subject represents something students can learn in general
Object of class Subject represents a particular class students can take, e.g. Math 2017
Grade does not belong in either of these, because it only makes sense with a combination of both. So I would suggest creating some data storage, e.g. a list of tuples to store a grade for each combination of student/subject objects you want to keep track of, e.g.
Grades = [
(john_smith, math_2017, 'A+'),
...
]
class Subject(object):
def __init__(self, name, grade=None):
self.name = name
self.grade = grade
class student:
def __init__(self,name,age,gender, subjects=[]):
self.name = name
self.age = age
self.gender = gender
self.subjects = {}
for sub in subjects:
self.subjects[sub] = Subject(sub)
# Create new student with 2 subjects (Art and Science)
new = student('Alan',17,'M', subjects=['Art', 'Science'])
# You can wrap the following processes in functions if so desired
# Add a new subject later on (Math)
new.subjects['Math'] = Subject('Math')
# Add grades
new.subjects['Art'].grade = 'C'
new.subjects['Science'].grade = 'A+'
new.subjects['Math'].grade = 'B-'
# Get a list of subjects and grades
print([(sub.name, sub.grade) for _, sub in new.subjects.items()])
>>>[('Art', 'C'), ('Science', 'A+'), ('Math', 'B-')]
But i [don't] understand how one student object can get more than one subject and probably a [grade] per subject.
Pass in a dictionary of {subject: grade} pairs.
Code
class Student:
def __init__(self, name, age, gender, subjects=None):
self.name = name
self.age = age
self.gender = gender
# Handle mutable keyword defaults
if subjects is None:
self.subjects = {}
else:
self.subjects = subjects
def __repr__(self):
return ("{0.name}, {0.age}, {0.gender}, {0.subjects}".format(self))
subjects = {"Math": "A", "Biology": "B-", "Chemistry": "A"}
s = Student("Joe", 20, "M", subjects=subjects)
s
# Joe, 20, M, {'Math': 'A', 'Chemistry': 'A', 'Biology': 'B-'}
s.subjects["Math"]
# 'A'
Assigning None to a keyword argument is a convention for avoiding a well-known gotcha when assigning mutable arguments, e.g. lists, dictionaries. The lines that handle subjects is equivalent to this one-liner:
self.subjects = {} if subjects is None else subjects
The __repr__() method was defined, which you may wish to include along with __str__().
Related
I am new to pyhton and also new to working with classes. I am working on the below problem where I want to multiply the class variable (raise_amount) by the instance salary. However, when i do this, I get None as output. I would like to get the salary amount per person multiplied by 1.04. Any help will be greatly appreciated.
class Person:
raise_amount = 1.04
def __init__(self, name, street_name, house_nr, post_code, salary): #:post_code, salary):
self.name = name
self.street_name = street_name
self.house_nr = house_nr
self.post_code = post_code
self.salary = salary
def street_name_and_house_nr(self):
return '{} {}'.format(self.street_name, self.house_nr)
def apply_raise(self): # here is the code that seems to have problems
self.salary = int(Person.raise_amount * self.salary)
def street_name_and_house_nr_salary(self):
return self.name + ' ' + str(self.salary)
prs_1 = Person("Mary's", 'Broadway', 304, '2526 CG', 10)
prs_2 = Person("Jhon's", 'Longstreet', 304, '2829 AK',7)
prs_3 = Person("Larry's", 'Chinstreet', 58, '3046 JP', 8)
print(Person.apply_raise(prs_1))
print(Person.apply_raise(prs_2))
print(Person.apply_raise(prs_3))
This is the output i get when i run the code
None
None
None
apply_raise() doesn't return the new salary, it just updates the salary attribute. So you should get that separately to print it.
prs_1.apply_raise()
print(prs_1.salary)
Other notes:
Conventionally the first argument to methods is self. Don't make up your own name (what does lelf mean?).
You should call methods using instance.method(), not Class.method(instance). This ensures that the proper method will be used when the instance is in a subclass.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
class Customer: #at this part ı defined the class for the customers in the file
def __init__(self, Name, Surname, Age, Balance):
self.name = Name;
self.sname = Surname;
self.age = Age;
self.balance = Balance;
def __str__(self):
return("Hello, "+str(self.name)+" "+str(self.sname)+" You have "+ str(self.balance)+" dollars in your account.");
Hello, you can see my class above
My aim - ask users name/surname and get the str part in the class.
I'm getting informations about customers from csv file.
ans = input("name")
ans2 = input("surname")
a = Customer(ans,ans2)
print(a)
With this part I've tried to do part that I explained above but I could'nt make the code work.
You have to define all the other attributes the class instance supposed to have that is Name, Surname, Age, Balance where you have only given Name and Surname. Python will also expect all other attributes you have given in __init__
Take this for example:
Age = input("age") #add these to take input too
Balance = input("balance") #add these to take input too
a = Customer(ans,ans2, Age, Balance)
Well, if your values sometimes supposed to be empty, make some values not necessary as in example:
class Customer:
def __init__(self, Name, Surname, Age=None, Balance=None): # specify the values which would be left as blank
self.name = Name;
self.sname = Surname;
self.age = Age;
self.balance = Balance;
# another code here
Then, if you pass only part of data to class constructor, you'll still get a working class instance without any errors:
>>> a = Customer('Name', 'Surname')
>>> a.Name
'Name'
>>> a.Surname
'Surname'
>>> a.Age
>>> # we got None here
Of course, you can use keyboard input too to enter the values, which is not provided by your csv data file by using the input() function.
I'm fairly new to the world of python and programming in general, and its rare that i get up the nerve to ask questions, but I'm stomped so i thought id suck it up and ask for help.
I'm making an Address book.
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
contact = Person('Mike','1-800-foo-spam','email#email.com')
My question is how would go about storing all these attributes in a dictionary with contact.name as the key and contact.number and contact.email as the values.
Bonus question.
Should the dictionary be outside the class, perhaps in the main function?
or
Does it need to be a class variable(not completely sure how those work)
or an object variable
something like
self.storage = {}
Any help would be greatly appreciated.
Thank you!
If I put this information in a dictionary, I would do it like that:
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
self.storage = {self.name: [self.number, self.email]}
def getStorage(self):
return self.storage
contact = Person('Mike','1-800-foo-spam','email#email.com')
print contact.storage
# or
print contact.getStorage()
But the whole idea of a dictionary is to have a number of keys and corresponding values. In this example, it always will be one only. So, another schema comes to my mind:
class Person():
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
# creating some example contacts
c1 = Person('Mike','1-800-foo-spam','email#email.com')
c2 = Person('Jim','1-700-foo-spam','e111mail#email.com')
c3 = Person('Kim','1-600-foo-spam','e222mail#email.com')
# creating a dictionary to fill it with c1..cn contacts
contacts = {}
# helper function to automate dictionary filling
def contactToDict(list_of_contacts):
for item in list_of_contacts:
contacts[item.name] = (item.number, item.email)
contactToDict([c1, c2, c3])
"""
expected output:
Mike: ('1-800-foo-spam', 'email#email.com')
Jim: ('1-700-foo-spam', 'e111mail#email.com')
Kim: ('1-600-foo-spam', 'e222mail#email.com')
"""
for key, val in contacts.items():
print str(key) + ": " + str(val)
The answer to the title of the question: a value should be a type of object with allows to have a "list" inside (i.e. list, tuple, another dictionary or custom type object having a number of attributes.)
You can pretty easily have a dictionary with tuples as the values.
a = {}
a["bob"] = ("1-800-whatever","bob#gmail.com")
If you wanted to make it a class variable, you'd just need to create an empty dictionary as part of the Person class:
class Person():
storage = {}
Then in __init__ you can store the new person's info in that dictionary:
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
Person.storage[name] = (number, email)
As you can see class attributes are accessed with the classname, but otherwise like any other attribute. You could store them as a tuple or a list if you need to update them. However if you intend to make changes, it might be better to store the actual Person object, to save having to update Person.storage and the actual person at the same time. This is even easier to do:
def __init__(self,name,number,email):
self.name = name
self.number = number
self.email = email
Person.storage[name] = self
self refers to the instance of Person that's being created with __init__. That's Mike in your example. Then you could access their values by attribute:
Person.storage["Mike"].number
Also as Kevin pointed out in a comment you might want to detect if the key already exists to avoid overwriting an old entry (eg. if there's already a Mike in the dictionary):
self.email = email
if name in Person.storage:
# Make unique name
Person.storage[name] = (number, email)
If I have 5 pieces of relevant data, I think it's fair to use a class in order to sort data effectively. However, I need to add these vars to a list.
If I have class "student(name, grade, attendance)", and I'm appending these values to a list, what would that look like?
# student class, inits with name and student id
class Student:
def __init__(self,name,grade, attendance):
self.name = name
self.grade = grade
self.attendance = attendance
def __str__(self):
return self.name
# list of students
students = []
# creates two students
s1 = Student('terry', 99, 99)
s2 = Student('jack', 42, 1)
# add students in the list
students.append(s1)
students.append(s2)
print students
Basically this is within a class which appends objects of another class to list self. There are 200 objects in list self. So basically if I call self[1] I will get ['John',['Alex', 'Rob']. Basically 'john' refers to self.firstname and the other names refer to there group members. For example the below will print the firstnames and groupmembers of each object for all 200 objects
for line in self:
print line.firstname
for line in self:
print line.groupmembers
Now I have to create something that goes through all the names and checks the names. So basically if John has Alex and Rob as members then there has to be another object with a first name Alex and another object with a firstname Rob. So say there is no object with firstname Alex I want to print 'mismatch'. This is what I have so far but its not doing what its intended to do.
def name(self):
firstnames = []
for item in self:
firstnames.append(item.firstname)
for item1 in self:
for i in item1.groupmembers:
if i not in hello:
print 'mismatch'
Okay so first off, line and self are bad variable names.
self should only be used within a class to be used as a way to call or use its own variables.
Secondly, you say each value in this self list contains values like ['John',['Alex', 'Rob'], but then you go on to use it like a class object... and frankly that don't do make none sense.
So to remedy this, I'm going to assume its done with class objects. I would also rename self to something like school, and instead of calling an element of self; line, which yields no information to the reader.. call it a student!
I'm going to assume your class would start looking like this:
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
Then if you have a list of people you can loop through them like so..
>>>school = [Student("foo", ["bar", "that guy"]),
Student("bar", ["foo", "that guy"])]
>>>for student in school:
print student.firstname
print student.groupmembers
foo
["bar", "that guy"]
bar
["foo", "that guy"]
Then to check it a students group members are in school you can add a function to the Student class
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
def group_present(self, school):
# This is how you would get all the names of kids in school without list comprehension
attendance = []
for student in school:
attendance.append(student.firstname)
# this is with list comprehension
attendance = [ student.firstname for student in school]
#compare group members with attendance
#note that I write student_name, not student
## helps point out that it is a string not a class
for student_name in self.groupmembers:
if not student_name in attendance:
print "Group member '{}' is missing :o!! GASP!".format(student_name)
In idle:
>>> school[0].group_present(school)
Group member 'that guy' is missing :o!! GASP!
Hope that helps!
I am not sure if i understand exactly but maybe you can use contains
self[1].__contains__('Alex')
this should return true in case of existence or false otherwise.