-
Compteur de contenus
10 129 -
Inscription
-
Dernière visite
Tout ce qui a été posté par Malky
-
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
Bon, j'ai une bonne heure de dispo ça devrait suffire. J'ai enlevé les fonctions lambda qui brouillent la lecture plus qu'autre chose, et on va voir ça ligne par ligne. schema = ['R', 'R', 'f', 'f', 'R', 'R', 'f', 'f', 'f'] suite = [1, 2, 3, 4, 5] Initialisation des variables d'entrée comme dans l'exemple def codage(x, y): return (x+y+1)*(x+y+2)/2-x-1 Definition de la fonction codage, je l'ai juste raccourcie pour tenir sur une ligne en ajoutant le '-1' à la fin pour corriger le petit offset schema=[(x=='R') and 'R' or suite.pop(0) for x in schema] Les hostilités commencent ici : le fameux and/or trick pour faire tenir un if/then/else dans une expression, et la compréhension de liste. Si tu coupe le code à cet endroit là et que tu ajoutes un print(schema) tu verras le résultat de cette ligne : dans la liste 'schema', les 'f' sont maintenant remplacés par les nombres de la liste 'suite' dans le bon ordre. Une compréhension de liste c'est la définition d'une liste de manière fonctionnelle, la forme générale c'est : liste2=[f(x) for x in liste] avec f(x) qui représente une opération sur x. Dans l'exemple de map() plus haut, tu peux aussi écrire : liste=[1, 2, 3, 4] liste2=[x+1 for x in liste] print(liste2) >>> [2, 3, 4, 5] La syntaxe est assez claire, je définis une liste qui contient x+1 pour tout x appartenant à 'liste'. Maintenant dans ce cas, l'opération sur x paraît beaucoup plus compliquée, mais en fait elle est assez simple : j'ai utilisé un comportement particulier des opérateurs 'and' et 'or' quand ils traitent autre chose que des booléens ainsi que la tendance générale des ordinateurs à être fainéants. Pour simplifier on va écrire 'a and b or c', l'interpréteur va naturellement évaluer cette expression 'booléenne' de gauche à droite. a est-il vrai ? -> oui, donc il faut évaluer b pour connaître le résultat de 'a and b' -> non, pas besoin d'évaluer b, a étant faux le résultat sera faux de toute façon. ensuite, si 'a and b' est vrai il n'y a pas besoin d'évaluer c car le résultat 'vrai or c' est de toute façon vrai si a ou b est faux, il faut évaluer c car c peut avoir une incidence sur le résultat au final 'a and b or c' revient à écrire : 'if a then b else c' c'est un if/then/else raccourci Mais en plus, python garde le type original des objets évalués : une string "pipi" vaut 'vrai' alors qu'une string "" (vide) vaut 'faux' sauf que les objets gardent leur type et leur valeur au travers des opérateur 'and' et 'or'. Dans la ligne de code en question : a -> (x=='R') <- booleen b -> 'R' <- string c -> suite.pop(0) <- nombre Dans ce cas 'a and b or c' signifie : if (x=='R') then 'R' else suite.pop(0) pour tout x appartenant à la liste 'schema' Le résultat est tout de suite visible : les 'R' restent des 'R', mais les 'f' (en fait tout ce qui n'est pas 'R') sont remplacés par le premier élément pris dans 'suite' et ainsi de... suite. Pourquoi and/or ? parce qu'on ne peut pas caser de if/then/else dans une expression, donc on ne peut pas non plus le caser dans une compréhension de liste. def R(liste): a, b, reste=liste[0], -1, liste[1:] On attaque R(). La première ligne est une assignation multiple : a=liste[0] b=-1 reste=liste[1:] Là tu as correctement interprété les assignations, le b=-1 c'est juste pour instancier la variable (sinon il existe un cas ou b peut être utilisé sans avoir été défini), j'aurais tout autant pu écrire b="coucougnette farcie" la valeur n'a aucune importance. J'assigne liste[0] à 'a' et juste après tu peux voir qu'il y a une autre assignation de a, mais qui est conditionnelle : si (juste après) liste[0] se révèle valoir 'R' la valeur de a va changer, en l'assignant dès le début à ligne[0] je donne sa valeur à a dans le cas où liste[0] n'est pas 'R'. Pour 'reste' il s'agit aussi d'une assignation par défaut : tous les éléments de liste sauf le premier (qui est dans 'a') if liste[0]=='R': (a, reste)=R(liste[1:]) Si liste[0] est 'R', je fais une assignation multiple avec le resultat d'un autre appel à la fonction 'R'. Si tu regardes un peu plus bas, la fonction 'R' possède deux lignes 'return' : une pour tout le long du déroulement du code, qui renvoie deux valeurs : codage(a, b ) et reste[1:], et une autre pour la fin du code quand la liste d'origine est réduite à un nombre : le résultat final (return a). Ici, on a pas encore fini de parcourir l'arbre donc R renvoie deux valeurs : un nombre et la partie de liste qui n'a pas encore été parcourue à ce moment là. La liste 'reste' est assez troublante : elle est rendue nécessaire par le fait que si tu connais le fils de gauche de ton noeud courant (c'est l'élément suivant dans la liste), tu ne connais pas la position du fils de droite avant d'avoir parcouru tout le sous-arbre de gauche. D'où la nécessité de découper la fonction récursive en deux parties : une simple qui gère les fils de gauche au fur et à mesure qu'ils se présentent, et une autre pour gérer les fils de droite une fois que la gestion des fils de gauche te retourne la liste qui reste une fois que le sous-arbre de gauche a été parcouru. Le fait que R soit récursive te garanti que quand le premier appel récursif à R se termine, la liste 'reste' que la fonction retourne commence par le fils de droite de ton noeud de départ, et il en va de même pour tous les noeuds intermédiaires. C'est assez ignoble au niveau de l'occupation mémoire comme algo, mais ça marche de manière 'purement' récursive alors que si tu utilises des variables globales et des compteurs, tu auras au mieux quelque chose d'hybride itero-récursif. Pour revenir au code : si le premier noeud rencontré est un 'R', on relance R sur le sous-arbre de gauche du noeud courant en l'explorant, à chaque fois, comme s'il s'agissait d'un arbre entier (avec d'autres noeuds et des fils de gauche et de droite). if reste: if reste[0]=='R': (b, reste)=R(reste[1:]) else: b=reste[0] return codage(a, , reste[1:] else: return a Là il y a une grosse partie de l'algo. On a d'abord une vérification : est-on à la fin de l'arbre ? Si c'est la cas, ça veut dire que l'invocation courante de R à été lancée avec une liste vide comme paramètre 'liste', donc je fais un check : if reste: (il reste des noeuds à explorer) else: return a <- à ce moment là 'a' contient le résultat du tout dernier 'codage' une fois que la liste est réduite à deux nombre, et ne contient plus du tout de 'R' S'il reste des noeuds à explorer : if reste[0]=='R': (b, reste)=R(reste[1:]) On fait la même chose que pour 'a' plus haut : si le fils de droite du noeud courant est un 'R', on relance la machine sur le reste de la liste. Note bien que dans cet appel de 'R' le paramètre reste[1:] va devenir la variable 'liste' de cet appel récursif. De nouveau il s'agit d'une assignation multiple : b=codage(a, b ) <- les variables a et b d'un autre appel à la fonction! et reste=le reste[1:] de l'autre appel également! En gros (c'est pas facile à expliquer en fait, ça risque de ne pas être facile à comprendre) la liste est 'grignotée' à chaque appel de fonction jusqu'à ce que les variables a et b dans l'instance de R contiennent tous les deux des nombres, auquel cas on peut enfin appliquer la fonction codage dessus, et retourner le résultat : else: b=reste[0]return codage(a, , reste[1:] A cet endroit du code, il n'y a plus de 'R' : à chaque fois qu'on on a rencontré un on a relancé la fonction R récursivement sur le sous-arbre, à gauche ou a droite. On est donc sûrs que a et b contiennent bien un nombre : soit parce qu'il s'agit d'un fils 'final', soit parce que les appels récursifs à R ont ramenés le sous-arbre correspondant à un seul nombre. On peut donc appliquer codage à nos deux nombres et retourner le résultat de l'opération à l'appel à R au dessus (on 'remonte' dans l'arbre avec le résultat du sous-arbre), accompagné à chaque fois du reste de la liste qui n'a pas encore été explorée. print(R(schema)) Et voilà, l'arbre est plié, il ne reste plus qu'un seul nombre : le résultat final de la fonction (du tout premier appel à R, donc) La récursivité c'est pas simple, et le sujet en lui même rajoute de la complexité avec cette histoire de fils de droite. J'aurais probablement du temps ce soir si tu as des questions (et il risque d'y en avoir, je n'ai pas l'impression d'avoir été limpide dans les explications) D'ici là, si tu as accès à un interpréteur python, en mettant des print partout tu peux facilement avoir un aperçu de comment l'algo fonctionne (en particulier comment il grignote la liste jusqu'à la fin) -
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
Petit errata : dans le code plus haut à la ligne "return codage(a, B, reste[1:]" le 'b' est en minuscule sinon l'interpréteur ronchonne. map(f, séquence) ça applique la fonction f a chaque élément de la séquence et ça retourne la séquence contenant les résultat de tous les appels à la fonction f liste=[1, 2, 3, 4] def f(x): return x+1 liste2=map(f, liste) print(liste2) >>> [2, 3, 4, 5] Elle peut facilement être remplacée par une list comprehention, c'est même plus dans l'esprit python (map c'est un peu vieillot maintenant) En list comprehension ça donne : schema=[(x=='R') and 'R' or suite.pop(0) for x in schema] Je devrais avoir 1h ou 2 de libre cet aprèm', j'essaierai de poster qqs commentaires sur la fonction R() qui n'est pas évidente à lire. -
Images fun et leurs interminables commentaires
Malky a répondu à un sujet de Librekom dans La Taverne
Le plus souvent (1 cas sur 2 environ) il y a juste besoin d'une pince étau avec des mords propres : dans ce cas ça prend environ 5 secondes et le type (ou la dame) passe le reste de la journée à se demander pourquoi il/elle a passé 5 secondes chaque jour à tourner la clé dans la serrure alors que bon... crac c'est ouvert. Quand la pince étau ne suffit pas, il faut la perceuse avec des mèches bien dures. Et il y a les barillets de sécurité avec plaque en tungstène inclinée pour faire casser les mèches, etc. Celles là sont plus coton. Dans le cas extrême il faut défoncer la porte... -
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
schema = ['R', 'R', 'f', 'f', 'R', 'R', 'f', 'f', 'f'] suite = [1, 2, 3, 4, 5] codage=lambda x, y: (x+y+1)*(x+y+2)/2-x-1 schema=list(map(lambda x: (x=='R') and 'R' or suite.pop(0), schema)) def R(liste): a, b, reste=liste[0], -1, liste[1:] if liste[0]=='R': (a, reste)=R(liste[1:]) if reste: if reste[0]=='R': (b, reste)=R(reste[1:]) else: b=reste[0] return codage(a, , reste[1:] else: return a print(R(schema)) 13 lignes en tout dont 10 pour le code hors initialisation des variables d'entrée et le print() de fin Résultat: python3 pipi.py 257394.0 Qui est à priori la réponse exacte : dans ta fonction codage (0,0) donne 1, alors que d'après le dessin ça devrait être 0 C'est vraiment du code torché vite fait et je ne te conseillerais pas de rendre le truc tel quel mais ça peut te donner des pistes. A la limite ça peut faire sourire le prof de lui emmener cette version en plus de la tienne, juste pour les "10 lignes minimum" -
Images fun et leurs interminables commentaires
Malky a répondu à un sujet de Librekom dans La Taverne
Tu serais surpris à la fois de la complexité de certaines serrures, et de l'extrême facilité avec laquelle on peut ouvrir à peu près toutes les autres -
huhu, je suppose qu'il y a causalité dans ce cas
- 5 338 réponses
-
Ooh elle est jolie celle là
-
Hollande plus socialiste encore que Sarkozy
Malky a répondu à un sujet de pankkake dans Politique, droit et questions de société
La passion de la pêche et le penchant pour les boissons alcoolisées qui titrent plus de quarante degrés. -
Mégaupload fermé ! + représailles…
Malky a répondu à un sujet de Sparo47 dans Science et technologie
J'en ai une de carte PCMCIA qui traine dans un carton, y'a marqué "hühessbeh m'a tuer" dessus en lettres de sang -
Mégaupload fermé ! + représailles…
Malky a répondu à un sujet de Sparo47 dans Science et technologie
Ou via disquette 5"1/4, c'est encore pire! -
Mégaupload fermé ! + représailles…
Malky a répondu à un sujet de Sparo47 dans Science et technologie
Voilà, c'est une tempête dans un verre d'eau. Le but n'est pas d'avoir un stockage ultra-turbo-sécurisé de toute façon. -
huhu là c'est du depardiou au cube
-
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
Oui il y en a, et non c'est pas pour débutants. Par contre c'est excellent pour assommer un débutant : ~1,5 kg pièce -
Hou c'est pas tout simple l'histoire d'Atari
-
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
(curieux double post) -
Introduction décente à l'orienté objet ?
Malky a répondu à un sujet de Yozz dans Science et technologie
BOOOOOOH (le premier tome est chez un ami en ce moment, du coup il n'est pas sur la fôtô) -
atari, amstrad, puis amiga, et au collège on avait les infâmes mo-5 et to-7 souvenirs...
-
C'est pas bien de se moquer du pitikiki des chinois.
-
Le PS dévoile son projet Éducation nationale
un sujet a répondu à Malky dans Politique, droit et questions de société
Mon prof de méca en sup/spé le faisait régulièrement, mais je pense que c'est assez anecdotique globalement. -
A l'epoch y'avait pas encore d'écran lcd aux caisses qui montrent une zolie foto du bidule qui vient de passer sous la douche(tte), et ce genre de combine n'était pas encore bien connu. Depuis la sécurité a fait des progrès et perso je ne m'y amuserais plus trop à part dans un supermarché de campagne peut-être. Mais bon malgré mes efforts (et il y en a eu) je n'ai jamais égalé une connaissance qui a réussi à faucher une échelle (et pas le petit modèle) dans un grand magasin de bricolage. Mais bon il a triché : il n'est pas passé aux caisses. Tiens ça me fait penser à un grand classique : qui ici s'est déjà amusé à armer des tapettes à souris dans un magasin juste pour le plaisir de savoir que quelqu'un aura mal aux doigts dans les jours qui suivent ?
-
Petit joueur n x une bouteille de ouiski potable qui passe au prix d'une bouteille de label 5, ça fait plus que rentabiliser les pages d'autocollants imprimables et le temps passé à noter les barcodes dans un calepin. Et ça, c'est juste pour les bouteilles de ouiski.
-
-
Port d'armes en France
Malky a répondu à un sujet de lord byron dans Politique, droit et questions de société
Le pire c'est à la fin je trouve, quand elles parlent au type qui s'est fait défoncer la portière "Vous inquiétez pas monsieur, on a tout vu, on pourra témoigner pour vous" "Mais il est où ?" "Ben il est parti" facepalm --intensity=max -
Émeutes Et Insécurité En France
Malky a répondu à un sujet de Wali dans Politique, droit et questions de société
Ooh je ne la connaissais pas celle-là, merci