# Vendredi 13 sur Hackinscience

**URL:** <https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836>\
**Category:** Entraide\
**Created:** [Novembre 28, 2023, 12:18 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836 "2023-11-28T12:18:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlexisAmand](https://discuss.afpy.org/user_avatar/discuss.afpy.org/alexisamand/32/1137_2.png) [@AlexisAmand](https://discuss.afpy.org/u/AlexisAmand)\
**Post date:** [Novembre 28, 2023, 12:18 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/1 "2023-11-28T12:18:22Z")

</div>

Bonjour tout le monde !

En plein apprentissage de Python, j’ai commencé les exercices proposés sur Hackinscience. Là, je suis arrivé à celui qui s’appelle “Vendredi 13”. J’ai écrit cette version qui semble tourner à perfection quand je l’exécute sur mon pc avec Visual Studio et Python 3.12.

Je précise que la dernière ligne me sert juste à faire mes tests en local.

Pourriez vous m’expliquer - simplement - pourquoi le code ne fonctionne pas une fois envoyé sur Hackinscience ? J’ai le message suivant :

```python
TypeError: FakeDatetime.date() takes 1 positional argument but 4 were given

```

Je trouve ça un peu étrange car je n’ai pas utilisé cette fonction, et je ne savais même pas qu’elle existait.

Voici mon code :

```python
# Vendredi 13

import datetime

def friday_the_13th():
    # date actuelle
    aujourdhui = datetime.datetime.now()    
    jour = int(aujourdhui.strftime('%d'))
    mois = int(aujourdhui.strftime('%m'))
    annee = int(aujourdhui.strftime('%Y'))
 
    # on teste si aujourd'hui, nous sommes un vendredi 13
    if jour == 13 and aujourdhui.date(annee, mois, jour).weekday() == 4:
        vendredi13 = str(annee) + "-" + str(mois) + "-13"
    else:   
        # sinon, on boucle sur les 13 des mois successifs
        # pour voir si ça tombe un vendredi 
        
        while datetime.date(annee, mois, 13).weekday() != 4:
            if mois < 12:
                mois += 1
            elif mois == 12:
                mois = 1
                annee += 1
                
        # le prochain vendredi 13
        # avec un ajustement sur le mois pour l'avoir avec 2 chiffres       
        mois = str(mois).rjust(2, "0")
        vendredi13 = str(annee) + "-" + str(mois) + "-13"
        
        return vendredi13
    
# test
print(friday_the_13th())

```

---

<div class="post-metadata">

**Author:** ![entwanne](https://discuss.afpy.org/user_avatar/discuss.afpy.org/entwanne/32/8_2.png) [@entwanne](https://discuss.afpy.org/u/entwanne)\
**Post date:** [Novembre 28, 2023, 1:02 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/2 "2023-11-28T13:02:36Z")

</div>

Bonjour,

Que t’attends-tu à avoir lorsque tu fais `aujourdhui.date(annee, mois, jour)`?

`aujourdhui` est un objet `datetime`, il possède bien une méthode `date` (pour récupérer la date associée) mais cette méthode ne prend par d’arguments.

---

<div class="post-metadata">

**Author:** ![AlexisAmand](https://discuss.afpy.org/user_avatar/discuss.afpy.org/alexisamand/32/1137_2.png) [@AlexisAmand](https://discuss.afpy.org/u/AlexisAmand)\
**Post date:** [Novembre 28, 2023, 1:19 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/3 "2023-11-28T13:19:43Z")

</div>

J’avais cru comprendre que c’était un moyen de définir la date sur laquelle on est en train de travailler. 😔

---

<div class="post-metadata">

**Author:** ![mdk](https://discuss.afpy.org/user_avatar/discuss.afpy.org/mdk/32/3_2.png) [@mdk](https://discuss.afpy.org/u/mdk)\
**Post date:** [Novembre 28, 2023, 2:07 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/4 "2023-11-28T14:07:41Z")

</div>

Bonjour !

C’est moi qui ai rédigé cet exercice 😉

> [@AlexisAmand](#):
>
> `TypeError: FakeDatetime.date() takes 1 positional argument but 4 were given`

Je comprend que ça fasse bizarre. C’est parce que pendant mes tests, je vérifie que ta fonction fonctionne bien si on la lance aujourd’hui, comme tu t’en doute, mais je vérifie aussi qu’elle fonctionnera dans le futur. Je fais plusieurs tests.

Pour ça j’utilise une bibliothèque nommée [freezegun](https://pypi.org/project/freezegun/), c’est elle qui remplace la vraie date par une “Fake” date.

Quant à ton problème, je suis très surpris que ton code fonctionne sur vscode, que t’affiche-il ?

Chez moi avec un Python 3.12 :

```python
>>> import datetime
>>> aujourdhui = datetime.datetime.now()
>>> aujourdhui.date(2023, 11, 28).weekday()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: datetime.date() takes no arguments (3 given)

```

@entwanne a raison, [la méthode date()](https://docs.python.org/3/library/datetime.html#datetime.datetime.date) n’accepte pas d’arguments.

---

<div class="post-metadata">

**Author:** ![mdk](https://discuss.afpy.org/user_avatar/discuss.afpy.org/mdk/32/3_2.png) [@mdk](https://discuss.afpy.org/u/mdk)\
**Post date:** [Novembre 28, 2023, 2:17 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/5 "2023-11-28T14:17:03Z")

</div>

> [@AlexisAmand](#):
>
> J’avais cru comprendre que c’était un moyen de définir la date sur laquelle on est en train de travailler. 😔

Tu semble confondre le module `datetime` et la classe `datetime`. C’est normal, ils ont le même nom.

Le module datetime tu l’obtiens via `import datetime`, et la classe datetime via `datetime.datetime` (par exemple quand tu fais `datetime.datetime.now()`).

Un bon moyen de ne pas se mélanger les pinceaux c’est de renommer le module `datetime` en `dt` à l’import, en plus c’est plus court à taper :

```
import datetime as dt

```

Comme ça plus d’ambiguité : `dt` c’est le module, `dt.datetime` c’est la classe.

Ainsi tu peux faire :

```python
import datetime as dt

aujourdhui = dt.datetime.now()
annee = aujourdhui.year
mois = aujourdhui.month
jour = aujourdhui.day

print(aujourdhui)

demain = dt.date(annee, mois, jour + 1)

print(demain)

```

Note que je n’utilise pas la méthode `date` de la classe `datetime` mais la classe `date` du module `datetime` (nommé `dt`).

Ahh aussi note que mes maths sont toutes pétées, `jour + 1` c’est plutôt risqué, ça explosera au 32ème jour du mois, mais c’était pour l’exemple 😉

---

<div class="post-metadata">

**Author:** ![AlexisAmand](https://discuss.afpy.org/user_avatar/discuss.afpy.org/alexisamand/32/1137_2.png) [@AlexisAmand](https://discuss.afpy.org/u/AlexisAmand)\
**Post date:** [Novembre 28, 2023, 3:24 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/6 "2023-11-28T15:24:46Z")

</div>

Aaaah d’accord ! Je crois que j’ai compris, j’ai l’impression que c’est un peu comme si j’avais confondu un contenu et un contenant qui auraient le même nom.

Je prends note que c’est plus pratique de renommer les modules !

Quoi qu’il en soit, j’ai pu envoyer un code fonctionnel sur Hackinscience ! Je vais juste voir si je peux l’améliorer, car j’ai quelques années d’expérience en programmation, mon instinct me dit que mon code est trop long, et qu’il a besoin d’être simplifié.

---

<div class="post-metadata">

**Author:** ![AlexisAmand](https://discuss.afpy.org/user_avatar/discuss.afpy.org/alexisamand/32/1137_2.png) [@AlexisAmand](https://discuss.afpy.org/u/AlexisAmand)\
**Post date:** [Novembre 28, 2023, 3:31 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/7 "2023-11-28T15:31:56Z")

</div>

> [@mdk](#):
>
> Quant à ton problème, je suis très surpris que ton code fonctionne sur vscode, que t’affiche-il ?

Je n’ai pas gardé le code, mais j’ai une capture d’écran de Visual Studio, avec une exécution dans la console. Le code est globalement celui que j’avais mis dans mon premier message, mis à part des changements au niveau des print pour me rapprocher du problème demandé.

 ![image](https://discuss.afpy.org/uploads/default/original/2X/1/1f4e2148a811e5fa5b4eb30d454c925bcbdb68a0.png)

Je me suis rendu compte après coup qu’il ne fonctionne pas dans tout un tas de cas à cause de mon while qui est codé avec les pieds.

---

<div class="post-metadata">

**Author:** ![mdk](https://discuss.afpy.org/user_avatar/discuss.afpy.org/mdk/32/3_2.png) [@mdk](https://discuss.afpy.org/u/mdk)\
**Post date:** [Novembre 28, 2023, 5:31 UTC](https://discuss.afpy.org/t/vendredi-13-sur-hackinscience/1836/8 "2023-11-28T17:31:13Z")

</div>

Ohhh je vois, c’est magique, voilà pourquoi ton code fonctionne : on est pas un 13.

@entwanne et moi nous étions arrêtés à la ligne :

```
if day == 13 and today.date(year, month, day).weekday() == 4:

```

en notant que `today.date()` n’accepte pas ces arguments…

Mais nous sommes le 28, pas le 13, et donc pour Python, lorsqu’il voit `day == 13 and ...` s’arrête net, pas besoin de continuer à évaluer, c’est faux dans tous les cas, (`False and True` et `False and False` sont tous les deux faux) donc pas de plantage à cette ligne.

Preuve :

```pycon
>>> if 1 == 2 and this_function_does_not_even_exist():
... pass
... 

```

pas de platage !

Et le reste de ton code utilisait `datetime.date(year, month, 13)`, ce qui est juste (ça crée une instance de la class `date` du module `datetime`), donc ça marchait chez toi.

Et une fois sur HackInScience, hop, je fais [plein de tests](https://framagit.org/hackinscience/hkis-exercises/-/blob/main/exercises/friday-the-13th/check.py?ref_type=heads#L103), des vendredis pas 13, des 13 pas vendredi, des veilles de vendredi 13, des lendemains, etc, etc…

Un de ces cas tombait donc sur `day == 13`, amenant Python à évaluer la partie de droite, après le `if`, celle qui ne fonctionne pas.
