From Working Code to Program Design · practice
When Data and Behavior Drift Apart
In the previous lesson, the quiz used check_answer to decide whether a response was correct. The quiz should give the same answer everywhere, so imagine that we add a second feature: a message that tells the learner "Correct" or "Try again".
Both features need to answer the same question:
Does this response match the expected answer?
The expected answer is stored in a question
question = {
"prompt": "Which keyword starts a function?",
"answer": "def",
}
The checking
def is_correct(question, response):
cleaned = response.strip().lower()
expected = question["answer"].lower()
return cleaned == expected
For example, both "def" and " DEF " count as correct.
The problem: a second function uses a different check
Suppose the new message function writes its own comparison:
def result_message(question, response):
if response == question["answer"]:
return "Correct"
return "Try again"
This comparison does not remove spaces or ignore letter case. The two parts of the same quiz now disagree about " DEF ":
is_correctreturnsTrue;result_messagereturns"Try again".
That disagreement is the problem named in this lesson’s title.
Data is the information stored by the program, such as the question’s prompt and expected answer.
Behavior is work the program performs with that information, such as checking a response.
The behavior has drifted apart when two parts of the program implement the same rule differently.
You do not need to memorize those terms. The practical lesson is simple: if two features must follow the same rule, do not write two separate versions of that rule.
Reuse the one checking function
Any feature that needs the verdict can call is_correct. For example, a points function can reuse the shared check:
def points_earned(question, response):
if is_correct(question, response):
return question["points"]
return 0
The scoring feature and the message feature can now use the same answer check. If the quiz’s comparison rule changes later, there is one place to update it.
Why is calling is_correct from result_message better than repeating the comparison?
The exercise makes this exact repair. You are not learning new syntax. You are making two familiar functions agree by keeping the shared rule in one place.
Task
Repair result_message so it calls is_correct to check the answer.
Do not repeat the cleaning or comparison rule. The three printed messages should be Correct, Correct, and Try again.