-
-
Notifications
You must be signed in to change notification settings - Fork 207
Revised Lasagna concept exercise #1079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
colinleach
wants to merge
8
commits into
exercism:main
Choose a base branch
from
colinleach:lasagna
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
67e5270
Revised Lasagna concept exercise
009536c
fix test file
6d7f209
update `UNITY_BEGIN()` line
1e06d1d
Update lasagna.h
colinleach 6d32bd4
Update lasagna.c
colinleach 96a8eff
Update test_lasagna.c
colinleach 8988eb6
Update test_lasagna.c
colinleach ffcbbb8
Update makefile
colinleach File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Hints | ||
|
|
||
| To repeat: please do not alter the `lasagna.h` file or the `#include` line. | ||
|
|
||
| These are designed to make this introductory exercise simpler for students. | ||
|
|
||
| ## 1. Define the expected oven time in minutes | ||
|
|
||
| - This is an assignment outside of any function. | ||
| - The type is `int`. | ||
| - The value should not change, so mark it as `const`. | ||
|
|
||
| ## 2. Calculate the remaining oven time in minutes | ||
|
|
||
| - C understands common arithmetic operators: `+`, `-`, `*`, `/`. | ||
| - The argument passed to the function can be accessed by name, in this case giving the elapsed time. | ||
| - Remember that C functions generally need a `return` keyword (_though `void` functions will be an exception, in later concepts_). | ||
|
|
||
| ## 3. Calculate the preparation time in minutes | ||
|
|
||
| - You can call other functions and use the returned value like variables: `return 22 * myOtherCalculation();` | ||
|
|
||
| ## 4. Calculate the elapsed time in minutes | ||
|
|
||
| - The output should combine the time for the preparation and the time the lasagna has already been in the oven. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # Instructions | ||
|
|
||
| Lucian's girlfriend is on her way home and he hasn't cooked their anniversary dinner! | ||
|
|
||
| In this exercise, you're going to write some code to help Lucian cook an exquisite lasagna from his favorite cookbook. | ||
|
|
||
| ~~~~exercism/note | ||
| The `lasagna.h` file, and the `#import` at the top of `lasagna.c` will be explained in later Concepts. | ||
|
|
||
| For now, please just leave these parts unchanged. | ||
| ~~~~ | ||
|
|
||
| You have four tasks, all related to the time spent cooking the lasagna. | ||
|
|
||
| All numerical values are of type `int`. | ||
|
|
||
| ## 1. Define the expected oven time in minutes | ||
|
|
||
| Define `expected_minutes_in_oven` as a `const int`, representing how many minutes the lasagna should be in the oven. | ||
| According to the cookbook, the expected oven time is 40 minutes: | ||
|
|
||
| ```c | ||
| expected_minutes_in_oven; | ||
| // => 40 | ||
| ``` | ||
|
|
||
| ## 2. Calculate the remaining oven time in minutes | ||
|
|
||
| Define the `remaining_minutes_in_oven(int actual_minutes_in_oven)` function that takes the actual minutes the lasagna has been in the oven as an argument and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task. | ||
|
|
||
| ```c | ||
| remaining_minutes_in_oven(30); | ||
| // => 10 | ||
| ``` | ||
|
|
||
| ## 3. Calculate the preparation time in minutes | ||
|
|
||
| Define the `preparation_time_in_minutes(int number_of_layers)` function that takes the number of layers you added to the lasagna as an argument and returns how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare. | ||
|
|
||
| ```c | ||
| preparation_time_in_minutes(2); | ||
| // => 4 | ||
| ``` | ||
|
|
||
| ## 4. Calculate the elapsed time in minutes | ||
|
|
||
| Define the `elapsed_time_in_minutes(int number_of_layers, int actual_minutes_in_oven)` function that takes two arguments: the first argument is the number of layers you added to the lasagna, and the second argument is the number of minutes the lasagna has been in the oven. | ||
| The function should return how many minutes you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment. | ||
|
|
||
| ```c | ||
| elapsed_time_in_minutes(3, 20); | ||
| // => 26 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Introduction | ||
|
|
||
| C is a statically typed language, which means that everything has a type at compile-time. | ||
| Choosing a name for a variable and setting its type is referred to as declaring a variable. | ||
|
|
||
| A variable is declared by explicitly specifying its type. | ||
| A variable name can start with either a letter or an underscore. | ||
|
|
||
| Some names cannot be used as they are reserved [for keywords][reserved-keywords] or [other identifiers][reserved-identifiers]. | ||
|
|
||
| Setting or updating the variable is done by variable assignment. | ||
| Setting the value defines that variable. | ||
| Defining the variable is also known as initialization. | ||
|
|
||
| ```c | ||
| int foo; // Declare an integer named var | ||
| foo = 10; // Define the variable | ||
|
|
||
| int bar = 15; // Both can also be done in a single statement | ||
| ``` | ||
|
|
||
| The value of a variable can be assigned and updated using the `=` simple assignment operator. | ||
| Once defined, a variable's type can never change. | ||
|
|
||
| ```c | ||
| int foo = 10; // Assign initial value | ||
| foo = 25; // Update to new value | ||
|
|
||
| foo = false; // Compiler error when assigning value of a different type | ||
| ``` | ||
|
|
||
| If a value should not be changed after initialization, it can be declared as `const`. | ||
| Attempted reassignment will then be flagged as an error. | ||
|
|
||
| ```c | ||
| const int baz = 42; | ||
|
|
||
| // changes not allowed! | ||
| baz = 43 | ||
| // => Error | ||
| ``` | ||
|
|
||
| C is an imperative procedural language. | ||
| All computation is carried out as part a series of statements that are part of a function or multiple functions. | ||
|
|
||
| Each function can have zero or more parameters. | ||
| When defining a function all parameters, and the return value must be explicitly typed. | ||
|
|
||
| Values are returned from functions using the `return` keyword. | ||
|
|
||
| Functions have `external storage class` by default, meaning that it exists for the lifetime of the program and can be visible externally to the file. | ||
|
|
||
| To prevent this, the `static` keyword can be added to specify visibility only within the current file. | ||
|
|
||
| ```c | ||
| static int add(int x, int y) { | ||
| return x + y; | ||
| } | ||
| ``` | ||
|
|
||
| In the above example, the variables `x` and `y` can only be used within the function that is, they have function scope. | ||
|
|
||
| Scope is the idea that the value associated with a name (of a program element) is only accessible within the code "area" where it is defined. | ||
|
|
||
| The principal code areas in C are: | ||
|
|
||
| - file | ||
| - function | ||
| - block (such as within loops and other constructs) | ||
|
|
||
| Functions are invoked by specifying the function name and passing arguments for each of the function parameters. | ||
|
|
||
| ```c | ||
| int sum = add(1, 2); | ||
| ``` | ||
|
|
||
| C supports two types of comments. | ||
| Single line comments are preceded by `//` (since C99) and multi-line comments are inserted between `/*` and `*/`. | ||
|
|
||
| [reserved-keywords]: https://en.cppreference.com/w/c/keyword | ||
| [reserved-identifiers]: https://en.cppreference.com/w/c/language/identifier |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "authors": [ | ||
| "wolf99" | ||
| ], | ||
| "contributors": [ | ||
| "colinleach" | ||
| ], | ||
| "files": { | ||
| "solution": [ | ||
| "lasagna.h", | ||
| "lasagna.c" | ||
| ], | ||
| "test": [ | ||
| "test_lasagna.c" | ||
| ], | ||
| "exemplar": [ | ||
| ".meta/exemplar.c" | ||
| ] | ||
| }, | ||
| "language_versions": "c99", | ||
| "forked_from": [ | ||
| "csharp/lucians-luscious-lasagna" | ||
| ], | ||
| "blurb": "Learn about the basics of C by following a lasagna recipe." | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Design | ||
|
|
||
| ## Learning objectives | ||
|
|
||
| - Know what a variable is | ||
| - Know how to declare and initialize a variable | ||
| - Know how to update a variable | ||
| - Know how to declare a constant | ||
| - Know how to define a function | ||
| - Know how to call a function | ||
| - Know how to return a value from a function | ||
| - Know how to use mathematical operators on integers | ||
| - Know how to define single- and multiline comments | ||
|
|
||
| ## Out of scope | ||
|
|
||
| - Memory and performance characteristics | ||
| - Optional parameters | ||
| - Organizing code in different files | ||
| - Organizing code with header files | ||
|
|
||
| ## Concepts | ||
|
|
||
| - `basics` | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| There are no prerequisites. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Please do not alter the include line below | ||
| #include "lasagna.h" | ||
|
|
||
| const int expected_minutes_in_oven = 40; | ||
|
|
||
| int remaining_minutes_in_oven(int actual_minutes_in_oven) | ||
| { | ||
| return expected_minutes_in_oven - actual_minutes_in_oven; | ||
| } | ||
|
|
||
| int preparation_time_in_minutes(int number_of_layers) | ||
| { | ||
| return number_of_layers * 2; | ||
| } | ||
|
|
||
| int elapsed_time_in_minutes(int number_of_layers, int actual_minutes_in_oven) | ||
| { | ||
| return preparation_time_in_minutes(number_of_layers) + | ||
| actual_minutes_in_oven; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // Please do not alter the include line below | ||
| #include "lasagna.h" | ||
|
|
||
| // TODO: define the expected_minutes_in_oven variable | ||
|
|
||
| // TODO: define the remaining_minutes_in_oven() function | ||
|
|
||
| // TODO: define the preparation_time_in_minutes() function | ||
|
|
||
| // TODO: define the elapsed_time_in_minutes() function |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // Please do not edit this file. It will be explained in a later Concept. | ||
|
|
||
| #ifndef LASAGNA_H | ||
| #define LASAGNA_H | ||
|
|
||
| extern const int expected_minutes_in_oven; | ||
|
|
||
| int remaining_minutes_in_oven(int actual_minutes_in_oven); | ||
|
|
||
| int preparation_time_in_minutes(int number_of_layers); | ||
|
|
||
| int elapsed_time_in_minutes(int number_of_layers, int actual_minutes_in_oven); | ||
|
|
||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| ### If you wish to use extra libraries (math.h for instance), | ||
| ### add their flags here (-lm in our case) in the "LIBS" variable. | ||
|
|
||
| LIBS = -lm | ||
|
|
||
| ### | ||
| CFLAGS = -std=c99 | ||
| CFLAGS += -g | ||
| CFLAGS += -Wall | ||
| CFLAGS += -Wextra | ||
| CFLAGS += -pedantic | ||
| CFLAGS += -Werror | ||
| CFLAGS += -Wmissing-declarations | ||
| CFLAGS += -DUNITY_SUPPORT_64 -DUNITY_OUTPUT_COLOR | ||
|
|
||
| ASANFLAGS = -fsanitize=address | ||
| ASANFLAGS += -fno-common | ||
| ASANFLAGS += -fno-omit-frame-pointer | ||
|
|
||
| .PHONY: test | ||
| test: tests.out | ||
| @./tests.out | ||
|
|
||
| .PHONY: memcheck | ||
| memcheck: ./*.c ./*.h | ||
| @echo Compiling $@ | ||
| @$(CC) $(ASANFLAGS) $(CFLAGS) test-framework/unity.c ./*.c -o memcheck.out $(LIBS) | ||
| @./memcheck.out | ||
| @echo "Memory check passed" | ||
|
|
||
| .PHONY: clean | ||
| clean: | ||
| rm -rf *.o *.out *.out.dSYM | ||
|
|
||
| tests.out: ./*.c ./*.h | ||
| @echo Compiling $@ | ||
| @$(CC) $(CFLAGS) test-framework/unity.c ./*.c -o tests.out $(LIBS) | ||
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about not providing this file at all and instead putting the declarations into
test_lasagna.c? Alternatively, we could just#include "lasagna.c"fromtest_lasagna.c(that's what the C++ version does). Students would see only thelasagna.ctemplate, so it doesn't matter which approach we use. But not having a header file would lower the chance for confusion.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wolf99 @ryanplusplus What do you think?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahans I haven't read through all the comments yet... is the intent to avoid introducing headers at this point? If so, I think this makes sense. It's weird to do either of these workarounds, but only to someone who is already familiar enough with C to be able to reason through the weirdness. I expect anyone who's just learning C to not even notice because they're focused on the basics.
I'd prefer including
lasagna.cin the test file if we have to pick a path.