Python : un problème sûrement très con

Répondre
Partager Rechercher
Citation :
Publié par Fugo
Tu veux dire de mettre en place une méthode de pseudo dichotomie ? On teste une valeur au hasard de km et selon où on se place (E>D ou E<D) on ajuste cette valeur en la divisant par deux ou en l'augmentant de 50% ?

Et la boucle while avec nombre maximum d'itération intuitivement j'aurai tendance à la fabriquer en ajoutant une nouvelle variable locale qui s'incrémente tout le temps, mais il y a mieux pour faire ça ?
C'est moins une dichotomie qu'une descente de gradient. Basiquement l'algo revient à faire évoluer x (le kilométrage) tel que : est une constante positive.

D'après la formule, x augmente si pour cette valeur le diesel est plus cher que l'essence, sinon il diminue. Le seul point d'équilibre est celui où ça revient au même.
Si le problème est mal posé alors l'algo peut boucler infiniment (on met alors une valeur maximum au nombre d'itérations dans la condition du while) ou bien retourner une réponse négative.
Pour moi c'est un bon exemple d'algo : on approxime la solution avec une méthode itérative, et on peut facilement illustrer ce qui se passe si le problème initial est mal posé ou n'a pas la solution attendue (ie il existe un kilométrage à partir duquel il vaut mieux rouler au diesel).
(attention, message pas sérieux)
Dans un esprit de complétude - et si tu veux donner des cauchemars au profs d'info - tu peux aussi essayer la troisième manière de faire les boucles: une fonction récursive.
Tu fais ta fonction de récursion, tu laisses Python crasher si la profondeur de récursion excède celle acceptée par Python, et tu récupères l'erreur dans un try/except.
C'est complètement idiot et dégueulasse, c'est spécifique à Python... mais ça peut être un entraînement à la récursion.

Edit: (partie plus sérieuse) ah oui, et aussi dans le code du premier message, l'erreur est "ValueError", pas "TypeError"

Dernière modification par Chernish ; 09/05/2019 à 08h02.
Citation :
Publié par Von
Le while à itérations limitées j'aurais aussi tendance à le faire avec une variable counter = 0, et incrémentation counter +=1 à chaque itération, et enfin un if counter == 10, break. Y a probablement plus élégant ceci dit
Un while (counter < 10) fonctionne tout aussi bien
Comme l'OP est en train d'apprendre et que je suis dans un bon jour, voilà un exemple complet à reconstruire petit à petit avec les étudiants :
Code:
prix_essence = 1.5
conso_essence = 6.7
prix_vehicule_essence = 16000

prix_diesel = 1.4
conso_diesel = 4.9
prix_vehicule_diesel = 19000

def E(x):
    return prix_vehicule_essence + prix_essence*conso_essence*x/100.

def D(x):
    return prix_vehicule_diesel + prix_diesel*conso_diesel*x/100.



if E(0) == D(0) and  E(1) == D(1):
    print('Essence identique a Diesel')
    
else:
    
    # config algorithme
    max_count = 1000
    precision = 0.1
    counter = 0
    k = 40
    
    # point de depart (pas important)
    x = 0

    while abs(D(x) - E(x)) > precision and counter < max_count:
        counter += 1
        dx = k*(D(x) - E(x))

        print('x = {:.1f} km \t {:.1f} (d) vs {:.1f} (e) \t dx = {:.2f}'.format(x, D(x), E(x), dx))
        x += dx
        
        
    if abs(D(x) - E(x)) < precision:
        # point d'equilibre
        if x < 0:  
            # solution incoherente
            print('Diesel toujours mieux')
        else:
            # bonne solution
            print('Kilometrage min pour le diesel : {:.1f} km'.format(x))
    else:
        # pas de solution
        print('Iteration max -> Essence toujours mieux')
Ok, c'est assez élégant comme approche effectivement.

Maintenant je me pose aussi des questions sur la manière d'aborder l'enseignement (en fait, je pense qu'il faudrait que ça soit pas le prof de maths qui fasse ça mais bon, on va pas trop en demander) de Python:
Je pense qu'il est assez pertinent dans un premier temps de fabriquer une version fonctionnelle d'un programme utilisant les bases du langage (déclaration de variables principalement) mais sans trop de technicité (déjà comprendre l'indentation, la déclaration, le while, ça me paraît beaucoup pour des 2nd)

En d'autres termes, mettre sur papier les objectifs du programme et ses étapes :
Je dois récupérer les variables
Je dois tester que
Je dois faire en sorte que
J'obtiens


ça c'était notre première version pour trouver la réponse (sans se soucier d'erreurs d'entrées et d'incohérence)

Code:
print ("prix du vehicule essence ?")  #On récupère les variables de l'exercice
p1= float(input())
print ("prix du vehicule diesel ?")
p2= float(input())
print ("consommation mixte essence?")
c1= float(input())
print ("consommation mixte diesel?")
c2= float(input())
print ("tarif du diesel?")
D= float(input())
print ("tarif de l'essence?")
E= float(input())
print ("entrer le pas a tester en km")
P= float (input()) #Le pas à définir par l'utilisateur : 1 sera long mais précis, 100 sera rapide mais imprécis.

M=0 #On initialise
K=p1 #On définit K et L comme les prix totaux des véhicules (qui, à l'achat, sont égaux au prix d'achat)
L=p2

while L>K: #Tant que la valeur cumulée du diesel est > à celle de l'essence

    K=p1+c1*M*E/100 #On recalcule K et L (première boucle pour m=0)
    L=p2+c2*M*D/100
    M+=P #On incrémente M du pas P définis dans la première partie
    print (M) #cette ligne ici affiche une ligne par calcul ce qui peut faire beaucoup de lignes


Et moi dans mon esprit après ça j'ai tenté de chercher les pistes d'amélioration et de monter en compétence pour les gérer et améliorer le code.

En fait la question : est-ce une approche pertinente pour apprendre (et aider à apprendre) le Python ou alors vaut-il mieux chercher tout de suite l'élégance et le moins de code possible ?
Gros débat

En tout cas, merci pour vos participations, déjà j'ai compris toutes les propositions faites, preuve que mon apprentissage avance ... !

Mon groupe de formation contient une majorité de collègues >45 ans qui regardent l'apparition de cet aspect de programmation et d'algorithmie d'un mauvais oeil, mais moi je suis bien content, ça me permet de travailler un domaine sympa et stimulant ^^
Personnellement, je trouve que dans cet exercice il y a trop d'entrées dans votre script Python.
D'ailleurs si j'ai bien compris toutes les valeurs sont dans l'exercice donc il ne devrait pas y avoir de données à saisir pendant l'exécution du script.
C'est juste 6 affectations de variables en début de script et pas 6 input qu'ils attendent.

Et imposer un pas de 1 km si vous voulez vraiment le faire avec une boucle (le "point d'équilibre" se trouve sans aucune boucle en résolvant une équation du premier degré avec une inconnue, ce qu'on voit en classe de 4ème)

L'utilisation de boucle me semble totalement inadaptée pour les élèves de secondes pour ce problème.
Il y a sans nul doute des problèmes bien meilleurs qui permettront aux élèves d'utiliser les boucles de manière pertinente.

Par exemple les bénéfices B(x) qui seraient une fonction polynômes du second degré où x est le nombre d'objet vendu.
Et déterminer combien ils doivent vendre d'objets pour que le bénéfice soit positif (ou dépasse un certain montant).

Ou alors une fonction recette R(x) et coût C(x) (polynômes du second degré) et ils doivent déterminer quand l'entreprise fait des bénéfices.

Dernière modification par Melchiorus ; 09/05/2019 à 19h30.
Citation :
Publié par Fugo
Maintenant je me pose aussi des questions sur la manière d'aborder l'enseignement (en fait, je pense qu'il faudrait que ça soit pas le prof de maths qui fasse ça mais bon, on va pas trop en demander) de Python:
Je pense qu'il est assez pertinent dans un premier temps de fabriquer une version fonctionnelle d'un programme utilisant les bases du langage (déclaration de variables principalement) mais sans trop de technicité (déjà comprendre l'indentation, la déclaration, le while, ça me paraît beaucoup pour des 2nd)
Je pense au contraire que les profs de maths sont de loin les plus appropriés à enseigner le code (et le Python en particulier). La conception d'algorithmes, même très simples, revient au final à poser un problème mathématique, et j'ai remarqué par exemple, en me remettant aux maths pour accompagner mon apprentissage du Python, que les similarités sont très grandes, ne serait-ce que la notion de fonction qui est très proche en maths et en code.

Le problème des maths au lycée c'est souvent qu'il est difficile d'intéresser les élevés quand on ne voit pas d'application pratique. L'ajout du code permet justement d'apporter cette application pratique, et faire le lien entre la théorie et la pratique.

Bref, ne pense pas que tu n'es pas le plus adapté pour faire ça, je pense que c'est au contraire une excellente chose ^^

De même, apprendre le fonctionnement de la syntaxe en Python est à la portée de n'importe quel élève de seconde, ce langage étant justement conçu pour avoir une syntaxe simple et lisible, puisque ça demande en gros de respecter deux gros principes simples, les : et l'indentation pour déclarer la hiérarchie. Les boucles for et while sont un niveau supérieur déjà, mais il est difficile de faire quelque chose d'un peu rigolo sans taper là dedans.
Citation :
Publié par Fugo
(...)En fait la question : est-ce une approche pertinente pour apprendre (et aider à apprendre) le Python ou alors vaut-il mieux chercher tout de suite l'élégance et le moins de code possible ?
Gros débat
(...)
Lors une première exposition au code, quel que soit le langage, c'est déjà beau si les élèves retiennent la grammaire de base. Leur demander de faire court ne servirait qu'à les embrouiller, d'autant plus que "plus court" n'est pas forcément "plus élégant", ni même "plus efficace".

Privilégie la lisibilité du code et la présence de commentaires à la brièveté ou à l'élégance. Enfin, dis-leur que tu privilégies la lisibilité, parce qu'en fait ils seront tellement occupés à obtenir le résultat juste que la lisibilité leur sera secondaire.
Citation :
Publié par Melchiorus
L'utilisation de boucle me semble totalement inadaptée pour les élèves de secondes pour ce problème.
Il y a sans nul doute des problèmes bien meilleurs qui permettront aux élèves d'utiliser les boucles de manière pertinente.

Par exemple les bénéfices B(x) qui seraient une fonction polynômes du second degré où x est le nombre d'objet vendu.
Et déterminer combien ils doivent vendre d'objets pour que le bénéfice soit positif (ou dépasse un certain montant).
Oui dans le cas de essence vs diesel le problème est trop simple à résoudre mathématiquement pour voir l'intérêt d'un algorithme (à part qu'on peut vérifier).
L'approche itérative (qui s'apparente à une descente de gradient très simplifiée puisque sans véritable dérivée) que j'ai présentée marche (à peu près) pour toutes les fonctions simples, faut juste avoir une idée de sa croissance ou décroissance.

Le débat sur l'élégance n'en est pas un, quasi tous les gourous mettent en avant la lisibilité et la communication des intentions avant l'élégance et même la performance. Mais pour des lycéens c'est HS, déjà que pour mes étudiants en Master c'est limite...
Citation :
Publié par Melchiorus
Personnellement, je trouve que dans cet exercice il y a trop d'entrées dans votre script Python.
D'ailleurs si j'ai bien compris toutes les valeurs sont dans l'exercice donc il ne devrait pas y avoir de données à saisir pendant l'exécution du script.
C'est juste 6 affectations de variables en début de script et pas 6 input qu'ils attendent.

Et imposer un pas de 1 km si vous voulez vraiment le faire avec une boucle (le "point d'équilibre" se trouve sans aucune boucle en résolvant une équation du premier degré avec une inconnue, ce qu'on voit en classe de 4ème)

L'utilisation de boucle me semble totalement inadaptée pour les élèves de secondes pour ce problème.
Il y a sans nul doute des problèmes bien meilleurs qui permettront aux élèves d'utiliser les boucles de manière pertinente.

Par exemple les bénéfices B(x) qui seraient une fonction polynômes du second degré où x est le nombre d'objet vendu.
Et déterminer combien ils doivent vendre d'objets pour que le bénéfice soit positif (ou dépasse un certain montant).

Ou alors une fonction recette R(x) et coût C(x) (polynômes du second degré) et ils doivent déterminer quand l'entreprise fait des bénéfices.
Oui, clairement, mais naivement on s'était demandé si on pouvait ensuite faire les essais avec d'autres véhicules d'autres marques ou type de voiture pour aller plus loin, d'où l'utilisation d'input.

Citation :
Publié par Von
Je pense au contraire que les profs de maths sont de loin les plus appropriés à enseigner le code (et le Python en particulier). La conception d'algorithmes, même très simples, revient au final à poser un problème mathématique, et j'ai remarqué par exemple, en me remettant aux maths pour accompagner mon apprentissage du Python, que les similarités sont très grandes, ne serait-ce que la notion de fonction qui est très proche en maths et en code.

Le problème des maths au lycée c'est souvent qu'il est difficile d'intéresser les élevés quand on ne voit pas d'application pratique. L'ajout du code permet justement d'apporter cette application pratique, et faire le lien entre la théorie et la pratique.

Bref, ne pense pas que tu n'es pas le plus adapté pour faire ça, je pense que c'est au contraire une excellente chose ^^

De même, apprendre le fonctionnement de la syntaxe en Python est à la portée de n'importe quel élève de seconde, ce langage étant justement conçu pour avoir une syntaxe simple et lisible, puisque ça demande en gros de respecter deux gros principes simples, les : et l'indentation pour déclarer la hiérarchie. Les boucles for et while sont un niveau supérieur déjà, mais il est difficile de faire quelque chose d'un peu rigolo sans taper là dedans.
C'est pas non plus faux, mon seul contre argument est que du coup je n'ai jamais étudié Python dans mes études (même si j'ai appris les bases d'autres langages), du coup ça nécessite (et je pense que je ne serai pas le seul) un immense travail de MAJ pour mon cerveau et je pense que mon niveau en Python ne pourra jamais être 'Exert'

Citation :
Publié par Chernish
Lors une première exposition au code, quel que soit le langage, c'est déjà beau si les élèves retiennent la grammaire de base. Leur demander de faire court ne servirait qu'à les embrouiller, d'autant plus que "plus court" n'est pas forcément "plus élégant", ni même "plus efficace".

Privilégie la lisibilité du code et la présence de commentaires à la brièveté ou à l'élégance. Enfin, dis-leur que tu privilégies la lisibilité, parce qu'en fait ils seront tellement occupés à obtenir le résultat juste que la lisibilité leur sera secondaire.
Oui, ça pour le coup ... C'est encore un point qui rejoint le précédent, parallèle maths / info sur la clarté et la maîtrise de la rédaction.


En tout cas merci pour vos interventions qui me font bien mettre en perspective
Je vais essayer de trouver un problème plus complexe mais toujours ancré dans la réalité pour essayer de voir plus loin
Citation :
Publié par Fugo
C'est pas non plus faux, mon seul contre argument est que du coup je n'ai jamais étudié Python dans mes études (même si j'ai appris les bases d'autres langages), du coup ça nécessite (et je pense que je ne serai pas le seul) un immense travail de MAJ pour mon cerveau et je pense que mon niveau en Python ne pourra jamais être 'Exert'
Ca clairement, même si en maths ton esprit a déjà la bonne tournure, ça reste beaucoup à apprendre, je me demande quels moyens met l'EN pour vous former là dedans d'ailleurs.

Sinon, je ne suis pas concerné tout de suite parce que ma fille rentre seulement au collège en septembre, mais j'essaie déjà de l'initier au code (avec du Scratch sur code.org), mais par curiosité, c'est quoi le programme de Python en seconde ? Il y a une page qui le référence ?
Pour le collège si ta fille gère le Scratch ça sera bien car un exo du DNB est sur Scratch (mais c'est assez facile généralement, fais toi une idée en regardant les annales)


Moi je suis en Lycée Professionnel (ce qui risque de ne pas t'intéresser) mais globalement :

https://www.ac-paris.fr/portail/uplo...le_1077311.pdf
Citation :
En seconde,les élèves passent progressivement de l’utilisation du langage de programmation visuel qu’ils ont utilisé dans les classes antérieures au langage interprété Python. Ce dernier a été choisi pour sa concision, sa simplicité, son implémentation dans de multiples environnements et son utilisation dans l’enseignement supérieur. On ne vise pas la maîtrise d’un langage de programmation ni une virtuosité technique ; la programmation est un outil au service de la formation des élèves à la pensée algorithmique. L’accent est mis sur la programmation modulaire qui consiste à découper une tâche complexe en tâches plus simples. Pour ce faire, les élèves utilisent des fonctions informatiques
2019-05-10 10_11_15-Window.png


Et en seconde générale, @Melchiorus sera probablement plus à même de répondre selon les derniers changements mais :


2019-05-10 10_13_28-Window.png
http://cache.media.education.gouv.fr...ths_757953.pdf


C'est le doc le plus récent que j'ai trouvé mais je ne sais pas si c'est encore actuel.
Citation :
Publié par Fugo
En tout cas merci pour vos interventions qui me font bien mettre en perspective
Je vais essayer de trouver un problème plus complexe mais toujours ancré dans la réalité pour essayer de voir plus loin
Pro tip : si ton problème est ancré dans la réalité alors les variables utilisées dans le code ont un sens, et leur nom devrait refléter ce sens.
conso_diesel sera toujours mieux que c1, surtout quand quelqu'un d'autre relit le code (ce quelqu'un d'autre pouvant être toi-même dans 2 mois).

Si les étudiants parlent un peu anglais, le programme doit quasiment pouvoir être lisible en tant que texte.
Souvent les noms de variables sont d'ailleurs écrite en anglais comme ça tlm comprends peu importe la langue d'ailleurs.
En tout cas relire du code ou le nom des variables n'est pas dans une langue que tu comprends et/ou ne veut rien dire (type c1, c2, c3, a, b, c,... c'est juste bon pour des indices) c'est vraiment casse couille car ça devient difficile de suivre.

Je plussoie donc très fortement Kermo.
Je vais faire gaffe aux noms de variables

Nouvel exercice de pensée : essayer un truc récursif + vérifier que l'entrée clavier soit bien un nombre (c'est ça qui m'aura le plus embêté)

Code:
from lycee import *

def fibonacci(n):
    if n==1 or n==2:
        return 1
    elif n==0:
        return 0
    else:
        return fibonacci(n-1) + fibonacci (n-2)

j=0
while j!=1:
    D = input("Indice du terme de la suite de Fibonacci à calculer ?")
    try:
        D = int(D)
        try:
            D > 0
        except:
            print("Le nombre doit être positif")
    except:
        print("Merci d'entrer un nombre !")
    j+=1

result = fibonacci(D)
print("La valeur de la suite de Fibonacci du terme d'indice {} est {}".format(D,result))

J'ai l'impression que le code est fonctionnel, mais ma question est : comment l'améliorer si c'est possible ?


edit: update avec un ajout d'affichage des précédentes valeurs de la suite
Code:
from lycee import *
from tabulate import *

def fibonacci(n):
    if n==1 or n==2:
        return 1
    elif n==0:
        return 0
    else:
        return fibonacci(n-1) + fibonacci (n-2)

j=0
while j!=1:
    D = input("Indice du terme de la suite de Fibonacci à calculer ?")
    try:
        D = int(D)
        try:
            D > 0
        except:
            print("Le nombre doit être positif")
    except:
        print("Merci d'entrer un nombre !")
    j+=1

result = fibonacci(D)

tableau={}
for i in range(0,D+1):
    tableau[i]=fibonacci(i)
data=sorted([(v,k) for v,k in tableau.items()])
print (tabulate(data,headers=['indice','valeur'], tablefmt="grid"))

print("La valeur de la suite de Fibonacci du terme d'indice {} est {}".format(D,result))

Dernière modification par Fugo ; 10/05/2019 à 11h38.
Ton code n'est pas fonctionnel. Essaie de mettre un D négatif, ou même un caractère, et tu verras.
Indices: un résultat de test négatif n'est pas une erreur. Et il faut incrémenter dans le bon bloc.

Sinon ton programme est clair. Tu pourrais améliorer la performance en enregistrant les indices déjà calculés dans une liste (edit: ou un dictionnaire, je vois que tu viens de la faire) et en t'y référant dans la fonction. Tu peux aussi faire remarquer à tes élèves que, bien qu'on montre traditionnellement la récursivité avec fibonacci car c'est facile à comprendre, c'est en fait une très mauvaise méthode pour le calculer (en termes de performance).

Edit2: A y réfléchir, je remplacerais ta variable "j" numérique par une variable "est_nombre_valide" booléenne.

Dernière modification par Chernish ; 10/05/2019 à 15h00.
Pour des élèves de seconde (voire de première et terminale) cette histoire de vérifier que les entrées sont "correctes" me semble inutile/trop compliqué pour des élèves lambda.
C'est compliquer le code inutilement.
Ce n'est pas un cours de Python mais un cours de maths où on utilise Python.
Dans une idée de lycée, je ne pense pas qu'intégrer une notion d'exception soit une bonne idée, surtout que ça ne s'utilise pas tout à fait comme ça. (Une exception c'est une erreur, donc quelque chose que tu ne peux pas faire genre 1/0... mais D > 0 n'en est pas une, il faut utiliser un if/else)

Après je suis pas tout a fait d'accord que mon voisin du dessus pour les inputs, c'est pas forcément une mauvaise idée, mais à aborder différemment : avec une notion plus progressive.

Par exemple : est ce qu'un variable est un chiffre. Ensuite est ce qu'une chaîne de caractère n'est constituée que de chiffres, etc...
Parce que l'utilisation de méthode plus poussé type int(...) ça peut-être rapidement plus confus et moins orienté algo.
Oui je suis d'accord que les vérifications de la bonne entrée du bon type de donnée est un peu overkill et trop compliquée, c'était plus pour moi pour le coup.


Citation :
Publié par Chernish
Ton code n'est pas fonctionnel. Essaie de mettre un D négatif, ou même un caractère, et tu verras.
Indices: un résultat de test négatif n'est pas une erreur. Et il faut incrémenter dans le bon bloc.


Edit2: A y réfléchir, je remplacerais ta variable "j" numérique par une variable "est_nombre_valide" booléenne.
Ah, effectivement, cela ne fonctionne pas mais j'avais testé.
Bon je lâche l'affaire du test alors ^^
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés