-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidators.py
More file actions
67 lines (44 loc) · 1.87 KB
/
Copy pathvalidators.py
File metadata and controls
67 lines (44 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Input validation independent of the terminal interface."""
from datetime import date
from decimal import Decimal, InvalidOperation
def required(value):
"""Reject empty text and control characters."""
value = value.strip()
if not value:
raise ValueError("This field is required.")
if any(ord(character) < 32 or ord(character) == 127 for character in value):
raise ValueError("Control characters are not allowed.")
return value
def iso_date(value, past=False):
"""Validate dates in YYYY-MM-DD format."""
value = required(value)
try:
parsed = date.fromisoformat(value)
except ValueError:
raise ValueError("Enter a valid date: YYYY-MM-DD.") from None
if parsed.isoformat() != value:
raise ValueError("Use the format YYYY-MM-DD.")
if past and parsed > date.today():
raise ValueError("Birth date cannot be in the future.")
return value
def number(value, minimum=0, maximum=None):
"""Validate numeric input and optional bounds."""
try:
result = Decimal(value.strip())
except InvalidOperation:
raise ValueError("Enter a valid number.") from None
if not result.is_finite():
raise ValueError("Enter a finite number.")
if result < minimum:
raise ValueError(f"Enter a number greater than or equal to {minimum}.")
if maximum is not None and result > maximum:
raise ValueError(f"Enter a number less than or equal to {maximum}.")
return result
def grade_result(written, oral):
"""Calculate the average without discarding decimal places."""
written_mark = number(str(written), 0, 100)
oral_mark = number(str(oral), 0, 100)
average = (written_mark + oral_mark) / 2
# Preserve the original project's pass rule: average must exceed 50.
result = "Passed" if average > 50 else "Failed"
return str(average), result