Coverage for src/actuariat_python/exams/ex2016.py: 100%
45 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-02 07:38 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-02 07:38 +0200
1"""
2@file
3@brief Dummy data for 2016
4"""
5import random
6import uuid
7from datetime import datetime, timedelta
10first_names = {"M": "Balthazar", "W": "Cendrillon",
11 True: "Balthazar", False: "Cendrillon"}
14def enumerate_person(hf=0.5, age=(18, 60), n=100):
15 """
16 enumerate a person randomly chosen
18 @param hf proportion of men
19 @param age range for age
20 @param n number of person to generate
21 @return enumerator of dictionaries
22 """
23 for _ in range(n):
24 hfi = random.random() <= hf
25 agei = random.randint(*age)
26 namei = first_names[hfi]
27 yield dict(gender=(1 if hfi else 0), age=agei, name=namei, idc=uuid.uuid4())
30def enumerate_appointments(persons, nb=(1, 4), price=(60., 120.),
31 first_date=None, end_date=None,
32 formula=None):
33 """
34 enumerate a list of appointments for a given list of ids
36 @param persons list of persons
37 @param nb range for the number of appointments
38 @param price range for prices
39 @param begin_date first date (or now - 2 months)
40 @param end_date end date (or now)
41 @param formula formula for the prices of the appointments
42 @return enumerator of dictionaries
43 """
44 if end_date is None:
45 end_date = datetime.now()
46 if first_date is None:
47 first_date = end_date - timedelta(days=60)
48 if formula is None:
49 def formula_default(age, gender, when, date):
50 p = age * 0.5
51 p += -2 if gender else 2
52 if when is not None:
53 if when < 0:
54 raise ValueError( # pragma: no cover
55 "When must be positive, when={0} - date={1}".format(
56 when, date))
57 p -= 10 / (when + 1)
58 if date.weekday() in (6, 7):
59 p += 20
60 p += random.gauss(0, 2)
61 p += price[0]
62 p = int(p / 5) * 5
63 return p
64 formula = formula_default
66 for person in persons:
67 age = person["age"]
68 gender = person["gender"]
69 idc = person["idc"]
70 ns = random.randint(*nb)
71 fd = first_date
72 prev = None
73 for n in range(ns):
74 nbdays = (end_date - fd).days
75 d = random.randint(0, int(max(nbdays * 1.0 / (ns - n), 1)))
76 fd = fd + timedelta(days=d)
77 last = None if prev is None else (fd - prev).days
78 p = formula(age, gender, last, fd)
79 p = min(price[1], max(p, price[0]))
80 yield dict(idr=uuid.uuid4(), price=p, date=fd, idc=idc)
81 prev = fd