Python backend debugged and tested

This commit is contained in:
Denis Merigoux 2021-06-25 00:47:12 +02:00
parent e38dc4c728
commit 03b44f5b15
No known key found for this signature in database
GPG Key ID: EE99DCFA365C3EE3
5 changed files with 67 additions and 16 deletions

View File

@ -170,7 +170,7 @@ test_examples: .FORCE
tests: test_suite test_examples
#> tests_ocaml : Run OCaml unit tests for the Catala-generated code
tests_ocaml: run_french_law_library_tests
tests_ocaml: run_french_law_library_ocaml_tests
#> bench_ocaml : Run OCaml benchmarks for the Catala-generated code
bench_ocaml: run_french_law_library_benchmark_ocaml
@ -178,6 +178,10 @@ bench_ocaml: run_french_law_library_benchmark_ocaml
#> bench_js : Run JS benchmarks for the Catala-generated code
bench_js: run_french_law_library_benchmark_js
#> tests_python : Run Python unit tests for the Catala-generated code
tests_python: run_french_law_library_python_tests
##########################################
# French law library
##########################################
@ -211,12 +215,12 @@ build_french_law_library_ocaml: generate_french_law_library_ocaml format
run_french_law_library_benchmark_ocaml: generate_french_law_library_ocaml
dune exec --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/bench.exe
run_french_law_library_ocaml_tests: build_french_law_library_ocaml
dune exec $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/run_tests.exe
run_french_law_library_benchmark_js: build_french_law_library_js
$(MAKE) -C $(FRENCH_LAW_JS_LIB_DIR) bench
run_french_law_library_tests: generate_french_law_library_ocaml
dune exec $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/run_tests.exe
#> build_french_law_library_js : Builds the JS version of the OCaml French law library
build_french_law_library_js: generate_french_law_library_ocaml format
dune build --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/api_web.bc.js
@ -233,6 +237,10 @@ type_french_law_library_python: generate_french_law_library_python
. $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\
$(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) type
run_french_law_library_python_tests: type_french_law_library_python
. $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\
$(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) test
##########################################
# Website assets

View File

@ -193,4 +193,27 @@ champ d'application Test9:
définition f.résidence égal à Guadeloupe
règle f.personne_charge_effective_permanente_est_parent rempli
assertion f.montant_versé = 0€
déclaration champ d'application Test10:
contexte f champ d'application InterfaceAllocationsFamiliales
champ d'application Test10:
définition f.enfants égal à [EnfantEntrée {
-- d_identifiant: 0
-- d_date_de_naissance: |2003-02-22|
-- d_rémuneration_mensuelle: 0€
-- d_prise_en_charge: EffectiveEtPermanente
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
};EnfantEntrée {
-- d_identifiant: 1
-- d_date_de_naissance: |2013-09-30|
-- d_rémuneration_mensuelle: 300€
-- d_prise_en_charge: GardeAlternéePartageAllocations
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
}]
définition f.ressources_ménage égal à 30000 €
définition f.date_courante égal à |2020-04-20|
définition f.résidence égal à Métropole
règle f.personne_charge_effective_permanente_est_parent rempli
assertion f.montant_versé = 99,37€
```

View File

@ -7,4 +7,7 @@ type:
mypy $(SOURCES)
format:
autopep8 --in-place $(SOURCES)
autopep8 --in-place $(SOURCES)
test:
python main.py

View File

@ -1,20 +1,20 @@
#!python3
from src.catala import date_of_numbers, Unit, integer_of_int, money_of_units_int, no_input
from src.catala import date_of_numbers, Unit, integer_of_int, money_of_units_int, no_input, money_to_float
from src.allocations_familiales import interface_allocations_familiales, InterfaceAllocationsFamilialesIn, EnfantEntree, PriseEnCharge, PriseEnCharge_Code, Collectivite, Collectivite_Code
def main():
print(interface_allocations_familiales(
out = interface_allocations_familiales(
InterfaceAllocationsFamilialesIn(
date_courante_in=lambda _: date_of_numbers(2020, 4, 20),
enfants_in=lambda _: [
EnfantEntree(d_identifiant=integer_of_int(0), d_remuneration_mensuelle=integer_of_int(0),
EnfantEntree(d_identifiant=integer_of_int(0), d_remuneration_mensuelle=money_of_units_int(0),
d_date_de_naissance=date_of_numbers(2003, 2, 2),
d_prise_en_charge=PriseEnCharge(
PriseEnCharge_Code.EffectiveEtPermanente, Unit()),
d_a_deja_ouvert_droit_aux_allocations_familiales=True),
EnfantEntree(d_identifiant=integer_of_int(1), d_remuneration_mensuelle=integer_of_int(300),
EnfantEntree(d_identifiant=integer_of_int(1), d_remuneration_mensuelle=money_of_units_int(300),
d_date_de_naissance=date_of_numbers(2013, 9, 30),
d_prise_en_charge=PriseEnCharge(
PriseEnCharge_Code.GardeAlterneePartageAllocations, Unit()),
@ -27,7 +27,9 @@ def main():
personne_charge_effective_permanente_remplit_titre_I_in=lambda _: True,
enfants_a_charge_in=no_input(),
montant_verse_in=no_input()
)))
))
money_given = money_to_float(out.montant_verse_out)
assert (money_given == 99.37)
if __name__ == '__main__':

View File

@ -9,7 +9,7 @@
# This file should be in sync with compiler/runtime.{ml, mli} !
from gmpy2 import log2, mpz, mpq, mpfr, mpc # type: ignore
from gmpy2 import log2, mpz, mpq, mpfr, t_divmod # type: ignore
import datetime
import dateutil.relativedelta
from typing import NewType, List, Callable, Tuple, Optional, TypeVar, Iterable, Union
@ -66,9 +66,12 @@ class Integer:
else:
return False
def __str__(self) -> str:
return self.value.__str__()
class Decimal:
def __init__(self, value: Union[str, int, float, Integer]) -> None:
def __init__(self, value: Union[str, int, float]) -> None:
self.value = mpq(value)
def __add__(self, other: 'Decimal') -> 'Decimal':
@ -110,6 +113,9 @@ class Decimal:
else:
return False
def __str__(self) -> str:
return self.value.__str__()
class Money:
def __init__(self, value: Integer) -> None:
@ -122,7 +128,15 @@ class Money:
return Money(self.value - other.value)
def __mul__(self, other: Decimal) -> 'Money':
return Money(Integer(self.value.value * other.value))
cents = self.value.value
coeff = other.value
rat_result = self.value.value * other.value
out = Money(Integer(rat_result))
res, remainder = t_divmod(rat_result.numerator, rat_result.denominator)
if 2 * remainder >= rat_result.denominator:
return Money(Integer(res + 1))
else:
return Money(Integer(res))
def __truediv__(self, other: 'Money') -> Decimal:
return Decimal(mpq(self.value.value / other.value.value))
@ -154,6 +168,9 @@ class Money:
else:
return False
def __str__(self) -> str:
return "${:.2}".format(self.value.value / 100)
class Date:
def __init__(self, value: datetime.date) -> None:
@ -449,7 +466,7 @@ def list_map(f: Callable[[Alpha], Beta], l: List[Alpha]) -> List[Beta]:
def list_length(l: List[Alpha]) -> Integer:
return mpz(len(l))
return Integer(len(l))
# ========
# Defaults
@ -506,6 +523,4 @@ def log_end_call(headings: List[str], value: Alpha) -> Alpha:
def log_decision_taken(pos: SourcePosition, value: bool) -> bool:
if value:
print(">> Decision taken {}".format(pos))
return value