From a57d6187cf2cce972a92ba2497b29744c5fa715d Mon Sep 17 00:00:00 2001 From: meatball Date: Sun, 14 Jul 2024 18:23:48 +0200 Subject: [PATCH 1/9] Start on concept --- concepts/getters-setters/.meta/config.json | 5 + concepts/getters-setters/.meta/template.md | 1 + concepts/getters-setters/about.md | 96 +++++++++++++++++ concepts/getters-setters/introduction.md | 102 ++++++++++++++++++ concepts/getters-setters/links.json | 6 ++ .../concept/weighing-machine/.docs/hints.md | 21 ++++ .../weighing-machine/.docs/instructions.md | 38 +++++++ .../weighing-machine/.docs/introduction.md | 1 + .../weighing-machine/.meta/config.json | 16 +++ .../weighing-machine/.meta/src/exemplar.cr | 17 +++ .../spec/weighing_machine_spec.cr | 35 ++++++ .../weighing-machine/src/weighing_machine.cr | 10 ++ 12 files changed, 348 insertions(+) create mode 100644 concepts/getters-setters/.meta/config.json create mode 100644 concepts/getters-setters/.meta/template.md create mode 100644 concepts/getters-setters/about.md create mode 100644 concepts/getters-setters/introduction.md create mode 100644 concepts/getters-setters/links.json create mode 100644 exercises/concept/weighing-machine/.docs/hints.md create mode 100644 exercises/concept/weighing-machine/.docs/instructions.md create mode 100644 exercises/concept/weighing-machine/.docs/introduction.md create mode 100644 exercises/concept/weighing-machine/.meta/config.json create mode 100644 exercises/concept/weighing-machine/.meta/src/exemplar.cr create mode 100644 exercises/concept/weighing-machine/spec/weighing_machine_spec.cr create mode 100644 exercises/concept/weighing-machine/src/weighing_machine.cr diff --git a/concepts/getters-setters/.meta/config.json b/concepts/getters-setters/.meta/config.json new file mode 100644 index 00000000..4365f0b2 --- /dev/null +++ b/concepts/getters-setters/.meta/config.json @@ -0,0 +1,5 @@ +{ + "blurb": "Crystal has macros for defining getters and setters. Which is used to access and modify the instance variables of a class.", + "authors": ["meatball133"], + "contributors": [""] +} diff --git a/concepts/getters-setters/.meta/template.md b/concepts/getters-setters/.meta/template.md new file mode 100644 index 00000000..72129c2c --- /dev/null +++ b/concepts/getters-setters/.meta/template.md @@ -0,0 +1 @@ +{% $getters-setters / $getters-setters.getter! %} diff --git a/concepts/getters-setters/about.md b/concepts/getters-setters/about.md new file mode 100644 index 00000000..3facb644 --- /dev/null +++ b/concepts/getters-setters/about.md @@ -0,0 +1,96 @@ +# Getters and setters + +Getters and setters are methods that allow you to read and write the value of an object's property. +Crystal has macros which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time and will be covered later in the macro concept. + +In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. +Crystal has defined these as `getter`, `setter` and `property` macros. + +## Getters + +Getter is a macro that defines a method that returns the value of an instance variable. +This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. + +The getter macro can accept multiple instance variables by separating them with a comma. + +```crystal +# This: +class Person + @nane : String + @age : Int32 + + def name + @name + end + + def age + @age + end +end + +# Is the same as this: +class Person + @name : String + @age : Int32 + + getter name, :age +end +``` + +As you can see using getter reduces the amount of code you have to write and makes it easier to read. +Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. +Symbols will be covered later in the symbols concept. + +## Setters + +Setters is a macro that defines a method that sets the value of an instance variable. +This macro isnt that often found and more commonly is the `property` macro used. +The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. + +This method defintion is a bit special since the argument the method recive is after the `=` sign. +There are several other special methods in Crystal that uses this syntax, like the `+` method for example. + +As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. + +```crystal +# This: +class Person + @name : String + @age : Int32 + + def name=(name : String) + @name = name + end + + def age=(age : Int32) + @age = age + end +end + +# Is the same as this: +class Person + @name : String + @age : Int32 + + setter name, :age +end +``` + +## Property + +Property is a macro that defines both a getter and a setter for an instance variable. + +```crystal +class Person + @name : String + @age : Int32 + + property name, :age +end +``` + +[getters_and_macros]: https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html#getters-and-setters +[getter]: https://crystal-lang.org/api/Object.html#getter%28%2Anames%2C%26block%29-macro +[setter]: https://crystal-lang.org/api/Object.html#setter%28%2Anames%29-macro +[property]: https://crystal-lang.org/api/Object.html#property%28%2Anames%2C%26block%29-macro \ No newline at end of file diff --git a/concepts/getters-setters/introduction.md b/concepts/getters-setters/introduction.md new file mode 100644 index 00000000..5e2d5472 --- /dev/null +++ b/concepts/getters-setters/introduction.md @@ -0,0 +1,102 @@ +# Modules + +[Modules][modules] in Crystal serve 2 purposes: + +The first purpose is to create a [namespace][namespace] to avoid name collisions. +But it also forms as a form of grouping code together, this is to make it easier to understand what the code is for. + +The second purpose is to define [mixins][mixin] to share code to types. + +Modules have similarities to classes, but the main difference is that modules cannot be instantiated, and thereby don't have instance variables. + +To declare a module you use the `module` keyword followed by the name of the module. + +```crystal +module Foo +end +``` + +## Namespace + +A namespace is a way to group code together, this is to avoid name clashes, but also to make it easier to understand what the code is for. +When wanting to access for example a constant or a class that has been placed inside a namespace you use the `::` operator. + +```crystal +module Foo + class Bar + end +end + +Foo::Bar.new +``` + +## Use it as a mixin + +This can be useful when, for example, wanting multiple classes to have the same "base" functionality or when wanting to share code between classes that are not related. +Or when wanting to share code between classes that are not related. + +There are 2 different ways to use a module as a mixin: the first one is to use the `include` keyword, the second one is to use the `extend` keyword. + +Both methods will make constants available to the type that includes or extends the module. + +### Include + +Include will make all methods in the module available as instance methods on the type that includes the module. +The `include` keyword should be written at the top of the type, followed by the name of the module. + +```crystal +module Foo + def foo + "foo" + end +end + +class Bar + include Foo +end + +Bar.new.foo # => "foo" +``` + +### Extend + +Extend works similarly to include, but instead of making the methods available as instance methods, it makes them available as class methods. +The `extend` keyword should be written at the top of the type followed by the name of the module. + +```crystal +module Foo + def foo + "foo" + end +end + +class Bar + extend Foo +end + +Bar.foo # => "foo" +``` + +## Extend self + +A quite common pattern in Crystal is to use the [`extend self`][extend self] pattern, in a module. +This will make all methods in the module available as class methods on the module itself. +This means you don't have to assign each method to the module itself using the `def self.method_name` syntax. + + +```crystal +module Foo + extend self + + def foo + "foo" + end +end + +Foo.foo # => "foo" +``` + +[mixin]: https://en.wikipedia.org/wiki/Mixin +[modules]: https://crystal-lang.org/reference/syntax_and_semantics/modules.html +[extend self]: https://crystal-lang.org/reference/syntax_and_semantics/modules.html#extend-self +[namespace]: https://en.wikipedia.org/wiki/Namespace diff --git a/concepts/getters-setters/links.json b/concepts/getters-setters/links.json new file mode 100644 index 00000000..8779e02c --- /dev/null +++ b/concepts/getters-setters/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://crystal-lang.org/reference/latest/syntax_and_semantics/modules.html", + "description": "Crystal docs: modules" + } +] diff --git a/exercises/concept/weighing-machine/.docs/hints.md b/exercises/concept/weighing-machine/.docs/hints.md new file mode 100644 index 00000000..157f47f4 --- /dev/null +++ b/exercises/concept/weighing-machine/.docs/hints.md @@ -0,0 +1,21 @@ +# Hints + +## General + +- To access and define instance variables you write `@` followed by the name of the variable. + +## 1. Initialize `TaskHandler` + +- To create a `Proc` use the `-> (args) { block }` syntax. +- When a `Proc` is defined for an instance variable, it needs to be explicitly typed. + This can be done by adding `: Proc(, )` after the variable name. + Or `-> (arg_1 : ) : { block }` syntax. +- The `Proc` should compare if the argument is greater than or equal to 0. + +## 2. Update the task condition logic + +- The method should take a block as an argument and assign it to the `@task_condition_logic` instance variable. + +## 3. Execute the next task + +- To execute a `Proc` you can use the `call` method which accepts the arguments for the proc. diff --git a/exercises/concept/weighing-machine/.docs/instructions.md b/exercises/concept/weighing-machine/.docs/instructions.md new file mode 100644 index 00000000..62563626 --- /dev/null +++ b/exercises/concept/weighing-machine/.docs/instructions.md @@ -0,0 +1,38 @@ +# Instructions + +In this exercise you'll be modelling a weighing machine with Kilograms as a Unit. + +## 1. Allow the weighing machine to have a precision + +To cater to different demands, we allow each weighing machine to be customized with a precision (the number of digits after the decimal separator). + +Implement the `WeighingMachine#precision` getter method to return the precision of the weighing machine. + +```crystal +precision = 3 +vm = WeighingMachine.new(precision) +vm.precision +# => 3 +``` + +## 2. Allow the machine to be switch between metric and imperial units + +Implement the `WeighingMachine#metric=` property to allow the unit to be set, it should accept a boolean value. + +```crystal +precision = 3 +wm = WeighingMachine.new(3) +wm.metric = false +``` + +## 3. Allow the weight to be set on the weighing machine + +Implement the `WeighingMachine#weight` property to allow the weight to be get _and_ set: + +```crystal +precision = 3 +wm = WeighingMachine.new(3) +wm.weight = 60.5 +wm.weight +# => 60.5 +``` diff --git a/exercises/concept/weighing-machine/.docs/introduction.md b/exercises/concept/weighing-machine/.docs/introduction.md new file mode 100644 index 00000000..f87f5c14 --- /dev/null +++ b/exercises/concept/weighing-machine/.docs/introduction.md @@ -0,0 +1 @@ +# TODO \ No newline at end of file diff --git a/exercises/concept/weighing-machine/.meta/config.json b/exercises/concept/weighing-machine/.meta/config.json new file mode 100644 index 00000000..60c00870 --- /dev/null +++ b/exercises/concept/weighing-machine/.meta/config.json @@ -0,0 +1,16 @@ +{ + "authors": ["meatball133"], + "files": { + "solution": [ + "src/task_handler.cr" + ], + "test": [ + "spec/task_handler_spec.cr" + ], + "exemplar": [ + ".meta/src/exemplar.cr" + ] + }, + "blurb": "Learn about Procs & blocks by implementing a simple task handler.", + "icon": "coordinate-transformation" +} diff --git a/exercises/concept/weighing-machine/.meta/src/exemplar.cr b/exercises/concept/weighing-machine/.meta/src/exemplar.cr new file mode 100644 index 00000000..9febc4a7 --- /dev/null +++ b/exercises/concept/weighing-machine/.meta/src/exemplar.cr @@ -0,0 +1,17 @@ +class WeighingMachine + getter precision : Int32 + setter metric : Bool + property weight : Float64 = 0.0 + + def initialize(precision : Int32, metric : Bool = true) + @precision = precision + @metric = metric + end + + # DO NOT MODIFY ANYTHING BELOW THIS LINE + def weigh(weight : Float64) : String + weight = weight.round(@precision) + weight = weight * 2.20462 unless @metric + weight + end +end diff --git a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr new file mode 100644 index 00000000..d2e1b82f --- /dev/null +++ b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr @@ -0,0 +1,35 @@ +require "spec" +require "../src/*" + +describe WeighingMachine do + describe "precision" do + it "should return the precision of the weighing machine" do + weighing_machine = WeighingMachine.new(3) + weighing_machine.precision.should eq(3) + end + + it "should return the precision of the weighing machine when precsion is 5" do + weighing_machine = WeighingMachine.new(5) + weighing_machine.precision.should eq(5) + end + end + + describe "metric" do + it "should be by default metric" do + weighing_machine = WeighingMachine.new(3) + weighing_machine.metric.should eq(true) + end + + it "should return the metric of the weighing machine when metric is false" do + weighing_machine = WeighingMachine.new(3, false) + weighing_machine.metric.should eq(false) + end + end + + describe "weight" do + it "should return the weight of the weighing machine" do + weighing_machine = WeighingMachine.new(3) + weighing_machine.weight.should eq(0.0) + end + end +end diff --git a/exercises/concept/weighing-machine/src/weighing_machine.cr b/exercises/concept/weighing-machine/src/weighing_machine.cr new file mode 100644 index 00000000..b4d95c71 --- /dev/null +++ b/exercises/concept/weighing-machine/src/weighing_machine.cr @@ -0,0 +1,10 @@ +class WeighingMachine + # Write your code here + + # DO NOT MODIFY ANYTHING BELOW THIS LINE + def weigh(weight : Float64) : String + weight = weight.round(@precision) + weight = weight * 2.20462 unless @metric + weight + end +end From 455c9ae9af44f06ac54092d8e6d94d0911b066cd Mon Sep 17 00:00:00 2001 From: Meatball Date: Fri, 26 Jul 2024 20:29:42 +0200 Subject: [PATCH 2/9] More progress --- concepts/getters-setters/.meta/template.md | 2 +- concepts/getters-setters/about.md | 2 +- concepts/getters-setters/introduction.md | 127 +++++++++--------- concepts/getters-setters/links.json | 4 +- config.json | 12 ++ exercises/concept/task-handler/.docs/test.cr | 5 + .../concept/weighing-machine/.docs/hints.md | 25 ++-- .../weighing-machine/.docs/instructions.md | 49 +++++-- .../weighing-machine/.docs/introduction.md | 96 ++++++++++++- .../weighing-machine/.meta/config.json | 9 +- .../weighing-machine/.meta/src/exemplar.cr | 6 +- .../weighing-machine/.meta/template.md | 1 + .../spec/weighing_machine_spec.cr | 86 ++++++++++-- .../weighing-machine/src/weighing_machine.cr | 6 +- 14 files changed, 313 insertions(+), 117 deletions(-) create mode 100644 exercises/concept/task-handler/.docs/test.cr create mode 100644 exercises/concept/weighing-machine/.meta/template.md diff --git a/concepts/getters-setters/.meta/template.md b/concepts/getters-setters/.meta/template.md index 72129c2c..577dbc90 100644 --- a/concepts/getters-setters/.meta/template.md +++ b/concepts/getters-setters/.meta/template.md @@ -1 +1 @@ -{% $getters-setters / $getters-setters.getter! %} +{% $getters-setters %} diff --git a/concepts/getters-setters/about.md b/concepts/getters-setters/about.md index 3facb644..e18c7e8e 100644 --- a/concepts/getters-setters/about.md +++ b/concepts/getters-setters/about.md @@ -93,4 +93,4 @@ end [getters_and_macros]: https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html#getters-and-setters [getter]: https://crystal-lang.org/api/Object.html#getter%28%2Anames%2C%26block%29-macro [setter]: https://crystal-lang.org/api/Object.html#setter%28%2Anames%29-macro -[property]: https://crystal-lang.org/api/Object.html#property%28%2Anames%2C%26block%29-macro \ No newline at end of file +[property]: https://crystal-lang.org/api/Object.html#property%28%2Anames%2C%26block%29-macro diff --git a/concepts/getters-setters/introduction.md b/concepts/getters-setters/introduction.md index 5e2d5472..8d8e38ec 100644 --- a/concepts/getters-setters/introduction.md +++ b/concepts/getters-setters/introduction.md @@ -1,102 +1,95 @@ -# Modules +# Getters and setters -[Modules][modules] in Crystal serve 2 purposes: +Getters and setters are methods that allow you to read and write the value of an object's property. +Crystal has macros which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time and will be covered later in the macro concept. -The first purpose is to create a [namespace][namespace] to avoid name collisions. -But it also forms as a form of grouping code together, this is to make it easier to understand what the code is for. +In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. +Crystal has defined these as `getter`, `setter` and `property` macros. -The second purpose is to define [mixins][mixin] to share code to types. +## Getters -Modules have similarities to classes, but the main difference is that modules cannot be instantiated, and thereby don't have instance variables. +Getter is a macro that defines a method that returns the value of an instance variable. +This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. -To declare a module you use the `module` keyword followed by the name of the module. +The getter macro can accept multiple instance variables by separating them with a comma. ```crystal -module Foo -end -``` - -## Namespace +# This: +class Person + @nane : String + @age : Int32 -A namespace is a way to group code together, this is to avoid name clashes, but also to make it easier to understand what the code is for. -When wanting to access for example a constant or a class that has been placed inside a namespace you use the `::` operator. + def name + @name + end -```crystal -module Foo - class Bar + def age + @age end end -Foo::Bar.new -``` +# Is the same as this: +class Person + @name : String + @age : Int32 -## Use it as a mixin + getter name, :age +end +``` -This can be useful when, for example, wanting multiple classes to have the same "base" functionality or when wanting to share code between classes that are not related. -Or when wanting to share code between classes that are not related. +As you can see using getter reduces the amount of code you have to write and makes it easier to read. +Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. +Symbols will be covered later in the symbols concept. -There are 2 different ways to use a module as a mixin: the first one is to use the `include` keyword, the second one is to use the `extend` keyword. +## Setters -Both methods will make constants available to the type that includes or extends the module. +Setters is a macro that defines a method that sets the value of an instance variable. +This macro isnt that often found and more commonly is the `property` macro used. +The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. -### Include +This method defintion is a bit special since the argument the method recive is after the `=` sign. +There are several other special methods in Crystal that uses this syntax, like the `+` method for example. -Include will make all methods in the module available as instance methods on the type that includes the module. -The `include` keyword should be written at the top of the type, followed by the name of the module. +As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. ```crystal -module Foo - def foo - "foo" - end -end - -class Bar - include Foo -end - -Bar.new.foo # => "foo" -``` +# This: +class Person + @name : String + @age : Int32 -### Extend - -Extend works similarly to include, but instead of making the methods available as instance methods, it makes them available as class methods. -The `extend` keyword should be written at the top of the type followed by the name of the module. + def name=(name : String) + @name = name + end -```crystal -module Foo - def foo - "foo" + def age=(age : Int32) + @age = age end end -class Bar - extend Foo -end +# Is the same as this: +class Person + @name : String + @age : Int32 -Bar.foo # => "foo" + setter name, :age +end ``` -## Extend self - -A quite common pattern in Crystal is to use the [`extend self`][extend self] pattern, in a module. -This will make all methods in the module available as class methods on the module itself. -This means you don't have to assign each method to the module itself using the `def self.method_name` syntax. +## Property +Property is a macro that defines both a getter and a setter for an instance variable. ```crystal -module Foo - extend self +class Person + @name : String + @age : Int32 - def foo - "foo" - end + property name, :age end - -Foo.foo # => "foo" ``` -[mixin]: https://en.wikipedia.org/wiki/Mixin -[modules]: https://crystal-lang.org/reference/syntax_and_semantics/modules.html -[extend self]: https://crystal-lang.org/reference/syntax_and_semantics/modules.html#extend-self -[namespace]: https://en.wikipedia.org/wiki/Namespace +[getter]: https://crystal-lang.org/api/Object.html#getter%28%2Anames%2C%26block%29-macro +[setter]: https://crystal-lang.org/api/Object.html#setter%28%2Anames%29-macro +[property]: https://crystal-lang.org/api/Object.html#property%28%2Anames%2C%26block%29-macro diff --git a/concepts/getters-setters/links.json b/concepts/getters-setters/links.json index 8779e02c..82eefaab 100644 --- a/concepts/getters-setters/links.json +++ b/concepts/getters-setters/links.json @@ -1,6 +1,6 @@ [ { - "url": "https://crystal-lang.org/reference/latest/syntax_and_semantics/modules.html", - "description": "Crystal docs: modules" + "url": "https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html#getters-and-setters", + "description": "Crystal docs: getters and setters" } ] diff --git a/config.json b/config.json index c288fbc8..7ae24978 100644 --- a/config.json +++ b/config.json @@ -277,6 +277,18 @@ "array-methods" ], "status": "beta" + }, + { + "slug": "weighing-machine", + "name": "Weighing Machine", + "uuid": "317930f4-4c97-4962-a04e-76e6d60b7fba", + "concepts": [ + "getter-setter" + ], + "prerequisites": [ + "strings" + ], + "status": "beta" } ], "practice": [ diff --git a/exercises/concept/task-handler/.docs/test.cr b/exercises/concept/task-handler/.docs/test.cr new file mode 100644 index 00000000..5862b662 --- /dev/null +++ b/exercises/concept/task-handler/.docs/test.cr @@ -0,0 +1,5 @@ +def my_method(&block : Int32, Int32 -> Int32) + 1 + yield(2, 3) + end + +p my_method { |x, y| x * y } \ No newline at end of file diff --git a/exercises/concept/weighing-machine/.docs/hints.md b/exercises/concept/weighing-machine/.docs/hints.md index 157f47f4..5ff25eae 100644 --- a/exercises/concept/weighing-machine/.docs/hints.md +++ b/exercises/concept/weighing-machine/.docs/hints.md @@ -2,20 +2,23 @@ ## General -- To access and define instance variables you write `@` followed by the name of the variable. +- To creat the getter and setter methods you should use the `getter`, `setter` and `property` macros. -## 1. Initialize `TaskHandler` +## 1. Create an initial state for the weighing machine -- To create a `Proc` use the `-> (args) { block }` syntax. -- When a `Proc` is defined for an instance variable, it needs to be explicitly typed. - This can be done by adding `: Proc(, )` after the variable name. - Or `-> (arg_1 : ) : { block }` syntax. -- The `Proc` should compare if the argument is greater than or equal to 0. +- To initialize the weighing machine you should use the `initialize` method. +- The method should take two arguments, `precision` and `metric` which should be a `Int32` and `Bool` respectively. + These should be used to set the instance variables `@precision` and `@metric`. +- The instance variable `@weight` should be set to `0.0`. -## 2. Update the task condition logic +## 2. Allow the weighing machine to have a precision -- The method should take a block as an argument and assign it to the `@task_condition_logic` instance variable. +- The `getter` macro allows you to define a method that returns the value of an instance variable. -## 3. Execute the next task +## 3. Allow the weight to be set on the weighing machine -- To execute a `Proc` you can use the `call` method which accepts the arguments for the proc. +- The `property` macro allows you to define a method that gets and sets the value of an instance variable. + +## 4. Allow the machine to be switch between metric and imperial units + +- The `setter` macro allows you to define a method that sets the value of an instance variable. diff --git a/exercises/concept/weighing-machine/.docs/instructions.md b/exercises/concept/weighing-machine/.docs/instructions.md index 62563626..e50885a6 100644 --- a/exercises/concept/weighing-machine/.docs/instructions.md +++ b/exercises/concept/weighing-machine/.docs/instructions.md @@ -1,28 +1,34 @@ # Instructions -In this exercise you'll be modelling a weighing machine with Kilograms as a Unit. +In this exercise you'll be modelling a weighing machine. -## 1. Allow the weighing machine to have a precision +## 1. Create an initial state for the weighing machine -To cater to different demands, we allow each weighing machine to be customized with a precision (the number of digits after the decimal separator). +The weighing machine when initalized should refer to its factory settings which is different for where the machine is sold. +Thereby the machine should be able to be initialized with a precision and if it is metric or imperial. -Implement the `WeighingMachine#precision` getter method to return the precision of the weighing machine. +Implement the `WeighingMachine#initialize` method which takes two arguments, `precision` which is an `Int32` and `metric` which is a `Bool`. +The `metric` argument when `true` means that the machine should use the metric system, otherwise it should use the imperial system. +The initizalized set should also set an instance variable, `@weight` to `0.0`. ```crystal precision = 3 -vm = WeighingMachine.new(precision) -vm.precision -# => 3 +metric = true +vm = WeighingMachine.new(precision, metric) ``` -## 2. Allow the machine to be switch between metric and imperial units +## 2. Allow the weighing machine to have a precision -Implement the `WeighingMachine#metric=` property to allow the unit to be set, it should accept a boolean value. +To cater to different demands, we allow each weighing machine to be customized with a precision (the number of digits after the decimal separator). + +Implement the `WeighingMachine#precision` getter method to return the precision of the weighing machine. ```crystal precision = 3 -wm = WeighingMachine.new(3) -wm.metric = false +metric = true +vm = WeighingMachine.new(precision, metric) +vm.precision +# => 3 ``` ## 3. Allow the weight to be set on the weighing machine @@ -31,8 +37,27 @@ Implement the `WeighingMachine#weight` property to allow the weight to be get _a ```crystal precision = 3 -wm = WeighingMachine.new(3) +metric = true +wm = WeighingMachine.new(precision, metric) wm.weight = 60.5 wm.weight # => 60.5 + +wm.weigh +# => 60.5 +``` + +## 4. Allow the machine to be switch between metric and imperial units + +Implement the `WeighingMachine#metric=` property to allow the unit to be set, it should accept a boolean value. + +```crystal +precision = 3 +metric = true +wm = WeighingMachine.new(precision, metric) +vm.weight = 60.5 +wm.metric = false + +vm.weigh +# => 133.377 ``` diff --git a/exercises/concept/weighing-machine/.docs/introduction.md b/exercises/concept/weighing-machine/.docs/introduction.md index f87f5c14..8d8e38ec 100644 --- a/exercises/concept/weighing-machine/.docs/introduction.md +++ b/exercises/concept/weighing-machine/.docs/introduction.md @@ -1 +1,95 @@ -# TODO \ No newline at end of file +# Getters and setters + +Getters and setters are methods that allow you to read and write the value of an object's property. +Crystal has macros which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time and will be covered later in the macro concept. + +In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. +Crystal has defined these as `getter`, `setter` and `property` macros. + +## Getters + +Getter is a macro that defines a method that returns the value of an instance variable. +This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. + +The getter macro can accept multiple instance variables by separating them with a comma. + +```crystal +# This: +class Person + @nane : String + @age : Int32 + + def name + @name + end + + def age + @age + end +end + +# Is the same as this: +class Person + @name : String + @age : Int32 + + getter name, :age +end +``` + +As you can see using getter reduces the amount of code you have to write and makes it easier to read. +Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. +Symbols will be covered later in the symbols concept. + +## Setters + +Setters is a macro that defines a method that sets the value of an instance variable. +This macro isnt that often found and more commonly is the `property` macro used. +The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. + +This method defintion is a bit special since the argument the method recive is after the `=` sign. +There are several other special methods in Crystal that uses this syntax, like the `+` method for example. + +As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. + +```crystal +# This: +class Person + @name : String + @age : Int32 + + def name=(name : String) + @name = name + end + + def age=(age : Int32) + @age = age + end +end + +# Is the same as this: +class Person + @name : String + @age : Int32 + + setter name, :age +end +``` + +## Property + +Property is a macro that defines both a getter and a setter for an instance variable. + +```crystal +class Person + @name : String + @age : Int32 + + property name, :age +end +``` + +[getter]: https://crystal-lang.org/api/Object.html#getter%28%2Anames%2C%26block%29-macro +[setter]: https://crystal-lang.org/api/Object.html#setter%28%2Anames%29-macro +[property]: https://crystal-lang.org/api/Object.html#property%28%2Anames%2C%26block%29-macro diff --git a/exercises/concept/weighing-machine/.meta/config.json b/exercises/concept/weighing-machine/.meta/config.json index 60c00870..738cfb17 100644 --- a/exercises/concept/weighing-machine/.meta/config.json +++ b/exercises/concept/weighing-machine/.meta/config.json @@ -2,15 +2,16 @@ "authors": ["meatball133"], "files": { "solution": [ - "src/task_handler.cr" + "src/weighing_machine.cr" ], "test": [ - "spec/task_handler_spec.cr" + "spec/weighing_machine_spec.cr" ], "exemplar": [ ".meta/src/exemplar.cr" ] }, - "blurb": "Learn about Procs & blocks by implementing a simple task handler.", - "icon": "coordinate-transformation" + "blurb": "Learn about getter and setters by implementing a weighing machine.", + "icon": "weighing-machine", + "forked_from": ["csharp/weighing-machine"] } diff --git a/exercises/concept/weighing-machine/.meta/src/exemplar.cr b/exercises/concept/weighing-machine/.meta/src/exemplar.cr index 9febc4a7..ad7a15a6 100644 --- a/exercises/concept/weighing-machine/.meta/src/exemplar.cr +++ b/exercises/concept/weighing-machine/.meta/src/exemplar.cr @@ -9,9 +9,9 @@ class WeighingMachine end # DO NOT MODIFY ANYTHING BELOW THIS LINE - def weigh(weight : Float64) : String + def weigh : String + weight = @metric ? @weight : @weight * 2.20462 weight = weight.round(@precision) - weight = weight * 2.20462 unless @metric - weight + weight.to_s end end diff --git a/exercises/concept/weighing-machine/.meta/template.md b/exercises/concept/weighing-machine/.meta/template.md new file mode 100644 index 00000000..577dbc90 --- /dev/null +++ b/exercises/concept/weighing-machine/.meta/template.md @@ -0,0 +1 @@ +{% $getters-setters %} diff --git a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr index d2e1b82f..4df27088 100644 --- a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr +++ b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr @@ -2,34 +2,96 @@ require "spec" require "../src/*" describe WeighingMachine do + describe "initialize" do + it "should initialize the weighing machine with precision 3" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.@precision.should eq(3) + weighing_machine.@metric.should be_true + weighing_machine.@weight.should eq(0.0) + end + + it "should initialize the weighing machine with precision 5 and metric be true" do + weighing_machine = WeighingMachine.new(5, true) + weighing_machine.@precision.should eq(5) + weighing_machine.@metric.should be_true + weighing_machine.@weight.should eq(0.0) + end + + it "should initialize the weighing machine with precision 3 and metric false" do + weighing_machine = WeighingMachine.new(3, false) + weighing_machine.@precision.should eq(3) + weighing_machine.@metric.should be_false + weighing_machine.@weight.should eq(0.0) + end + + it "should allow the weigh method to be called" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.weigh.should eq("0.0") + end + end + + describe "precision" do it "should return the precision of the weighing machine" do - weighing_machine = WeighingMachine.new(3) + weighing_machine = WeighingMachine.new(3, true) weighing_machine.precision.should eq(3) end it "should return the precision of the weighing machine when precsion is 5" do - weighing_machine = WeighingMachine.new(5) + weighing_machine = WeighingMachine.new(5, true) weighing_machine.precision.should eq(5) end + + it "should not allowed to be modify" do + {% if WeighingMachine.has_method? "precision=" %} + raise "Error: precision should not have a setter" + {% end %} + end + end + + describe "weight" do + it "should return the weight of the weighing machine" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.weight.should eq(0.0) + end + + it "should return the weight of the weighing machine when weight is 5.0" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.weight = 5.0 + weighing_machine.weight.should eq(5.0) + end + + it "should work to call weigh method" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.weight = 5.0 + weighing_machine.weigh.should eq("5.0") + end end describe "metric" do - it "should be by default metric" do - weighing_machine = WeighingMachine.new(3) - weighing_machine.metric.should eq(true) + it "should be able to change to imperial" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.metric = false + weighing_machine.@metric.should eq(false) end - it "should return the metric of the weighing machine when metric is false" do + it "should allow the initial to be imperial and then change to metric" do weighing_machine = WeighingMachine.new(3, false) - weighing_machine.metric.should eq(false) + weighing_machine.metric = true + weighing_machine.@metric.should eq(true) end - end - describe "weight" do - it "should return the weight of the weighing machine" do - weighing_machine = WeighingMachine.new(3) - weighing_machine.weight.should eq(0.0) + it "should affect the weigh method" do + weighing_machine = WeighingMachine.new(3, true) + weighing_machine.weight = 5.0 + weighing_machine.metric = false + weighing_machine.weigh.should eq("11.023") + end + + it "should not allowed to be get" do + {% if WeighingMachine.has_method? "metric" %} + raise "Error: metric should not have a getter" + {% end %} end end end diff --git a/exercises/concept/weighing-machine/src/weighing_machine.cr b/exercises/concept/weighing-machine/src/weighing_machine.cr index b4d95c71..13f94d68 100644 --- a/exercises/concept/weighing-machine/src/weighing_machine.cr +++ b/exercises/concept/weighing-machine/src/weighing_machine.cr @@ -2,9 +2,9 @@ class WeighingMachine # Write your code here # DO NOT MODIFY ANYTHING BELOW THIS LINE - def weigh(weight : Float64) : String + def weigh : String + weight = @metric ? @weight : @weight * 2.20462 weight = weight.round(@precision) - weight = weight * 2.20462 unless @metric - weight + weight.to_s end end From cdb63e5d76e85cc01d4427143dbc3b68a96c0d68 Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:43:38 +0000 Subject: [PATCH 3/9] Update config and concept text --- concepts/getters-setters/about.md | 44 +++++++++---------- concepts/getters-setters/introduction.md | 44 +++++++++---------- config.json | 29 +++++++----- .../weighing-machine/.docs/introduction.md | 44 +++++++++---------- 4 files changed, 83 insertions(+), 78 deletions(-) diff --git a/concepts/getters-setters/about.md b/concepts/getters-setters/about.md index e18c7e8e..969091ae 100644 --- a/concepts/getters-setters/about.md +++ b/concepts/getters-setters/about.md @@ -1,8 +1,8 @@ # Getters and setters Getters and setters are methods that allow you to read and write the value of an object's property. -Crystal has macros which makes it easy to define getters and setters for a property. -Macros are a way to generate code at compile time and will be covered later in the macro concept. +Crystal has macros, which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time, which will be covered later in the macro concept. In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. Crystal has defined these as `getter`, `setter` and `property` macros. @@ -10,7 +10,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. ## Getters Getter is a macro that defines a method that returns the value of an instance variable. -This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. +This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. The getter macro can accept multiple instance variables by separating them with a comma. @@ -20,13 +20,13 @@ class Person @nane : String @age : Int32 - def name +  def name @name - end +  end - def age +  def age @age - end +  end end # Is the same as this: @@ -34,24 +34,24 @@ class Person @name : String @age : Int32 - getter name, :age +  getter name, :age end ``` -As you can see using getter reduces the amount of code you have to write and makes it easier to read. -Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. -Symbols will be covered later in the symbols concept. +As you can see, using getter reduces the amount of code you write and makes it easier to read. +Also, Ruby and Crystal differ in that Crystal accepts both the variable name and symbol as arguments for the getter macro. +Symbols will be covered later in the symbol concept. ## Setters Setters is a macro that defines a method that sets the value of an instance variable. -This macro isnt that often found and more commonly is the `property` macro used. -The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. +This macro isn't that often found and is commonly the `property` macro used instead. +The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. -This method defintion is a bit special since the argument the method recive is after the `=` sign. -There are several other special methods in Crystal that uses this syntax, like the `+` method for example. +This method definition is a bit special since the argument the method receives is after the `=` sign. +Several other special methods in Crystal use this syntax, like the `+` method. -As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. +As with the getter macro, when you want to update the value of an instance variable after defining a setter, you can call the method that the setter macro has defined. ```crystal # This: @@ -59,13 +59,13 @@ class Person @name : String @age : Int32 - def name=(name : String) +  def name=(name : String) @name = name - end +  end - def age=(age : Int32) +  def age=(age : Int32) @age = age - end +  end end # Is the same as this: @@ -73,7 +73,7 @@ class Person @name : String @age : Int32 - setter name, :age +  setter name, :age end ``` @@ -86,7 +86,7 @@ class Person @name : String @age : Int32 - property name, :age +  property name, :age end ``` diff --git a/concepts/getters-setters/introduction.md b/concepts/getters-setters/introduction.md index 8d8e38ec..01a5024b 100644 --- a/concepts/getters-setters/introduction.md +++ b/concepts/getters-setters/introduction.md @@ -1,8 +1,8 @@ # Getters and setters Getters and setters are methods that allow you to read and write the value of an object's property. -Crystal has macros which makes it easy to define getters and setters for a property. -Macros are a way to generate code at compile time and will be covered later in the macro concept. +Crystal has macros, which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time, which will be covered later in the macro concept. In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. Crystal has defined these as `getter`, `setter` and `property` macros. @@ -10,7 +10,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. ## Getters Getter is a macro that defines a method that returns the value of an instance variable. -This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. +This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. The getter macro can accept multiple instance variables by separating them with a comma. @@ -20,13 +20,13 @@ class Person @nane : String @age : Int32 - def name +  def name @name - end +  end - def age +  def age @age - end +  end end # Is the same as this: @@ -34,24 +34,24 @@ class Person @name : String @age : Int32 - getter name, :age +  getter name, :age end ``` -As you can see using getter reduces the amount of code you have to write and makes it easier to read. -Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. -Symbols will be covered later in the symbols concept. +As you can see, using getter reduces the amount of code you write and makes it easier to read. +Also, Ruby and Crystal differ in that Crystal accepts both the variable name and symbol as arguments for the getter macro. +Symbols will be covered later in the symbol concept. ## Setters Setters is a macro that defines a method that sets the value of an instance variable. -This macro isnt that often found and more commonly is the `property` macro used. -The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. +This macro isn't that often found and is commonly the `property` macro used instead. +The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. -This method defintion is a bit special since the argument the method recive is after the `=` sign. -There are several other special methods in Crystal that uses this syntax, like the `+` method for example. +This method definition is a bit special since the argument the method receives is after the `=` sign. +Several other special methods in Crystal use this syntax, like the `+` method. -As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. +As with the getter macro, when you want to update the value of an instance variable after defining a setter, you can call the method that the setter macro has defined. ```crystal # This: @@ -59,13 +59,13 @@ class Person @name : String @age : Int32 - def name=(name : String) +  def name=(name : String) @name = name - end +  end - def age=(age : Int32) +  def age=(age : Int32) @age = age - end +  end end # Is the same as this: @@ -73,7 +73,7 @@ class Person @name : String @age : Int32 - setter name, :age +  setter name, :age end ``` @@ -86,7 +86,7 @@ class Person @name : String @age : Int32 - property name, :age +  property name, :age end ``` diff --git a/config.json b/config.json index 7ae24978..1492f886 100644 --- a/config.json +++ b/config.json @@ -105,6 +105,18 @@ ], "status": "beta" }, + { + "slug": "weighing-machine", + "name": "Weighing Machine", + "uuid": "317930f4-4c97-4962-a04e-76e6d60b7fba", + "concepts": [ + "getter-setter" + ], + "prerequisites": [ + "strings" + ], + "status": "beta" + }, { "slug": "high-school-sweetheart", "name": "High School Sweetheart", @@ -277,18 +289,6 @@ "array-methods" ], "status": "beta" - }, - { - "slug": "weighing-machine", - "name": "Weighing Machine", - "uuid": "317930f4-4c97-4962-a04e-76e6d60b7fba", - "concepts": [ - "getter-setter" - ], - "prerequisites": [ - "strings" - ], - "status": "beta" } ], "practice": [ @@ -1495,6 +1495,11 @@ "slug": "strings", "name": "Strings" }, + { + "uuid": "b5f40f9a-d3bf-4e82-9918-a04649f08655", + "slug": "getter-setter", + "name": "Getter and Setter" + }, { "uuid": "4dd28cdc-f197-490b-bbfb-5cd33bbdb6af", "slug": "binary-octal-hexadecimal", diff --git a/exercises/concept/weighing-machine/.docs/introduction.md b/exercises/concept/weighing-machine/.docs/introduction.md index 8d8e38ec..01a5024b 100644 --- a/exercises/concept/weighing-machine/.docs/introduction.md +++ b/exercises/concept/weighing-machine/.docs/introduction.md @@ -1,8 +1,8 @@ # Getters and setters Getters and setters are methods that allow you to read and write the value of an object's property. -Crystal has macros which makes it easy to define getters and setters for a property. -Macros are a way to generate code at compile time and will be covered later in the macro concept. +Crystal has macros, which makes it easy to define getters and setters for a property. +Macros are a way to generate code at compile time, which will be covered later in the macro concept. In Ruby these methods are defined using the `attr_reader`, `attr_writer` and `attr_accessor` methods and are very similar to Crystals implementation on the surface. Crystal has defined these as `getter`, `setter` and `property` macros. @@ -10,7 +10,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. ## Getters Getter is a macro that defines a method that returns the value of an instance variable. -This makes so you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding intillize), instead you can call the method that the getter macro has defined. +This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. The getter macro can accept multiple instance variables by separating them with a comma. @@ -20,13 +20,13 @@ class Person @nane : String @age : Int32 - def name +  def name @name - end +  end - def age +  def age @age - end +  end end # Is the same as this: @@ -34,24 +34,24 @@ class Person @name : String @age : Int32 - getter name, :age +  getter name, :age end ``` -As you can see using getter reduces the amount of code you have to write and makes it easier to read. -Also a difference between Ruby and Crystal is that Crystal accepts both the variable name and symbol as arguments to the getter macro. -Symbols will be covered later in the symbols concept. +As you can see, using getter reduces the amount of code you write and makes it easier to read. +Also, Ruby and Crystal differ in that Crystal accepts both the variable name and symbol as arguments for the getter macro. +Symbols will be covered later in the symbol concept. ## Setters Setters is a macro that defines a method that sets the value of an instance variable. -This macro isnt that often found and more commonly is the `property` macro used. -The methods which will be created will look like `name_of_method=`, the `=` is what makes so the property can be set. +This macro isn't that often found and is commonly the `property` macro used instead. +The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. -This method defintion is a bit special since the argument the method recive is after the `=` sign. -There are several other special methods in Crystal that uses this syntax, like the `+` method for example. +This method definition is a bit special since the argument the method receives is after the `=` sign. +Several other special methods in Crystal use this syntax, like the `+` method. -As with the getter macro when you want to update the value of an instance variable after defining a setter you can call the method that the setter macro has defined. +As with the getter macro, when you want to update the value of an instance variable after defining a setter, you can call the method that the setter macro has defined. ```crystal # This: @@ -59,13 +59,13 @@ class Person @name : String @age : Int32 - def name=(name : String) +  def name=(name : String) @name = name - end +  end - def age=(age : Int32) +  def age=(age : Int32) @age = age - end +  end end # Is the same as this: @@ -73,7 +73,7 @@ class Person @name : String @age : Int32 - setter name, :age +  setter name, :age end ``` @@ -86,7 +86,7 @@ class Person @name : String @age : Int32 - property name, :age +  property name, :age end ``` From 3980f34dd0aa70e8de000afa63f7707e0cfddd3c Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:44:40 +0000 Subject: [PATCH 4/9] Fix config --- concepts/getters-setters/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/getters-setters/.meta/config.json b/concepts/getters-setters/.meta/config.json index 4365f0b2..1bc4bc97 100644 --- a/concepts/getters-setters/.meta/config.json +++ b/concepts/getters-setters/.meta/config.json @@ -1,5 +1,5 @@ { "blurb": "Crystal has macros for defining getters and setters. Which is used to access and modify the instance variables of a class.", "authors": ["meatball133"], - "contributors": [""] + "contributors": [] } From 628cefbb92f4e836831da10d1294ea93b51fe288 Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:47:11 +0000 Subject: [PATCH 5/9] Fix config name --- config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 1492f886..8e03f89b 100644 --- a/config.json +++ b/config.json @@ -110,7 +110,7 @@ "name": "Weighing Machine", "uuid": "317930f4-4c97-4962-a04e-76e6d60b7fba", "concepts": [ - "getter-setter" + "getters-setters" ], "prerequisites": [ "strings" @@ -1497,8 +1497,8 @@ }, { "uuid": "b5f40f9a-d3bf-4e82-9918-a04649f08655", - "slug": "getter-setter", - "name": "Getter and Setter" + "slug": "getters-setters", + "name": "Getters and Setters" }, { "uuid": "4dd28cdc-f197-490b-bbfb-5cd33bbdb6af", From 646f1545ff569d23263ee6563a2333cf92c4d2d2 Mon Sep 17 00:00:00 2001 From: meatball Date: Tue, 13 Aug 2024 22:51:45 +0200 Subject: [PATCH 6/9] Fix formatting --- exercises/concept/weighing-machine/.meta/src/exemplar.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/weighing-machine/.meta/src/exemplar.cr b/exercises/concept/weighing-machine/.meta/src/exemplar.cr index ad7a15a6..7ebe42ec 100644 --- a/exercises/concept/weighing-machine/.meta/src/exemplar.cr +++ b/exercises/concept/weighing-machine/.meta/src/exemplar.cr @@ -2,7 +2,7 @@ class WeighingMachine getter precision : Int32 setter metric : Bool property weight : Float64 = 0.0 - + def initialize(precision : Int32, metric : Bool = true) @precision = precision @metric = metric From f950f395ee0573ad5683b3d01ba9d77442ccd363 Mon Sep 17 00:00:00 2001 From: meatball Date: Tue, 13 Aug 2024 22:53:11 +0200 Subject: [PATCH 7/9] Fix formatting again --- exercises/concept/weighing-machine/spec/weighing_machine_spec.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr index 4df27088..2c88e10e 100644 --- a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr +++ b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr @@ -30,7 +30,6 @@ describe WeighingMachine do end end - describe "precision" do it "should return the precision of the weighing machine" do weighing_machine = WeighingMachine.new(3, true) From 2ae574472d54e704293d6881f8a61ec725def3a1 Mon Sep 17 00:00:00 2001 From: meatball Date: Sat, 17 Aug 2024 16:01:14 +0200 Subject: [PATCH 8/9] Changes based on feedback --- concepts/getters-setters/.meta/config.json | 4 ++-- concepts/getters-setters/about.md | 4 ++-- concepts/getters-setters/introduction.md | 4 ++-- exercises/concept/task-handler/.docs/test.cr | 5 ----- exercises/concept/weighing-machine/.docs/hints.md | 4 ++-- exercises/concept/weighing-machine/.docs/instructions.md | 9 +++++---- exercises/concept/weighing-machine/.docs/introduction.md | 4 ++-- exercises/concept/weighing-machine/.meta/config.json | 1 + .../weighing-machine/spec/weighing_machine_spec.cr | 4 ++-- 9 files changed, 18 insertions(+), 21 deletions(-) delete mode 100644 exercises/concept/task-handler/.docs/test.cr diff --git a/concepts/getters-setters/.meta/config.json b/concepts/getters-setters/.meta/config.json index 1bc4bc97..b5cf3f2b 100644 --- a/concepts/getters-setters/.meta/config.json +++ b/concepts/getters-setters/.meta/config.json @@ -1,5 +1,5 @@ { - "blurb": "Crystal has macros for defining getters and setters. Which is used to access and modify the instance variables of a class.", + "blurb": "Crystal has macros for defining getters and setters. These are used to access and modify the instance variables of a class.", "authors": ["meatball133"], - "contributors": [] + "contributors": ["ryanplusplus"] } diff --git a/concepts/getters-setters/about.md b/concepts/getters-setters/about.md index 969091ae..1bbdec87 100644 --- a/concepts/getters-setters/about.md +++ b/concepts/getters-setters/about.md @@ -12,7 +12,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. Getter is a macro that defines a method that returns the value of an instance variable. This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. -The getter macro can accept multiple instance variables by separating them with a comma. +The getter macro can accept multiple instance variables by separating them with commas. ```crystal # This: @@ -44,7 +44,7 @@ Symbols will be covered later in the symbol concept. ## Setters -Setters is a macro that defines a method that sets the value of an instance variable. +Setter is a macro that defines a method that sets the value of an instance variable. This macro isn't that often found and is commonly the `property` macro used instead. The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. diff --git a/concepts/getters-setters/introduction.md b/concepts/getters-setters/introduction.md index 01a5024b..adc75f71 100644 --- a/concepts/getters-setters/introduction.md +++ b/concepts/getters-setters/introduction.md @@ -12,7 +12,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. Getter is a macro that defines a method that returns the value of an instance variable. This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. -The getter macro can accept multiple instance variables by separating them with a comma. +The getter macro can accept multiple instance variables by separating them with commas. ```crystal # This: @@ -44,7 +44,7 @@ Symbols will be covered later in the symbol concept. ## Setters -Setters is a macro that defines a method that sets the value of an instance variable. +Setter is a macro that defines a method that sets the value of an instance variable. This macro isn't that often found and is commonly the `property` macro used instead. The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. diff --git a/exercises/concept/task-handler/.docs/test.cr b/exercises/concept/task-handler/.docs/test.cr deleted file mode 100644 index 5862b662..00000000 --- a/exercises/concept/task-handler/.docs/test.cr +++ /dev/null @@ -1,5 +0,0 @@ -def my_method(&block : Int32, Int32 -> Int32) - 1 + yield(2, 3) - end - -p my_method { |x, y| x * y } \ No newline at end of file diff --git a/exercises/concept/weighing-machine/.docs/hints.md b/exercises/concept/weighing-machine/.docs/hints.md index 5ff25eae..ee3362cc 100644 --- a/exercises/concept/weighing-machine/.docs/hints.md +++ b/exercises/concept/weighing-machine/.docs/hints.md @@ -2,12 +2,12 @@ ## General -- To creat the getter and setter methods you should use the `getter`, `setter` and `property` macros. +- To create the getter and setter methods you should use the `getter`, `setter` and `property` macros. ## 1. Create an initial state for the weighing machine - To initialize the weighing machine you should use the `initialize` method. -- The method should take two arguments, `precision` and `metric` which should be a `Int32` and `Bool` respectively. +- The method should take two arguments, `precision` and `metric`, which should be an `Int32` and `Bool`, respectively. These should be used to set the instance variables `@precision` and `@metric`. - The instance variable `@weight` should be set to `0.0`. diff --git a/exercises/concept/weighing-machine/.docs/instructions.md b/exercises/concept/weighing-machine/.docs/instructions.md index e50885a6..49626ab7 100644 --- a/exercises/concept/weighing-machine/.docs/instructions.md +++ b/exercises/concept/weighing-machine/.docs/instructions.md @@ -1,15 +1,15 @@ # Instructions -In this exercise you'll be modelling a weighing machine. +In this exercise you'll be modeling a weighing machine. ## 1. Create an initial state for the weighing machine -The weighing machine when initalized should refer to its factory settings which is different for where the machine is sold. +When initialized, the weighing machine should refer to its factory settings which is different for where the machine is sold. Thereby the machine should be able to be initialized with a precision and if it is metric or imperial. Implement the `WeighingMachine#initialize` method which takes two arguments, `precision` which is an `Int32` and `metric` which is a `Bool`. The `metric` argument when `true` means that the machine should use the metric system, otherwise it should use the imperial system. -The initizalized set should also set an instance variable, `@weight` to `0.0`. +The initialize method set should also set the instance variable `@weight` to `0.0`. ```crystal precision = 3 @@ -49,7 +49,8 @@ wm.weigh ## 4. Allow the machine to be switch between metric and imperial units -Implement the `WeighingMachine#metric=` property to allow the unit to be set, it should accept a boolean value. +Implement the `WeighingMachine#metric=` property to allow the unit to be set. +It should accept a boolean value. ```crystal precision = 3 diff --git a/exercises/concept/weighing-machine/.docs/introduction.md b/exercises/concept/weighing-machine/.docs/introduction.md index 01a5024b..adc75f71 100644 --- a/exercises/concept/weighing-machine/.docs/introduction.md +++ b/exercises/concept/weighing-machine/.docs/introduction.md @@ -12,7 +12,7 @@ Crystal has defined these as `getter`, `setter` and `property` macros. Getter is a macro that defines a method that returns the value of an instance variable. This means that you no longer have to write `@` in front of the instance variable when you want to access it (in methods, excluding initialize); instead, you can call the method that the getter macro has defined. -The getter macro can accept multiple instance variables by separating them with a comma. +The getter macro can accept multiple instance variables by separating them with commas. ```crystal # This: @@ -44,7 +44,7 @@ Symbols will be covered later in the symbol concept. ## Setters -Setters is a macro that defines a method that sets the value of an instance variable. +Setter is a macro that defines a method that sets the value of an instance variable. This macro isn't that often found and is commonly the `property` macro used instead. The methods that will be created will look like `name_of_method=`; the `=` is what makes it so the property can be set. diff --git a/exercises/concept/weighing-machine/.meta/config.json b/exercises/concept/weighing-machine/.meta/config.json index 738cfb17..edb2b14f 100644 --- a/exercises/concept/weighing-machine/.meta/config.json +++ b/exercises/concept/weighing-machine/.meta/config.json @@ -1,5 +1,6 @@ { "authors": ["meatball133"], + "contributors": "ryanplusplus", "files": { "solution": [ "src/weighing_machine.cr" diff --git a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr index 2c88e10e..c4b602c8 100644 --- a/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr +++ b/exercises/concept/weighing-machine/spec/weighing_machine_spec.cr @@ -41,7 +41,7 @@ describe WeighingMachine do weighing_machine.precision.should eq(5) end - it "should not allowed to be modify" do + it "should not allow modification" do {% if WeighingMachine.has_method? "precision=" %} raise "Error: precision should not have a setter" {% end %} @@ -87,7 +87,7 @@ describe WeighingMachine do weighing_machine.weigh.should eq("11.023") end - it "should not allowed to be get" do + it "should not allow getting" do {% if WeighingMachine.has_method? "metric" %} raise "Error: metric should not have a getter" {% end %} From 1cefbddb29e6be4c07a65d1eebccdccee6b1f025 Mon Sep 17 00:00:00 2001 From: meatball Date: Sat, 17 Aug 2024 16:08:03 +0200 Subject: [PATCH 9/9] Update config --- exercises/concept/weighing-machine/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/weighing-machine/.meta/config.json b/exercises/concept/weighing-machine/.meta/config.json index edb2b14f..cfc76eed 100644 --- a/exercises/concept/weighing-machine/.meta/config.json +++ b/exercises/concept/weighing-machine/.meta/config.json @@ -1,6 +1,6 @@ { "authors": ["meatball133"], - "contributors": "ryanplusplus", + "contributors": ["ryanplusplus"], "files": { "solution": [ "src/weighing_machine.cr"