From b6e8ae5c706c60fe4ed8e5e02b6c14373ff1b4ea Mon Sep 17 00:00:00 2001 From: Nenad Date: Tue, 5 Aug 2025 19:00:13 +0200 Subject: [PATCH 01/15] implement tests and stub --- .../concept/rpn-calculator/.meta/config.json | 4 +- exercises/concept/rpn-calculator/Scarb.toml | 7 + .../concept/rpn-calculator/src/lib.cairo | 14 ++ .../rpn-calculator/tests/rpn_calculator.cairo | 171 ++++++++++++++++++ 4 files changed, 194 insertions(+), 2 deletions(-) diff --git a/exercises/concept/rpn-calculator/.meta/config.json b/exercises/concept/rpn-calculator/.meta/config.json index b8399302..b26a480c 100644 --- a/exercises/concept/rpn-calculator/.meta/config.json +++ b/exercises/concept/rpn-calculator/.meta/config.json @@ -1,6 +1,6 @@ { "authors": [ - "" + "0xNeshi" ], "files": { "solution": [ @@ -19,5 +19,5 @@ "forked_from": [ "rust/rpn-calculator" ], - "blurb": "Use some of `Array`'s methods to evaluate Reverse Polish notation" + "blurb": "Use some of `Span`'s methods to evaluate Reverse Polish notation" } diff --git a/exercises/concept/rpn-calculator/Scarb.toml b/exercises/concept/rpn-calculator/Scarb.toml index e69de29b..08bc8d35 100644 --- a/exercises/concept/rpn-calculator/Scarb.toml +++ b/exercises/concept/rpn-calculator/Scarb.toml @@ -0,0 +1,7 @@ +[package] +name = "rpn_calculator" +version = "0.1.0" +edition = "2024_07" + +[dev-dependencies] +cairo_test = "2.9.2" diff --git a/exercises/concept/rpn-calculator/src/lib.cairo b/exercises/concept/rpn-calculator/src/lib.cairo index e69de29b..6fef9108 100644 --- a/exercises/concept/rpn-calculator/src/lib.cairo +++ b/exercises/concept/rpn-calculator/src/lib.cairo @@ -0,0 +1,14 @@ +#[derive(Debug, Drop)] +pub enum CalculatorInput { + Add, + Subtract, + Multiply, + Divide, + Value: i32, +} + +pub fn evaluate(inputs: Span) -> Option { + panic!( + "Given the inputs: {inputs:?}, evaluate them as though they were a Reverse Polish notation expression", + ) +} diff --git a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo index e69de29b..6cfda6ec 100644 --- a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo +++ b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo @@ -0,0 +1,171 @@ +use rpn_calculator::*; + +fn calculator_input(s: ByteArray) -> Span { + let mut calc_input = ArrayTrait::new(); + + let components = split_input_into_components(s); + for c in components { + let ci = if c == @"+" { + CalculatorInput::Add + } else if c == @"-" { + CalculatorInput::Subtract + } else if c == @"*" { + CalculatorInput::Multiply + } else if c == @"/" { + CalculatorInput::Divide + } else { + CalculatorInput::Value(parse_int(c).unwrap()) + }; + calc_input.append(ci) + }; + + calc_input.span() +} + + +fn parse_int(num: @ByteArray) -> Option { + let mut result: Option = Option::Some(0); + let mut size = num.len(); + let mut i = 0; + + let mut is_signed = false; + if num.at(i).unwrap() == '-' { + is_signed = true; + i += 1; + } + + for i in i..size { + match char_to_digit(num[i]) { + Option::Some(v) => { + if let Option::Some(num) = result { + result = Option::Some(num * 10 + v.into()); + } + }, + Option::None => { + result = Option::None; + break; + }, + } + }; + + if let Option::Some(val) = result { + if (is_signed) { + result = Option::Some(val * -1) + } + } + result +} + + +// Utility function to convert a char representing a digit into its numerical value (u32 equivalent) +fn char_to_digit(c: u8) -> Option { + let zero_ascii = '0'; + let nine_ascii = '9'; + + if c >= zero_ascii && c <= nine_ascii { + Option::Some(c - zero_ascii) + } else { + Option::None // Return None for invalid characters + } +} + +fn split_input_into_components(input: ByteArray) -> Span { + let mut components: Array = ArrayTrait::new(); + let mut current_component = ""; + + let mut i = 0; + while i < input.len() { + let char = input[i]; + + if char == ' ' { + components.append(current_component.clone()); + current_component = ""; + } else { + current_component.append_byte(char); + } + + i += 1; + }; + + if current_component.len() > 0 { + components.append(current_component); + } + + components.span() +} + +#[test] +fn empty_input_returns_none() { + let input = calculator_input(""); + assert_eq!(evaluate(input), Option::None); +} + +#[test] +#[ignore] +fn simple_value() { + let input = calculator_input("10"); + assert_eq!(evaluate(input), Option::Some(10)); +} + +#[test] +#[ignore] +fn simple_addition() { + let input = calculator_input("2 2 +"); + assert_eq!(evaluate(input), Option::Some(4)); +} + +#[test] +#[ignore] +fn simple_subtraction() { + let input = calculator_input("7 11 -"); + assert_eq!(evaluate(input), Option::Some(-4)); +} + +#[test] +#[ignore] +fn simple_multiplication() { + let input = calculator_input("6 9 *"); + assert_eq!(evaluate(input), Option::Some(54)); +} + +#[test] +#[ignore] +fn simple_division() { + let input = calculator_input("57 19 /"); + assert_eq!(evaluate(input), Option::Some(3)); +} + +#[test] +#[ignore] +fn complex_operation() { + let input = calculator_input("4 8 + 7 5 - /"); + assert_eq!(evaluate(input), Option::Some(6)); +} + +#[test] +#[ignore] +fn too_few_operands_returns_none() { + let input = calculator_input("2 +"); + assert_eq!(evaluate(input), Option::None); +} + +#[test] +#[ignore] +fn too_many_operands_returns_none() { + let input = calculator_input("2 2"); + assert_eq!(evaluate(input), Option::None); +} + +#[test] +#[ignore] +fn zero_operands_returns_none() { + let input = calculator_input("+"); + assert_eq!(evaluate(input), Option::None); +} + +#[test] +#[ignore] +fn intermediate_error_returns_none() { + let input = calculator_input("+ 2 2 *"); + assert_eq!(evaluate(input), Option::None); +} From 564c2fa5ea1f5b2b2951f23e64e3a271860d2a4d Mon Sep 17 00:00:00 2001 From: Nenad Date: Tue, 5 Aug 2025 21:45:26 +0200 Subject: [PATCH 02/15] impl exemplar --- .../rpn-calculator/.meta/exemplar.cairo | 113 ++++++++++++++++++ .../concept/rpn-calculator/src/lib.cairo | 2 +- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/exercises/concept/rpn-calculator/.meta/exemplar.cairo b/exercises/concept/rpn-calculator/.meta/exemplar.cairo index e69de29b..e3329a96 100644 --- a/exercises/concept/rpn-calculator/.meta/exemplar.cairo +++ b/exercises/concept/rpn-calculator/.meta/exemplar.cairo @@ -0,0 +1,113 @@ +#[derive(Drop, Debug)] +pub enum CalculatorInput { + Add, + Subtract, + Multiply, + Divide, + Value: i32, +} + +pub fn evaluate(inputs: Span) -> Option { + let mut stack: Array = ArrayTrait::new(); + + let mut cancelled = false; + + for input in inputs { + match input { + CalculatorInput::Add => { + let mut stack_span = stack.span(); + let rhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + let lhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + stack = array![]; + stack.append_span(stack_span); + stack.append(lhs + rhs); + }, + CalculatorInput::Subtract => { + let mut stack_span = stack.span(); + let rhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + let lhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + + stack = array![]; + stack.append_span(stack_span); + stack.append(lhs - rhs); + }, + CalculatorInput::Multiply => { + let mut stack_span = stack.span(); + let rhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + let lhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + + stack = array![]; + stack.append_span(stack_span); + stack.append(lhs * rhs); + }, + CalculatorInput::Divide => { + let mut stack_span = stack.span(); + let rhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + let lhs = match stack_span.pop_back() { + Option::Some(value) => *value, + Option::None => { + cancelled = true; + break; + }, + }; + stack = array![]; + stack.append_span(stack_span); + stack.append(lhs / rhs); + }, + CalculatorInput::Value(value) => stack.append(*value), + } + }; + + if cancelled { + return Option::None; + } + + let output = stack.pop_front(); + if stack.is_empty() { + output + } else { + Option::None + } +} diff --git a/exercises/concept/rpn-calculator/src/lib.cairo b/exercises/concept/rpn-calculator/src/lib.cairo index 6fef9108..291502f4 100644 --- a/exercises/concept/rpn-calculator/src/lib.cairo +++ b/exercises/concept/rpn-calculator/src/lib.cairo @@ -1,4 +1,4 @@ -#[derive(Debug, Drop)] +#[derive(Drop, Debug)] pub enum CalculatorInput { Add, Subtract, From ef05a51fa0e8ecaff82817fa0127dda8b15ce3d5 Mon Sep 17 00:00:00 2001 From: Nenad Date: Tue, 5 Aug 2025 22:52:19 +0200 Subject: [PATCH 03/15] ref to use panics (broken) --- .../concept/rpn-calculator/.meta/design.md | 22 +++++++++++++++++++ .../concept/rpn-calculator/src/lib.cairo | 6 ++--- .../rpn-calculator/tests/rpn_calculator.cairo | 12 +++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/exercises/concept/rpn-calculator/.meta/design.md b/exercises/concept/rpn-calculator/.meta/design.md index e69de29b..290fb652 100644 --- a/exercises/concept/rpn-calculator/.meta/design.md +++ b/exercises/concept/rpn-calculator/.meta/design.md @@ -0,0 +1,22 @@ +# Design + +## Learning objectives + +- Know how to use control flow constructs. +- Know how to use enums. +- Know how to use pattern matching. + +## Out of scope + +- Generic enums. +- `if let` and `while let` statements. +- The `Option` and `Result` enums. + +## Concepts + +- Control flow +- Enums + +## Prerequisites + +- Arrays diff --git a/exercises/concept/rpn-calculator/src/lib.cairo b/exercises/concept/rpn-calculator/src/lib.cairo index 291502f4..627c265d 100644 --- a/exercises/concept/rpn-calculator/src/lib.cairo +++ b/exercises/concept/rpn-calculator/src/lib.cairo @@ -7,8 +7,6 @@ pub enum CalculatorInput { Value: i32, } -pub fn evaluate(inputs: Span) -> Option { - panic!( - "Given the inputs: {inputs:?}, evaluate them as though they were a Reverse Polish notation expression", - ) +pub fn evaluate(inputs: Span) -> i32 { + panic!("implement `evaluate`") } diff --git a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo index 6cfda6ec..66fca248 100644 --- a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo +++ b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo @@ -104,42 +104,42 @@ fn empty_input_returns_none() { #[ignore] fn simple_value() { let input = calculator_input("10"); - assert_eq!(evaluate(input), Option::Some(10)); + assert_eq!(evaluate(input), 10); } #[test] #[ignore] fn simple_addition() { let input = calculator_input("2 2 +"); - assert_eq!(evaluate(input), Option::Some(4)); + assert_eq!(evaluate(input), 4); } #[test] #[ignore] fn simple_subtraction() { let input = calculator_input("7 11 -"); - assert_eq!(evaluate(input), Option::Some(-4)); + assert_eq!(evaluate(input), -4); } #[test] #[ignore] fn simple_multiplication() { let input = calculator_input("6 9 *"); - assert_eq!(evaluate(input), Option::Some(54)); + assert_eq!(evaluate(input), 54); } #[test] #[ignore] fn simple_division() { let input = calculator_input("57 19 /"); - assert_eq!(evaluate(input), Option::Some(3)); + assert_eq!(evaluate(input), 3); } #[test] #[ignore] fn complex_operation() { let input = calculator_input("4 8 + 7 5 - /"); - assert_eq!(evaluate(input), Option::Some(6)); + assert_eq!(evaluate(input), 6); } #[test] From cc151073074fe490aba184ad2eed110c0ad4da3b Mon Sep 17 00:00:00 2001 From: Nenad Date: Sat, 9 Aug 2025 14:33:10 +0200 Subject: [PATCH 04/15] implement a new exercise weather-report --- config.json | 10 +- .../concept/rpn-calculator/.docs/hints.md | 0 .../rpn-calculator/.docs/instructions.md | 0 .../rpn-calculator/.docs/introduction.md | 0 .../rpn-calculator/.meta/exemplar.cairo | 113 ------------ .../concept/rpn-calculator/src/lib.cairo | 12 -- .../rpn-calculator/tests/rpn_calculator.cairo | 171 ------------------ .../concept/weather-report/.docs/hints.md | 15 ++ .../weather-report/.docs/instructions.md | 34 ++++ .../weather-report/.docs/introduction.md | 66 +++++++ .../.meta/config.json | 5 +- .../.meta/design.md | 5 +- .../weather-report/.meta/exemplar.cairo | 25 +++ .../Scarb.toml | 2 +- .../concept/weather-report/src/lib.cairo | 15 ++ .../weather-report/tests/weather_report.cairo | 63 +++++++ 16 files changed, 227 insertions(+), 309 deletions(-) delete mode 100644 exercises/concept/rpn-calculator/.docs/hints.md delete mode 100644 exercises/concept/rpn-calculator/.docs/instructions.md delete mode 100644 exercises/concept/rpn-calculator/.docs/introduction.md delete mode 100644 exercises/concept/rpn-calculator/.meta/exemplar.cairo delete mode 100644 exercises/concept/rpn-calculator/src/lib.cairo delete mode 100644 exercises/concept/rpn-calculator/tests/rpn_calculator.cairo create mode 100644 exercises/concept/weather-report/.docs/hints.md create mode 100644 exercises/concept/weather-report/.docs/instructions.md create mode 100644 exercises/concept/weather-report/.docs/introduction.md rename exercises/concept/{rpn-calculator => weather-report}/.meta/config.json (66%) rename exercises/concept/{rpn-calculator => weather-report}/.meta/design.md (78%) create mode 100644 exercises/concept/weather-report/.meta/exemplar.cairo rename exercises/concept/{rpn-calculator => weather-report}/Scarb.toml (78%) create mode 100644 exercises/concept/weather-report/src/lib.cairo create mode 100644 exercises/concept/weather-report/tests/weather_report.cairo diff --git a/config.json b/config.json index e9cd57ec..382928b6 100644 --- a/config.json +++ b/config.json @@ -88,15 +88,15 @@ "status": "wip" }, { - "slug": "rpn-calculator", - "name": "RPN Calculator", + "slug": "weather-report", + "name": "Weather Report", "uuid": "536d9f09-5910-4a26-93fd-2242667b0b87", "concepts": [ - "control-flow", - "enums" + "enums", + "match-basics" ], "prerequisites": [ - "arrays" + "felts" ], "status": "wip" }, diff --git a/exercises/concept/rpn-calculator/.docs/hints.md b/exercises/concept/rpn-calculator/.docs/hints.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/rpn-calculator/.docs/instructions.md b/exercises/concept/rpn-calculator/.docs/instructions.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/rpn-calculator/.docs/introduction.md b/exercises/concept/rpn-calculator/.docs/introduction.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/rpn-calculator/.meta/exemplar.cairo b/exercises/concept/rpn-calculator/.meta/exemplar.cairo deleted file mode 100644 index e3329a96..00000000 --- a/exercises/concept/rpn-calculator/.meta/exemplar.cairo +++ /dev/null @@ -1,113 +0,0 @@ -#[derive(Drop, Debug)] -pub enum CalculatorInput { - Add, - Subtract, - Multiply, - Divide, - Value: i32, -} - -pub fn evaluate(inputs: Span) -> Option { - let mut stack: Array = ArrayTrait::new(); - - let mut cancelled = false; - - for input in inputs { - match input { - CalculatorInput::Add => { - let mut stack_span = stack.span(); - let rhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - let lhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - stack = array![]; - stack.append_span(stack_span); - stack.append(lhs + rhs); - }, - CalculatorInput::Subtract => { - let mut stack_span = stack.span(); - let rhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - let lhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - - stack = array![]; - stack.append_span(stack_span); - stack.append(lhs - rhs); - }, - CalculatorInput::Multiply => { - let mut stack_span = stack.span(); - let rhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - let lhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - - stack = array![]; - stack.append_span(stack_span); - stack.append(lhs * rhs); - }, - CalculatorInput::Divide => { - let mut stack_span = stack.span(); - let rhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - let lhs = match stack_span.pop_back() { - Option::Some(value) => *value, - Option::None => { - cancelled = true; - break; - }, - }; - stack = array![]; - stack.append_span(stack_span); - stack.append(lhs / rhs); - }, - CalculatorInput::Value(value) => stack.append(*value), - } - }; - - if cancelled { - return Option::None; - } - - let output = stack.pop_front(); - if stack.is_empty() { - output - } else { - Option::None - } -} diff --git a/exercises/concept/rpn-calculator/src/lib.cairo b/exercises/concept/rpn-calculator/src/lib.cairo deleted file mode 100644 index 627c265d..00000000 --- a/exercises/concept/rpn-calculator/src/lib.cairo +++ /dev/null @@ -1,12 +0,0 @@ -#[derive(Drop, Debug)] -pub enum CalculatorInput { - Add, - Subtract, - Multiply, - Divide, - Value: i32, -} - -pub fn evaluate(inputs: Span) -> i32 { - panic!("implement `evaluate`") -} diff --git a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo deleted file mode 100644 index 66fca248..00000000 --- a/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo +++ /dev/null @@ -1,171 +0,0 @@ -use rpn_calculator::*; - -fn calculator_input(s: ByteArray) -> Span { - let mut calc_input = ArrayTrait::new(); - - let components = split_input_into_components(s); - for c in components { - let ci = if c == @"+" { - CalculatorInput::Add - } else if c == @"-" { - CalculatorInput::Subtract - } else if c == @"*" { - CalculatorInput::Multiply - } else if c == @"/" { - CalculatorInput::Divide - } else { - CalculatorInput::Value(parse_int(c).unwrap()) - }; - calc_input.append(ci) - }; - - calc_input.span() -} - - -fn parse_int(num: @ByteArray) -> Option { - let mut result: Option = Option::Some(0); - let mut size = num.len(); - let mut i = 0; - - let mut is_signed = false; - if num.at(i).unwrap() == '-' { - is_signed = true; - i += 1; - } - - for i in i..size { - match char_to_digit(num[i]) { - Option::Some(v) => { - if let Option::Some(num) = result { - result = Option::Some(num * 10 + v.into()); - } - }, - Option::None => { - result = Option::None; - break; - }, - } - }; - - if let Option::Some(val) = result { - if (is_signed) { - result = Option::Some(val * -1) - } - } - result -} - - -// Utility function to convert a char representing a digit into its numerical value (u32 equivalent) -fn char_to_digit(c: u8) -> Option { - let zero_ascii = '0'; - let nine_ascii = '9'; - - if c >= zero_ascii && c <= nine_ascii { - Option::Some(c - zero_ascii) - } else { - Option::None // Return None for invalid characters - } -} - -fn split_input_into_components(input: ByteArray) -> Span { - let mut components: Array = ArrayTrait::new(); - let mut current_component = ""; - - let mut i = 0; - while i < input.len() { - let char = input[i]; - - if char == ' ' { - components.append(current_component.clone()); - current_component = ""; - } else { - current_component.append_byte(char); - } - - i += 1; - }; - - if current_component.len() > 0 { - components.append(current_component); - } - - components.span() -} - -#[test] -fn empty_input_returns_none() { - let input = calculator_input(""); - assert_eq!(evaluate(input), Option::None); -} - -#[test] -#[ignore] -fn simple_value() { - let input = calculator_input("10"); - assert_eq!(evaluate(input), 10); -} - -#[test] -#[ignore] -fn simple_addition() { - let input = calculator_input("2 2 +"); - assert_eq!(evaluate(input), 4); -} - -#[test] -#[ignore] -fn simple_subtraction() { - let input = calculator_input("7 11 -"); - assert_eq!(evaluate(input), -4); -} - -#[test] -#[ignore] -fn simple_multiplication() { - let input = calculator_input("6 9 *"); - assert_eq!(evaluate(input), 54); -} - -#[test] -#[ignore] -fn simple_division() { - let input = calculator_input("57 19 /"); - assert_eq!(evaluate(input), 3); -} - -#[test] -#[ignore] -fn complex_operation() { - let input = calculator_input("4 8 + 7 5 - /"); - assert_eq!(evaluate(input), 6); -} - -#[test] -#[ignore] -fn too_few_operands_returns_none() { - let input = calculator_input("2 +"); - assert_eq!(evaluate(input), Option::None); -} - -#[test] -#[ignore] -fn too_many_operands_returns_none() { - let input = calculator_input("2 2"); - assert_eq!(evaluate(input), Option::None); -} - -#[test] -#[ignore] -fn zero_operands_returns_none() { - let input = calculator_input("+"); - assert_eq!(evaluate(input), Option::None); -} - -#[test] -#[ignore] -fn intermediate_error_returns_none() { - let input = calculator_input("+ 2 2 *"); - assert_eq!(evaluate(input), Option::None); -} diff --git a/exercises/concept/weather-report/.docs/hints.md b/exercises/concept/weather-report/.docs/hints.md new file mode 100644 index 00000000..b5f97f98 --- /dev/null +++ b/exercises/concept/weather-report/.docs/hints.md @@ -0,0 +1,15 @@ +# Hints + +## General + +- [The Cairo Book - Enums][tcb-enums] +- [The Cairo Book - Match][tcb-match] + +## 1. Generate weather reports + +- `match` comes in handy when working with enums. + In this case, see how you might use it when figuring out what kind of weather report to generate. +- Remember to convert the enum variants to uppercase strings in your reports. + +[tcb-enums]: https://www.starknet.io/cairo-book/ch06-01-enums.html +[tcb-match]: https://www.starknet.io/cairo-book/ch06-02-the-match-control-flow-construct.html diff --git a/exercises/concept/weather-report/.docs/instructions.md b/exercises/concept/weather-report/.docs/instructions.md new file mode 100644 index 00000000..0abd8487 --- /dev/null +++ b/exercises/concept/weather-report/.docs/instructions.md @@ -0,0 +1,34 @@ +# Instructions + +In this exercise you'll be generating weather reports for a local news station. + +## Generate weather reports + +You'll start with some stubbed functions and the following enum: + +```rust +#[derive(Drop, Clone, PartialEq, Debug)] +pub enum WeatherCondition { + Sunny, + Rainy, + Cloudy, + Stormy +} +``` + +Your goal is to emit a weather report as follows: `"Today is with a temperature of degrees Celsius."`. +You'll need to implement functions that correspond with weather conditions. + +For example, the below snippet demonstrates an expected output for the `get_weather_report` function. + +```rust +get_weather_report(WeatherCondition::Rainy, "25") +// Returns: "Today is RAINY with a temperature of 25 degrees Celsius." +``` + +And for `sunny_day`: + +```rust +get_weather_report(WeatherCondition::Sunny, "30") +// Returns: "Today is SUNNY with a temperature of 30 degrees Celsius." +``` diff --git a/exercises/concept/weather-report/.docs/introduction.md b/exercises/concept/weather-report/.docs/introduction.md new file mode 100644 index 00000000..a326e963 --- /dev/null +++ b/exercises/concept/weather-report/.docs/introduction.md @@ -0,0 +1,66 @@ +# Introduction + +Enums in Cairo allow you to define a type that can be one of several named variants. + +## Basics + +Enums, short for enumerations, limit all possible values of some data to a predefined set. The possible values of an `enum` are called variants: + +```rust +#[derive(Drop)] +enum Direction { + North, + South, + East, + West, +} +``` + +Create enum values by specifying the variant: + +```rust +let my_direction = Direction::North; +let another_direction = Direction::West; +``` + +## Pattern Matching + +Use match to handle different enum variants: + +```rust +match my_direction { + Direction::North => println!("Going north!"), + Direction::South => println!("Going south!"), + Direction::East => println!("Going east!"), + Direction::West => println!("Going west!"), +} +``` + +Each arm of the match handles one variant of the enum. + +## Enums with Data + +Enum variants can hold additional data: + +```rust +struct Location { + x: u32, + y: u32, +} + +enum Message { + Text: ByteArray, + Number: u32, + Location: Location, +} +``` + +Pattern match to extract the data: + +```rust +match msg { + Message::Text(content) => println!("Text: {}", content), + Message::Number(val) => println!("Number: {}", val), + Message::Location(Location { x, y }) => println!("Position: ({}, {})", x, y), +} +``` diff --git a/exercises/concept/rpn-calculator/.meta/config.json b/exercises/concept/weather-report/.meta/config.json similarity index 66% rename from exercises/concept/rpn-calculator/.meta/config.json rename to exercises/concept/weather-report/.meta/config.json index b26a480c..3f0e8845 100644 --- a/exercises/concept/rpn-calculator/.meta/config.json +++ b/exercises/concept/weather-report/.meta/config.json @@ -16,8 +16,5 @@ "Scarb.toml" ] }, - "forked_from": [ - "rust/rpn-calculator" - ], - "blurb": "Use some of `Span`'s methods to evaluate Reverse Polish notation" + "blurb": "Learn enums while building a weather reporting system." } diff --git a/exercises/concept/rpn-calculator/.meta/design.md b/exercises/concept/weather-report/.meta/design.md similarity index 78% rename from exercises/concept/rpn-calculator/.meta/design.md rename to exercises/concept/weather-report/.meta/design.md index 290fb652..9a3ad6e4 100644 --- a/exercises/concept/rpn-calculator/.meta/design.md +++ b/exercises/concept/weather-report/.meta/design.md @@ -2,7 +2,6 @@ ## Learning objectives -- Know how to use control flow constructs. - Know how to use enums. - Know how to use pattern matching. @@ -14,9 +13,9 @@ ## Concepts -- Control flow - Enums +- Pattern matching basics ## Prerequisites -- Arrays +- Felts diff --git a/exercises/concept/weather-report/.meta/exemplar.cairo b/exercises/concept/weather-report/.meta/exemplar.cairo new file mode 100644 index 00000000..7027b49c --- /dev/null +++ b/exercises/concept/weather-report/.meta/exemplar.cairo @@ -0,0 +1,25 @@ +#[derive(Drop)] +pub enum WeatherCondition { + Sunny, + Rainy, + Cloudy, + Stormy, +} + +pub fn get_weather_report(condition: WeatherCondition, temperature: ByteArray) -> ByteArray { + match condition { + WeatherCondition::Sunny => format!( + "Today is SUNNY with a temperature of {temperature} degrees Celsius.", + ), + WeatherCondition::Rainy => format!( + "Today is RAINY with a temperature of {temperature} degrees Celsius.", + ), + WeatherCondition::Cloudy => format!( + "Today is CLOUDY with a temperature of {temperature} degrees Celsius.", + ), + WeatherCondition::Stormy => format!( + "Today is STORMY with a temperature of {temperature} degrees Celsius.", + ), + } +} + diff --git a/exercises/concept/rpn-calculator/Scarb.toml b/exercises/concept/weather-report/Scarb.toml similarity index 78% rename from exercises/concept/rpn-calculator/Scarb.toml rename to exercises/concept/weather-report/Scarb.toml index 08bc8d35..1ff0d4ce 100644 --- a/exercises/concept/rpn-calculator/Scarb.toml +++ b/exercises/concept/weather-report/Scarb.toml @@ -1,5 +1,5 @@ [package] -name = "rpn_calculator" +name = "weather_report" version = "0.1.0" edition = "2024_07" diff --git a/exercises/concept/weather-report/src/lib.cairo b/exercises/concept/weather-report/src/lib.cairo new file mode 100644 index 00000000..63f11c7b --- /dev/null +++ b/exercises/concept/weather-report/src/lib.cairo @@ -0,0 +1,15 @@ +/// various weather conditions +#[derive(Drop)] +pub enum WeatherCondition { + Sunny, + Rainy, + Cloudy, + Stormy, +} + +/// primary function for generating weather reports +pub fn get_weather_report(condition: WeatherCondition, temperature: ByteArray) -> ByteArray { + // return a weather report for the given condition + panic!("implement `get_weather_report`") +} + diff --git a/exercises/concept/weather-report/tests/weather_report.cairo b/exercises/concept/weather-report/tests/weather_report.cairo new file mode 100644 index 00000000..bec1976b --- /dev/null +++ b/exercises/concept/weather-report/tests/weather_report.cairo @@ -0,0 +1,63 @@ +use weather_report::{get_weather_report, WeatherCondition}; + +#[test] +fn reports_sunny_weather() { + assert_eq!( + get_weather_report(WeatherCondition::Sunny, "30"), + "Today is SUNNY with a temperature of 30 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn reports_rainy_weather() { + assert_eq!( + get_weather_report(WeatherCondition::Rainy, "25"), + "Today is RAINY with a temperature of 25 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn reports_cloudy_weather() { + assert_eq!( + get_weather_report(WeatherCondition::Cloudy, "27"), + "Today is CLOUDY with a temperature of 27 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn get_weather_report_sunny() { + assert_eq!( + get_weather_report(WeatherCondition::Sunny, "35"), + "Today is SUNNY with a temperature of 35 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn get_weather_report_rainy() { + assert_eq!( + get_weather_report(WeatherCondition::Rainy, "20"), + "Today is RAINY with a temperature of 20 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn get_weather_report_cloudy() { + assert_eq!( + get_weather_report(WeatherCondition::Cloudy, "22"), + "Today is CLOUDY with a temperature of 22 degrees Celsius.", + ); +} + +#[test] +#[ignore] +fn add_stormy_variant() { + assert_eq!( + get_weather_report(WeatherCondition::Stormy, "15"), + "Today is STORMY with a temperature of 15 degrees Celsius.", + ); +} From ef405410c598cf0f3628822594ca1c1b8c203fda Mon Sep 17 00:00:00 2001 From: Nenad Date: Sat, 9 Aug 2025 14:37:41 +0200 Subject: [PATCH 05/15] fix config name --- exercises/concept/weather-report/.docs/introduction.md | 3 ++- exercises/concept/weather-report/.meta/config.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/exercises/concept/weather-report/.docs/introduction.md b/exercises/concept/weather-report/.docs/introduction.md index a326e963..68041012 100644 --- a/exercises/concept/weather-report/.docs/introduction.md +++ b/exercises/concept/weather-report/.docs/introduction.md @@ -4,7 +4,8 @@ Enums in Cairo allow you to define a type that can be one of several named varia ## Basics -Enums, short for enumerations, limit all possible values of some data to a predefined set. The possible values of an `enum` are called variants: +Enums, short for enumerations, limit all possible values of some data to a predefined set. +The possible values of an `enum` are called variants: ```rust #[derive(Drop)] diff --git a/exercises/concept/weather-report/.meta/config.json b/exercises/concept/weather-report/.meta/config.json index 3f0e8845..b50232ca 100644 --- a/exercises/concept/weather-report/.meta/config.json +++ b/exercises/concept/weather-report/.meta/config.json @@ -7,7 +7,7 @@ "src/lib.cairo" ], "test": [ - "tests/rpn_calculator.cairo" + "tests/weather_report.cairo" ], "exemplar": [ ".meta/exemplar.cairo" From 73cf4345e148d94707219d392a046a4ea4f85b43 Mon Sep 17 00:00:00 2001 From: Nenad Date: Sun, 10 Aug 2025 10:32:05 +0200 Subject: [PATCH 06/15] change prerequisite to functions --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 382928b6..5523da8b 100644 --- a/config.json +++ b/config.json @@ -96,7 +96,7 @@ "match-basics" ], "prerequisites": [ - "felts" + "functions" ], "status": "wip" }, From 418cc80ff63b45d1f5b951d6597b8d561e0224fc Mon Sep 17 00:00:00 2001 From: Nenad Date: Sun, 10 Aug 2025 10:33:59 +0200 Subject: [PATCH 07/15] wip -> beta --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 5523da8b..ce0f718d 100644 --- a/config.json +++ b/config.json @@ -98,7 +98,7 @@ "prerequisites": [ "functions" ], - "status": "wip" + "status": "beta" }, { "slug": "welcome-to-tech-palace", From ab57e880db6e1ad0687c7446e80ead01a9248e55 Mon Sep 17 00:00:00 2001 From: Nenad Date: Sun, 17 Aug 2025 09:47:47 +0200 Subject: [PATCH 08/15] Update exercises/concept/weather-report/.docs/instructions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: AndrĂ¡s B Nagy <20251272+BNAndras@users.noreply.github.com> --- exercises/concept/weather-report/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/weather-report/.docs/instructions.md b/exercises/concept/weather-report/.docs/instructions.md index 0abd8487..60b2ff1b 100644 --- a/exercises/concept/weather-report/.docs/instructions.md +++ b/exercises/concept/weather-report/.docs/instructions.md @@ -16,7 +16,7 @@ pub enum WeatherCondition { } ``` -Your goal is to emit a weather report as follows: `"Today is with a temperature of degrees Celsius."`. +You will need to format a weather report like `"Today is with a temperature of degrees Celsius."`. You'll need to implement functions that correspond with weather conditions. For example, the below snippet demonstrates an expected output for the `get_weather_report` function. From c83612ea1fd7dc2da789e192571b80ea757a0c68 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 10:04:14 +0200 Subject: [PATCH 09/15] apply review suggestions --- .../concept/weather-report/.docs/instructions.md | 6 +++--- .../concept/weather-report/.meta/exemplar.cairo | 2 +- exercises/concept/weather-report/src/lib.cairo | 2 +- .../weather-report/tests/weather_report.cairo | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/exercises/concept/weather-report/.docs/instructions.md b/exercises/concept/weather-report/.docs/instructions.md index 60b2ff1b..251333f9 100644 --- a/exercises/concept/weather-report/.docs/instructions.md +++ b/exercises/concept/weather-report/.docs/instructions.md @@ -17,16 +17,16 @@ pub enum WeatherCondition { ``` You will need to format a weather report like `"Today is with a temperature of degrees Celsius."`. -You'll need to implement functions that correspond with weather conditions. +You'll need to implement the function that outputs the correct weather conditions. -For example, the below snippet demonstrates an expected output for the `get_weather_report` function. +For example, the below snippet demonstrates an expected output for the `get_weather_report` function for a "rainy" day. ```rust get_weather_report(WeatherCondition::Rainy, "25") // Returns: "Today is RAINY with a temperature of 25 degrees Celsius." ``` -And for `sunny_day`: +And for a "sunny" day: ```rust get_weather_report(WeatherCondition::Sunny, "30") diff --git a/exercises/concept/weather-report/.meta/exemplar.cairo b/exercises/concept/weather-report/.meta/exemplar.cairo index 7027b49c..de3deca8 100644 --- a/exercises/concept/weather-report/.meta/exemplar.cairo +++ b/exercises/concept/weather-report/.meta/exemplar.cairo @@ -6,7 +6,7 @@ pub enum WeatherCondition { Stormy, } -pub fn get_weather_report(condition: WeatherCondition, temperature: ByteArray) -> ByteArray { +pub fn get_weather_report(condition: WeatherCondition, temperature: u32) -> ByteArray { match condition { WeatherCondition::Sunny => format!( "Today is SUNNY with a temperature of {temperature} degrees Celsius.", diff --git a/exercises/concept/weather-report/src/lib.cairo b/exercises/concept/weather-report/src/lib.cairo index 63f11c7b..0ec921c7 100644 --- a/exercises/concept/weather-report/src/lib.cairo +++ b/exercises/concept/weather-report/src/lib.cairo @@ -8,7 +8,7 @@ pub enum WeatherCondition { } /// primary function for generating weather reports -pub fn get_weather_report(condition: WeatherCondition, temperature: ByteArray) -> ByteArray { +pub fn get_weather_report(condition: WeatherCondition, temperature: u32) -> ByteArray { // return a weather report for the given condition panic!("implement `get_weather_report`") } diff --git a/exercises/concept/weather-report/tests/weather_report.cairo b/exercises/concept/weather-report/tests/weather_report.cairo index bec1976b..3eb123a5 100644 --- a/exercises/concept/weather-report/tests/weather_report.cairo +++ b/exercises/concept/weather-report/tests/weather_report.cairo @@ -3,7 +3,7 @@ use weather_report::{get_weather_report, WeatherCondition}; #[test] fn reports_sunny_weather() { assert_eq!( - get_weather_report(WeatherCondition::Sunny, "30"), + get_weather_report(WeatherCondition::Sunny, 30), "Today is SUNNY with a temperature of 30 degrees Celsius.", ); } @@ -12,7 +12,7 @@ fn reports_sunny_weather() { #[ignore] fn reports_rainy_weather() { assert_eq!( - get_weather_report(WeatherCondition::Rainy, "25"), + get_weather_report(WeatherCondition::Rainy, 25), "Today is RAINY with a temperature of 25 degrees Celsius.", ); } @@ -21,7 +21,7 @@ fn reports_rainy_weather() { #[ignore] fn reports_cloudy_weather() { assert_eq!( - get_weather_report(WeatherCondition::Cloudy, "27"), + get_weather_report(WeatherCondition::Cloudy, 27), "Today is CLOUDY with a temperature of 27 degrees Celsius.", ); } @@ -30,7 +30,7 @@ fn reports_cloudy_weather() { #[ignore] fn get_weather_report_sunny() { assert_eq!( - get_weather_report(WeatherCondition::Sunny, "35"), + get_weather_report(WeatherCondition::Sunny, 35), "Today is SUNNY with a temperature of 35 degrees Celsius.", ); } @@ -39,7 +39,7 @@ fn get_weather_report_sunny() { #[ignore] fn get_weather_report_rainy() { assert_eq!( - get_weather_report(WeatherCondition::Rainy, "20"), + get_weather_report(WeatherCondition::Rainy, 20), "Today is RAINY with a temperature of 20 degrees Celsius.", ); } @@ -48,7 +48,7 @@ fn get_weather_report_rainy() { #[ignore] fn get_weather_report_cloudy() { assert_eq!( - get_weather_report(WeatherCondition::Cloudy, "22"), + get_weather_report(WeatherCondition::Cloudy, 22), "Today is CLOUDY with a temperature of 22 degrees Celsius.", ); } @@ -57,7 +57,7 @@ fn get_weather_report_cloudy() { #[ignore] fn add_stormy_variant() { assert_eq!( - get_weather_report(WeatherCondition::Stormy, "15"), + get_weather_report(WeatherCondition::Stormy, 15), "Today is STORMY with a temperature of 15 degrees Celsius.", ); } From 0a0fa58d370865a19b255d426cadb3b393f26f4e Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 10:12:34 +0200 Subject: [PATCH 10/15] add back rpn-calculator (deprecated) + create new uuid for weather-report --- config.json | 28 ++++++++++++------- .../concept/rpn-calculator/.docs/hints.md | 0 .../rpn-calculator/.docs/instructions.md | 0 .../rpn-calculator/.docs/introduction.md | 0 .../concept/rpn-calculator/.meta/config.json | 23 +++++++++++++++ .../concept/rpn-calculator/.meta/design.md | 0 .../rpn-calculator/.meta/exemplar.cairo | 0 exercises/concept/rpn-calculator/Scarb.toml | 0 .../concept/rpn-calculator/src/lib.cairo | 0 .../tests/the_realm_of_echoes.cairo | 0 10 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 exercises/concept/rpn-calculator/.docs/hints.md create mode 100644 exercises/concept/rpn-calculator/.docs/instructions.md create mode 100644 exercises/concept/rpn-calculator/.docs/introduction.md create mode 100644 exercises/concept/rpn-calculator/.meta/config.json create mode 100644 exercises/concept/rpn-calculator/.meta/design.md create mode 100644 exercises/concept/rpn-calculator/.meta/exemplar.cairo create mode 100644 exercises/concept/rpn-calculator/Scarb.toml create mode 100644 exercises/concept/rpn-calculator/src/lib.cairo create mode 100644 exercises/concept/rpn-calculator/tests/the_realm_of_echoes.cairo diff --git a/config.json b/config.json index 8b3de8e9..9d16d231 100644 --- a/config.json +++ b/config.json @@ -94,17 +94,12 @@ "status": "beta" }, { - "slug": "weather-report", - "name": "Weather Report", + "slug": "rpn-calculator", + "name": "RPN Calculator", "uuid": "536d9f09-5910-4a26-93fd-2242667b0b87", - "concepts": [ - "enums", - "match-basics" - ], - "prerequisites": [ - "functions" - ], - "status": "beta" + "concepts": [], + "prerequisites": [], + "status": "deprecated" }, { "slug": "welcome-to-tech-palace", @@ -264,6 +259,19 @@ "error-handling" ], "status": "beta" + }, + { + "slug": "weather-report", + "name": "weather-report", + "uuid": "b91da5c2-f639-40cb-8a28-607228e6b48b", + "concepts": [ + "enums", + "match-basics" + ], + "prerequisites": [ + "functions" + ], + "status": "beta" } ], "practice": [ diff --git a/exercises/concept/rpn-calculator/.docs/hints.md b/exercises/concept/rpn-calculator/.docs/hints.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/.docs/instructions.md b/exercises/concept/rpn-calculator/.docs/instructions.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/.docs/introduction.md b/exercises/concept/rpn-calculator/.docs/introduction.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/.meta/config.json b/exercises/concept/rpn-calculator/.meta/config.json new file mode 100644 index 00000000..b8399302 --- /dev/null +++ b/exercises/concept/rpn-calculator/.meta/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "" + ], + "files": { + "solution": [ + "src/lib.cairo" + ], + "test": [ + "tests/rpn_calculator.cairo" + ], + "exemplar": [ + ".meta/exemplar.cairo" + ], + "invalidator": [ + "Scarb.toml" + ] + }, + "forked_from": [ + "rust/rpn-calculator" + ], + "blurb": "Use some of `Array`'s methods to evaluate Reverse Polish notation" +} diff --git a/exercises/concept/rpn-calculator/.meta/design.md b/exercises/concept/rpn-calculator/.meta/design.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/.meta/exemplar.cairo b/exercises/concept/rpn-calculator/.meta/exemplar.cairo new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/Scarb.toml b/exercises/concept/rpn-calculator/Scarb.toml new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/src/lib.cairo b/exercises/concept/rpn-calculator/src/lib.cairo new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/rpn-calculator/tests/the_realm_of_echoes.cairo b/exercises/concept/rpn-calculator/tests/the_realm_of_echoes.cairo new file mode 100644 index 00000000..e69de29b From 1b6123f311f27d88185851e89b26b384d1195648 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 10:12:53 +0200 Subject: [PATCH 11/15] fix test name --- .../tests/{the_realm_of_echoes.cairo => rpn_calculator.cairo} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename exercises/concept/rpn-calculator/tests/{the_realm_of_echoes.cairo => rpn_calculator.cairo} (100%) diff --git a/exercises/concept/rpn-calculator/tests/the_realm_of_echoes.cairo b/exercises/concept/rpn-calculator/tests/rpn_calculator.cairo similarity index 100% rename from exercises/concept/rpn-calculator/tests/the_realm_of_echoes.cairo rename to exercises/concept/rpn-calculator/tests/rpn_calculator.cairo From c45e3334298fc00cc6a57ecb17c21034ac265b87 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 15:32:04 +0200 Subject: [PATCH 12/15] add bakery-order-system scaffold --- config.json | 12 +++ .../bakery-order-system/.docs/hints.md | 0 .../bakery-order-system/.docs/instructions.md | 0 .../bakery-order-system/.docs/introduction.md | 0 .../bakery-order-system/.meta/config.json | 20 +++++ .../bakery-order-system/.meta/design.md | 0 .../bakery-order-system/.meta/exemplar.cairo | 0 .../concept/bakery-order-system/Scarb.toml | 1 + .../concept/bakery-order-system/src/lib.cairo | 0 .../tests/bakery_order_system.cairo | 84 +++++++++++++++++++ 10 files changed, 117 insertions(+) create mode 100644 exercises/concept/bakery-order-system/.docs/hints.md create mode 100644 exercises/concept/bakery-order-system/.docs/instructions.md create mode 100644 exercises/concept/bakery-order-system/.docs/introduction.md create mode 100644 exercises/concept/bakery-order-system/.meta/config.json create mode 100644 exercises/concept/bakery-order-system/.meta/design.md create mode 100644 exercises/concept/bakery-order-system/.meta/exemplar.cairo create mode 100644 exercises/concept/bakery-order-system/Scarb.toml create mode 100644 exercises/concept/bakery-order-system/src/lib.cairo create mode 100644 exercises/concept/bakery-order-system/tests/bakery_order_system.cairo diff --git a/config.json b/config.json index 9d16d231..2f32fe4c 100644 --- a/config.json +++ b/config.json @@ -101,6 +101,18 @@ "prerequisites": [], "status": "deprecated" }, + { + "slug": "bakery-order-system", + "name": "Bakery Order System", + "uuid": "a979b9a0-7fd9-46f7-bacf-f0044c3c9bb0", + "concepts": [ + "control-flow" + ], + "prerequisites": [ + "match-basics" + ], + "status": "wip" + }, { "slug": "welcome-to-tech-palace", "name": "Welcome To Tech Palace!", diff --git a/exercises/concept/bakery-order-system/.docs/hints.md b/exercises/concept/bakery-order-system/.docs/hints.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/.docs/instructions.md b/exercises/concept/bakery-order-system/.docs/instructions.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/.docs/introduction.md b/exercises/concept/bakery-order-system/.docs/introduction.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/.meta/config.json b/exercises/concept/bakery-order-system/.meta/config.json new file mode 100644 index 00000000..1e086ed8 --- /dev/null +++ b/exercises/concept/bakery-order-system/.meta/config.json @@ -0,0 +1,20 @@ +{ + "authors": [ + "" + ], + "files": { + "solution": [ + "src/lib.cairo" + ], + "test": [ + "tests/bakery_order_system.cairo" + ], + "exemplar": [ + ".meta/exemplar.cairo" + ], + "invalidator": [ + "Scarb.toml" + ] + }, + "blurb": "" +} diff --git a/exercises/concept/bakery-order-system/.meta/design.md b/exercises/concept/bakery-order-system/.meta/design.md new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/.meta/exemplar.cairo b/exercises/concept/bakery-order-system/.meta/exemplar.cairo new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/Scarb.toml b/exercises/concept/bakery-order-system/Scarb.toml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/exercises/concept/bakery-order-system/Scarb.toml @@ -0,0 +1 @@ + diff --git a/exercises/concept/bakery-order-system/src/lib.cairo b/exercises/concept/bakery-order-system/src/lib.cairo new file mode 100644 index 00000000..e69de29b diff --git a/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo b/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo new file mode 100644 index 00000000..13b7f095 --- /dev/null +++ b/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo @@ -0,0 +1,84 @@ +use welcome_to_tech_palace::*; + +#[test] +fn welcome_message_for_customer_with_first_letter_capitalized() { + let customer = 'Judy'; + let actual = welcome_message(customer); + let expected = "Welcome to the Tech Palace, JUDY"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn welcome_message_for_customer_with_only_lowercase_letters() { + let customer = 'lars'; + let actual = welcome_message(customer); + let expected = "Welcome to the Tech Palace, LARS"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn welcome_message_for_customer_with_dash_in_name() { + let customer = 'Peter-James'; + let actual = welcome_message(customer); + let expected = "Welcome to the Tech Palace, PETER-JAMES"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn welcome_message_for_customer_with_only_uppercase_letters() { + let customer = 'MJ'; + let actual = welcome_message(customer); + let expected = "Welcome to the Tech Palace, MJ"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn add_border_with_10_stars_per_line() { + let welcome_msg = "Welcome!"; + let num_stars_per_line = 10; + let actual = add_border(welcome_msg, num_stars_per_line); + let expected = "**********\nWelcome!\n**********"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn add_border_with_2_stars_per_line() { + let welcome_msg = "Hi"; + let num_stars_per_line = 2; + let actual = add_border(welcome_msg, num_stars_per_line); + let expected = "**\nHi\n**"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn clean_up_message_with_many_stars_and_leading_and_trailing_whitespace() { + let old_msg = + "**************************\n* BUY NOW, SAVE 10% *\n**************************"; + let actual = clean_up_message(old_msg); + let expected = "BUY NOW, SAVE 10%"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn clean_up_message_without_leading_or_trailing_whitespace() { + let old_msg = "**********\n*DISCOUNT*\n**********"; + let actual = clean_up_message(old_msg); + let expected = "DISCOUNT"; + assert_eq!(expected, actual); +} + +#[test] +#[ignore] +fn clean_up_message_without_leading_whitespace() { + let old_msg = "*****\n SALE\n*****"; + let actual = clean_up_message(old_msg); + let expected = "SALE"; + assert_eq!(expected, actual); +} From f75763926f54ba278d3643382b3775ae0ed4d4d5 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 15:36:04 +0200 Subject: [PATCH 13/15] remove scarb.toml in bos --- exercises/concept/bakery-order-system/Scarb.toml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 exercises/concept/bakery-order-system/Scarb.toml diff --git a/exercises/concept/bakery-order-system/Scarb.toml b/exercises/concept/bakery-order-system/Scarb.toml deleted file mode 100644 index 8b137891..00000000 --- a/exercises/concept/bakery-order-system/Scarb.toml +++ /dev/null @@ -1 +0,0 @@ - From 162d0950f47b7f08fdd3219f7dd1e0f2023ba93d Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 15:48:51 +0200 Subject: [PATCH 14/15] Revert "remove scarb.toml in bos" This reverts commit f75763926f54ba278d3643382b3775ae0ed4d4d5. --- exercises/concept/bakery-order-system/Scarb.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/concept/bakery-order-system/Scarb.toml diff --git a/exercises/concept/bakery-order-system/Scarb.toml b/exercises/concept/bakery-order-system/Scarb.toml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/exercises/concept/bakery-order-system/Scarb.toml @@ -0,0 +1 @@ + From 9644a9d92c5c838733d8683d08d70c8bd6201add Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Sun, 17 Aug 2025 15:48:51 +0200 Subject: [PATCH 15/15] Revert "add bakery-order-system scaffold" This reverts commit c45e3334298fc00cc6a57ecb17c21034ac265b87. --- config.json | 12 --- .../bakery-order-system/.docs/hints.md | 0 .../bakery-order-system/.docs/instructions.md | 0 .../bakery-order-system/.docs/introduction.md | 0 .../bakery-order-system/.meta/config.json | 20 ----- .../bakery-order-system/.meta/design.md | 0 .../bakery-order-system/.meta/exemplar.cairo | 0 .../concept/bakery-order-system/Scarb.toml | 1 - .../concept/bakery-order-system/src/lib.cairo | 0 .../tests/bakery_order_system.cairo | 84 ------------------- 10 files changed, 117 deletions(-) delete mode 100644 exercises/concept/bakery-order-system/.docs/hints.md delete mode 100644 exercises/concept/bakery-order-system/.docs/instructions.md delete mode 100644 exercises/concept/bakery-order-system/.docs/introduction.md delete mode 100644 exercises/concept/bakery-order-system/.meta/config.json delete mode 100644 exercises/concept/bakery-order-system/.meta/design.md delete mode 100644 exercises/concept/bakery-order-system/.meta/exemplar.cairo delete mode 100644 exercises/concept/bakery-order-system/Scarb.toml delete mode 100644 exercises/concept/bakery-order-system/src/lib.cairo delete mode 100644 exercises/concept/bakery-order-system/tests/bakery_order_system.cairo diff --git a/config.json b/config.json index 2f32fe4c..9d16d231 100644 --- a/config.json +++ b/config.json @@ -101,18 +101,6 @@ "prerequisites": [], "status": "deprecated" }, - { - "slug": "bakery-order-system", - "name": "Bakery Order System", - "uuid": "a979b9a0-7fd9-46f7-bacf-f0044c3c9bb0", - "concepts": [ - "control-flow" - ], - "prerequisites": [ - "match-basics" - ], - "status": "wip" - }, { "slug": "welcome-to-tech-palace", "name": "Welcome To Tech Palace!", diff --git a/exercises/concept/bakery-order-system/.docs/hints.md b/exercises/concept/bakery-order-system/.docs/hints.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/.docs/instructions.md b/exercises/concept/bakery-order-system/.docs/instructions.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/.docs/introduction.md b/exercises/concept/bakery-order-system/.docs/introduction.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/.meta/config.json b/exercises/concept/bakery-order-system/.meta/config.json deleted file mode 100644 index 1e086ed8..00000000 --- a/exercises/concept/bakery-order-system/.meta/config.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "authors": [ - "" - ], - "files": { - "solution": [ - "src/lib.cairo" - ], - "test": [ - "tests/bakery_order_system.cairo" - ], - "exemplar": [ - ".meta/exemplar.cairo" - ], - "invalidator": [ - "Scarb.toml" - ] - }, - "blurb": "" -} diff --git a/exercises/concept/bakery-order-system/.meta/design.md b/exercises/concept/bakery-order-system/.meta/design.md deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/.meta/exemplar.cairo b/exercises/concept/bakery-order-system/.meta/exemplar.cairo deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/Scarb.toml b/exercises/concept/bakery-order-system/Scarb.toml deleted file mode 100644 index 8b137891..00000000 --- a/exercises/concept/bakery-order-system/Scarb.toml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/exercises/concept/bakery-order-system/src/lib.cairo b/exercises/concept/bakery-order-system/src/lib.cairo deleted file mode 100644 index e69de29b..00000000 diff --git a/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo b/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo deleted file mode 100644 index 13b7f095..00000000 --- a/exercises/concept/bakery-order-system/tests/bakery_order_system.cairo +++ /dev/null @@ -1,84 +0,0 @@ -use welcome_to_tech_palace::*; - -#[test] -fn welcome_message_for_customer_with_first_letter_capitalized() { - let customer = 'Judy'; - let actual = welcome_message(customer); - let expected = "Welcome to the Tech Palace, JUDY"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn welcome_message_for_customer_with_only_lowercase_letters() { - let customer = 'lars'; - let actual = welcome_message(customer); - let expected = "Welcome to the Tech Palace, LARS"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn welcome_message_for_customer_with_dash_in_name() { - let customer = 'Peter-James'; - let actual = welcome_message(customer); - let expected = "Welcome to the Tech Palace, PETER-JAMES"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn welcome_message_for_customer_with_only_uppercase_letters() { - let customer = 'MJ'; - let actual = welcome_message(customer); - let expected = "Welcome to the Tech Palace, MJ"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn add_border_with_10_stars_per_line() { - let welcome_msg = "Welcome!"; - let num_stars_per_line = 10; - let actual = add_border(welcome_msg, num_stars_per_line); - let expected = "**********\nWelcome!\n**********"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn add_border_with_2_stars_per_line() { - let welcome_msg = "Hi"; - let num_stars_per_line = 2; - let actual = add_border(welcome_msg, num_stars_per_line); - let expected = "**\nHi\n**"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn clean_up_message_with_many_stars_and_leading_and_trailing_whitespace() { - let old_msg = - "**************************\n* BUY NOW, SAVE 10% *\n**************************"; - let actual = clean_up_message(old_msg); - let expected = "BUY NOW, SAVE 10%"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn clean_up_message_without_leading_or_trailing_whitespace() { - let old_msg = "**********\n*DISCOUNT*\n**********"; - let actual = clean_up_message(old_msg); - let expected = "DISCOUNT"; - assert_eq!(expected, actual); -} - -#[test] -#[ignore] -fn clean_up_message_without_leading_whitespace() { - let old_msg = "*****\n SALE\n*****"; - let actual = clean_up_message(old_msg); - let expected = "SALE"; - assert_eq!(expected, actual); -}