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

1""" 

2@file 

3@brief Dummy data for 2016 

4""" 

5import random 

6import uuid 

7from datetime import datetime, timedelta 

8 

9 

10first_names = {"M": "Balthazar", "W": "Cendrillon", 

11 True: "Balthazar", False: "Cendrillon"} 

12 

13 

14def enumerate_person(hf=0.5, age=(18, 60), n=100): 

15 """ 

16 enumerate a person randomly chosen 

17 

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()) 

28 

29 

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 

35 

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 

65 

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