|
1 | | -# Dig deeper |
2 | | -There is only one correct and safe way to deal with date and datetime in python. We are going to use the built-in `datetime` module. A `datetime` object contains multiple attributes, like `year`, `month`, `day`, `hour`, `minute` and `second`. |
3 | | -But you can't update a `datetime` object directly like: |
| 1 | +# Dig Deeper |
| 2 | +When working with dates and datetime in Python, it's essential to use the built-in `datetime` module. |
| 3 | + |
| 4 | +## General Guidance |
| 5 | +### How to represent one gigasecond (1 billion)? |
| 6 | +In python, there are multiple ways to represent 1 billion in numerical form: |
| 7 | +| Method | Value | |
| 8 | +| ------------------- | -------------------------------------------------- | |
| 9 | +| Exponentiation | 10**9 | |
| 10 | +| Power function | pow(10, 9), math.pow(10, 9) and numpy.pow(10,9) | |
| 11 | +| Scientific notation | 1e9 | |
| 12 | +| Underscore notation | 1_000_000_000 | |
| 13 | +| Literal integer | 1000000000 | |
| 14 | + |
| 15 | +### What is a `datetime` and a `timedelta` ? |
| 16 | +A `datetime` object is a way to represent a specific point in time, including the date and time of day. It contains multiple attributes, such as `year`, `month`, `day`, `hour`, `minute`, and `second`. However, updating a `datetime` object directly is not possible. Instead, we'll explore various approaches to solve the problem of adding a gigasecond to a given `datetime`. |
| 17 | +The key to solving this problem lies in using the `timedelta` object, which represents a time interval. We can add or subtract a `timedelta` from a `datetime` object to create a new `datetime` object with the updated values. |
| 18 | +Here is a quick example of how to use a date and time: |
4 | 19 | ```py |
5 | 20 | from datetime import datetime |
6 | 21 | datetime_2000_01_25 = datetime(year = 2000, month = 1, day = 25) |
7 | 22 | wrong_date = datetime_2000_01_25 + "2 weeks" # This won't work at all |
8 | 23 | ``` |
9 | | -Instead, we have to use another one object, `timedelta`. It will be used to accomplish the same thing as shown in the previous example. This object is a time interval, which can be used to modify a `datetime` object. We can add or subtract the `timedelta` to a `datetime` object to create a new `datetime` object with the updated values. |
| 24 | +Instead, we have to use another one object, `timedelta`. It will be used to accomplish the same thing as shown in the previous example. This object is a time interval, which can be used to modify a `datetime` object. We can add or subtract the `timedelta` to a given `datetime` object to create a new `datetime` object with the updated values. |
10 | 25 | ```py |
11 | 26 | from datetime import timedelta, datetime |
12 | 27 | datetime_2000_01_01 = datetime(year = 2000, month = 1, day = 1) |
13 | | -delta = timedelta(weeks=2) |
| 28 | +delta = timedelta(weeks=2) |
14 | 29 | datetime_2000_01_15 = datetime_2000_01_01 + delta |
15 | 30 | ``` |
16 | | -In the exercise, we have one `datetime` parameter, so one of the correct answer is: |
| 31 | +To create a `timedelta`, you can use positional or named arguments. |
| 32 | +```py |
| 33 | +# By default, timedelta is equal to: |
| 34 | +a = timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) |
| 35 | +# Is equal to: |
| 36 | +a = timedelta(0, 0, 0, 0, 0, 0, 0) |
| 37 | +a = timedelta() |
| 38 | +# Which can be confusing with large functions. |
| 39 | +# For an example "days=0" mean "days" is an optional argument, and by default it is equal to 0. |
| 40 | +# In python functions, arguments is positionnal, that mean if you want a 10 seconds "timedelta", you can do: |
| 41 | +ten_seconds = timedelta(0, 10) # 0 days, 10 seconds |
| 42 | +# Or you can directly name the argument: |
| 43 | +ten_seconds = timedelta(seconds=10) |
| 44 | +``` |
| 45 | +### Defining variables |
| 46 | + |
| 47 | +You have several options for defining your variables |
| 48 | +You can define variables with a global scope (outside functions) or local functions (inside). |
| 49 | +Note that there are no immutable `constants` in python. To symbolize a constant, we write it in uppercase with underscore to replace spaces (Screaming Snake Case). Here is a quick example: |
| 50 | +```py |
| 51 | +GLOBAL_CONSTANT = "global" # Global scope variable (defined outside a function), in Screaming Snake Case (constant) |
| 52 | +def test(): |
| 53 | + LOCAL_CONSTANT = "local" # Local scope variable (defined inside a function), only accessible inside this function |
| 54 | +``` |
| 55 | +You can choose both, with their pros and cons. |
| 56 | +#### Global variables |
| 57 | +You should define a global variable when: |
| 58 | +* you want to reduce the size of functions |
| 59 | +```py |
| 60 | +def test(): |
| 61 | + str1 = "abc" |
| 62 | + str2 = "def" |
| 63 | + return str1 + str2 |
| 64 | + |
| 65 | +# Became |
| 66 | + |
| 67 | +STR1 = "abc" |
| 68 | +STR2 = "def" |
| 69 | +def test(): |
| 70 | + return STR1 + STR2 |
| 71 | +``` |
| 72 | +* you need to reuse a value multiple times, like constants (for example, the 1 trillion number) |
| 73 | +```py |
| 74 | +def add_number(n): |
| 75 | + return n + 10 |
| 76 | + |
| 77 | +def add_number_2_times(n): |
| 78 | + return n + 20 |
| 79 | + |
| 80 | +# Became |
| 81 | + |
| 82 | +BONUS = 10 |
| 83 | +def add_number(n): |
| 84 | + return n + BONUS |
| 85 | + |
| 86 | +def add_number_2_times(n): |
| 87 | + return n + BONUS * 2 |
| 88 | +``` |
| 89 | +* you don't want to execute multiple times the same function, or creating a variable (for example, creating the `timedelta` object) |
| 90 | +```py |
| 91 | +def is_vowel(char): |
| 92 | + # This array will be recreated each time this function is executed. |
| 93 | + vowels = ["a","e","i","o","u"] |
| 94 | + return char in vowels |
| 95 | + |
| 96 | +# Became |
| 97 | + |
| 98 | +VOWELS = ["a","e","i","o","u"] |
| 99 | +def is_vowel(char): |
| 100 | + return char in VOWELS |
| 101 | +``` |
| 102 | +#### Local variables |
| 103 | +You should define a local variable when: |
| 104 | +* you don't need to reuse the variable |
| 105 | +* the variable consumes too much memory (like a big array) |
| 106 | +## Approach |
| 107 | +### Approach: global variable with scientific notation |
| 108 | +```py |
| 109 | +from datetime import timedelta, datetime |
| 110 | +ONE_BILLION = 1e9 |
| 111 | +GIGASECOND = timedelta(seconds=ONE_BILLION ) |
| 112 | +def add(moment: datetime) -> datetime: |
| 113 | + return moment + GIGASECOND |
| 114 | +``` |
| 115 | +### Approach: without variable with exponentiation |
17 | 116 | ```py |
18 | 117 | from datetime import timedelta, datetime |
19 | 118 | def add(moment: datetime) -> datetime: |
20 | 119 | return moment + timedelta(seconds=10**9) |
21 | 120 | ``` |
22 | | -For more information, check the official [datetime documentation](https://docs.python.org/3/library/datetime.html#datetime.datetime.year) |
| 121 | +### Approach: global number variable with underscore notation |
| 122 | +```py |
| 123 | +from datetime import timedelta, datetime |
| 124 | +ONE_BILLION = 1_000_000_000 |
| 125 | +def add(moment: datetime) -> datetime: |
| 126 | + return moment + timedelta(seconds=ONE_BILLION) |
| 127 | +``` |
| 128 | +### Approach: local variable with pow() |
| 129 | +```py |
| 130 | +from datetime import timedelta, datetime |
| 131 | +def add(moment: datetime) -> datetime: |
| 132 | + ONE_BILLION = pow(10, 9) |
| 133 | + GIGASECOND = timedelta(seconds=ONE_BILLION ) |
| 134 | + return moment + GIGASECOND |
| 135 | +``` |
| 136 | +For more information, check the official [timedelta documentation](https://docs.python.org/3/library/datetime.html#timedelta-objects) |
0 commit comments