This is a page where we write responses to weekly feedback given through Lovelace either in exercise or page specific feedback boxes. We will also write a note here when something has been changed due to feedback.
This is a collection of feedback + response combos that come up yearly.
Giving Feedback on Exercises¶
"My program works on my computer but is not accepted by the checker"
Questions along this line are more than welcome. However, the feedback box is the wrong place for them because the feedback box is anonymous. Therefore we cannot actually help you figure out what the problem is, because we don't know who you are or how to obtain your code. If your feedback contains a question, you should send it as a question via Mattermost or email - this way you will actually receive an answer or explanation.
"The exercise specification was not clear"
While we understand the frustration of not understanding what is being asked, this feedback is not very useful. It's usually much more helpful for all parties if you ask about the unclear parts via Mattermost or email. This way you will receive an answer, and we receive more accurate information about what part of the specification is potentially misleading.
Why Your Exercise Answer is Rejected¶
Most commonly the cause of rejection is incorrect function implementation. The most important part of each programming exercise specificiation is the function specification. Individual functions are what the checkers will actually check, and they will be checked in isolation, based on the specification given in the exercise text. If your function doesn't have the described interface (name + parameters + return values), or you have placed some of the function's tasks into another part of the program, your function cannot be accepted. Likewise if your function is not truly independent - meaning it accesses values from the global scope that were not speficied as accessible in the exercise specification - it cannot pass.
"Redefining name from outer scope"¶
This is a Pylint warning that is most commonly asked about. It results from using the same variable in both the main program (global scope) and inside a function (local variable). This is a clarification what are the potential problems this warning tries to warn you about.
Everything is related to the fact that all names from the
global scopeare readable inside
functions. Here is a familiar example from the first exercises with one small change.
import math def calculate_area(radius): return 4 * math.pi * radius ** 2 def calculate_volume(radius): return 4 / 3 * math.pi * radius ** 3 def calculate_radius(circ): return ball_circumference / (math.pi * 2) def calculate_ball_properties(circumference): radius = calculate_radius(circumference) area = calculate_area(radius) volume = calculate_volume(radius) return area, volume circumference = float(input("Enter ball circumference: ")) ball_area, ball_volume = calculate_ball_properties(circumference) print("Volume:", round(ball_volume, 4)) print("Surface area:", round(ball_area, 4))
In this example the circumference name is used in the
main program, and also as a function
parameter. This by itself is not a problem - the local
variablealways overrides the global variable with the same name. However, if we decide to later change this parameter name to something else without remembering to change every reference to it inside the function, i.e. we do:
def calculate_radius(circ): return circumference / (math.pi * 2)
This does not cause any
exceptionsbecause there still is a variable called circumference - it's in the main program. However, this becomes a problem when the function is called multiple times - which is what the checkers will do. You can witness the issue in the
consoleif you open it in the same folder where you have the ball module.
In : import ball Enter ball circumference: 23 Volume: 205.4625 Surface area: 168.3859
module. So far everything looks the same as in the example and the program calculates correctly. However, if we call the function directly to calculate the values for another ball:
In : ball.calculate_ball_properties(5) Out: (168.38592979122527, 205.46247356272062)
We now get the exact same results despite a much smalle circumference for the ball. This is where the issue materializes: we received a value for the circumference variable when the module was imported and it was not changed since. The error in the
calculate_radiusfunction now causes it to produce wrong results without any error notifications. This is because it is using the main program value, not the 5 we provided in the above
function call. However, if the parameter's name would have been something else to begin with e.g. ball_circumference and we'd do the same error of changing the parameter name without updating all references to it:
def calculate_radius(circ): return ball_circumference / (math.pi * 2)
Something very different happens if we try to import the ball module:
In : import ball Enter ball circumference: 23 --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-75c476b98463> in <module> ----> 1 import ball ~\Documents\ball.py in <module> 17 18 circumference = float(input("Enter ball circumference: ")) ---> 19 ball_area, ball_volume = calculate_ball_properties(circumference) 20 print("Volume:", round(ball_volume, 4)) 21 print("Surface area:", round(ball_area, 4)) ~\Documents\ball.py in calculate_ball_properties(circumference) 11 12 def calculate_ball_properties(circumference): ---> 13 radius = calculate_radius(circumference) 14 area = calculate_area(radius) 15 volume = calculate_volume(radius) ~\Documents\ball.py in calculate_radius(circ) 8 9 def calculate_radius(circ): ---> 10 return ball_circumference / (math.pi * 2) 11 12 def calculate_ball_properties(circumference): NameError: name 'ball_circumference' is not defined
Now we get a proper error message from this sneaky little bug because the funcion cannot pull a "replacement" from a variable with the same name in the main program. Another way to entirely avoid this issue is to make a main function instead of a main program. All the main program code goes inside this function, and the main program itself is just a call to this function. Like this:
Now the global scope only contains function names - no variables at all. Doing the same mistake would once again produce a NameError exception. We also don't need to invent a different name for circumference "just to be safe" because every circumference in the code is now a local variable. Even Pylint is now happy. You are free to use this solution in exercises if you'd rather avoid the warnings. Your main program can be contain the main program code, or it can contain a call a function that contains the main program code - the checkers do not care.
Naturally the example here is very artificial since the function has a whopping one line of code inside it. However, a problem like this can easily be realized in a bigger project where it's impossible to see all of the code at once. Especially if you're careless when editing your code.
One recurring topic is the love of spaces in the text field exercises. We've made a principal decision to use hard measures to instruct students in writing pretty code. In the past we used to allow all kinds of styles of writing code, and this was reflected in the course projects, and it was not pretty. It would actually be easier for us to accept answers with offending use of spaces than it is to give separate hints about them. There should be a hint about spaces in every task once your answer is otherwise correct. Let us know if that is not the case.
We understand that this can be frustrating in the beginning, but being careful is also a part of programming. While it may not seem relevant, hunting missing or extra spaces can be helpful in noticing other errors resulting from carelesness in the future - in situations where they actually cause bugs. It's also easier to notice other errors when your code looks clean and consistent. Likewise if you want to put your code (e.g. course project) into your Github it will make you look much better if it follows style guidelines.
There aren't that many space rules:
- There's a space after each comma
- There's a space on both sides of an operator
- Exception: when the operator is a keyword assignment
- In practice this applies to dictionary definition
We haven't made up any of these rules, they are based on Python's official style guide.
Give feedback on this content