Skip to content

Commit

Permalink
Fixing tutorial to prepare 2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
denismerigoux committed Jan 28, 2025
1 parent 18c940f commit 0726eb1
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 4 deletions.
83 changes: 83 additions & 0 deletions src/2-1-basic-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,89 @@ Catala also has built-in `date` and `duration` types with the common associated
operations (adding a duration to a date, substracting two dates to get a
duration, etc.). For a deeper look at date computations (which are [very tricky](https://link.springer.com/chapter/10.1007/978-3-031-57267-8_16)!), look at the [language reference](./5-catala.md).


## Testing the code

Now that we have implemented a few articles in Catala, it is time to test
our code to check that it behaves correctly. We encourage you to test your
code a lot, as early as possible, and check the test result in a continuous
integration system to prevent regressions.

The testing of Catala code is done with the interpreter inside the compiler,
accessible with the `interpret` command and the `--scope` option that specifies
the scope to be interpreted?


~~~admonish failure title="Why can't I test `IncomeTaxComputation` directly?" collapsible=true
The reflex at this point is to execute the following command:
```text
$ catala interpret tutorial.catala_en --scope=IncomeTaxComputation
┌[ERROR]─
│ This scope needs input arguments to be executed. But the Catala built-in interpreter does not have a way to retrieve input values from the command line, so it cannot execute this scope.
│ Please create another scope that provides the input arguments to this one and execute it instead.
├─➤ tutorial.catala_en
│ │
│ │ input individual content Individual
│ │ ‾‾‾‾‾‾‾‾‾‾
└─
```
As the error message says, trying to interpret directly `IncomeTaxComputation` is like
trying to compute the taxes of somebody without knowing the income of the person!
To be executed, the scope needs to be called with concrete values for the income
and the number of children of the individual. Otherwise, Catala will complain
that `input` variables of the scope are missing for the interpretation.
~~~

The pattern for testing make use of concepts that will be seen
[later](./2-3-list-modular.md) in the tutorial, so it is okay to take part of
the following as some mysterious syntax that performs what we want. Basically,
we will be creating for our test case a new test that will pass specific
arguments to `IncomeTaxComputation` which is being tested:

~~~admonish note title="Defining a test"
```catala
declaration scope Test:
# The following line is mysterious for now
output computation content IncomeTaxComputation
scope Test:
definition computation equals
# The following line is mysterious for now
output of IncomeTaxComputation with {
# Below, we pass the input variables for "IncomeTaxComputation"
-- individual:
# "individual" has a structure type, so we need to build the
# structure "Individual" with the following syntax
Individual {
# "income" and "number_of_children" are the fields of the structure;
# we give them the values we want for our test
-- income: $20,000
-- number_of_children: 0
}
}
```
~~~

This test can now be executed through the Catala interpreter:

```text
$ catala interpret tutorial.catala_en --scope=Test
┌─[RESULT]─
│ computation = IncomeTaxComputation { -- income_tax: $4,000.00 }
└─
```

We can now check that `$4,000 = $20,000 * 20%`; the result is correct.

~~~admonish tip title="Test, test, test!"
Use this test to regularly play with the code during the tutorial and inspect
its results under various input scenarios. This will help you understand
the behavior of Catala programs, and spot errors in your code 😀
~~~

## Checkpoint

This concludes the first section of the tutorial. By setting up data structures
Expand Down
23 changes: 20 additions & 3 deletions src/2-2-conditionals-exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ involving exceptions, and be able to structure groups of variable definitions
according to their exceptional status and relative priority.

~~~~~~admonish info collapsible=true title="Recap of the previous section"
This section of the tutorial builds up on the [previous one](2-1-basic-blocks.md),
This section of the tutorial builds up on the [previous one](./2-1-basic-blocks.md),
and will reuse the same running example, but all the Catala code necessary
to execute the example is included below for reference.
Expand Down Expand Up @@ -42,6 +42,23 @@ The fixed percentage mentioned at article 1 is equal to 20 %.
scope IncomeTaxComputation:
definition tax_rate equals 20 %
```
## Test
```catala
declaration scope Test:
output computation content IncomeTaxComputation
scope Test:
definition computation equals
output of IncomeTaxComputation with {
-- individual:
Individual {
-- income: $20,000
-- number_of_children: 0
}
}
```
~~~
~~~~~~

Expand Down Expand Up @@ -497,7 +514,7 @@ The fixed percentage mentioned at article 1 is equal to 20 %.
```catala
scope IncomeTaxComputation:
label article_2 definition tax_rate under condition
curent_date < |2000-01-01|
current_date < |2000-01-01|
consequence equals 20 %
```
Expand All @@ -510,7 +527,7 @@ scope IncomeTaxComputation:
# Simply use the same label "article_2" as the previous definition to group
# them together
label article_2 definition tax_rate under condition
curent_date >= |2000-01-01|
current_date >= |2000-01-01|
consequence equals 21 %
```
~~~
Expand Down
130 changes: 129 additions & 1 deletion src/2-3-list-modular.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,132 @@
In this section, the tutorial tackles a common pattern that significantly
increases the complexity of a codebase: the need to deal with lists and rules
applying to each element of the list. Here, Catala reuses all the common tricks
from functional programming to ease
and patterns from functional programming to elegantly structure the code while
performing expressive operations on lists.

~~~~~~admonish info collapsible=true title="Recap of the previous section"
This section of the tutorial builds up on the [previous one](./2-2-conditionals-exceptions.md),
and will reuse the same running example, but all the Catala code necessary
to execute the example is included below for reference.
~~~
```catala
declaration structure Individual:
data income content money
data number_of_children content integer
declaration scope IncomeTaxComputation:
input current_date content date
input individual content Individual
input overseas_territories content boolean
internal tax_rate content decimal
output income_tax content money
```
## Article 1
The income tax for an individual is defined as a fixed percentage of the
individual's income over a year.
```catala
scope IncomeTaxComputation:
definition income_tax equals
individual.income * tax_rate
```
#### Article 2 (new version before 2000)
The fixed percentage mentioned at article 1 is equal to 20 %.
```catala
scope IncomeTaxComputation:
label article_2
definition tax_rate under condition
current_date < |2000-01-01|
consequence equals 20%
```
#### Article 2 (new version after 2000)
The fixed percentage mentioned at article 1 is equal to 21 % %.
```catala
scope IncomeTaxComputation:
# Simply use the same label "article_2" as the previous definition to group
# them together
label article_2
definition tax_rate under condition
current_date >= |2000-01-01|
consequence equals 21%
```
## Article 3
If the individual is in charge of 2 or more children, then the fixed
percentage mentioned at article 1 is equal to 15 %.
```catala
scope IncomeTaxComputation:
label article_3 exception article_2
definition tax_rate under condition
individual.number_of_children >= 2
consequence equals 15%
```
## Article 4
Individuals earning less than $10,000 are exempted of the income tax mentioned
at article 1.
```catala
scope IncomeTaxComputation:
label article_4 exception article_3
definition tax_rate under condition
individual.income <= $10,000
consequence equals 0%
```
## Article 5
Individuals earning more than $100,000 are subjects to a tax rate of
30%, regardless of their number of children.
```catala
scope IncomeTaxComputation:
label article_5 exception article_3
definition tax_rate under condition
individual.income > $100,000
consequence equals 30%
```
## Article 6
In the overseas territories, the tax rate for individuals earning
more than $100,000 specified at article 5 is reduced to 25 %.
```catala
scope IncomeTaxComputation:
label article_6 exception article_5
definition tax_rate under condition
individual.income > $100,000 and overseas_territories
consequence equals 25%
```
## Test
```catala
declaration scope Test:
output computation content IncomeTaxComputation
scope Test:
definition computation equals
output of IncomeTaxComputation with {
-- individual:
Individual {
-- income: $20,000
-- number_of_children: 0
}
-- overseas_territories: false
-- current_date: |1999-01-01|
}
```
~~~
~~~~~~

0 comments on commit 0726eb1

Please sign in to comment.