Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recreating "private" class variables in Python

Tags:

python

private

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

Here's my problem: I'm creating a class project. In this class project, students design an agent that takes a multiple choice test. We want to be able to grade the agents' answers immediately so that the agents can learn from their wrong answers to previous problems. So, we need the correct answer to each problem to be stored in the program. Students are running these projects on their local machine, so they can see all the tester's code. They can't modify it -- we overwrite any of their changes to the tester code when they turn it in. They just turn in a new file representing their agent.

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

I need to recreate this behavior in Python, and so far I'm at a loss. It seems that no matter where in the program correctAnswer is stored, agents can access it -- I'm familiar with the underscore convention, but in this problem, I need agents to be incapable of accessing the right answer. The only thing I can think of is to name correctAnswer something different when we're testing students' code so that their agents can't anticipate what it will be called, but that's an inelegant solution.

Any suggestions? It's acceptable for agents to be able to read correctAnswer so long as we can detect when they read it (so we can set the 'agent's answer' variable to read-only after that... although then I'll need a way to do that, too, oof).

like image 956
David Avatar asked Dec 26 '22 06:12

David


2 Answers

Change the rules. Don't store the correct answer in the program. Store the correct answer on a secured server:

def checkAnswer(studentAnswer):
    response = requests.get('http://teacher-server.example.edu/checkAnswer?%s'%studentAnswer)
    return response.text == 'Yes'
like image 88
Robᵩ Avatar answered Dec 31 '22 14:12

Robᵩ


You can change the name of the the correctAnswer attribute in the code that you overwrite the tester with. This will instantly break all solutions that rely on the name of correctAnswer.

Furthermore, you could run both versions of the tester and diff the outputs. If there is a difference, then their code relies on the attribute name in some way.

like image 38
skyler Avatar answered Dec 31 '22 12:12

skyler