You know, my first programming language that I learned was C. I had no tutors, just a keen eye for excellent writing. Even after finding one VERY good book on the subject that helped me understand pointers (on a college short course later the instructor warned us, if you are going to write code that could possibly be used to guide missles to targets in this nuclear age we are living in, please really KNOW pointers – when pointers go astray with missles, Cities DIE!) I still would run into problems hard to figure out. But then I heard about a practice of using a Rubber Duck! Seriously, a Rubber Duck! You talk to the duck, explain what you are given, what is supposed to happen to what you were given, what you did to make that happen and what is the result when you tried those things. I think if you did that here you would understand what is goin wrong.
ahh thank you and ok so let me recal from my momory maybe this will help but the instructions first of all getting the whole bakery senario in head was overwhelming, i think the variable names could use improvement, maybe shorten them up and you know how is their this pannel of code under task saying import lasagna and stuff and yea that was confusing too cuz i kept on trying to look at it but apparently that had nothing to do with what i had to write.
In a whole getting the bakery exercise in my head as begginer was confusing. it wasnt hard but everything was just not straight forward and it took me time to figure things out (which was frustrating). I also struggled with the overwheling information on page 1, i think its too much inforamtion to the point it gets confusing
as a beginner i don’t know what a function is, and if supposei am a beginner and i read the introducting that were given up, thats just so overhwhelming and gets confusing like you hardly understood a thing
i think the exercise and the introductiong should be more beginnner friendly maybe even introducing an exercise before this one with even more basic and simple introdcutiong could be amazing
You’re expected to self-study (read, or google things) to figure out how some of these things work. No exercise is going to be able to “teach” you programming if you have no experience.
Exercism’s leadership team is working on a programming course and language for total beginners that will provide exactly what you’re asking for @Jawad6942 . Shortening variable names or function names isn’t going to make the exercise any easier.
@BethanyG / @IsaacG I do recommend you adopt the comment block approach we took on some other tracks to explain directives at the top of the file, like the import statements.
Hi Bethany,
I’ve been exploring the forum after I wrote this: Educational value of accidental complexity - input validation case. I mentioned there problems with accidental complexity, but perhaps there is also the case for over-the-top complexity in descriptions.
Don’t get me wrong, the Guido’s Lasagna instructions are full of fascinating facts, but they read very much like encyclopaedia entry. I am currently helping somebody brand new to programming start. She is on a course (3 weeks in) learning python and so I suggested Exercism and the python track. The Hello World exercise went great, full self service. Then Guildo’s Lasagna showed up, and I spent close to two hours translating things like dynamic and strongly typed, to do that I started explaining what typing is. Then there were things like object-oriented, Zen of Python and pythonc and many, many more things which somebody just learning the language (and programming) not only doesn’t need to know, but shouldn’t be expected to explore (with kindly provided links) on the second ever programming exercise.
I think what others were saying above, is that the exercise is overwhelming. It is difficult to figure out what needs doing, what information is essential to make it work, what concepts they have to learn to progress to the next exercise, and what is just “FYI”.
Who is exercism form? I think this is an interesting question. And a challenge! If it for somebody who knows many other languages and wants to try a new one, somebody for whom all that information will be meaningful? Or is it for somebody just starting? Or, perhaps, somebody between the two extremes. How does the information provided match with the task and its place in the learning path? If somebody is able to benefit from that detailed description, will they benefit from an exercise that asks them to define a couple of constants? Would it be better to have the detail on a separate page?
I don’t know. I’m not sure I have any answers, but I have been recently struggling myself to learn new programming languages after a few decades of software development, and observing/helping others move on their career path, and I see a gap filled with assumptions that somehow needs bridging. But since you asked
Having specific suggestions or quotes of what is confusing and why, with proposals for how to clarify would be really really helpful.
I would suggest to simplify the description and keep it the basic, and keep the extra information somewhere else behind a link clearly marked with “there be dragons”.
An interesting point @SleeplessByte . I agree that people need to put effort outside of exercises on elixir and I’m really looking forward to what that basic programming course will be like, however I also think that overloading people with up-front information that is not necessary for the exercise is not helpful. That suggests that to learn to make the next step somebody has to study all those links provided, and understand all those fancy terms used. And it is simply not the case.
Please try to refrain from calling things simple, for that would imply, to me, that it is easy to simplify the instructions without removing information that may or may not be vital. (Take this comment at face value, it’s not one that is emotionally charged - it is commonplace on Exercism to not use “just” or “simple” because of the aforementioned hidden complexity of maintaining).
I do not know Python, but I know other programming languages. I have therefore completed the exercise myself, and this is my solution:
EXPECTED_BAKE_TIME = 40
PREPARATION_TIME = 2
def bake_time_remaining(elapsed_bake_time):
"""Calculate the bake time remaining.
:param elapsed_bake_time: int baking time already elapsed.
:return: int remaining bake time derived from 'EXPECTED_BAKE_TIME'.
Function that takes the actual minutes the lasagna has been in the oven as
an argument and returns how many minutes the lasagna still needs to bake
based on the `EXPECTED_BAKE_TIME`.
"""
return EXPECTED_BAKE_TIME - elapsed_bake_time
def preparation_time_in_minutes(layers):
"""
Return preparation time.
This function takes the number of layers and returns how many minutes you would spend
making them.
"""
return layers * PREPARATION_TIME
def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
"""
Return elapsed cooking time.
This function takes two numbers representing the number of layers & the time already spent
baking and calculates the total elapsed minutes spent cooking the lasagna.
"""
return preparation_time_in_minutes(number_of_layers) + elapsed_bake_time
In my understanding, I did a few things:
- declared a constant
- assigned a number to that constant (despite not yet knowing what numbers are)
- added some docstrings to the function bodies
- implemented some basic arithmatic
In order to do this, the absolute minumum I need to know is:
- Numbers are written as literal digets (copyable from the instructions)
- Indentation is important
- Functions exist
- Functions are declared using
def identifier(args...)
- Functions are called using parenthesis and comma separated list of arguments.
- Variables exist
- UPPER_CASE variables (constants) exist
- Assignment of a value can be done using the equals sign (as indicated in the stub)
- There are operators to perform arithmatic using
-
and+
- I do not need to indicate types on function signatures
- I do not need to indicate types on variable declarations
- I do not need to indicate types on operators
- Functions when called can be called using the identifier it was declared with.
Reducing the list above is possible by giving away more information “for free”, but that doesn’t make it easier because it doesn’t mean I understand. This is important. This exercise is very basic because you do not need to write functions wholly yourself, or deal with string manipulation. It only has four concepts:
- basic operators (arithmatic)
- basic numbers
- basic variables / constants
- calling a function
Now regarding the so called information overload:
- If you come from a language that is strongly typed, you will absolutely require the information that this Python is dynamically typed.
- If you come from a language that requires casts, you will absolutely require the information that casting isn’t a thing in this exercise.
- If you come from a language that has insignificant whitespace, or you are complete beginner, you need to know that whitespace is important.
- If you come from a language that has constants but uses a keyword such as
const
, you must understand that python doesn’t have that. - If you are a complete beginner or come from a language without functions, understanding
def
is a keyword that indicates a function is important. - If you come from a language that has header files for signature or that doesn’t use parameter passing using a comma separated list, you’ll need this information too.
- If you come from a language without return values or implicit returns, the
return
keyword becomes important. This is also important for beginners. - If you come from a language that doesn’t call functions using its name (identifier), or if you are a beginner, you need this information.
- The section about default values should be removed
- The section about method names bound to imports should be removed
- The section about comments should be improved by adding a comment to the stub
My three suggestions of simplifying the instructions are bold up here (cc @IsaacG / @BethanyG )
@michalporeba please provide further examples that don’t violate the rules above to simplify these instructions. I don’t think there will be many, but I do think Bethany and Isaac would like your concrete input as well.
FWIW the language being developped/designed is meant to no longer have to explain things like functions or variables at the basics so a lot of the points above will go away. @iHiD can probably tell you more about it, but he is very busy at the moment.
Thanks for sharing your thoughts.
Exercism is aimed at developers not total newbies. So your student is going to find it tough here. Exercises have to be targeted at one or the other. If an experienced developer had to wade through understanding the basics of coding they’d find Exercism incredibly frustrating. But that means that we have to expect a baseline of conceptual programming knowledge.
As well the pure “learn to code” thing we’re building which will be separate to Exercise (which @SleeplessByte mentions above), another in-between idea would be to have pages that define terms like “dynamic” and “strongly typed” which are hyperlinked out to in descriptions.
So I think there’s probably some improvements that can always be made to any exercise (which @SleeplessByte has done his normally wonderful job of dissecting) but there’s also some Exercism principles about our target user, which ties the hands of maintainers so that they can’t do too much.
One final note - the introduction.md
should give the minimum amount of information needed to solve the exercise, and the extra stuff should go into the about.md
file which shows up afterwards. As maintainers will tell you, we do an awful job on communicating that that file even shows, so they understably put a lot of content in that initial file. That’s maybe something that we need to work out how to resolve better during 2023. But ideally we’d not have terms/references that are unnecessary in the introductions. So tangibly maybe OOP or the Zen of Python aren’t entirely necessary in the introduction, but at the same time I know the Python team will have put thought into that and so have opinions about why they should be introduced early too. Maybe, though, as an idea, these things could be put in a “note” block if they’re not already?
Thanks for your thoughts @SleeplessByte, @iHiD. I will first respond to the more generic points by Jeremy, and then (perhaps later or tomorrow) address the very specific and interesting points by @SleeplessByte
I think you will agree that it is a fluid scale, from newbies to seasoned developers. I know you have sometimes make a choice, but I think it would be great to cater for as wide spectrum as possible, when feasible. That student of mine… well, I’ll be helping a little and I’m sure she will get a lot out of exercism as many others do. That’s not the point. I was inspired by the long thread with a number of people complaining about the problems with the exercise so wanted to contribute some ideas.
The point is, that I think that using concepts like content design, information architecture, or perhaps accessibility more could make what is already a great resource into something fantastic! Simple things like order of tests (from my other post), or offloading unnecessary but interesting information somewhere else can broaden the appeal and usability of a track.
I will follow more thoroughly with answers to the specific challenges above, but let’s look at one. “If you come from a language that is strongly typed, you will absolutely require the information that this Python is dynamically typed.”. Fair enough. However there are different ways to convey that knowledge. We can lead the instructions with
Python is a dynamic and strongly typed object-oriented programming language. It employs both duck typing and gradual typing, via type hints.
Or we could start with something else, and then slip something like this in
In Python you don’t have to worry about types (but you can read about types in Python if you would like to know more).
Both of those phrases have enough information for both an expert and a novice with an added benefit that both of them can easily get the gist of what it is.
In fact it might be easier for the experienced person who already read a lot about the language and would just like to practice.
Jeremy, you make a very valid point that perhaps the maintainers considered it and made a decision that it is essential. We don’t know, but wouldn’t it be great, and wouldn’t it help the longer term plan of reducing load of maintainers, if decisions like that were documented and publicly available? And maybe they are, and I don’t know where to look.
Still, I hope you don’t mind me attempting a constructive critique here on the forum. (I’ll keep my uncritically positive thoughts to twitter and such like ;) )
Totally understandable. I’d say the majority of the people who post on the forum struggling with a Lasagna or similar “basics” exercise are relatively new to programming though, so actively not the people the exercise is written for. (Bare in mind thousands of people a day sign up to Exercism and many more use it daily, so the frustration is good to consider in that context also. But equally, I appreciate it takes a brave few to complain and that most will just silently leave!)
It would. But there’s already an overwhelming workload for maintainers trying to just build tracks in their spare time, and them documenting specific decisions adds even more work (and generally even more un-fun work) which burns them out further.
There is lots of documentation on how Concept Exercises should be written etc (e.g. here and here, and where there are org-wide decisions that we can make to make these things clearer for maintainers, that’d be great, but Exercism doesn’t (and can’t tangibly) work on any basis other than these decisions being delegated to maintainers who have to use their own judgement to make them.
I personally really like that initial sentence, as it conveys to me the mindset to approach the language with right away. But also I could entirely see how it could be reworded to be more accessible via the method you suggest. However, I still think that the whole exercise will either be overwhelming or not depending on your experience as a developer. For someone who can code, I don’t think the existing sentence is overly scary. For someone who can’t the whole thing will be scary.
But yes, maybe we can remove anything that’s not needed for this exercise and introduce it further on instead. I wrote the Ruby lasagna introduction, which is a bit more minimal than Python’s - maybe that’s more aligned to your thinking?
Not at all. And I appreciate the tone in which you’re going about it.
All I’d say is that the people building these exercises have spent thousands of hours discussing, debating and considering all these things over the last few years, and are in a constant state of having to compromise for many different perspectives and opinions. My job is to provide the best possible guide-rails for maintainers and then trust them to do the best job they can and help protect them from becoming overwhelmed and exhausted by the vast amount of feedback they receive. The reason we paused community contributions was that these discussions take huge amounts of maintainers time to resolve often only a paragraph here or there, which mean that much more substantial changes to the site (and often the stuff maintainers enjoy working on) don’t get done.
You’d be amazed at how much feedback we get the other way moaning that these documents are way too simply written and should be compressed to be more technical. It’s hard.
I know given the time, the Python maintainers would love to go through and work even more on every exercise, but there’s also a mass of other work that would make a huge difference too. Bethany and others have spent dozens, if not hundreds, of hours working on this exercise alone, and I imagine are sick to the sight of it at this stage And maybe this exercise is special, as it’s the first one and so the one that most people will need a good onramp via, and it’s also the one that gets the most feedback as a result.
The final thing I’d say is that tangible examples help. Suggestions to rewrite X as Y (with the logic provided as you’ve done) are infinitely more useful than just “this could be better” style comments. So I think the more tangible suggestions you can make, the better, as often those are liberating for maintainers who can look at something and be like “YES, that’s better. Thank you!” rather than feeling “Urgh, I know it’s not perfect, but it’s the best I’ve got capacity for” when only provided with general feedback. The tangible suggestions on the other thread about input-testing are a perfect example of this and meant that I immediately responded to that post with a real sense of positivity, rather than frustration. So I just want to reenforce that as a final note.
Everyone: I’m having the weekend off now. Play nice, folks!
Yes please. I rather have ten more of your posts than not. I meant it when I said “take it at face value”, as everything else in my post is without any frustration or emotion towards you.
I wanted to respond to this right now, and I’ll look into a more contentful response later (as I’m doing a “deploy of death” on friday night aaaaah).
Hi community, I am new to Python but I’ve done the same challenge in “Go”.
The first task is to declare a constant and I did it like this:
```EXPECTED_BAKED_TIME = 40````
And I’m getting:
ImportError while importing test module '.mnt.exercism-iteration.lasagna_test.py'.
Hint: make sure your test modules.packages have valid Python names.
Traceback:
.mnt.exercism-iteration.lasagna_test.py:6: in <module>
from lasagna import (EXPECTED_BAKE_TIME,
E ImportError: cannot import name 'EXPECTED_BAKE_TIME' from 'lasagna' (.mnt.exercism-iteration.lasagna.py)
During handling of the above exception, another exception occurred:
.usr.local.lib.python3.10.importlib.__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
.mnt.exercism-iteration.lasagna_test.py:23: in <module>
raise ImportError("In your 'lasagna.py' file, we can not find or import the"
E ImportError: In your 'lasagna.py' file, we can not find or import the function named 'EXPECTED_BAKE_TIME()'. Did you mis-name or forget to define it?
Can you help me understand what am I doing wrong?
You have BAKED
instead of BAKE
Good catch!
But unfortunately, fixing does not solve the problem.
I think the main issue is the:
ImportError: cannot import name 'EXPECTED_BAKE_TIME' from 'lasagna' (.mnt.exercism-iteration.lasagna.py)
Can you share your entire code? Or, better yet, if you use the CLI, you can use the Exercism command to submit your code for mentoring!
Thanks! I did and they help me
That stack trace text (sadly) is a bug.
It’s fixed in this PR (Test Runner #110) and this PR (Content #3339), but they’ve been waiting on review and approval to merge.
What the message is trying to tell you on the last two lines (and it will be clearer after the fix to the error text!) is that the test runner is trying to import both constant names and function names in order to runt the tests on them. You’ve provided the constant name, but you (I am guessing) have not yet filled in the two function names described in tasks 3 and 4.
Once you do that, the ImportError
will go away, and the tests will start passing or failing.
Python stack traces can look really intimidating at first, and can be confusing to read if you are not familiar with them (it doesn’t help here that we’ve screwed up the error message).
The easiest thing is to start at the very bottom, with the last line. Almost always, that’s the error that triggered everything else. From there, you can read “up” the stack to see what other havoc was caused – but the last line of a stack trace is most often the source of the problem.
Let me know if any of that helps, and if you have any additional questions or issues.
Hi @BethanyG!
Thanks for being so clear on this. Once I passed the fear of the first lines, I decided to continue with the code and then when I tested it was (pretty much) working.
I was able to fix it and finish the exercise!
I have approved both, but I think my “approval” powers have diminished in one and I never had that power in the other.