From b81e941ff33289ccb991d7ddfa88a40e2c427442 Mon Sep 17 00:00:00 2001 From: Nenad Date: Tue, 3 Sep 2024 07:01:27 +0200 Subject: [PATCH 1/6] Implement AbsTrait in low-power-embedded-game --- config.json | 11 ++++++----- .../low-power-embedded-game/.meta/exemplar.cairo | 2 ++ .../concept/low-power-embedded-game/src/lib.cairo | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index 66dabfa7..69e22eec 100644 --- a/config.json +++ b/config.json @@ -42,12 +42,13 @@ "name": "Low-power Embedded Game", "uuid": "f3b7ce44-1667-42b4-b792-401d36aee2f1", "concepts": [ - "tuples", - "traits", - "generics" + "traits" ], - "prerequisites": [], - "status": "wip" + "prerequisites": [ + "generics", + "tuples" + ], + "status": "beta" } ], "practice": [ diff --git a/exercises/concept/low-power-embedded-game/.meta/exemplar.cairo b/exercises/concept/low-power-embedded-game/.meta/exemplar.cairo index d817b65a..d51cfd32 100644 --- a/exercises/concept/low-power-embedded-game/.meta/exemplar.cairo +++ b/exercises/concept/low-power-embedded-game/.meta/exemplar.cairo @@ -30,6 +30,8 @@ pub impl PositionImpl of PositionTrait { } } +// The below trait enables calling `abs` on an i16 variable +// to get the absolute value #[generate_trait] impl AbsImpl of AbsTrait { fn abs(self: @i16) -> u16 { diff --git a/exercises/concept/low-power-embedded-game/src/lib.cairo b/exercises/concept/low-power-embedded-game/src/lib.cairo index 736b4582..8a6e1c13 100644 --- a/exercises/concept/low-power-embedded-game/src/lib.cairo +++ b/exercises/concept/low-power-embedded-game/src/lib.cairo @@ -20,3 +20,17 @@ pub impl PositionImpl of PositionTrait { panic!("implement `manhattan`") } } + +// The below trait enables calling `abs` on an i16 variable +// to get the absolute value +#[generate_trait] +impl AbsImpl of AbsTrait { + fn abs(self: @i16) -> u16 { + let val = if *self < 0 { + -*self + } else { + *self + }; + val.try_into().unwrap() + } +} From 6420e28aebb90f71aa3811c6fc6d0fdaa2ac5097 Mon Sep 17 00:00:00 2001 From: Nenad Date: Tue, 3 Sep 2024 07:52:01 +0200 Subject: [PATCH 2/6] Update introduction into low-power-embedded-game --- .../.docs/introduction.md | 49 +------------------ .../low-power-embedded-game/.meta/design.md | 5 +- 2 files changed, 4 insertions(+), 50 deletions(-) diff --git a/exercises/concept/low-power-embedded-game/.docs/introduction.md b/exercises/concept/low-power-embedded-game/.docs/introduction.md index 00c6cf68..6787d570 100644 --- a/exercises/concept/low-power-embedded-game/.docs/introduction.md +++ b/exercises/concept/low-power-embedded-game/.docs/introduction.md @@ -4,9 +4,7 @@ Tuples are a lightweight way to group a fixed set of arbitrary types of data tog a particular name; naming a data structure turns it into a `struct`. A tuple's fields don't have names; they are accessed by means of destructuring or by position. -## Syntax - -### Creation +## Creation Tuples are always created with a tuple expression: @@ -21,7 +19,7 @@ let two_element = (123, "elements can be of differing types"); Tuples can have an arbitrary number of elements. -### Access by destructuring +## Access by destructuring It is possible to access the elements of a tuple by destructuring. This just means assigning variable names to the individual elements of the tuple, consuming it. @@ -30,46 +28,3 @@ names to the individual elements of the tuple, consuming it. let (elem1, _elem2) = two_element; assert_eq!(elem1, 123); ``` - -### Access by position - -It is also possible to access the elements of a tuple by numeric positional index. Indexing, as always, -begins at 0. - -```rust -let notation = single_element.0; -assert_eq!(notation, "note the comma"); -``` - -## Tuple Structs - -You will also be asked to work with tuple structs. Like normal structs, these are named types; unlike -normal structs, they have anonymous fields. Their syntax is very similar to normal tuple syntax. It is -legal to use both destructuring and positional access. - -```rust -struct TupleStruct(u8, i32); -let my_tuple_struct = TupleStruct(123, -321); -let neg = my_tuple_struct.1; -let TupleStruct(byte, _) = my_tuple_struct; -assert_eq!(neg, -321); -assert_eq!(byte, 123); -``` - -### Field Visibility - -All fields of anonymous tuples are always public. However, fields of tuple structs have individual -visibility which defaults to private, just like fields of standard structs. You can make the fields -public with the `pub` modifier, just as in a standard struct. - -```rust -// fails due to private fields -mod tuple { pub struct TupleStruct(u8, i32); } -fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); } -``` - -```rust -// succeeds: fields are public -mod tuple { pub struct TupleStruct(pub u8, pub i32); } -fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); } -``` diff --git a/exercises/concept/low-power-embedded-game/.meta/design.md b/exercises/concept/low-power-embedded-game/.meta/design.md index 8d967ba3..f700d267 100644 --- a/exercises/concept/low-power-embedded-game/.meta/design.md +++ b/exercises/concept/low-power-embedded-game/.meta/design.md @@ -16,13 +16,12 @@ Introduce the student to tuples and how to work with them. Understand that trait ## Concepts -- tuples -- destructuring - traits ## Prerequisites -- traits +- generics +- tuples ## Resources to refer to From 61270796591500a44c63045189f93c59f646621d Mon Sep 17 00:00:00 2001 From: Nenad Date: Wed, 4 Sep 2024 16:31:37 +0200 Subject: [PATCH 3/6] Focus low-power-embedded-game on tuples --- config.json | 5 ++--- .../concept/low-power-embedded-game/.meta/design.md | 13 ++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/config.json b/config.json index 69e22eec..368f333b 100644 --- a/config.json +++ b/config.json @@ -42,11 +42,10 @@ "name": "Low-power Embedded Game", "uuid": "f3b7ce44-1667-42b4-b792-401d36aee2f1", "concepts": [ - "traits" + "tuples" ], "prerequisites": [ - "generics", - "tuples" + "traits" ], "status": "beta" } diff --git a/exercises/concept/low-power-embedded-game/.meta/design.md b/exercises/concept/low-power-embedded-game/.meta/design.md index f700d267..f9a85b5f 100644 --- a/exercises/concept/low-power-embedded-game/.meta/design.md +++ b/exercises/concept/low-power-embedded-game/.meta/design.md @@ -2,30 +2,25 @@ ## Goal -Introduce the student to tuples and how to work with them. Understand that traits can be automatically generated from an implementation. +Introduce the student to tuples and how to work with them. ## Learning objectives -- know how to create tuples and tuple structs +- know how to create tuples - know how to destructure tuples into new variables, e.g. `let (x, y) = a_point;`; -- see that traits can be automatically generated by the compiler if the `impl` is annotated with the `#[generate_trait]` attribute. ## Out of scope -- enum variants with tuple structs - ## Concepts -- traits +- tuples ## Prerequisites -- generics -- tuples +- traits ## Resources to refer to ### Hints - -- From f040fe350355c294465878ec0fe2802f1f0f26b7 Mon Sep 17 00:00:00 2001 From: Nenad Date: Wed, 4 Sep 2024 17:20:19 +0200 Subject: [PATCH 4/6] Turn lucians-luscious-lasagna into concept exercise --- config.json | 20 ++--- .../lucians-luscious-lasagna/.docs/hints.md | 39 +++++++++ .../.docs/instructions.md | 0 .../.docs/introduction.md | 82 +++++++++++++++++++ .../.meta/config.json | 4 +- .../lucians-luscious-lasagna/.meta/design.md | 23 ++++++ .../.meta/exemplar.cairo} | 0 .../lucians-luscious-lasagna/Scarb.toml | 0 .../lucians-luscious-lasagna/src/lib.cairo | 0 .../tests/lucians_luscious_lasagna.cairo | 0 .../lucians-luscious-lasagna/.docs/hints.md | 37 --------- .../lucians-luscious-lasagna/.meta/design.md | 37 --------- 12 files changed, 156 insertions(+), 86 deletions(-) create mode 100644 exercises/concept/lucians-luscious-lasagna/.docs/hints.md rename exercises/{practice => concept}/lucians-luscious-lasagna/.docs/instructions.md (100%) create mode 100644 exercises/concept/lucians-luscious-lasagna/.docs/introduction.md rename exercises/{practice => concept}/lucians-luscious-lasagna/.meta/config.json (87%) create mode 100644 exercises/concept/lucians-luscious-lasagna/.meta/design.md rename exercises/{practice/lucians-luscious-lasagna/.meta/example.cairo => concept/lucians-luscious-lasagna/.meta/exemplar.cairo} (100%) rename exercises/{practice => concept}/lucians-luscious-lasagna/Scarb.toml (100%) rename exercises/{practice => concept}/lucians-luscious-lasagna/src/lib.cairo (100%) rename exercises/{practice => concept}/lucians-luscious-lasagna/tests/lucians_luscious_lasagna.cairo (100%) delete mode 100644 exercises/practice/lucians-luscious-lasagna/.docs/hints.md delete mode 100644 exercises/practice/lucians-luscious-lasagna/.meta/design.md diff --git a/config.json b/config.json index 368f333b..42ccb814 100644 --- a/config.json +++ b/config.json @@ -48,6 +48,16 @@ "traits" ], "status": "beta" + }, + { + + "slug": "lucians-luscious-lasagna", + "name": "Lucian's Luscious Lasagna", + "uuid": "8302f8de-14d7-45dd-9a65-812bc1ed5464", + "concepts": [ + "functions" + ], + "status": "beta" } ], "practice": [ @@ -144,16 +154,6 @@ "prerequisites": [], "difficulty": 2 }, - { - "slug": "lucians-luscious-lasagna", - "name": "Lucian's Luscious Lasagna", - "uuid": "8302f8de-14d7-45dd-9a65-812bc1ed5464", - "practices": [ - "functions" - ], - "prerequisites": [], - "difficulty": 2 - }, { "slug": "pangram", "name": "Pangram", diff --git a/exercises/concept/lucians-luscious-lasagna/.docs/hints.md b/exercises/concept/lucians-luscious-lasagna/.docs/hints.md new file mode 100644 index 00000000..947ff7f9 --- /dev/null +++ b/exercises/concept/lucians-luscious-lasagna/.docs/hints.md @@ -0,0 +1,39 @@ +# Hints + +## General + +- An [integer value][integers] can be defined as one or more consecutive digits. +- If you see a `panic` error when running the tests, this is because you have not implemented one of the functions (it should say which one) or you have left the boilerplate in place. You need to remove the `panic!(...)` line from the supplied code and replace it with a real implementation. + +## 1. Define the expected oven time in minutes + +- You need to define a [function][functions] without any parameters. +- You need to [return][return] the expected oven time in minutes from the function. + +## 2. Calculate the remaining oven time in minutes + +- You need to define a [function][functions] with a single parameter. +- The function's parameter is an [integer][integers]. +- You have to [explicitly return an integer][return] from a function. +- You can [call][functions] one of the other functions you've defined previously. +- You can use the [mathematical operator for subtraction][operators] to subtract values. + +## 3. Calculate the preparation time in minutes + +- You need to define a [function][functions] with a single parameter. +- The function's parameter is an [integer][integers]. +- You have to [explicitly return an integer][return] from a function. +- You can use the [mathematical operator for multiplication][operators] to multiply values. + +## 4. Calculate the elapsed working time in minutes + +- You need to define a [function][functions] with two parameters. +- The function's parameter is an [integer][integers]. +- You have to [explicitly return an integer][return] from a function. +- You can [call][functions] one of the other functions you've defined previously. +- You can use the [mathematical operator for addition][operators] to add values. + +[functions]: https://book.cairo-lang.org/ch02-03-functions.html +[return]: https://book.cairo-lang.org/ch02-03-functions.html#functions-with-return-values +[operators]: https://book.cairo-lang.org/appendix-02-operators-and-symbols.html +[integers]: https://book.cairo-lang.org/ch02-02-data-types.html#integer-types diff --git a/exercises/practice/lucians-luscious-lasagna/.docs/instructions.md b/exercises/concept/lucians-luscious-lasagna/.docs/instructions.md similarity index 100% rename from exercises/practice/lucians-luscious-lasagna/.docs/instructions.md rename to exercises/concept/lucians-luscious-lasagna/.docs/instructions.md diff --git a/exercises/concept/lucians-luscious-lasagna/.docs/introduction.md b/exercises/concept/lucians-luscious-lasagna/.docs/introduction.md new file mode 100644 index 00000000..daccd9a3 --- /dev/null +++ b/exercises/concept/lucians-luscious-lasagna/.docs/introduction.md @@ -0,0 +1,82 @@ +# Introduction + +A function in Cairo allows you to group code into a reusable unit, making your programs more modular and easier to understand. Functions in Cairo consist of the `fn` keyword, followed by the function name, a list of parameters in parentheses, and a code block that defines what the function does. + +## Function Parameters + +In Cairo, all function parameters must be explicitly typed. Unlike some languages, Cairo does not infer types, and there are no default parameter values, so all parameters are required. + +```rust +// Function with no parameters +fn print_hello() { + // Function body +} + +// Function with two parameters +fn print_greeting_name(greeting: ByteArray, name: ByteArray) { + // Function body +} +``` + +## Parameters vs. Arguments + +It's important to distinguish between `parameters` and `arguments`: + +- **Parameters** are the variable names used in the function definition, such as `greeting` and `name` in the function `print_greeting_name`. +- **Arguments** are the actual values passed to the function when it is called. + +```rust +// Calling the function with arguments +print_greeting_name(123, 456) +``` + +## Statements and Expressions + +Function bodies are made up of a series of statements optionally ending in an expression. + +- Statements are instructions that perform some action and do not return a value. +- Expressions evaluate to a resultant value. + +Creating a variable and assigning a value to it with the `let` keyword is a statement. + +```rust +let y = 6; +``` + +But the `6` in the above statement is an expression that evaluates to the value `6`. + +Calling a function is an expression since it always evaluates to a value: the function's explicit return value, if specified, or the 'unit' type `()` otherwise. + +## Return Values + +Cairo functions can return values to the code that calls them. Return values are listed after the parameters, separated by an arrow `->`. In Cairo, the return value of the function is synonymous with the value of the final expression in the block of the body of a function. You can return early from a function by using the `return` keyword and specifying a value. + +```rust +// Function returning the last (and only) expression +fn hello(name: ByteArray) -> ByteArray { + "Hello " + name +} + +// Function returning using the `return` keyword +fn double_if_even(value: u32) -> u32 { + if value % 2 == 0 { + return value * 2; + } + return value; +} +``` + +## Invoking Functions + +To call a function in Cairo, you simply use the function name followed by arguments in parentheses. + +```rust +// Calling a function with no parameters +print_hello() + +// Calling a function with one parameter +let greeting = hello("John") + +// Calling a function with multiple parameters +print_greeting_name("Howdy", "Joel") +``` diff --git a/exercises/practice/lucians-luscious-lasagna/.meta/config.json b/exercises/concept/lucians-luscious-lasagna/.meta/config.json similarity index 87% rename from exercises/practice/lucians-luscious-lasagna/.meta/config.json rename to exercises/concept/lucians-luscious-lasagna/.meta/config.json index 77f1e065..c5fccb21 100644 --- a/exercises/practice/lucians-luscious-lasagna/.meta/config.json +++ b/exercises/concept/lucians-luscious-lasagna/.meta/config.json @@ -9,8 +9,8 @@ "test": [ "tests/lucians_luscious_lasagna.cairo" ], - "example": [ - ".meta/example.cairo" + "exemplar": [ + ".meta/exemplar.cairo" ], "invalidator": [ "Scarb.toml" diff --git a/exercises/concept/lucians-luscious-lasagna/.meta/design.md b/exercises/concept/lucians-luscious-lasagna/.meta/design.md new file mode 100644 index 00000000..47b63282 --- /dev/null +++ b/exercises/concept/lucians-luscious-lasagna/.meta/design.md @@ -0,0 +1,23 @@ +# Design + +## Learning objectives + +- How to define a function +- How to invoke a function +- How to pass parameters to a function +- How to return a value from a function +- How to receive returned values from a function + +## Out of scope + +- Data types + +## Concepts + +The Concepts this exercise unlocks are: + +- `functions` + +## Prerequisites + +There are no prerequisites. diff --git a/exercises/practice/lucians-luscious-lasagna/.meta/example.cairo b/exercises/concept/lucians-luscious-lasagna/.meta/exemplar.cairo similarity index 100% rename from exercises/practice/lucians-luscious-lasagna/.meta/example.cairo rename to exercises/concept/lucians-luscious-lasagna/.meta/exemplar.cairo diff --git a/exercises/practice/lucians-luscious-lasagna/Scarb.toml b/exercises/concept/lucians-luscious-lasagna/Scarb.toml similarity index 100% rename from exercises/practice/lucians-luscious-lasagna/Scarb.toml rename to exercises/concept/lucians-luscious-lasagna/Scarb.toml diff --git a/exercises/practice/lucians-luscious-lasagna/src/lib.cairo b/exercises/concept/lucians-luscious-lasagna/src/lib.cairo similarity index 100% rename from exercises/practice/lucians-luscious-lasagna/src/lib.cairo rename to exercises/concept/lucians-luscious-lasagna/src/lib.cairo diff --git a/exercises/practice/lucians-luscious-lasagna/tests/lucians_luscious_lasagna.cairo b/exercises/concept/lucians-luscious-lasagna/tests/lucians_luscious_lasagna.cairo similarity index 100% rename from exercises/practice/lucians-luscious-lasagna/tests/lucians_luscious_lasagna.cairo rename to exercises/concept/lucians-luscious-lasagna/tests/lucians_luscious_lasagna.cairo diff --git a/exercises/practice/lucians-luscious-lasagna/.docs/hints.md b/exercises/practice/lucians-luscious-lasagna/.docs/hints.md deleted file mode 100644 index c660140b..00000000 --- a/exercises/practice/lucians-luscious-lasagna/.docs/hints.md +++ /dev/null @@ -1,37 +0,0 @@ -# Hints - -## General - -- An integer literal can be defined as one or more consecutive digits. - -## 1. Define the expected oven time in minutes - -- You need to define a [function][functions] without any parameters. - -## 2. Calculate the remaining oven time in minutes - -- You need to define a [function][functions] with a single parameter. -- You can use and refer to the previously defined item by its name. -- The last expression in a function is [automatically returned][return-values] - from the function; you don't have to explicitly indicate which value to - return. -- You can use the [mathematical operator for subtraction][operators] to - subtract values. - -## 3. Calculate the preparation time in minutes - -- You need to define a [function][functions] with a single parameter. -- You can use the [mathematical operator for multiplication][operators] to - multiply values. - -## 4. Calculate the elapsed time in minutes - -- You need to define a [function][functions] with two parameters. -- You can [call][functions] one of the other functions you've defined - previously. -- You can use the [mathematical operator for addition][operators] to add - values. - -[functions]: https://book.cairo-lang.org/ch02-03-functions.html -[return-values]: https://book.cairo-lang.org/ch02-03-functions.html#functions-with-return-values -[operators]: https://book.cairo-lang.org/appendix-02-operators-and-symbols.html diff --git a/exercises/practice/lucians-luscious-lasagna/.meta/design.md b/exercises/practice/lucians-luscious-lasagna/.meta/design.md deleted file mode 100644 index 5edb8a76..00000000 --- a/exercises/practice/lucians-luscious-lasagna/.meta/design.md +++ /dev/null @@ -1,37 +0,0 @@ -# Design - -## Learning objectives - -- Know how to define a function -- Know how to return a value from a function - -## Out of scope - -- Know how to work with `const` values - -## Concepts - -- Functions - -## Prerequisites - -None - -## Resources to refer to - -### Hints - -- [Functions](https://book.cairo-lang.org/ch02-03-functions.html) -- [Return values](https://book.cairo-lang.org/ch02-03-functions.html#functions-with-return-values) -- [Operators](https://book.cairo-lang.org/appendix-02-operators-and-symbols.html) - -### After - -## Representer - -This exercise does not require any specific representation logic to be added to -the representer. - -## Analyzer - -This exercise does not require any specific logic to be added to the analyzer. From 7c71fa5cfd6d2d971323189aa530242c61e2d905 Mon Sep 17 00:00:00 2001 From: Nenad Date: Wed, 4 Sep 2024 17:24:30 +0200 Subject: [PATCH 5/6] Add forked_from for lll --- exercises/concept/lucians-luscious-lasagna/.meta/config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exercises/concept/lucians-luscious-lasagna/.meta/config.json b/exercises/concept/lucians-luscious-lasagna/.meta/config.json index c5fccb21..22103571 100644 --- a/exercises/concept/lucians-luscious-lasagna/.meta/config.json +++ b/exercises/concept/lucians-luscious-lasagna/.meta/config.json @@ -16,6 +16,9 @@ "Scarb.toml" ] }, + "forked_from": [ + "rust/lucians-luscious-lasagna" + ], "icon": "lasagna", "blurb": "Learn about the basics of Cairo by following a lasagna recipe." } From b5065ca394397111f8ddccb911452ef9d01cb412 Mon Sep 17 00:00:00 2001 From: Nenad Date: Wed, 4 Sep 2024 17:26:40 +0200 Subject: [PATCH 6/6] Add missing prerequisites key to lll + turn status to wip for lpeg --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 42ccb814..b05918ca 100644 --- a/config.json +++ b/config.json @@ -47,16 +47,16 @@ "prerequisites": [ "traits" ], - "status": "beta" + "status": "wip" }, { - "slug": "lucians-luscious-lasagna", "name": "Lucian's Luscious Lasagna", "uuid": "8302f8de-14d7-45dd-9a65-812bc1ed5464", "concepts": [ "functions" ], + "prerequisites": [], "status": "beta" } ],