Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
},
"exercises": {
"concept": [
{
"slug": "freelancer-rates",
"name": "Freelancer Rates",
"uuid": "0aff2fa7-55ea-47e9-af4a-78927d916baf",
"concepts": [
"numbers",
"arithmetic-operators"
],
"prerequisites": [
"basics"
],
"status": "beta"
},
{
"slug": "lasagna",
"name": "Lucian's Luscious Lasagna",
Expand Down
16 changes: 16 additions & 0 deletions exercises/concept/freelancer-rates/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Hints

## 1. Calculate the day rate given an hourly rate

- Use the arithmetic operators as mentioned in the introduction of this exercise.

## 2. Calculate the number of workdays given a budget

- First determine the day rate, then calculate the number of days, and finally round that number down.

## 3. Calculate the discounted rate for large projects

- Round down the result from division to get the number of full months.
- `100% - discount` equals the percentage charged after the discount is applied.
- Use `%`, the remainder operator, to calculate the number of days exceeding full months.
- Add the discounted month rates and full day rates and round it up
45 changes: 45 additions & 0 deletions exercises/concept/freelancer-rates/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Instructions

In this exercise you will be writing code to help a freelancer communicate with his clients about the prices of certain projects. You will write a few utility functions to quickly calculate the costs for the clients.

## 1. Calculate the day rate given an hourly rate

A client contacts the freelancer to enquire about his rates.
The freelancer explains that he **_works 8 hours a day._**
However, the freelancer knows only his hourly rates for the project.
Help him estimate a day rate given an hourly rate.

```c
DATA(lcl_freelancer_rates) = new zcl_freelancer_rates( ).
DATA(lv_day_rate) = lcl_freelancer_rates->day_rate( 16 ).
WRITE |My Day Rate is: { lv_day_rate }|.
// => My Day Rate is: 128
```

The day rate does not need to be rounded or changed to a "fixed" precision.

## 2. Calculate the number of workdays given a fixed budget

Another day, a project manager offers the freelancer to work on a project with a fixed budget.
Given the fixed budget and the freelancer's hourly rate, help him calculate the number of days he would work until the budget is exhausted.
The result _must_ be **rounded** to the nearest number with 2 decimal places.

```c
DATA(lcl_freelancer_rates) = new zcl_freelancer_rates( ).
DATA(lv_days_in_budget) = lcl_freelancer_rates->DAYS_IN_BUDGET( budget = 1280 rate_per_hour = 16 ).
WRITE |Budget would last for { lv_days_in_budget } days.|.
// => Budget would last for 10 days.
```

## 3. Calculate the discounted rate for large projects

Often, the freelancer's clients hire him for projects spanning over multiple months.
In these cases, the freelancer decides to offer a discount for every full month, and the remaining days are billed at day rate.
**_Every month has 22 billable days._**
Help him estimate his cost for such projects, given an hourly rate, the number of days the project spans, and a monthly discount rate.
The discount is always passed as a number, where `42%` becomes `0.42`. The result _must_ be **rounded up** to the nearest whole number.

```javascript
priceWithMonthlyDiscount(89, 230, 0.42);
// => 97972
```
84 changes: 84 additions & 0 deletions exercises/concept/freelancer-rates/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Introduction

## Numbers

Many programming languages have specific numeric types to represent different types of numbers, but JavaScript only has two:

- `number`: a numeric data type in the double-precision 64-bit floating-point format (IEEE 754).
Examples are `-6`, `-2.4`, `0`, `0.1`, `1`, `3.14`, `16.984025`, `25`, `976`, `1024.0` and `500000`.
- `bigint`: a numeric data type that can represent _integers_ in the arbitrary precision format.
Examples are `-12n`, `0n`, `4n`, and `9007199254740991n`.

If you require arbitrary precision or work with extremely large numbers, use the `bigint` type.
Otherwise, the `number` type is likely the better option.

### Rounding

There is a built-in global object called `Math` that provides various [rounding functions][ref-math-object-rounding]. For example, you can round down (`floor`) or round up (`ceil`) decimal numbers to the nearest whole numbers.

```javascript
Math.floor(234.34); // => 234
Math.ceil(234.34); // => 235
```

## Arithmetic Operators

JavaScript provides 6 different operators to perform basic arithmetic operations on numbers.

- `+`: The addition operator is used to find the sum of numbers.
- `-`: The subtraction operator is used to find the difference between two numbers
- `*`: The multiplication operator is used to find the product of two numbers.
- `/`: The division operator is used to divide two numbers.

```javascript
2 - 1.5; //=> 0.5
19 / 2; //=> 9.5
```

- `%`: The remainder operator is used to find the remainder of a division performed.

```javascript
40 % 4; // => 0
-11 % 4; // => -3
```

- `**`: The exponentiation operator is used to raise a number to a power.

```javascript
4 ** 3; // => 64
4 ** 1 / 2; // => 2
```

### Order of Operations

When using multiple operators in a line, JavaScript follows an order of precedence as shown in [this precedence table][mdn-operator-precedence].
To simplify it to our context, JavaScript uses the PEDMAS (Parentheses, Exponents, Division/Multiplication, Addition/Subtraction) rule we've learnt in elementary math classes.

<!-- prettier-ignore-start -->
```javascript
const result = 3 ** 3 + 9 * 4 / (3 - 1);
// => 3 ** 3 + 9 * 4/2
// => 27 + 9 * 4/2
// => 27 + 18
// => 45
```
<!-- prettier-ignore-end -->

### Shorthand Assignment Operators

Shorthand assignment operators are a shorter way of writing code conducting arithmetic operations on a variable, and assigning the new value to the same variable.
For example, consider two variables `x` and `y`.
Then, `x += y` is same as `x = x + y`.
Often, this is used with a number instead of a variable `y`.
The 5 other operations can also be conducted in a similar style.

```javascript
let x = 5;
x += 25; // x is now 30

let y = 31;
y %= 3; // y is now 1
```

[mdn-operator-precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table
[ref-math-object-rounding]: https://javascript.info/number#rounding
19 changes: 19 additions & 0 deletions exercises/concept/freelancer-rates/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"marianfoo"
],
"contributors": [
],
"files": {
"solution": [
"zcl_freelancer_rates.clas.abap"
],
"test": [
"zcl_freelancer_rates.clas.testclasses.abap"
],
"exemplar": [
".meta/zcl_freelancer_rates.clas.abap"
]
},
"blurb": "Learn about numbers whilst helping a freelancer communicate with a project manager about day- and month rates."
}
24 changes: 24 additions & 0 deletions exercises/concept/freelancer-rates/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Design

## Learning objectives

- Know how to write floating point literals.
- Know their underlying type (double precision).
- Know their basic limitations (not all numbers can be represented, e.g. `0.1 + 0.2`).
- Know how to truncate floating point numbers to a certain decimal place (`Math.ceil`, `Math.floor`, `Math.round`)
- Know how to use arithmetic operators (`+`, `-`, `*`, `/`, `%`, `**`)
- Learn about shorthand assignment operators (`+=`, etc.)

## Out of scope

- Parsing integers and floats from strings.
- Converting integers and floats to strings.

## Concepts

- `numbers`
- `arithmetic-operators`

## Prerequisites

- `basics`
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
CLASS zcl_freelancer_rates DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

METHODS day_rate
IMPORTING
!rate_per_hour TYPE f
RETURNING
VALUE(result) TYPE f .
METHODS days_in_budget
IMPORTING
!budget TYPE f
!rate_per_hour TYPE f
RETURNING
VALUE(result) TYPE i .
METHODS price_with_monthly_discount
IMPORTING
!rate_per_hour TYPE f
!num_days TYPE f
!discount TYPE f
RETURNING
VALUE(result) TYPE f .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS zcl_freelancer_rates IMPLEMENTATION.



METHOD day_rate.
result = round( val = rate_per_hour * 8 dec = 2 ) .
ENDMETHOD.

METHOD days_in_budget.
result = floor( budget / day_rate( rate_per_hour ) ).
ENDMETHOD.


METHOD price_with_monthly_discount.
DATA(lv_months) = floor( num_days / 22 ).
DATA(lv_monthly_rate) = 22 * day_rate( rate_per_hour ).
DATA(lv_monthly_discount_rate) = ( 1 - discount ) * lv_monthly_rate.

DATA(lv_extra_days) = num_days MOD 22.
DATA(lv_price_extra_days) = lv_extra_days * day_rate( rate_per_hour ).

result = ceil( lv_months * lv_monthly_discount_rate + lv_price_extra_days ).
ENDMETHOD.
ENDCLASS.
10 changes: 10 additions & 0 deletions exercises/concept/freelancer-rates/package.devc.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Freelancer Rates</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>
51 changes: 51 additions & 0 deletions exercises/concept/freelancer-rates/zcl_freelancer_rates.clas.abap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
CLASS zcl_freelancer_rates DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

METHODS day_rate
IMPORTING
!rate_per_hour TYPE f
RETURNING
VALUE(result) TYPE f.

METHODS days_in_budget
IMPORTING
!budget TYPE f
!rate_per_hour TYPE f
RETURNING
VALUE(result) TYPE i.

METHODS price_with_monthly_discount
IMPORTING
!rate_per_hour TYPE f
!num_days TYPE f
!discount TYPE f
RETURNING
VALUE(result) TYPE f.

PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS zcl_freelancer_rates IMPLEMENTATION.


METHOD days_in_budget.
* add solution here
ENDMETHOD.


METHOD day_rate.
* add solution here
ENDMETHOD.


METHOD price_with_monthly_discount.
* add solution here
ENDMETHOD.
ENDCLASS.
Loading