Emfin2429 commited on
Commit
c815fca
·
verified ·
1 Parent(s): 55e2185

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +98 -0
  2. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Per Diem / Leave Start Date Calculator (Form e49)
3
+
4
+ Reserve members accrue leave (typically 15 days for a 6-month deployment)
5
+ and take it during the last 15 days of the deployment, so the last day of
6
+ leave equals the end date on their orders. Given that end date, this app
7
+ tells them when their leave starts.
8
+
9
+ Rule: leave is 15 days inclusive of start and end date.
10
+ If the end date falls on a weekend or federal holiday, the member gets
11
+ one extra day of leave (so the start date shifts one day earlier).
12
+ """
13
+
14
+ import gradio as gr
15
+ import holidays
16
+ from datetime import date, datetime, timedelta
17
+
18
+ US_HOLIDAYS = holidays.US()
19
+
20
+
21
+ def is_holiday(end_date: date) -> bool:
22
+ """Return True if end_date is a US federal holiday."""
23
+ return end_date in US_HOLIDAYS
24
+
25
+
26
+ def is_weekend(end_date: date) -> bool:
27
+ """Return True if end_date is a Saturday or Sunday."""
28
+ return end_date.weekday() >= 5
29
+
30
+
31
+ def fifteen_days_prior(end_date: date, exception: bool) -> date:
32
+ """
33
+ Return the date 15 days (inclusive) before end_date.
34
+ If `exception` is True (end date is a weekend/holiday), the member
35
+ gets one extra day of leave, so we go back 15 days instead of 14.
36
+ """
37
+ if exception:
38
+ return end_date - timedelta(days=15)
39
+ return end_date - timedelta(days=14)
40
+
41
+
42
+ def calc_leave_dates(end_date: date) -> tuple[date, date]:
43
+ """Determine the leave start date given the leave end date."""
44
+ exception = is_weekend(end_date) or is_holiday(end_date)
45
+ start_date = fifteen_days_prior(end_date, exception)
46
+ return start_date, end_date
47
+
48
+
49
+ def submit_leave_date(end_of_leave):
50
+ if end_of_leave is None:
51
+ return "Please select a date."
52
+
53
+ # gr.DateTime can hand back either a datetime object or a string
54
+ # depending on how the value was set, so handle both defensively.
55
+ if isinstance(end_of_leave, str):
56
+ end_of_leave = datetime.strptime(
57
+ end_of_leave.split(" ")[0], "%Y-%m-%d"
58
+ ).date()
59
+ elif isinstance(end_of_leave, (int, float)):
60
+ end_of_leave = datetime.fromtimestamp(end_of_leave).date()
61
+ else:
62
+ end_of_leave = end_of_leave.date()
63
+
64
+ start_date, end_date = calc_leave_dates(end_of_leave)
65
+
66
+ reason = []
67
+ if is_weekend(end_date):
68
+ reason.append("your end date falls on a weekend")
69
+ if is_holiday(end_date):
70
+ reason.append("your end date is a federal holiday")
71
+ extra_note = f" (You get an extra day of leave because {' and '.join(reason)}.)" if reason else ""
72
+
73
+ return (
74
+ f"Your leave starts on {start_date:%B %d, %Y} "
75
+ f"and ends on {end_date:%B %d, %Y}.{extra_note}"
76
+ )
77
+
78
+
79
+ with gr.Blocks(title="Leave Start Date Calculator") as app:
80
+ gr.Markdown(
81
+ "# Leave Start Date Calculator\n"
82
+ "Enter the **end date of your deployment (Form e49 end date)** "
83
+ "to find out when your 15 days of leave will start."
84
+ )
85
+ date_input = gr.DateTime(
86
+ label="When is the end of your leave?",
87
+ include_time=False,
88
+ type="datetime",
89
+ )
90
+ submit_btn = gr.Button("Calculate", variant="primary")
91
+ output = gr.Textbox(label="Result", interactive=False)
92
+
93
+ submit_btn.click(fn=submit_leave_date, inputs=date_input, outputs=output)
94
+ date_input.submit(fn=submit_leave_date, inputs=date_input, outputs=output)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ app.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ holidays