From f8501ce1a371fa2ad664e51fcebc97da6154031f Mon Sep 17 00:00:00 2001 From: SNEAXIII <74428850+SNEAXIII@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:58:16 +0200 Subject: [PATCH 1/3] Create intoduction for dig deeper in gigasecond exercise --- .../gigasecond/.approaches/introduction.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 exercises/practice/gigasecond/.approaches/introduction.md diff --git a/exercises/practice/gigasecond/.approaches/introduction.md b/exercises/practice/gigasecond/.approaches/introduction.md new file mode 100644 index 0000000000..cf6b8c1ed0 --- /dev/null +++ b/exercises/practice/gigasecond/.approaches/introduction.md @@ -0,0 +1,22 @@ +# Dig deeper +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`. +But you can't update a `datetime` object directly like: +```py +from datetime import datetime +datetime_2000_01_25 = datetime(year = 2000, month = 1, day = 25) +wrong_date = datetime_2000_01_25 + "2 weeks" # This won't work at all +``` +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. +```py +from datetime import timedelta, datetime +datetime_2000_01_01 = datetime(year = 2000, month = 1, day = 1) +delta = timedelta(weeks=2) +datetime_2000_01_15 = datetime_2000_01_01 + delta +``` +In the exercise, we have one `datetime` parameter, so one of the correct answer is: +```py +from datetime import timedelta, datetime +def add(moment: datetime) -> datetime: + return moment + timedelta(seconds=10**9) +``` +For more information, check the official [datetime documentation](https://docs.python.org/3/library/datetime.html#datetime.datetime.year) From 59a29d8e610fc8ff674ad3feee211eec26474a6c Mon Sep 17 00:00:00 2001 From: SNEAXIII <74428850+SNEAXIII@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:23:20 +0200 Subject: [PATCH 2/3] Create config.json --- exercises/practice/gigasecond/.approaches/config.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 exercises/practice/gigasecond/.approaches/config.json diff --git a/exercises/practice/gigasecond/.approaches/config.json b/exercises/practice/gigasecond/.approaches/config.json new file mode 100644 index 0000000000..307e37cbf1 --- /dev/null +++ b/exercises/practice/gigasecond/.approaches/config.json @@ -0,0 +1,6 @@ +{ + "introduction": { + "authors": ["SNEAXIII"], + "contributors": [] + } +} From 67d8a22fddb15b8f6c0f63802339f48c9c97a8d3 Mon Sep 17 00:00:00 2001 From: SNEAXIII <74428850+SNEAXIII@users.noreply.github.com> Date: Fri, 20 Sep 2024 23:51:23 +0200 Subject: [PATCH 3/3] Update introduction.md --- .../gigasecond/.approaches/introduction.md | 128 +++++++++++++++++- 1 file changed, 121 insertions(+), 7 deletions(-) diff --git a/exercises/practice/gigasecond/.approaches/introduction.md b/exercises/practice/gigasecond/.approaches/introduction.md index cf6b8c1ed0..c235c4c167 100644 --- a/exercises/practice/gigasecond/.approaches/introduction.md +++ b/exercises/practice/gigasecond/.approaches/introduction.md @@ -1,22 +1,136 @@ -# Dig deeper -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`. -But you can't update a `datetime` object directly like: +# Dig Deeper +When working with dates and datetime in Python, it's essential to use the built-in `datetime` module. + +## General Guidance +### How to represent one gigasecond (1 billion)? +In python, there are multiple ways to represent 1 billion in numerical form: +| Method | Value | +| ------------------- | -------------------------------------------------- | +| Exponentiation | 10**9 | +| Power function | pow(10, 9), math.pow(10, 9) and numpy.pow(10,9) | +| Scientific notation | 1e9 | +| Underscore notation | 1_000_000_000 | +| Literal integer | 1000000000 | + +### What is a `datetime` and a `timedelta` ? +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`. +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. +Here is a quick example of how to use a date and time: ```py from datetime import datetime datetime_2000_01_25 = datetime(year = 2000, month = 1, day = 25) wrong_date = datetime_2000_01_25 + "2 weeks" # This won't work at all ``` -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. +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. ```py from datetime import timedelta, datetime datetime_2000_01_01 = datetime(year = 2000, month = 1, day = 1) -delta = timedelta(weeks=2) +delta = timedelta(weeks=2) datetime_2000_01_15 = datetime_2000_01_01 + delta ``` -In the exercise, we have one `datetime` parameter, so one of the correct answer is: +To create a `timedelta`, you can use positional or named arguments. +```py +# By default, timedelta is equal to: +a = timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) +# Is equal to: +a = timedelta(0, 0, 0, 0, 0, 0, 0) +a = timedelta() +# Which can be confusing with large functions. +# For an example "days=0" mean "days" is an optional argument, and by default it is equal to 0. +# In python functions, arguments is positionnal, that mean if you want a 10 seconds "timedelta", you can do: +ten_seconds = timedelta(0, 10) # 0 days, 10 seconds +# Or you can directly name the argument: +ten_seconds = timedelta(seconds=10) +``` +### Defining variables + +You have several options for defining your variables +You can define variables with a global scope (outside functions) or local functions (inside). +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: +```py +GLOBAL_CONSTANT = "global" # Global scope variable (defined outside a function), in Screaming Snake Case (constant) +def test(): + LOCAL_CONSTANT = "local" # Local scope variable (defined inside a function), only accessible inside this function +``` +You can choose both, with their pros and cons. +#### Global variables +You should define a global variable when: +* you want to reduce the size of functions +```py +def test(): + str1 = "abc" + str2 = "def" + return str1 + str2 + +# Became + +STR1 = "abc" +STR2 = "def" +def test(): + return STR1 + STR2 +``` +* you need to reuse a value multiple times, like constants (for example, the 1 trillion number) +```py +def add_number(n): + return n + 10 + +def add_number_2_times(n): + return n + 20 + +# Became + +BONUS = 10 +def add_number(n): + return n + BONUS + +def add_number_2_times(n): + return n + BONUS * 2 +``` +* you don't want to execute multiple times the same function, or creating a variable (for example, creating the `timedelta` object) +```py +def is_vowel(char): + # This array will be recreated each time this function is executed. + vowels = ["a","e","i","o","u"] + return char in vowels + +# Became + +VOWELS = ["a","e","i","o","u"] +def is_vowel(char): + return char in VOWELS +``` +#### Local variables +You should define a local variable when: +* you don't need to reuse the variable +* the variable consumes too much memory (like a big array) +## Approach +### Approach: global variable with scientific notation +```py +from datetime import timedelta, datetime +ONE_BILLION = 1e9 +GIGASECOND = timedelta(seconds=ONE_BILLION ) +def add(moment: datetime) -> datetime: + return moment + GIGASECOND +``` +### Approach: without variable with exponentiation ```py from datetime import timedelta, datetime def add(moment: datetime) -> datetime: return moment + timedelta(seconds=10**9) ``` -For more information, check the official [datetime documentation](https://docs.python.org/3/library/datetime.html#datetime.datetime.year) +### Approach: global number variable with underscore notation +```py +from datetime import timedelta, datetime +ONE_BILLION = 1_000_000_000 +def add(moment: datetime) -> datetime: + return moment + timedelta(seconds=ONE_BILLION) +``` +### Approach: local variable with pow() +```py +from datetime import timedelta, datetime +def add(moment: datetime) -> datetime: + ONE_BILLION = pow(10, 9) + GIGASECOND = timedelta(seconds=ONE_BILLION ) + return moment + GIGASECOND +``` +For more information, check the official [timedelta documentation](https://docs.python.org/3/library/datetime.html#timedelta-objects)