HackInScience.org: Temperature Class

Bonjour à tout le monde…

J’en suis rendu au problème Training #26.

J’ai dû passer l’équivalent d’une journée sur ce problème, et je n’arrive toujours pas à trouver la solution.

Dans le code suivant:

class Temperature:
    fahrenheit = TransF()
    celsius = TransC()
    kelvin = TransK()


t = Temperature()
t.celsius = 100

Lorsque je tape t.celius = 100, j’aimerais que la valeur 100 soit passée à la classe TransC().

Mais ce qui se passe, c’est que la valeur de la variable celsius est tout simplement remplacée par 100 et TransC() est remplacée.

Je pense que je dois repenser tout le problème… et revoir des principes de bases.

La le problème c’est qu’il faut que lorsqu’on modifie l’attribut d’une instance de classe, il faut que cela enclenche la modification des autres attributs de cette instance.

Et là je bloque. Comment, en modifiant un attribut d’une instance de classe, je pourrais automatiquement modifier ses autres attributs ?

Il doit y avoir une question de setter et de getter mais je ne vois pas comment les organiser…

Voici ci dessous le code complet que j’ai réalisé, mais qui ne fonctionne pas pour la raison que je donne ci-dessus…

class TransF:
    def __init__(self, initial_value=None): #initial_value est toujours égale à None...)
        if initial_value is None:
            self.val_f = 0
        else:
            self.val_f= initial_value

    def __get__(self, obj, objtype):
        print(self.val_f)
        obj.celsius = (self.val_f - 32) * (5/9)
        obj.kelvin = (self.val_f + 459.67) * (5/9)
        return self.val_f

    def __set__(self, obj, val_f):
        self.val_f = val_f


class TransC:
    def __init__(self, initial_value=None):
        if initial_value is None:
            self.val = 0
        else:
            self.val = initial_value

    def __get__(self, obj, objtype):
        obj.kelvin = self.val + 273.15
        obj.fahrenheit = self.val * 1.8 + 32
        return self.val

    def __set__(self, obj, val):
        self.val = val


class TransK:
    def __init__(self, initial_value=None):
        if initial_value is None:
            self.val = 0
        else:
            self.val = initial_value

    def __get__(self, obj, objtype):
        obj.celsius = self.val - 273.15
        obj.fahrenheit = self.val * (9/5) - 459.67
        return self.val

    def __set__(self, obj, val):
        self.val = val


class Temperature:
    fahrenheit = TransF()
    celsius = TransC()
    kelvin = TransK()


t = Temperature()
t.celsius = 100

print(t.fahrenheit)
print(t.celsius)
print(t.kelvin)

Bonjour,

La question propose de lire la doc python à propos des descriptors, (par exemple property )

https://docs.python.org/fr/3/library/functions.html#property

C’est une très bonne piste…

Bonjour,

oui je vais la relire, il y a un truc qui a dû m’échapper.

1 J'aime

Ce que je te conseille @RafaRemote c’est de n’avoir qu’une seule source de vérité dans ta classe.

Personellement j’utilise kelvin comme source de vérité, mais peu importe.

Donc :

t1.kelvin = 0  # met juste kelvin à jour
t1.celsius = 0  # fait la conversion et met kelvin à jour
print(t1.fahrenheit)  # consulte la valeur de kelvin, la seule stockée, la seule vérité, et la transforme en farenheit, et la renvoie

Merci pour le conseil ! J’en prends bonne note.

Ça me paraît étrange en voyant ton code, puisque celsius est un attribut de classe de type descripteur, qui permet donc ce genre de comportement.

De loin comme ça, grosso modo c’est sûrement un truc dans ce genre là, sauf que ça ne marche pas héhé…

J’avoue que cette exercice m’a mis un petit coup au moral en voyant que je n’étais capable de piger le truc… qui paraît pourtant pas si compliqué que ça… Du coup j’ai rien fichu depuis ma dernière tentative, et c’est pas bon du tout… Et j’ai plein de trucs à faire à côté de ça, des cours à lire, un projet à étudier, mais je me suis pourtant mis dans la tête de finir au moins la partie training de HackInScience avant de faire quoique ce doit d’autre… (mon coach m’avait conseillé de m’exercer sur le site avant de continuer). Je dois absolument réussir à résoudre ce genre ce problème, si je n’arrive pas à me dépatouiller avec cet exercice maintenant, c’est pas la peine de continuer les études que j’ai entrepris.

Il faut absolument que je comprenne comment ça marche, la logique qui se met en place, ce qui se passe.

Ce n’est sans doute pas la meilleure des façons de penser, sans doute, c’est pourtant ce que je ressens.

Je m’y remet de suite, je vais relever mes manches et ré-attaquer la doc! Je sens que je vais pas bien dormir ce soir si j’y arrive pas avant d’aller me coucher. Allez hop!

2 J'aime

Je peux te conseiller ce cours que j’ai écrit et notamment la partie dédiée aux descripteurs : Accesseurs et descripteurs - Notions de Python avancées • Tutoriels • Zeste de Savoir
C’était d’ailleurs illustré avec un exemple sur la température.

Si tu connais déjà en bref le modèle objet de Python, tu devrais pouvoir suivre le chapitre

1 J'aime

@RafaRemote n’hésite pas si a un moment une retour du bot n’est pas super explicite, je peux toujours améliorer ça.

Je pense que le plus simple est d’utiliser le decorator @property tel l’exemple class C ici.

https://docs.python.org/fr/3/library/functions.html#property

self._kelvin (par exemple) remplacerait self._x

Merci, je vais lire ça ce soir.

Merci ! Ben du coup juste une question… est-ce qu’on peut utiliser le décorateur property ?

Oui, je me posais justement la question, du coup comme tu vois j’ai posé la question à mdk.

Je l’ai utilisé avec succès sur cette exercice :wink:

Oui, et si ça valide comme ça c’est bon pour moi. Tu pourras revenir dessus plus tard pour t’entraîner à le faire avec un descripteur le jour où tu voudras t’entraîner sur les descripteurs.

(J’ai rédigé cet exercice pour un élève qui voulait s’entraîner avec les descripteurs, mais tant que vos réponses fonctionnent elles sont bonnes ^^)

Ah ok, parce que la je m’acharnais à contourner ‘property’… Je pense que je peux trouver la solution en utilisant ‘super()’ , mais ça me donne l’impression de contourner le problème…

Peut-être que le cours que je suis va m’éclairer aussi, car là je viens de voir les property et c’était limpide.

L’espoir fait vivre hein …

Mais tu as raison, je vais pas resté bloqué là dessus. Je reviendrais avec une solution 100% descripteurs plus tard.

1 J'aime

Bonjour,
Rafaremote, un cour en vidéo que je peux te conseiller suf fun MOOC:
https://www.fun-mooc.fr/fr/cours/python-3-des-fondamentaux-aux-concepts-avances-du-langage/

il y a une partie property très bien expliquée.

2 J'aime

Bonjour :slight_smile:

Les property je pense bien avoir compris, même si je n’ai pas encore réussi à solutionner le problème avec.

Mais je vais tout de même regarder la référence que tu donnes, je vais voir si quelque chose m’a échappé.

J’ai comme l’impression que l’usage de super() est assez important.

Tu sais que c’est lui que j’écoutais ce matin sur la vieille chaîne Youtube:

https://www.youtube.com/channel/UCWpkVtH93qQ5JpSZEwONjGA/videos

hehe

Mais je crois que dans le site que tu indiques les cours ont du être rafraichi. Je vais voir ça.