10

I am a newbie to Python. I need to create a simple student class which includes first name, last name, id, and a dictionary which maps course name to its grade.

class Student:
    def __init__(self, firstName, lastName, id, _____ (dictionary values)):
        self._firstName = firstName;
        self._lastName = lastName;
        self._id = id;

        self.

My question is how can I initizalize the dictionary values inside the constructor?

For example, let`s say I would like to add 3 course to grade mappings: "math: 100" "bio: 90" "history: 80"

For example:

student1 = Student("Edward", "Gates", "0456789", math: 100, bio: 90, history: 80)

The last 3 values should go into the dictionary.

Since the number of key-value which can be part of the dictionary can vary, what should I write in the constructor parameter signature?

I want to send all the student values when I call the constructor...

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
qwerty
  • 670
  • 5
  • 10
  • 20

5 Answers5

11

If you are looking to add a dictionary Mathias' answer suffices with the key word arguments in python.

However, if you wish to add object variables from the key word arguments, you require setattr

For example, if you want something like this:

student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})
print student1.math #prints 100
print student1.bio  #prints 90

Then this will do the trick:

class Student(object):
    def __init__(self, first_name, last_name, id, **kwargs):
        self.first_name = first_name
        self.last_name = last_name
        self.id = id
        for key, value in kwargs.iteritems():
            setattr(self, key, value)

student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})

Note that **kwargs will unpack only something like dictionary or tuple of tuples. If you wish to send a list of values without keys, you should use *args. Check here to know more.

thiruvenkadam
  • 4,170
  • 4
  • 27
  • 26
  • When I try the same command, I get this error: ""TypeError: Student.__init__() takes 4 positional arguments but 5 were given"" Why? – Nilay İnel Mar 20 '23 at 16:05
2

Python collects all keyword arguments for you.

class Student:
    def __init__(self, firstName, lastName, id, **kwargs):
        self._firstName = firstName;
        self._lastName = lastName;
        self._id = id;

        self. _grades = kwargs

Here is an excellent explanation about kwargs in python

Community
  • 1
  • 1
Mathias
  • 6,777
  • 2
  • 20
  • 32
2

Why not send the complete grades dictionary to the your class and store it in a variable. (Also please note that in Python there is no semicolon at the end of the line)

class Student:
    def __init__(self, firstName, lastName, id, grade_dict):
        self._firstName = firstName
        self._lastName = lastName
        self._id = id
        self._grades = grade_dict

    def get_grades(self):
        return self._grades

and then when you want to initialize and use the grades:

student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})
grades = student1.get_grades()
for key, value in grades.items():
    print 'Marks in {}: {}'.format(key, str(value))

Which prints:

Marks in bio: 90
Marks in math: 100
Marks in history: 80
sk11
  • 1,779
  • 1
  • 17
  • 29
1

You can try something like:

student = Student("Edward", "Gates", "0456789", {"math": 100, "bio": 90, "history": 80})

And inside your constructor you can copy these values to a new dictionary:

class Student:
    def __init__(self, firstName, lastName, id, grades):
        self._firstName = firstName;
        self._lastName = lastName;
        self._id = id;

        self._grades = grades.copy()

Notice that we're copying the dictionary to a new attribute because we want to avoid keeping a reference.

Gustavo Meira
  • 2,875
  • 3
  • 21
  • 33
1

First, make sure to remove the semicolon ; from your code - it won't compile! Second, I believe you're looking to do something like:

class Student:

    def __init__(self, first_name, last_name, _id, **courses):
        self._first_name = first_name
        self._last_name = last_name
        self._id = _id
        self.courses = courses

    def print_student(self):
        print self._first_name
        print self._last_name
        print self._id
        for key in self.courses:
            print key, self.courses[key]


courses = {'math': 100, 'bio': 90, 'history': 80}    
s = Student("John", "Smith", 5, **courses)
s.print_student()

OUTPUT

John
Smith
5
bio 90
math 100
history 80
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129