Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope
Python & Zope Forum d'entraide sur la programmation en Python et Zope. Avant de poster -> F.A.Q Python
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 22/11/2012, 03h58   #1
zebrac
Invité de passage
 
Homme
Inscription : novembre 2012
Messages : 11
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2012
Messages : 11
Points : 1
Points : 1
Par défaut Conversion d'un nombre nb arabe en chiffres romains

Bonjour,

J'ai un dm en python à faire mais je n'y comprend absolument rien.


Voici les consignes :


Le nombre nb est un entier de 4 chiffres maximum compris entre 0 exclus et 3 500 inclus (ce contrôle de nb est à faire)

On appelle echelle de nombres le tableau suivant à utiliser avec l'algorithme :
M CM D CD C XC L XL
1000 900 500 400 100 90 50 40X
X IX V IV I
10 9 5 4 1


Voici une façon de procéder pour écrire un nombre en chiffre romains :

1) chercher le plus grand nombre (noté max) de l'échelle contenue dans nb
2) écrire ce plus grand nombre en chiffres romains (noté rom)
3) récupérer le reste (noté reste) et recommencer avec le reste en repartant à l'étape 1

Premier exemple : nb = 1947

1) 1947 contient comme plus grand nombre 1 000 donc max = 1 000
2) on en déduit que rom = "M"
3) on en déduit que reste = 1 947 – 1 000 = 947

On recommence avec le reste qui joue le rôle de nb :
1) 947 contient comme plus grand nombre 900 donc max = 900
2) on en déduit que rom = "CM"
3) on en déduit que reste = 947 – 900 = 47

On recommence avec le reste qui joue le rôle de nb :
1) 47 contient comme plus grand nombre 40 donc max = 40
2) on en déduit que rom = "XL"
3) on en déduit que reste = 47 – 40 = 7

On recommence avec le reste qui joue le rôle de nb :
1) 7 contient comme plus grand nombre 5 donc max = 5
2) on en déduit que rom = "V"
3) on en déduit que reste = 7 – 5 = 2

On recommence avec le reste qui joue le rôle de nb :
1) 2 contient comme plus grand nombre 1 donc max = 1
2) on en déduit que rom = "I"
3) on en déduit que reste = 2 – 1 = 1

On recommence avec le reste qui joue le rôle de nb :
1) 1 contient comme plus grand nombre 1 donc max = 1
2) on en déduit que rom = "I"
3) on en déduit que reste = 1 – 1 = 0

Et là, on s'arrête.
Vous afficherez alors que le nombre 1947 s'écrit MCMXLVII







Pour l'instant, je n'est réussi quà faire le tableau.

Ca fait 3h que je bloque pour chercher le plus grand nombre


Comment faire ?

Merci d'avence pour votre aide



Voici ce que j'ai fait :
Code Python :
1
2
3
4
5
6
7
8
9
10
11
12
13
romain=['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
arabe=[1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
question = input("Saisir un nombre entier en chiffre arabe suppérieur à 0")
tab=[]
 
def arabe (n):
    res=""
    for k, v in reversed(sorted(numlist.iteritems())):
        while n >=k:
            n-= k
            res += v
    return res
print arabe (n)
zebrac est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 11h13   #2
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations professionnelles :
Activité : Développeur en systèmes embarqués
Secteur : Industrie

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
Salut,

je ne suis pas tout à fait sûr d'avoir compris ta question, mais si c'est "combien de fois y a t-il le 1000, le 900, le 500 etc..." alors peut-être quelque chose comme ça?

Code :
1
2
3
4
5
6
7
values=[1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
user_value = input("Saisir un nombre entier en chiffre arabe superieur a 0:")
for value in values:
    reste = user_value % value
    resultat = user_value / value
    user_value = reste
    print value, resultat
Si la saisie de l'utilisateur s'appelle "question", pourquoi passes tu en paramètre "n" au lieu de "question" à la fonction "arabe"?

A+

Pfeuh
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 11h26   #3
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 941
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 941
Points : 1 412
Points : 1 412
Bonjour,

Ton approche n'est pas forcément mauvaise mais j'ai pensé que divmod() pouvait t'aider.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
>>> n = 1947
>>> e, n = divmod(n, 1000)
>>> e
1         # Nombre de 'M'
>>> n
947      # Restant (équivalent de modulo)
>>> e, n = divmod(n, 900)
>>> e
1         # Nombre de 'CM'
>>> e, n = divmod(n, 500)
>>> e
0         # Nombre de 'D'
>>> e, n = divmod(n, 100)
>>> e
0         # Nombre de 'C'
>>> e, n = divmod(n, 40)
>>> e
1         # Nombre de 'XL'
 
...
 
>>> e, n = divmod(n, 5)
>>> e
1         # Nombre de 'V'
>>> e, n = divmod(n, 1)
>>> e
2         # Nombre de 'I'
>>>
J'en ai sauté quelques uns mais tu as compris le principe.

Evidemment il faut utiliser ceci dans une boucle qui itère sur tes listes comme tu l'as fait.
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 13h36   #4
zebrac
Invité de passage
 
Homme
Inscription : novembre 2012
Messages : 11
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2012
Messages : 11
Points : 1
Points : 1
Citation:
Envoyé par pfeuh Voir le message
Salut,

je ne suis pas tout à fait sûr d'avoir compris ta question, mais si c'est "combien de fois y a t-il le 1000, le 900, le 500 etc..." alors peut-être quelque chose comme ça?

Code :
1
2
3
4
5
6
7
values=[1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
user_value = input("Saisir un nombre entier en chiffre arabe superieur a 0:")
for value in values:
    reste = user_value % value
    resultat = user_value / value
    user_value = reste
    print value, resultat
Si la saisie de l'utilisateur s'appelle "question", pourquoi passes tu en paramètre "n" au lieu de "question" à la fonction "arabe"?

A+

Pfeuh

Salut

La question est bien "combien de fois y a t-il le 1000, le 900, le 500 etc...".
Effectivement, il s'agit d'une erreur de ma part pour le "n".

Merci de ton aide











Citation:
Envoyé par VinsS Voir le message
Bonjour,

Ton approche n'est pas forcément mauvaise mais j'ai pensé que divmod() pouvait t'aider.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
>>> n = 1947
>>> e, n = divmod(n, 1000)
>>> e
1         # Nombre de 'M'
>>> n
947      # Restant (équivalent de modulo)
>>> e, n = divmod(n, 900)
>>> e
1         # Nombre de 'CM'
>>> e, n = divmod(n, 500)
>>> e
0         # Nombre de 'D'
>>> e, n = divmod(n, 100)
>>> e
0         # Nombre de 'C'
>>> e, n = divmod(n, 40)
>>> e
1         # Nombre de 'XL'
 
...
 
>>> e, n = divmod(n, 5)
>>> e
1         # Nombre de 'V'
>>> e, n = divmod(n, 1)
>>> e
2         # Nombre de 'I'
>>>
J'en ai sauté quelques uns mais tu as compris le principe.

Evidemment il faut utiliser ceci dans une boucle qui itère sur tes listes comme tu l'as fait.

Salut,

Je n'est pas encore étudié divmod() donc c'est pour cela que je ne l'utiliserai pas.

Merci quand même pour ton aide


Voici mon nouveau code :
Code Python :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
arabe=[1000,900,500,400,100,90,50,40,10,9,5,4,1]
romain=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]
rom=""
i=0
 
nb=input("Entrez un nombre arabe entier superieur a 0")
nbold=nb
 
 
for arabe in range (1,13):
    reste = 0
    reste = nb%arabe
    resultat = nb / arabe
    nb = reste
    print arabe, resultat
 
 
 
for i in range (13):
    while (nb >= arabe[i]):
        nb=nb-arabe[i]
        rom=rom+romain[i]
print nbold, "vaut en chiffre romain", rom

la partie :
Code Python :
1
2
3
4
5
for i in range (13):
    while (nb >= arabe[i]):
        nb=nb-arabe[i]
        rom=rom+romain[i]
print nbold, "vaut en chiffre romain", rom
me donne bien le résultat final.

Mais la partie
Code Python :
1
2
3
4
5
6
for arabe in range (1,13):
    reste = 0
    reste = nb%arabe
    resultat = nb / arabe
    nb = reste
    print arabe, resultat
me donne le nombre arabe que l'utilisateur entre, puis me met 0 à toutes les autres valeurs

exemple :
Code Python :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
1 1947
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0





Autre problème, si je lance tout le code en même temps, j'ai un message erreur qui m'affiche
« TypError : 'Int' objet is unsubscriptable » sur la ligne « while (nb >= arabe[i]): »
zebrac est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 14h34   #5
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 941
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 941
Points : 1 412
Points : 1 412
Si je comprend bien, tu soustrais chaque valeur de arabe autant de fois que c'est possible avant de passer à la suivante.

La division te permet d'accélerer les choses.
Ton énoncé parlait aussi de valeurs initiales dans un tableau et de vérifier l'entrée utilisateur.

Ceci devrait alors être plus conforme:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
# -*- coding: utf-8 -*-
 
import sys
 
NUMB = ((1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), 
        (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), 
        (4, 'IV'), (1, 'I'))
 
data = raw_input('Entrez un nombre entier entre 1 et 3500: ')
 
try:
    nb = int(data)
except:
    sys.exit()
 
if 1 > nb or nb > 3500:
    sys.exit()
 
def convert(n):
    roman = ''
    for num in NUMB:
        e, n = divmod(n, num[0])
        roman += num[1] * e
 
    return roman
 
print "Le nombre %s s'écrit %s" %(nb, convert(nb))
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 14h36   #6
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 709
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 709
Points : 4 541
Points : 4 541
Voir la discussion sur ce même sujet.
- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 15h58   #7
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations professionnelles :
Activité : Développeur en systèmes embarqués
Secteur : Industrie

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
Citation:
Envoyé par VinsS Voir le message
j'ai pensé que divmod() pouvait t'aider.
On gagne effectivement deux lignes... Mais on perd en lisibilité, non?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
# -*- coding: utf-8 -*-
CONVERT_VALUES =    ((1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), 
            (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), 
            (4, 'IV'), (1, 'I'))
 
def convert(input_text):
    user_value = int(input_text)
    if user_value < 1 or user_value > 3500:
        raise Exception('out of range!')
    output_text = ''
    for arabeval, romantext in CONVERT_VALUES:
        (resultat, user_value) = divmod(user_value, arabeval)
        #~ reste = user_value % arabeval
        #~ resultat = user_value / arabeval
        #~ user_value = reste
        for index in range(resultat):
            output_text += romantext
    return output_text
 
if __name__ == "__main__":
 
    assert convert('1958') == 'MCMLVIII'
    print convert(raw_input('Entrez un entier entre 1 et 3500:'))
zebrac, quelques notions supplémentaires au cas où: Les test unitaires, grâce au mot clef "assert" et la levée d'une exception. La gestion des exceptions, c'est ton choix. Tu peux soit ignorer les erreurs comme le propose VinsS, donc arrêter le programme en masquant les erreurs si quelque chose n'est pas bon dans la saisie de l'utilisateur. Tu peux aussi au contraire tester un maximum de choses et lever une exception s'il y a un problème.

A+

Pfeuh
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 18h55   #8
zebrac
Invité de passage
 
Homme
Inscription : novembre 2012
Messages : 11
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2012
Messages : 11
Points : 1
Points : 1
J'ai réussi.

Merci beaucoup de m'avoir aidé.
zebrac est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 22h44.


 
 
 
 
Partenaires

Hébergement Web