CS1101 Discussion Assignment Unit 4 - Three possibilities to consider if a function is not working

Questions

Section 6.9 of your textbook (“Debugging”) lists three possibilities to consider if a function is not working.
1.Describe each possibility in your own words.
2.Define “precondition” and “postcondition” as part of your description.
3.Create your own example of each possibility in Python code. List the code for each example, along with sample output from trying to run it.

1. Definition of the terms

A precondition is “a requirement that should be satisfied by the caller before a function starts” (Downey, 2015, p.37);

A postcondition is “a requirement that should be satisfied by the function before it ends” (Downey, 2015, p.37);

A return value is something that a function returns to the caller after it is executed. It can be None, a number, a string, a complex expression, or even a function.

2. Description of the three possibilities

When we call a function, there are three possibilities for the function’s not working:

The first case is that the preconditions are not met. Specifically, the arguments we pass to the function are incorrect, such as the arguments’ types do not match the parameters’ types or arguments’ amount mismatches the parameters’ amount, etc;

The second case is that the post-conditions are not met. Specifically, the code in the function’s body does not achieve the desired effect, maybe because the statement’s logic is incorrect, or the statements’ format is wrong, etc;

The third case is there is a problem with the return value of the function. Specifically, it may be that the function’s return value is not the value we want, or the returned value is correct, but we did not use it correctly.

3. Examples of the three possibilities

3.1. The example without errors

Codes:

1
2
3
4
5
6
7
8
def recipe(fish, salt, oil):
ingredients = fish + ", " + salt + ", and " + oil
cooked_dish = "A delicious fish is ready, and its ingredients include " + ingredients
return cooked_dish


result = recipe("fish", "salt", "oil")
print(result)

Outputs:

1
A delicious fish is ready, and its ingredients include fish, salt, and oil

Explanation:
The function recipe requires three string-type parameters. When I called this function, I passed three string-type arguments(namely “fish,” “salt,” and “oil”) to the function’s parameters. Then, the function received the arguments, and the statements inside the function concatenated these strings. Finally, the function returned the concatenated string as a return value: A delicious fish is ready, and its ingredients include fish, salt, and oil.

3.2. The example of a precondition violation

Codes:

1
2
3
4
5
6
7
8
def recipe(fish, salt, oil):
ingredients = fish + ", " + salt + ", and " + oil
cooked_dish = "A delicious fish is ready, and its ingredients include " + ingredients
return cooked_dish


result = recipe(0, "salt", "oil")
print(result)

Outputs:

1
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Explanation:
The function recipe requires three string-type parameters. However, when I called this function, I passed an int-type number 0 as a parameter, which caused an error in the string concatenation inside the function. Because an int-type number can not concatenate with a string, the interpreter returned the TypeError. Therefore, the arguments mismatched the parameters. This program is an example of a precondition violation.

3.3. The example of a postcondition violation

Codes:

1
2
3
4
5
6
7
8
def recipe(fish, salt, oil):
ingredients = 2 + fish + ", " + salt + ", and " + oil
cooked_dish = "A delicious fish is ready, and its ingredients include " + ingredients
return cooked_dish


result = recipe("fish", "salt", "oil")
print(result)

Outputs:

1
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Explanation:
The function recipe requires three string-type parameters. When I called this function, I passed three string-type arguments(namely “fish,” “salt,” and “oil”) to the parameters. So the precondition was met. But inside the body of the function, an int-type number 2 and the strings were concatenated. Because the int-type number can not concatenate with a string, the interpreter returned the TypeError. This error occurs inside the function, so this program is an example of a postcondition violation.

3.4. The example with an incorrect return value

Codes:

1
2
3
4
5
6
7
8
def recipe(fish, salt, oil):
ingredients = fish + ", " + salt + ", and " + oil
cooked_dish = "A delicious fish is ready, and its ingredients include " + ingredients
return 2


result = recipe("fish", "salt", "oil")
print(result)

Outputs:

1
2

Explanation:
The function recipe requires three string-type parameters. When I called this function, I passed three string-type arguments(namely “fish,” “salt,” and “oil”) to the parameters. So the precondition was met.

Besides, inside the function, the strings were correctly concatenated and successfully assigned to the variable cooked_dish. The value of the variable cooked_dish was what I wanted, so the post-condition was also satisfied.

But the function returned an int-type number 2 instead of the cookded_dish, so it returned a value that I did not want. Hence, this program is an example with an incorrect return value.

3.5. The example of the misuse of the return value

Codes:

1
2
3
4
5
6
7
8
def recipe(fish, salt, oil):
ingredients = fish + ", " + salt + ", and " + oil
cooked_dish = "A delicious fish is ready, and its ingredients include " + ingredients
return cooked_dish


result = recipe("fish", "salt", "oil")
print(result + 2)

Outputs:

1
TypeError: can only concatenate str (not "int") to str

Explanation:
The function recipe requires three string-type parameters. When I called this function, I passed three string-type arguments(namely “fish,” “salt,” and “oil”) to the parameters. So the precondition was met.

Besides, inside the function, the strings were correctly concatenated and successfully assigned to the variable cooked_dish. The value of the variable cooked_dish was what I wanted, so the postcondition was also satisfied.

Furthermore, the function returned the value of cooked_dish, so the return value was correct.

But when I printed the return value, I concatenated it with an int-type number 2. Because the int-type number cannot concatenate with a string, the interpreter returned the TypeError.

In this example, the precondition and the postcondition were both met, and the return value was correct, but I misused it. So this is an example of the misuse of the return value.

4. A little story to help understand the terms and the three possibilities

4.1. Part I

Imagine you are very hungry. You go to a restaurant and order a delicious fish to relieve your hunger.

To cook a fish, the chef needs fish, salt, and oil. Providing the chef fish, salt, and oil is the precondition for cooking a fish. If the chef is given some potatoes, then the precondition is not met. If the chef does get the fish, salt, and oil, then the precondition is satisfied.

Assuming that the precondition is met, the chef also needs a recipe for cooking fish. This recipe is a postcondition. If this recipe is wrong, that is to say, according to its procedures, the chef cannot cook delicious fish, for example, the fish is scorched, then the mistake of this recipe is that the postcondition is not satisfied. If the procedure in the recipe is correct, for example, the cooking time is just right, the fish will not be scorched and will be delicious, then the postcondition is satisfied.

Assuming that both the precondition and postcondition are met, the chef has cooked a delicious fish with the right ingredients and recipe. Now, the waiter brings the fish to you. The fish served is equivalent to the return value. If the waiter brought you a bowl of soup instead of fish, the return value is wrong because you ordered a fish. If the waiter did serve a delicious fish, the return value is correct. However, If you don’t eat this fish but use it to appreciate the chef’s superb cooking skills, it misuses the return value. Because you are hungry, you need to eat the fish instead of watching it.

4.2. Part II

For programming, the fish, salt, and oil in the above story are similar to arguments, and the recipe is identical to the function. The fish served by the waiter is like the return value.

If the ingredients match the elements required by the recipe or say the arguments match the parameters, it means the precondition is met. Conversely, if the ingredients mismatch the elements required by the recipe or say the arguments mismatch the parameters, it means the precondition is not satisfied.

If the steps in the recipe are correct, and the chef can cook a delicious fish according to these steps, or say the statement in the function can achieve the effect we want, it means the postcondition is satisfied. In contrast, if the steps in the recipe are incorrect, and you can not cook a delicious fish according to these steps, or say the statement in the function can not achieve the effect we want, it means the postcondition is not satisfied.

If the waiter brings you delicious fish or say the function’s return value is the value we want, the return value is correct. On the contrary, if the waiter does not bring you delicious fish or say the function’s return value is not the value we expect to get, it means the return value is incorrect.

If you eat this fish to relieve hunger instead of using it to appreciate the cooking, this is equivalent to that you use the return value correctly. On the contrary, if you don’t eat this fish to relieve hunger but use it to appreciate the cooking, this is equivalent to the misuse of the return value.

Word count: 1512

References

1.Downey, A. (2015). Think Python. Green Tea Press.
https://greenteapress.com/thinkpython2/thinkpython2.pdf

​


This is the ending, thanks for reading.