Playing private class variables in Python

I read a number of SO threads about why Python doesn't have truly private variables, and I understand this for most applications.

Here is my problem: I am creating a class project. In this class of the project, students develop an agent that conducts a multiple choice test. We want us to evaluate agent responses immediately so that agents can learn from their incorrect answers to previous problems. So, we need the right answer to every problem that will be stored in the program. Students run these projects on their local machine, so they can see all the tester code. They cannot change it - we overwrite any of their changes in the tester code when they are turned on. They simply transform a new file representing their agent.

In Java, it is simple. In the class "Problem" there is a private correct variable "Answer". correctAnswer always saves the correct answer to the problem. Agents can only read the correct answers through the checkAnswer method, and in order to call checkAnswer, agents must actually give an answer to a question that cannot be changed later.

I need to recreate this behavior in Python, and so far I'm out of order. It seems that no matter where the answer is stored correctly in the program, agents can access it - I am familiar with the underscore agreement, but in this problem I need agents who can’t get the correct answer. The only thing I can think of is to call correctAnswer something else when we test the students code so that their agents cannot foresee what it will be called, but this is not an elegant solution.

Any suggestions? It is permissible for agents to read correctAnswer while we can detect when they are reading it (so we can set the "agent answer" variable to read only after that ... although then I need a way to do this too, oof).

+4
5

, . , correctAnswer.

, . , - .

+3

. . :

def checkAnswer(studentAnswer):
    response = requests.get('http://teacher-server.example.edu/checkAnswer?%s'%studentAnswer)
    return response.text == 'Yes'
+5

__getattr__

. , , . , , :

x = myClass.myAttribute

.

+1

, , , Python - , Python, . , __getattr__, , object.__getattribute__. "" , , , . Java, Python , . , .

multiprocessing . - :

import multiprocessing as mp
import multiprocessing.managers

class Problem(object):
    def __init__(self, correctAnswer):
        self.answer = None
        self.correctAnswer = correctAnswer

    def checkAnswer(self, answer):
        if self.answer == None:
            self.answer = answer
        return self.answer == self.correctAnswer

    def __getstate__(self):
        raise ValueError("don't pickle me");

class Problem_proxy(mp.managers.BaseProxy):
    def checkAnswer(self, answer):
        return self._callmethod("checkAnswer", (answer,))

class mymanager(mp.managers.BaseManager):
    pass

mymanager.register("Problem", Problem, Problem_proxy)

def other_process(problems):
    # uncommenting either of these should cause an exception
    # print problems[0].correctAnswer
    # print problems[0]._getvalue().correctAnswer

    import agent       # module provide by the student
    agent.answer_problems(problems)

def main():
    manager = mymanager()
    manager.start()

    meaningoflife = manager.Problem(42)
    problems = [meaningoflife]

    proc = mp.Process(target = other_process,
              args = ([meaningoflife],))
    proc.start()
    proc.join()


if __name__ == "__main__":
    main()

. , , , . , - / , .

+1

correctAnswer , -, .

, :

import inspect

class Problem(object):
    @property
    def correctAnswer(self):
        frm = inspect.currentframe()
        caller = inspect.getouterframes(frm)[0]

        _,_,_,name,_,_ = caller

        if name != YOUR_TESTING_FUNCTION:
            raise BadStudentError()

        return self._correctAnswer

, , _correctAnswer, ( .correctAnswer , @property , ).


, , , , .

, . , , .

HTTP- , (checkAnswer ), .

0
source

All Articles