-1

I want to create a Python class which stores the name, surname and grades of a student and checks whether the grades are in the correct range or not (0-10).

Is there any way to change the attributes which are greater than 10 to 0 (not one by one)?

class Student:
    def __init__(self, name, lastName, programming, algebra,
             calculus, physics, writing):
        self.name = name
        self.lastName = lastName
        self.programming = programming
        self.algebra = algebra
        self.calculus = calculus
        self.physics = physics
        self.writing = writing
    def check(self):
        if self.programming or self.algebra or self.calculus or self.physics or self.writing not in range(11):
            #Change the value of the attributes which are > 10 to 0
        #Is there any way to do it apart from this one?
        #if self.programming not in range(11):
            #self.programming = 0
        #if self.algebra not in range(11):
            #self.algebra = 0
         ................... 
mpb
  • 1,277
  • 15
  • 18
Sergio
  • 7
  • 1
  • 3
    Yes. See: https://stackoverflow.com/questions/11637293/iterate-over-object-attributes-in-python. Alternatively, you could store all of those attributes in a dictionary `student.marks` and iterate over that – c2huc2hu Nov 10 '18 at 17:56

1 Answers1

1

You can use properties and setters and guard against wrong values inside the setters:

class Student:
    def __init__(self, name, programming ):
        self.name = name
        self.programming = programming # using the setter so our business rule is applied

    @property
    def programming(self):
        return self._programming

    @programming.setter
    def programming(self,n):
        # apply the businessrule of n being in 1 to 10 else 0
        self._programming = n if 0 < n < 11 else 0


studs = [ Student("Enya",20), Student("Eric",0), Student("Karl",5)]

for s in studs:
    print(s.name, s.programming)

Output:

Enya 0
Eric 0
Karl 5

Read more about @property's at python.org property() and @property

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • I just add, that when using getter and setter, attribute `programming` per se should be (conventionally) "private", i.e. `self._programming = programming` – Michal Polovka Nov 10 '18 at 18:59
  • @MichalPolovka you cant name the backing variable of the getter the same - and I used the convention of one `_` thats by convention signifies "privateness" - so I do not quite get what you mean. – Patrick Artner Nov 10 '18 at 19:07
  • @MichalPolovka and the assignment in `__init__(self)` if purposefully using the property setter - so the buisinessrules are applied - you _can_ use the private one directly but then you circumvent the setter buisiness rule implementation which would make it silly to use in the first place... – Patrick Artner Nov 10 '18 at 19:11