bonjour, j' ai poste un post hier et j' ai eu une reponse de la part de Olygrim qui me rediriger vers un sujet similaire mais je n'ai pas su comment il falait faire pour resoudre le probleme et j'aurais besoin d' un exemple concret et si possible avec mon programme.
Je fais actuellement le cours de POO Python, et je rencontre un problème avec mon code lorsque j'initialise les zones :
class Zone:
...
def initialize_zones(cls):
for latitude in range(cls.MIN_LATITUDE_DEG, cls.MAX_LATITUDE_DEG, cls.HEIGHT_DEG):
for longitude in range(cls.MIN_LONGITUDE_DEG, cls.MAX_LONGITUDE_DEG, cls.WIDTH_DEG):
bottom_left_corner = Position(longitude, latitude)
top_right_corner = Position(longitude + cls.WIDTH_DEG, latitude + cls.HEIGHT_DEG)
zone = Zone(bottom_left_corner, top_right_corner)
cls.ZONES.append(zone)
Il semblerait qu'à la ligne :
zone = Zone(bottom_left_corner, top_right_corner)
la méthode de classe initialize_zones(cls) se relance, ce qui cause une boucle infinie, et surtout, une surcharge de la mémoire et la première fois, j'ai du reboot mon ordinateur... (maintenant j'ai rajouté de quoi sortir de là si ça dépasse les 64800 zones)
J'ai regardé le code de la correction de ce chapitre, mais je ne vois strictement aucune différence avec mon code, si ce n'est que pour les attributs de classe j'ai abrégé le DEGREES par DEG mais ce n'est qu'un nom.
J'ai commencé le cours "Découvrez la programmation orientée objet avec Python" et je ne comprends pas le concept de "attr_value", "attr_name" et "setattr()".
Qu'est-ce que c'est ?
Est-ce que c'est applicable seulement pour les dictionnaires ?
setattr est une fonction qui permet de modifier dynamiquement la valeur d'un attribut.
attr_name est probablement une variable contenant un nom d'attribut, et attr_value une valeur à donner à cet attribut.
On utilise un fichier json et on le parcours à l'aide du constructeur __init__(). Durant ce parcours, on affiche la clé et la valeur qui est dans le json.
Je pensais que setattr, attr_name, attr_value était réservé uniquement pour les dictionnaires.
J'ai réalisé le cours Démarrez votre projet avec Python et je souhaitait passer un peu de temps sur le cours Bonus 'Stockez des citations dans un fichier avec le module Json.
Seulement, en essayant de refaire l'exercice d'import, j'ai le message d'erreur suivant dans l'IDLE:
Traceback (most recent call last):
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 28, in <module>
print(random_quote())
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 24, in random_quote
all_values = read_values_from_json()
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 9, in read_values_from_json
data = json.load(f)
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 299, in load
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 342, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 25)
A chaque fois que je fais un test, j'ai toujours ce type de message. Et même en recopiant le code du cours, j'ai le message ci-dessus (characters_test.py étant le fichier contenant le code)
Elle ne fait pas l'affaire car la 1ère partie de cette ligne récupère uniquement les nombres:
[el[1] for el in inventaire] #-> [22, 4, 18, 76, 51]
Donc le tri va se faire sur cette liste (qui est totalement décorrélé de inventaire) et ce n'est pas vraiment ce qu'on veut.
Ensuite le tri par défaut de la méthode sort est par ordre croissant. Pour trier par ordre décroissant, il faut spécifier le paramètre reverse à True.
Enfin, cette méthode ne doit pas s'appliquer directement sur la liste que tu es en train de construire, car comme c'est une méthode qui trie *in-place* elle te renverra la valeur None (et non ta liste triée):
lst = [el[1] for el in inventaire].sort() #-> lst = None
Donc pour trier ta liste, il faut utiliser le paramètre reverse (le mettre à True) et utiliser le paramètre key (qui permet d'indiquer la condition du tri):
inventaire = [("pommes", 22),
("melons", 4),
("poires", 18),
("fraises", 76),
("prunes", 51)]
#Tri *in-place*
#Ici on trie par rapport au 2nd élément de chaque tuple -> x[1]
inventaire.sort(reverse=True, key=lambda x: x[1])
print(inventaire)
#Ou une copie si on veut garder la liste initiale
inventaire_trie = sorted(inventaire, reverse=True, key=lambda x: x[1])
print(inventaire_trie)
Un tout grand merci pour ta réponse claire et pour ta solution.
Maintenant j'ai une confusion sur la partie key = lambda x :x [1]
Si je comprend bien, le mot-clé key permet de spécifier la variable sur laquelle on fait le tri. La fonction lambda sort en sortie le deuxième élément du tuple...mais comment sait elle que x[1] correspond au 2nd élément du tuple? c'est une façon standard d'y accéder?
Ce n'est pas un mot-clé, mais juste le nom du paramètre. Celui-ci attend une fonction qui sera utilisée sur chacun des éléments de ta liste. Ici, j'ai associé à ce paramètre la lambda, qui dispose d'un paramètre x. Et c'est ce paramètre qui va recevoir chacun des éléments de ta liste. Autrement dit, la lambda va être exécutée sur chacun des éléments de la liste.
Ce que va renvoyer la fonction sera ce sur quoi va s'effectuer le tri. Ici, on veut faire le tri en fonction du deuxième élément de chaque objet, donc c'est pour ça qu'on renvoie cette valeur. La même écriture avec une fonction "classique":
Cependant, j'ai des erreurs d'indentation et je n'arrive pas à les résoudre.
Par exemple, où est l'erreur juste dans cette partie de code ( il y a une erreur d'indentation, et malgré plusieurs test en enlevant des tab ou en rajouter des tab, ça ne fonctionne toujours pas. Et une erreur de syntaxe à la fin apparemment. Ces quelques lignes paraissent tellement simple et pourtant ...
Généralement, python indique la ligne où se situe l'erreur. Ici elle est à la ligne 3, où le if devrait se trouver au même niveau que la première ligne:
choix_numero = ...
if choix_numero ...
L'indentation se fait avec des espaces (4 par conventions) plutôt que par des tabulations.
PS: Pour insérer du code sur le forum, utilises le bouton </>
Merci pour cette réponse, cependant je ne comprends toujours pas :
même en faisant ça, j'ai toujours une erreur.
Et surtout, pourquoi je ne peux pas tester ce morceau de code ? ni dans le terminal, ni via un fichier (ça s'ouvre une fraction de seconde et ça se referme : je suppose que suite à une erreur, le programme s'arrête et donc se ferme, c'est cela ?)
import os
cn = input("Saisissez un numero entre 0 et 49 : ")
if cn >49 or cn <0 :
cn = input("vous avez choisi un numero qui n'est pas entre 0 et 49, veuillez choisir un nouveau numero :")
choixmise = input (" combien voulez vous miser ? ")
print ("vous avez misé ",choixmise)
os.system("pause")
Je dois faire quelques choses de mal, mais je ne vois pas.
Dans mes test, en enlevant les ligne 4 et 5, ça se lance. Et si je copie le code dans le terminal, ça ne fait rien, ça copie juste le code, sans rien lancer, sans produire d'erreur, pourquoi ?
Pour tester un code, il ne faut pas double-cliquer dessus, mais l'exécuter dans un terminal.
Ensuite ton code comporte de nouveau une erreur d'indentation (à la ligne 5). Il faut décaler la ligne:
number_user = int(input("Saisissez un numero entre 0 et 49: "))
while not 0 <= number_user <= 49:
print("Vous avez choisi un numéro qui n'est pas entre 0 et 49.")
number_user = int(input("Veuillez choisir un nouveau numéro: "))
mise_user = int(input("Combien voulez-vous miser: "))
print("Vous avez misé {}€".format(mise_user))
Si tu es en python 2.X, il faut utiliser raw_input à la place d'input. Néanmoins comme le tuto est écrit pour la v3, je te conseille d'upgrader ta version.
Du coup, je venais de trouver qu'il fallait décaler la ligne 5. Cependant, en recopiant mon code :
#-*-coding:Latin-1 -*
import os
cn = input("Saisissez un numero entre 0 et 49 : ")
if cn >49 or cn <0 :
cn = input("vous avez choisi un numero qui n'est pas entre 0 et 49, veuillez choisir un nouveau numero :")
choixmise = input (" combien voulez vous miser ? ")
print ("vous avez misé ",choixmise, "sur le numero ",cn)
os.system("pause")
Maintenant, on me demande bien de saisir un numéro, puis une fois que j'entre un numéro, le programme se ferme sans me demander combien je souhaite miser. Ais-je fait une bêtise ?
Autre question : j'écris mon code sous notepad. Pour le tester directement dans le terminal, dois-je bien juste le copier coller ?
Et enfin, même avec le code plus haut, j'ai cette erreur :
>>> cn = input("Saisissez un numero entre 0 et 49 : ")
Saisissez un numero entre 0 et 49 : if cn >49 or cn <0 :
>>> cn = input("vous avez choisi un numero qui n'est pas entre 0 et 49, veuillez choisir un nouveau numero :")
File "<stdin>", line 1
cn = input("vous avez choisi un numero qui n'est pas entre 0 et 49, veuillez choisir un nouveau numero :")
^
IndentationError: unexpected indent
>>>
>>> choixmise = input (" combien voulez vous miser ? ")
combien voulez vous miser ? print ("vous avez misé ",choixmise, "sur le numero ",cn)
Ce n'est pas la vesion Python le problème : Mieux vaut la v3.x que la v2.x si vous débutez en Python, ! (euh c'est possible de rajouter un Smiley Python dans ceux disponibles ?)
Hello, beaucoup de post et pas beaucoup de réponse pour l'instant sur ce forum... ça va venir ! c'est rigolo, j'ai la musique de "Ma sorcière bien aimé" dans la tête maintenant...
Concernant le Bonus dans le premier cours Python du pacours du même nom qui permet de mettre les données dans des fichiers JSON et bien le cours favorise le fait de se casser la tête sur ce qui ne marche pas : La structure du code json dans les fichiers proposés dans le cours n'est pas bon : ça plantait aussi chez moi.
il doit être :
[
{...},
{...}
]
ça marchera mieux comme cela.
Ensuite le programme...et bien j'en ai réécrit une partie pour que ça marche a peu près...En fait il me manque encore quelque chose ne connaissant pas bien JSON : j'y reviendrai plus tard (Vous aussi j'en suis sûr pour me donner la solution...). Ceci dit mon code fonctionne tout de même. Le voici :
# -*- coding: utf-8 -*-
import random
import json
#------------------------------------
#-- Lire le contenu d'un fichier json
#------------------------------------
def read_values_from_json(filename):
values = []
with open(filename) as f:
data = json.load(f)
for entry in data:
values.append(entry)
return values
#----------------------------------------
#-- Extrait un item au hasard d'une liste+
#----------------------------------------
def random_item_in(object_list):
rand_numb = random.randint(0, len(object_list) - 1)
item = object_list[rand_numb]
return item
#---------------------------------------
# Return a random value from a json file
#---------------------------------------
def get_random_character_from_json_file(filename):
all_values = read_values_from_json(filename)
return random_item_in(all_values)
#--------------------------------------------------
#-- Met la première lettre d'une chine en majuscule
#--------------------------------------------------
def capitalize(words):
for word in words:
word.capitalize()
return words
#-----------------------------------------------
#-- Retourne une citation dite par un personnage
#-----------------------------------------------
def message(character, quote):
n_character = capitalize(character)
n_quote = capitalize(quote)
return "{} a dit : {}".format(n_character, n_quote)
#---------------------------------------
#-- Lancement du programme
#---------------------------------------
#-- Attend une entrée au clavier :
#-- [Enter] : Affiche une citation
#-- [quit] : fin du programme
#-- [autre touche] : On boucle
user_answer = input('Tapez entrée pour connaître une autre citation ou "quit" pour quitter le programme.')
while user_answer != "quit":
print( message( get_random_character_from_json_file("characters.json"), get_random_character_from_json_file("quotes.json") ) )
user_answer = input('Tapez entrée pour connaître une autre citation ou "quit" pour quitter le programme.')
Une petite remarque au passage...les commentaires aident bien a structurer la masse de code n'hésitez pas à en mettre.
Autre point, l'IDE : J'utile Brackets souvent mais il est temps de passer sur une plateforme professionnelle : Eclipse + Pydev (plugin)...vous aurez un cours UML bientôt...
JujuNunu a écrit:
Bonjour à tous!
J'ai réalisé le cours Démarrez votre projet avec Python et je souhaitait passer un peu de temps sur le cours Bonus 'Stockez des citations dans un fichier avec le module Json.
Seulement, en essayant de refaire l'exercice d'import, j'ai le message d'erreur suivant dans l'IDLE:
Traceback (most recent call last):
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 28, in <module>
print(random_quote())
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 24, in random_quote
all_values = read_values_from_json()
File "C:\Users\julie\Documents\cours_python\exercices\characters_test.py", line 9, in read_values_from_json
data = json.load(f)
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 299, in load
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\julie\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 342, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 25)
A chaque fois que je fais un test, j'ai toujours ce type de message. Et même en recopiant le code du cours, j'ai le message ci-dessus (characters_test.py étant le fichier contenant le code)
Voici le code utilisé au final pour le cours:
# -*- coding: latin-1 -*-
import random
import json
# Give a Json file and return a List
def read_values_from_json():
values = []
with open("characters.json") as f:
data = json.load(f)
for entry in data:
values.append(entry["character"])
return values
def random_item_in(object_list):
rand_numb = random.randint(0, len(object_list) - 1)
return object_list[rand_numb]
def capitalize(words):
for word in words:
word.capitalize()
# Return a random value from a json file
def random_quote():
all_values = read_values_from_json()
capitalize(all_values)
return random_item_in(all_values)
print(random_quote())
def message(character, quote):
capitalize(character)
capitalize(quote)
return "{} a dit : {}".format(character, quote)
user_answer = input('Tapez entrée pour connaitre une autre citation ou B pour quitter le programme.')
Auriez-vous une idée du problème? Est-ce dû à ma version Python? J'ai téléchargé la 3.6.1:
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
Je vous remercie pour votre aide!
Julien
- Edité par Vifier Lockla 7 juillet 2017 à 16:45:20
Depuis le premier TP (Zcasino) j'ai un comportement logique mais peu pratique : une fois les interactions avec l'utilisateur réalisées, le code s'exécute tout seul jusqu'à ce que l'utilisateur n'ait plus d'argent, sans qu'il ait la possibilité de rejouer.
Code :
#!/usr/bin/python3
#-*-coding:Utf-8 -*
import math #Importe le module "math"
from random import randrange #Importe la fonction "randrange"
from math import ceil #Importe la fonction "ceil"
cash = 500 #Somme dépensable au départ.
print("Vous venez au casino avec :", cash,"$")
num = input("Saisissez le numéro d'une case (compris entre 0 et 49) :")
num = int(num)
bet = input("Saisissez le montant de votre mise :")
bet = int(bet)
result = randrange(50) #Simulation d'un hasard dans l'intervalle 0 à 49.
print("Le numéro gagnant est :", result)
while cash > 0: #Tant que la somme dépensable est supérieure à 0.
if num == result: #En cas d'égalité entre le numéro choisit(num) et le numéro gagnant(result).
cash += bet * 3
print("Vous remportez", bet * 3,"$ !")
elif num != result and num % 2 == result % 2: #Numéros différents mais couleur identique.
bet = ceil(bet * 0.5)
print("Vous récupérez la moitié de votre mise :", bet,"$.")
cash += bet
else: #Numéros et couleurs différentes.
print("Vous perdez votre mise.")
cash -= bet
if cash <= 0: #Comportement quand le portefeuille est vide.
print("Vous n'avez plus d'argent.")
else:
print("Il vous reste :", cash,"$.")
Voici le retour terminal :
antoine@debian:~/python/travauxPratiques$ ./zcasino.py
Vous venez au casino avec : 500 $
Saisissez le numéro d'une case (compris entre 0 et 49) :45
Saisissez le montant de votre mise :34
Le numéro gagnant est : 28
Vous perdez votre mise.
Il vous reste : 466 $.
Vous perdez votre mise.
Il vous reste : 432 $.
Vous perdez votre mise.
Il vous reste : 398 $.
Vous perdez votre mise.
Il vous reste : 364 $.
Vous perdez votre mise.
Il vous reste : 330 $.
[...]
Il vous reste : 58 $.
Vous perdez votre mise.
Il vous reste : 24 $.
Vous perdez votre mise.
Vous n'avez plus d'argent.
En soit le déroulement est « logique » et, content d'avoir retirée toutes les petites erreurs, j'essaie de comprendre ce qui permettrait là l'utilisateur de rejouer entre chaque tour. J'imagine une boucle à insérer quelque part, et là, malgré plusieurs essais aléatoires, je ne trouve pas de logique pour y parvenir.
Auriez-vous des conseils ou des pistes que je pourrais approfondir ? Aussi, je m'efforce à ne pas regarder la solution proposée pour des raisons purement didactiques.
le contenu de la boucle doit être mis dans une fonction calculCash() par exemple mais sans la boucle (sans le While); passez un paramètre dans cette fonction pour lui indiquer le numéro choisi par le joueur. En outre, elle retournera le nouveau cash du joueur. Voyez comment fonctionne une fonction dans le cours.
Réutilisez le while pour y glisser le code qui demande au joueur d'entrer un numéro pour jouer. A la suite dans la boucle, appelez la fonction qui calcul le gain.
N'oubliez pas de créer les conditions de sortie de la boucle (soit je demande à quitter par appui d'une touche "q" par exemple pour quitter, soit le cash est à 0 ou en dessous de 0)
N'oubliez pas de remettre à jour le cash à chaque tour avant que le joueur choisisse un nouveau numéro.
Enjoy !
adumondel a écrit:
Bonjour,
Depuis le premier TP (Zcasino) j'ai un comportement logique mais peu pratique : une fois les interactions avec l'utilisateur réalisées, le code s'exécute tout seul jusqu'à ce que l'utilisateur n'ait plus d'argent, sans qu'il est la possibilité de rejouer.
Code :
#!/usr/bin/python3
#-*-coding:Utf-8 -*
import math #Importe le module "math"
from random import randrange #Importe la fonction "randrange"
from math import ceil #Importe la fonction "ceil"
cash = 500 #Somme dépensable au départ.
print("Vous venez au casino avec :", cash,"$")
num = input("Saisissez le numéro d'une case (compris entre 0 et 49) :")
num = int(num)
bet = input("Saisissez le montant de votre mise :")
bet = int(bet)
result = randrange(50) #Simulation d'un hasard dans l'intervalle 0 à 49.
print("Le numéro gagnant est :", result)
while cash > 0: #Tant que la somme dépensable est supérieure à 0.
if num == result: #En cas d'égalité entre le numéro choisit(num) et le numéro gagnant(result).
cash += bet * 3
print("Vous remportez", bet * 3,"$ !")
elif num != result and num % 2 == result % 2: #Numéros différents mais couleur identique.
bet = ceil(bet * 0.5)
print("Vous récupérez la moitié de votre mise :", bet,"$.")
cash += bet
else: #Numéros et couleurs différentes.
print("Vous perdez votre mise.")
cash -= bet
if cash <= 0: #Comportement quand le portefeuille est vide.
print("Vous n'avez plus d'argent.")
else:
print("Il vous reste :", cash,"$.")
Voici le retour terminal :
antoine@debian:~/python/travauxPratiques$ ./zcasino.py
Vous venez au casino avec : 500 $
Saisissez le numéro d'une case (compris entre 0 et 49) :45
Saisissez le montant de votre mise :34
Le numéro gagnant est : 28
Vous perdez votre mise.
Il vous reste : 466 $.
Vous perdez votre mise.
Il vous reste : 432 $.
Vous perdez votre mise.
Il vous reste : 398 $.
Vous perdez votre mise.
Il vous reste : 364 $.
Vous perdez votre mise.
Il vous reste : 330 $.
[...]
Il vous reste : 58 $.
Vous perdez votre mise.
Il vous reste : 24 $.
Vous perdez votre mise.
Vous n'avez plus d'argent.
En soit le déroulement est « logique » et, content d'avoir retirée toutes les petites erreurs, j'essaie de comprendre ce qui permettrait là l'utilisateur de rejouer entre chaque tour. J'imagine une boucle à insérer quelque part, et là, malgré plusieurs essais aléatoires, je ne trouve pas de logique pour y parvenir.
Auriez-vous des conseils ou des pistes que je pourrais approfondir ? Aussi, je m'efforce à ne pas regarder la solution proposée pour des raisons purement didactiques.
Cordialement,
- Edité par adumondel il y a environ 16 heures
- Edité par Vifier Lockla 9 juillet 2017 à 8:30:37
...Or, sauf erreur de ma part, une division entre deux entiers en python donnera toujours un int, avec un résultat arrondi. à moins de convertir au moins l'un des deux opérandes en float.
C'est facilement vérifiable avec un simple interpréteur.
Non pour preuve :
et même
Il faut utiliser les // pour avoir le comportement que tu décris
Stéphane Nédélec, Mentor Python
Exercices Python créés spécifiquement pour illustrer le cours OpenClassrooms "Démarrer votre projet avec Python" :
T'es sûr d'être en python 3.6? De base, il existe une v2 de python sur mac (donc si tu as installé la 3.6 ça signifie que ton mac dispose de deux versions de python).
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique