diff --git a/concepts/basics/about.md b/concepts/basics/about.md new file mode 100644 index 00000000..e22b4d71 --- /dev/null +++ b/concepts/basics/about.md @@ -0,0 +1,89 @@ +# About + +Functions, methods and classes allows you to group code into a reusable unit. We are focusing on on methods, which +are functions that attached to a class. You'll learn more about classes concepts later on. + +## Variables and values + +All parameters must be explicitly typed; there is no type inference for parameters. +It is good practice to initialize values right after the declaration. + +## Arithmetics operators + +All arithmetic operators compute the result of specific arithmetic operation and returns its result. The arguments are not modified. Examples are `*`, `+` or `/`. + +```cpp +int i = 6; +int j = 7; +int addition = i + j; // addition is 13 +int multiplication = i * j; // multiplication is 42 +``` + +## Methods + +Methods in the same class can be called without any prefixes. They differ by return type, name and the number of parameters and their types. If you call a method you have to match all of these. + +```cpp +// A definition of a method that returns and integer and has three integer arguments: +int myFormula(int a, int b, int c) { + int x = a * b; + int m = -c; + return m*x; +} + +int intermediate = myFormula(1, 3, 52); +int final_result = myFormula(10, intermediate, 11); +``` + +## A word on classes + +C++ code is often divided into a header file, that ends in `.h` and the implementation in the `.cpp` file. +The definition of the class can tell you, which methods it has and how you can use them. + +```cpp +namespace bikeInfo { + class ShigeruSpecial { + public: + static int getGears(); + int getID(); + }; +} +``` +The code above does not tell you about the implementation details, but you know that the `ShigeruSpecial` bike has +a `getGears` and a `getID` method. Both return an integer. Both have the `public` modifier, meaning they can be accessed from code outside the `ShigeruSpecial` class. Another information is the `static` modifier. It tells you, that the `getGears` method can be invoked without creating an object of the class first. All those bikes have the same amount of gears, but every bike has its own ID. + +## Invoking methods + +Invoking a function is done by specifying the function's name and passing arguments for each of the function's parameters in parenthesis. It is also possible to have function and methods without parameters. Class methods +can be called with the `.` operator with the object, or with the `::` operator, when you do not want to create +an object for a static method. + +When you are writing methods in a class you can invoke other class methods without the `::` operator. + +```cpp + +using namespace bikeInfo; + +// calling the static method directly +int gearNumber = ShigeruSpecial::getGears(); + +// Creating the object and calling the method on the object +ShigeruSpecial bike = new ShigeruSpecial(); +int gearsFromObject = bike.gearNumber(); + +// this way you can also call non-static methods: +int id = bike.getID(); +``` + +## Comments + +C++ has single line comments that start with `//` and continue until the end of the line. There are also multi-line comments as shown below: + +```cpp +int myInteger = -1; // Comments can be in the same line as instructions + +/* Multi-line comments + do not end + until they are closed via: +*/ +``` \ No newline at end of file diff --git a/exercises/concept/lasagna-master/.docs/hints.md b/exercises/concept/lasagna-master/.docs/hints.md new file mode 100644 index 00000000..20753215 --- /dev/null +++ b/exercises/concept/lasagna-master/.docs/hints.md @@ -0,0 +1,24 @@ +# Hints + +## General + +- Don't forget the `;` after each statement. +- You can define an integer with `int myInteger = 44;`. + +## 1. Get the time that is spend baking. + +- The introduction has information on the time for the recipe. +- A method can return a value in the form of `return 2;` + +## 2. Get the preparation time. + +- You can access the number of layers by using the respective parameter. +- You can do calculations when you define an integer: `int myInteger = 3 + myOtherInteger;` + +## 3. Calculate the time left in the oven + +- You can call other methods and use them like variables: `return 22 * myOtherCalculation();` + +## 4. Calculate the total time spend for the lasagna + +- The output should combine the time for the preparation and the time the lasagna has already spent in the oven. diff --git a/exercises/concept/lasagna-master/.docs/instructions.md b/exercises/concept/lasagna-master/.docs/instructions.md new file mode 100644 index 00000000..a14edc72 --- /dev/null +++ b/exercises/concept/lasagna-master/.docs/instructions.md @@ -0,0 +1,42 @@ +# Instructions + +In this exercise you'll be automating some timing tasks for your weekly lasagna cooking session. +As you vary your recipes often, you want to know how much time you have to spend for different +lasagna types. + +You want to write a program to show you the time the lasagna has to be in the oven, how much time +you will have preparing and also how much time is left until the lasagna is ready. + +All you lasagna recipes need `40` minutes in the oven and the preparation takes `2` minutes per layer. + +## 1. Get the time that is spend baking. + +Implement the `lasagna::ovenTime` method to return a the minutes the lasagna has to stay in the oven. + +## 2. Get the preparation time. + +Implement the `lasagna::preparationTime` method to return the preparation time based on the number of layers. + +```cpp +lasagna::preparationTime(11) +// => 22 +``` + +## 3. Calculate the time left in the oven + +Implement the `lasagna::remainingOvenTime` method that takes the number of minutes the lasagna has already spend in the oven and +returns the remaining minutes. + +```cpp +`lasagna::remainingOvenTimet(4) +// => 36 +``` + +## 4. Calculate the total time spend for the lasagna + +Implement the `lasagna::elapsedTime` method that takes the number of layers and the number of minutes the lasagna has already spend in the oven and returns the total time spend preparing and waiting for the oven to finish. + +```cpp +`lasagna::elapsedTime(40, 20) +// => 100 +``` \ No newline at end of file diff --git a/exercises/concept/lasagna-master/.docs/introduction.md b/exercises/concept/lasagna-master/.docs/introduction.md new file mode 100644 index 00000000..7e2e7c18 --- /dev/null +++ b/exercises/concept/lasagna-master/.docs/introduction.md @@ -0,0 +1,114 @@ +# Introduction + +Functions, methods and classes allows you to group code into a reusable unit. We are focusing on on methods, which +are functions that attached to a class. You'll learn more about classes concepts later on. + +## Variables and values + +All parameters must be explicitly typed; there is no type inference for parameters. +It is good practice to initialize values right after the declaration. + +## Arithmetics operators + +All arithmetic operators compute the result of specific arithmetic operation and returns its result. The arguments are not modified. Examples are `*`, `+` or `/`. + +```cpp +int i = 6; +int j = 7; +int addition = i + j; // addition is 13 +int multiplication = i * j; // multiplication is 42 +``` + +## Methods + +Methods in the same class can be called without any prefixes. They differ by return type, name and the number of parameters and their types. If you call a method you have to match all of these. + +```cpp +// A definition of a method that returns and integer and has three integer arguments: +int myFormula(int a, int b, int c) { + int x = a * b; + int m = -c; + return m*x; +} + +int intermediate = myFormula(1, 3, 52); +int final_result = myFormula(10, intermediate, 11); +``` + +## Parameters vs. Arguments + +```cpp +int secretFormula(int first, int second) { + int secret = 14; + return first * secret - second; +} +``` +Let's quickly cover two terms that are often confused together: `parameters` and `arguments`. +Method parameters are the names defined in the function's signature, such as `first` and `second` in the function `secretFormula` above. +The arguments are the concrete values passed to the method parameters when we invoke the function. +For instance, in the example below, `11` and `-4` are the arguments passed to the `first` and `second` parameters: + +```cpp +secretFormula(11, 1-4); +``` + +## Return Values + +Values are returned to the calling code from functions using the `return` keyword. +The execution of the function ends as soon as it hits one of those `return` statements. +The type of the return value is defined by the type in front of the method's name. In the +case above we know that `secretFormula` will return an integer. The hello-world example was +a function that returned a `string`. + +## A word on classes + +C++ code is often divided into a header file, that ends in `.h` and the implementation in the `.cpp` file. +The definition of the class can tell you, which methods it has and how you can use them. + +```cpp +namespace bikeInfo { + class ShigeruSpecial { + public: + static int getGears(); + int getID(); + }; +} +``` +The code above does not tell you about the implementation details, but you know that the `ShigeruSpecial` bike has +a `getGears` and a `getID` method. Both return an integer. Both have the `public` modifier, meaning they can be accessed from code outside the `ShigeruSpecial` class. Another information is the `static` modifier. It tells you, that the `getGears` method can be invoked without creating an object of the class first. All those bikes have the same amount of gears, but every bike has its own ID. + +## Invoking methods + +Invoking a function is done by specifying the function's name and passing arguments for each of the function's parameters in parenthesis. It is also possible to have function and methods without parameters. Class methods +can be called with the `.` operator with the object, or with the `::` operator, when you do not want to create +an object for a static method. + +When you are writing methods in a class you can invoke other class methods without the `::` operator. + +```cpp + +using namespace bikeInfo; + +// calling the static method directly +int gearNumber = ShigeruSpecial::getGears(); + +// Creating the object and calling the method on the object +ShigeruSpecial bike = new ShigeruSpecial(); +int gearsFromObject = bike.gearNumber(); + +// this way you can also call non-static methods: +int id = bike.getID(); +``` + +## Comments + +C++ has single line comments that start with `//` and continue until the end of the line. There are also multi-line comments as shown below: + +```cpp +int myInteger = -1; // Comments can be in the same line as instructions + +/* Multi-line comments + do not end + until they are closed via: +*/ +``` \ No newline at end of file diff --git a/exercises/concept/lasagna-master/.meta/config.json b/exercises/concept/lasagna-master/.meta/config.json new file mode 100644 index 00000000..0350fdeb --- /dev/null +++ b/exercises/concept/lasagna-master/.meta/config.json @@ -0,0 +1,11 @@ +{ + "authors": [ + { + "github_username": "vaeng", + "exercism_username": "vaeng" + } + ], + "forked_from": [ + "go/lasagna" + ] +} diff --git a/exercises/concept/lasagna-master/.meta/design.md b/exercises/concept/lasagna-master/.meta/design.md new file mode 100644 index 00000000..cd223622 --- /dev/null +++ b/exercises/concept/lasagna-master/.meta/design.md @@ -0,0 +1,36 @@ +## Learning objectives + +- Know what a variable is. +- Know how to define a variable. +- Know how to update a variable. +- Know how to use type inference for variables. +- Know how to define a method. +- Know how to return a value from a method. +- Know how to call a method. +- Know that methods must be defined in classes. +- Know about the public access modifier. +- Know about the static modifier. +- Know how to define an integer. +- Know how to use mathematical operators on integers. +- Know how to define single- and multiline comments. + + +## Out of scope + +- Naming rules for identifiers. +- Generic values. +- Memory and performance characteristics. +- Method overloads. +- Lambda's. +- Classes. +- Organizing methods in namespaces. +- Visibility. + + +## Concepts + +- `basics`: know what a variable is; know how to define a variable; know how to update a variable; know how to use type inference for variables; know how to define a method; know how to return a value from a method; know how to call a method; know that methods must be defined in classes; know about the `public` access modifier; know about the `static` modifier; know how to defined an integer; know how to use mathematical operators on integers; know how to define single and multiline comments. + +## Prerequisites + +- There are no prerequisites. diff --git a/exercises/concept/lasagna-master/.meta/exemplar.cpp b/exercises/concept/lasagna-master/.meta/exemplar.cpp new file mode 100644 index 00000000..483b77e9 --- /dev/null +++ b/exercises/concept/lasagna-master/.meta/exemplar.cpp @@ -0,0 +1,28 @@ +#include "lasagna_master.h" + +namespace lasagna_master { + // ovenTime returns the amount in minutes that the lasagna should stay in the oven. + int Lasagna::ovenTime() { + return 40; + } + + /* PreparationTim estimates the preparation time based on the number + of layers and an average time per layer and returns it. + */ + int Lasagna::preparationTime(int numberOfLayers) { + int prepTimePerLayer = 2; + return numberOfLayers*prepTimePerLayer; + } + + /* RemainingOvenTime returns the remaining + minutes based on the actual minutes already in the oven. + */ + int Lasagna::remainingOvenTime(int actualMinutesInOven) { + return ovenTime()-actualMinutesInOven; + } + + // ElapsedTime calculates the total time spend to create and bake the Lasagna so far. + int Lasagna::elapsedTime(int numberOfLayers, int actualMinutesInOven) { + return preparationTime(numberOfLayers) + actualMinutesInOven; + } +} // namespace lasagna_master diff --git a/exercises/concept/lasagna-master/.meta/exemplar.h b/exercises/concept/lasagna-master/.meta/exemplar.h new file mode 100644 index 00000000..63b51552 --- /dev/null +++ b/exercises/concept/lasagna-master/.meta/exemplar.h @@ -0,0 +1,21 @@ +#if !defined(LASAGNA_MASTER_H_) +#define LASAGNA_MASTER_H_ + +/* IMPORTANT: + To solve this exercise you do not need to edit + the contents of this file. +*/ + + +namespace lasagna_master { + class lasagna { + public: + static int ovenTime(); + static int preparationTime(int numberOfLayers); + static int remainingOvenTime(int actualMinutesInOven); + static int elapsedTime(int numberOfLayers, int actualMinutesInOven); + }; + +} // namespace lasagna_master + +#endif diff --git a/exercises/concept/lasagna-master/CMakeLists.txt b/exercises/concept/lasagna-master/CMakeLists.txt new file mode 100644 index 00000000..2beb1d2b --- /dev/null +++ b/exercises/concept/lasagna-master/CMakeLists.txt @@ -0,0 +1,70 @@ +# Get the exercise name from the current directory +get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +# Basic CMake project +cmake_minimum_required(VERSION 3.5.1) + +# Name the project after the exercise +project(${exercise} CXX) + +# Get a source filename from the exercise name by replacing -'s with _'s +string(REPLACE "-" "_" file ${exercise}) + +# Implementation could be only a header +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp) + set(exercise_cpp ${file}.cpp) +else() + set(exercise_cpp "") +endif() + +# Downloads Catch library used for testing +set(CATCH_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/test/catch.hpp") +set(CATCH_DOWNLOAD_URL "https://github.com/catchorg/Catch2/releases/download/v2.11.3/catch.hpp") +if (NOT EXISTS "${CATCH_HEADER}") + file(DOWNLOAD "${CATCH_DOWNLOAD_URL}" "${CATCH_HEADER}") +endif() + +# Use the common Catch library? +if(EXERCISM_COMMON_CATCH) + # For Exercism track development only + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $) +elseif(EXERCISM_TEST_SUITE) + # The Exercism test suite is being run, the Docker image already + # includes a pre-built version of Catch. + find_package(Catch2 REQUIRED) + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h) + target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain) + # When Catch is installed system wide we need to include a different + # header, we need this define to use the correct one. + target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE) +else() + # Build executable from sources and headers + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp) +endif() + +set_target_properties(${exercise} PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED OFF + CXX_EXTENSIONS OFF +) + +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)") + set_target_properties(${exercise} PROPERTIES + COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror" + ) +endif() + +# Configure to run all the tests? +if(${EXERCISM_RUN_ALL_TESTS}) + target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS) +endif() + +# Tell MSVC not to warn us about unchecked iterators in debug builds +if(${MSVC}) + set_target_properties(${exercise} PROPERTIES + COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS) +endif() + +# Run the tests on every build +add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise}) + diff --git a/exercises/concept/lasagna-master/lasagna_master.cpp b/exercises/concept/lasagna-master/lasagna_master.cpp new file mode 100644 index 00000000..edcebb99 --- /dev/null +++ b/exercises/concept/lasagna-master/lasagna_master.cpp @@ -0,0 +1,33 @@ +#include "lasagna_master.h" + +// ovenTime returns the amount in minutes that the lasagna should stay in the +// oven. +int ovenTime() { + // TODO: Return the correct time. + return 0; +} + +/* PreparationTim estimates the preparation time based on the number + of layers and an average time per layer and returns it. +*/ +int preparationTime(int numberOfLayers) { + // TODO: Calculate and return the preparation time with the + // `numberOfLayers`. + return 0; +} + +/* RemainingOvenTime returns the remaining +minutes based on the actual minutes already in the oven. +*/ +int remainingOvenTime(int actualMinutesInOven) { + // TODO: Calculate and return the remaining in the oven based on the time + // `actualMinutesInOven` the Lasagna has already spent there. + return 0; +} + +// ElapsedTime calculates the total time spent to create and bake the lasagna so +// far. +int elapsedTime(int numberOfLayers, int actualMinutesInOven) { + // TODO: Calculate and return the time total time so far. + return 0; +} diff --git a/exercises/concept/lasagna-master/lasagna_master.h b/exercises/concept/lasagna-master/lasagna_master.h new file mode 100644 index 00000000..78ebe2fe --- /dev/null +++ b/exercises/concept/lasagna-master/lasagna_master.h @@ -0,0 +1,14 @@ +#if !defined(LASAGNA_MASTER_H_) +#define LASAGNA_MASTER_H_ + +/* IMPORTANT: + To solve this exercise you do not need to edit + the contents of this file. +*/ + +int ovenTime(); +int preparationTime(int numberOfLayers); +int remainingOvenTime(int actualMinutesInOven); +int elapsedTime(int numberOfLayers, int actualMinutesInOven); + +#endif diff --git a/exercises/concept/lasagna-master/lasagna_master_test.cpp b/exercises/concept/lasagna-master/lasagna_master_test.cpp new file mode 100644 index 00000000..6338499c --- /dev/null +++ b/exercises/concept/lasagna-master/lasagna_master_test.cpp @@ -0,0 +1,81 @@ +#include "lasagna_master.h" +#ifdef EXERCISM_TEST_SUITE +#include +#else +#include "test/catch.hpp" +#endif + +using namespace std; + +TEST_CASE("Preparation time correct") +{ + const int actual = 40; + int expected = lasagna_master::Lasagna::ovenTime(); + + REQUIRE(expected == actual); +} + +#if defined(EXERCISM_RUN_ALL_TESTS) +TEST_CASE("Correct for six layers") +{ + const int timePerLayer = 2; + const int layers = 36; + const int actual = lasagna_master::Lasagna::preparationTime(layers); + const int expected{timePerLayer*layers}; + + REQUIRE(expected == actual); +} + +TEST_CASE("Correct for 11 layers") +{ + const int timePerLayer = 2; + const int layers = 11; + const int actual = lasagna_master::Lasagna::preparationTime(layers); + const int expected{timePerLayer*layers}; + + REQUIRE(expected == actual); +} + +TEST_CASE("Fresh in the oven") +{ + const int timeSpendInOven = 0; + const int neededBakeTime = 40; + const int actual = lasagna_master::Lasagna::remainingOvenTime(timeSpendInOven); + const int expected{neededBakeTime-timeSpendInOven}; + + REQUIRE(expected == actual); +} + +TEST_CASE("Halfway done") +{ + const int timeSpendInOven = 20; + const int neededBakeTime = 40; + const int actual = lasagna_master::Lasagna::remainingOvenTime(timeSpendInOven); + const int expected{neededBakeTime-timeSpendInOven}; + + REQUIRE(expected == actual); +} + +TEST_CASE("Fresh in the oven, 12 layers!") +{ + const int timeSpendInOven = 0; + const int timePerLayer = 2; + const int layers = 11; + const int actual = lasagna_master::Lasagna::elapsedTime(layers, timeSpendInOven); + const int expected{timePerLayer*layers + timeSpendInOven}; + + REQUIRE(expected == actual); +} + +TEST_CASE("One minute left, 5 layers!") +{ + const int timeSpendInOven = 39; + const int timePerLayer = 2; + const int layers = 5; + const int actual = lasagna_master::Lasagna::elapsedTime(layers, timeSpendInOven); + const int expected{timePerLayer*layers + timeSpendInOven}; + + REQUIRE(expected == actual); +} + +#endif diff --git a/exercises/concept/lasagna-master/test/tests-main.cpp b/exercises/concept/lasagna-master/test/tests-main.cpp new file mode 100644 index 00000000..0c7c351f --- /dev/null +++ b/exercises/concept/lasagna-master/test/tests-main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include "catch.hpp"