Home > Back-end >  How to write @property correctly?
How to write @property correctly?

Time:01-26

Unfortunately, I can't give you the condition of the problem, but I can briefly describe it we need to create two classes:

  1. The first class creates an exam ticket. The teacher writes the name of the subject, the correct answers to the test and the minimum percentage for successful completion.
  2. The second grade is the student's test.
class Testpaper:
    def __init__(self, subject, markscheme, pass_mark):
        self.subject = subject
        self.markscheme = markscheme
        self.pass_mark = pass_mark

class Student:
    def __init__(self, tests_taken = {}):
        self._tests_taken = tests_taken

    @property
    def tests_taken(self):
        if self._tests_taken == {}:
            self._tests_taken = "No tests taken"
            return self._tests_taken 
        else:
            return self._tests_taken
    
    def take_test(self, testpaper, answers):
        self._tests_taken = {}
        pass_mark = 0
        for answer in answers:
            if answer in testpaper.markscheme:
                percent = 100 / len(testpaper.markscheme)
                pass_mark  = percent
        
        if pass_mark >= int(testpaper.pass_mark[:-1]):
            self._tests_taken[testpaper.subject] = f"Passed! ({round(pass_mark)}%)"
            return self._tests_taken
        else:
            self._tests_taken[testpaper.subject] = f"Failed! ({round(pass_mark)}%)"
            return self._tests_taken

Here's what I need to check:

paper1 = Testpaper("Maths", ["1A", "2C", "3D", "4A", "5A"], "60%")
paper2 = Testpaper("Chemistry", ["1C", "2C", "3D", "4A"], "75%")
paper3 = Testpaper("Computing", ["1D", "2C", "3C", "4B", "5D", "6C", "7A"], "75%")

student1 = Student()
student2 = Student()
paper3 = Testpaper('Computing', ['1D', '2C', '3C', '4B', '5D', '6C', '7A'], '75%')
student2 = Student()
student3 = Student()
student2.take_test(paper3, ['1A', '2C', '3A', '4C', '5D', '6C', '7B'])
print(student3.tests_taken)
student3.take_test(paper1, ['1C', '2D', '3A', '4C', '5A'])
student3.take_test(paper3, ['1A', '2C', '3A', '4C', '5D', '6C', '7B'])
print(student3.tests_taken)
print(paper3.subject)
print(paper3.markscheme)
print(paper3.pass_mark)

This is my output:

No tests taken
{'Computing': 'Failed! (43%)'}
Computing
['1D', '2C', '3C', '4B', '5D', '6C', '7A']
75%

And this is the correct output:

No tests taken
{'Maths': 'Failed! (20%)', 'Computing': 'Failed! (43%)'}
Computing
['1D', '2C', '3C', '4B', '5D', '6C', '7A']
75%

What I must change?

CodePudding user response:

Just change tests taken to read like so:

def tests_taken(self):
        if self._tests_taken == {}:
            return "No tests taken"
        else:
            return self._tests_taken

Full code is this:

class Testpaper:
    def __init__(self, subject, markscheme, pass_mark):
        self.subject = subject
        self.markscheme = markscheme
        self.pass_mark = pass_mark

class Student:
    def __init__(self, tests_taken = {}):
        self._tests_taken = tests_taken

    @property
    def tests_taken(self):
        if self._tests_taken == {}:
            return "No tests taken"
        else:
            return self._tests_taken
    
    def take_test(self, testpaper, answers):
        self._tests_taken = {}   
        pass_mark = 0
        for answer in answers:
            if answer in testpaper.markscheme:
                percent = 100 / len(testpaper.markscheme)
                pass_mark  = percent
        
        if pass_mark >= int(testpaper.pass_mark[:-1]):
            self._tests_taken[testpaper.subject] = f"Passed! ({round(pass_mark)}%)"
            return self._tests_taken
        else:
            self._tests_taken[testpaper.subject] = f"Failed! ({round(pass_mark)}%)"
            return self._tests_taken


paper1 = Testpaper("Maths", ["1A", "2C", "3D", "4A", "5A"], "60%")
paper2 = Testpaper("Chemistry", ["1C", "2C", "3D", "4A"], "75%")
paper3 = Testpaper("Computing", ["1D", "2C", "3C", "4B", "5D", "6C", "7A"], "75%")

student1 = Student()
student2 = Student()
paper3 = Testpaper('Computing', ['1D', '2C', '3C', '4B', '5D', '6C', '7A'], '75%')
student2 = Student()
student3 = Student()
student2.take_test(paper3, ['1A', '2C', '3A', '4C', '5D', '6C', '7B'])
print(student3.tests_taken)
student3.take_test(paper1, ['1C', '2D', '3A', '4C', '5A'])
student3.take_test(paper3, ['1A', '2C', '3A', '4C', '5D', '6C', '7B'])
print(student3.tests_taken)
print(paper3.subject)
print(paper3.markscheme)
print(paper3.pass_mark)

Output:

No tests taken
{'Computing': 'Failed! (43%)'}
Computing
['1D', '2C', '3C', '4B', '5D', '6C', '7A']
75%

CodePudding user response:

Delete the row, that resets ._tests_taken variable and it should be better :)

def take_test(self, testpaper, answers):
    self._tests_taken = {}        # this row resets the object._tests_taken
    pass_mark = 0

You don't have to reinitialise that dictionary, because in here:

self._tests_taken[testpaper.subject] = f"Passed! ({round(pass_mark)}%)"

You add (replace if taken again) the correct value anyway.

Also change your property to that:

@property
def tests_taken(self):
    if self._tests_taken == {}:
        return "No tests taken"
    else:
        return self._tests_taken
  •  Tags:  
  • Related