IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Au Pied Levé - À Main Levée

[TUTORIEL] Traduction textuelle d’un montant numérique

Noter ce billet
par , 01/04/2021 à 10h45 (358 Affichages)
Travaux Pratiques d'algorithmique (Force 3/7)

Exercice corrigé et proposition de refactoring

Public :
  • étudiants
  • débutants
  • et pourquoi pas, enseignants

Contenu :
  • la boucle DO
  • la structure itérative LCP
  • la structure linéaire CORIG
  • l’orthographe des nombres en lettres
TUTORIEL

Traduction textuelle d’un montant numérique

■ ■ ■ SOMMAIRE DU BILLET ■ ■ ■

  1. Traduction textuelle d’un montant numérique
  2. Compréhension de la problématique
    • Simulation
    • Règles orthographiques des nombres en lettres
      • Million et milliard
      • Mille ou Milles ?
      • Cent ou Cents ?
      • Vingt ou Vingts ?
      • Les nombres de 20 à 99
  3. L'Algorigramme
  4. L'Algorithme
  5. Exercice pratique de refactoring
  6. ANNEXES
    • Divagations méthodologiques
    • De l'instruction PRINT FILE
    • Discussions similaires
§ 1. Traduction textuelle d’un montant numérique

Cet exercice a fait l’objet d’une discussion ouverte le 25/12/2021 sur le Forum Algorithmes et structures de données :


Dans une carrière de développeur, il n’est pas évident d’abstraire de ses développements des sujets d’algorithmique originaux et exploitables pédagogiquement.

La traduction textuelle d’un montant numérique n’est pas une fonctionnalité d’une grande complexité algorithmique mais demande quand même un peu de réflexion assujettie à un minimum d’orthographe. C’est surtout un prétexte pour ressusciter deux méthodologies des années 60-70, LCP et CORIG.

Anecdote :

Chacun de nous à un jour rongé son frein à la caisse d’un magasin ou d’un supermarché, le temps que le client devant soi remplisse consciencieusement son chèque.

Imaginez le pensum imposé par la TG (Trésorerie Générale) à un service administratif de formation continue qui doit libeller chaque montant d’un Certificat Administratif ou d’un État de Liquidation.

Un Certificat Administratif est une pièce comptable transmise à la TG, équivalente à une facture, pour s’acquitter de l’achat de matériel pédagogique.

Un État de Liquidation est une autre pièce comptable transmise à la TG, équivalente à un bulletin de paie, pour rémunérer les prestations des formateurs.

Jusqu’à présent, un État de Liquidation "hebdomadaire" globalisant les sommes de toutes les prestations à liquider est produit manuellement. Cet État de Liquidation "collectif" se présente sous forme d’un tableau avec une ligne par prestation formateur à indemniser et une ligne de totalisations avec le montant total brut, les sommes à déduire (la solidarité, la retenue RDS, la retenue CSG appliquée sur le montant total brut) et le montant total net qu’il reste ensuite à libeller.

Le procédé minimise certes l’écriture manuelle ou dactylographique des sommes en lettres, sauf que les déductions sur la ligne des totalisations se réfèrent au montant total brut pour ne pas perturber les contrôleurs de la TG. Ce faisant, elles ne peuvent jamais correspondre à la somme des déductions appliquées sur chaque montant d’une ligne du tableau. Ce petit détail a pour conséquence de devoir produire en fin d’année budgétaire, un document spécifique avec des écritures comptables d’ajustement pour justifier l’incohérence du bilan annuel auprès de la TG.
La Solution :

Assainir la procédure de liquidation et libérer les gestionnaires de leurs contraintes implique la possibilité d’imprimer des États de Liquidation "individuels" avec la traduction textuelle des montants numériques. L’occasionnel Certificat Administratif, profitera opportunément de la fonctionnalité déjà programmée.

« Pour la petite histoire, réaliser cette fonctionnalité et l’optimiser pour ne pas vexer la susceptibilité du compilateur - "Programme trop complexe" disait-il - n’a pas été le plus compliqué. L’État de Liquidation programmé d’abord classiquement, avec des caractères semi-graphiques pour tracer le tableau, a néanmoins fini par pousser le pauvre compilateur à la faute. Correct à la compilation, il suffisait d’une instruction de trop, même inopérante, pour que le programme donne des résultats complètement fantaisistes. Trop conséquent et sans doute saturé d’instructions conditionnelles, la situation paraissait désespérée jusqu’à ce qu’un de mes neurones se souvienne d’une petite instruction insolite, toute simple, à laquelle je ne m’étais jamais intéressé : PRINT FILE chemin_du_formulaire. Vraisemblablement crée pour moi uniquement, cette instruction va simplifier miraculeusement le programme et me permettre désormais de concevoir autrement mes éditions. »

Cette digression mise à part, ce petit exercice d’algorithmique et de français vous inspire-t-il ?



§ 2. Compréhension de la problématique

§ 2.1. Simulation

Compte-tenu de l’objectif des programmes, on peut convenir sans risque que la fonctionnalité ne doit traduire textuellement que des montants inférieurs au million d’Euros. Le montant chiffré maximum à traduire est donc : 999.999,99 Euros.

Soit :

NEUF-CENT-QUATRE-VINGT-DIX-NEUF-MILLE-NEUF-CENT-QUATRE-VINGT-DIX-NEUF EUROS QUATRE-VINGT-DIX-NEUF CENTIMES.

On observe alors que pour les Euros, la traduction textuelle est la même, appliquée aux milliers d’Euros et aux Euros compris entre 1 et 999 ; il s’agit de traduire les centaines, les dizaines et les unités... s’il y en a bien sûr.

Pour les centimes, la traduction textuelle ne concerne que les dizaines et les unités... s’il y en a.

La fonctionnalité ainsi exprimée, l’algorigramme est pratiquement fait ! L’observation concernant les Euros suggère une boucle exécutée deux fois plutôt qu’un traitement linéaire dupliqué.



§ 2.2. Règles orthographiques des nombres en lettres

Une petite révision ne fait pas de mal. Vous pouvez tester votre orthographe en cliquant sur les liens d’où sont extraits les questionnaires dont je vous propose les corrigés ci-dessous.

  • Million et milliard

    Million et milliard sont des noms (et non des adjectifs numéraux). Ils s'accordent donc en nombre et, placés après vingt ou cent, ils n'empêchent pas l'accord de ceux-ci : quatre-vingts millions d'habitants ; cinq cents milliards de kilomètres.

  • Mille ou Milles ?

    "MILLE" est un adjectif numéral toujours invariable. Historiquement, mille était le pluriel de mil, ce qui explique pourquoi mille est invariable.
    Placé après CENT, il empêche l'accord de celui-ci ; on écrit TROIS-CENT MILLE.

    Exemples :

    1. J'ai gagné vingt mille euros.
    2. J'aimerais partir à dix mille kilomètres d'ici.
    3. Je vais répéter la même chose mille fois. Mille millions de mille sabords ! (Capitaine Haddock)

  • CENT ou CENTS ?

    "CENT" est un numéral qui prend la marque du pluriel -S seulement s'il est multiplié (par un nombre) sans être suivi d'un déterminant numéral (autrement dit s'il termine le numéral). Nous devons par exemple écrire : TROIS CENTS, mais TROIS CENT CINQUANTE.

    Dans tous les autres cas, "CENT" reste invariable : CINQ MILLE CENT, page TROIS CENT.

    Exemples :

    1. C'est un très gros livre. Il y a environ cinq cents pages.
    2. Ce poulet doit bien peser quatre cent cinquante grammes.
    3. Le lot gagnant porte le numéro trois cent.
    4. Il me reste les cent dernières pages à lire.
    5. Ce poulet doit bien peser dans les quatre cents grammes.
    6. Cette maison fut construite en mille neuf cent.
    7. Le budget de la ville s'élève à huit cents millions d'euro(s)
    8. Ce poulet pèse probablement plus de cinq cents grammes.
    9. Dès les premiers jours, ce livre s'est vendu à près de trois cent mille exemplaires !
    10. La réponse à votre question se trouve à la page deux cent.

  • VINGT ou VINGTS ?

    "VINGT" ne prend normalement pas la marque du pluriel, sauf dans "QUATRE-VINGTS" s'il n'est pas un ordinal (un ordinal est par exemple un numéro de page, un millésime, une année, un numéro d'ordre, etc.) et s'il n'est pas suivi d'un autre cardinal numéral (QUATRE-VINGTS, TROIS CENT QUATRE-VINGTS, mais QUATRE-VINGT-SIX, DEUX CENT QUATRE-VINGT-DEUX…).

    Exemples :

    1. Il me reste encore deux cent vingt pages à lire pour achever la lecture de ce livre.
      Invariable, règle générale.
    2. Ma voisine va organiser une fête pour ses vingt ans.
      Invariable, règle générale.
    3. Ma grand-mère a au moins quatre-vingts ans.
      Pluriel (exception) car 80 n'est suivi d'aucun cardinal numéral et n'est pas un ordinal.
    4. Mon grand-père va fêter ses quatre-vingt-dix ans.
      Invariable, car 80 est suivi d'un cardinal numéral.
    5. Ce poulet pèse probablement plus de six cent quatre-vingts grammes.
      Pluriel (exception) car 80 n'est suivi d'aucun autre cardinal numéral et n'est pas un ordinal.
    6. Ce film a rapporté près de quatre-vingts millions d'euros.
      Pluriel (exception) car 80 n'est suivi d'aucun cardinal numéral (million n'est pas un cardinal numéral : c'est un nom).
    7. Cette pétition a obtenu plus de quatre-vingt mille signatures.
      Invariable, car 80 est suivi d'un cardinal numéral (mille est un cardinal numéral, contrairement à million qui est un nom).
    8. Nous devons faire l'exercice de la page quatre-vingt pour demain.
      Invariable, car 80 est ici un ordinal (un numéro de page).
    9. Nous l'attendons depuis vingt-quatre heures.
      Invariable, règle générale.
    10. Cette chanson date des années quatre-vingt.
      Invariable, car 80 est ici un ordinal.

  • Les nombres de 20 à 99

    Les nombres composés jusqu'à cent prennent un trait d'union sauf lorsqu'il y a "et".

    Mais depuis la réforme de 1990, on peut mettre des traits d'union partout.

    Le rapport de 1990 sur les rectifications orthographiques propose de nouvelles règles sur les traits d'union. On écrit les numéraux composés avec des traits d'union entre chaque élément (ex. : vingt-et-un-mille-trois-cent-deux). Mais milliard (tout comme millier et million) étant un substantif, il n'est pas concerné par cette rectification et ne prendra donc de trait d'union ni avant, ni après (ex. : cinq-cents milliards six-cent-quatre-vingt-dix-sept-mille).

    20 -21-22-23-24
    -25-26-27-28-29
    VINGT
    vingt et un
    vingt-deux
    vingt-trois
    vingt-quatre
    vingt-cinq
    vingt-six
    vingt-sept
    vingt-huit
    vingt-neuf
    60 -61-62-63-64
    -65-66-67-68-69
    SOIXANTE
    soixante et un
    soixante-deux
    soixante-trois
    soixante-quatre
    soixante-cinq
    soixante-six
    soixante-sept
    soixante-huit
    soixante-neuf
    30 -31-32-33-34
    -35-36-37-38-39
    TRENTE
    trente et un
    trente-deux
    trente-trois
    trente-quatre
    trente-cinq
    trente-six
    trente-sept
    trente-huit
    trente-neuf
    70 -71-72-73-74
    -75-76-77-78-79
    SOIXANTE-DIX
    soixante et onze
    soixante-douze
    soixante-treize
    soixante-quatorze
    soixante-quinze
    soixante-seize
    soixante-dix-sept
    soixante-dix-huit
    soixante-dix-neuf
    40 -41-42-43-44
    -45-46-47-48-49
    QUARANTE
    quarante et un
    quarante-deux
    quarante-trois
    quarante-quatre
    quarante-cinq
    quarante-six
    quarante-sept
    quarante-huit
    quarante-neuf
    80 -81-82-83-84
    -85-86-87-88-89
    QUATRE-VINGTS
    quatre-vingt-un
    quatre-vingt-deux
    quatre-vingt-trois
    quatre-vingt-quatre
    quatre-vingt-cinq
    quatre-vingt-six
    quatre-vingt-sept
    quatre-vingt-huit
    quatre-vingt-neuf
    50 -51-52-53-54
    -55-56-57-58-59
    CINQUANTE
    cinquante et un
    cinquante-deux
    cinquante-trois
    cinquante-quatre
    cinquante-cinq
    cinquante-six
    cinquante-sept
    cinquante-huit
    cinquante-neuf
    90 -91-92-93-94
    -95-96-97-98-99
    QUATRE-VINGT-DIX
    quatre-vingt-onze
    quatre-vingt-douze
    quatre-vingt-treize
    quatre-vingt-quatorze
    quatre-vingt-quinze
    quatre-vingt-seize
    quatre-vingt-dix-sept
    quatre-vingt-dix-huit
    quatre-vingt-dix-neuf



§ 3. L'Algorigramme

L’algorigramme de cette fonctionnalité a été réalisé le 18/11/2021 pour argumenter cette discussion. Il associe les deux méthodes de programmation LCP et CORIG. On distingue clairement la structure itérative LCP, de même que les structures linéaires et conditionnelles de CORIG.

L’algorigramme reste au niveau logique des traitements :


                     ┌─────────────────────────────────┐
              D-PROG │        v_total = ""             │
                     │              j = 1              │
                     └────────────────┬────────────────┘
                                      │◄───────────────────────────┐
         ┌────────────────────────────┼──────────────────────┐     │
T-EUROS  │           ┌────────────────┴────────────────┐     │     │
         │           │ J=1 Calcul des milliers d’Euros │     │     │
         │           │ J=2 Calcul des Euros de 1 à 999 │     │     │
         │           │    v_centaines = ""             │     │     │
         │           │    v_dizaines  = ""             │     │     │
         │           │    v_unites    = ""             │     │     │
         │           │        v_euros = centaines      │     │     │
         │           │        v_euros >= 100 ?         │     │     │
         │      non  └────────────────┬────────────────┘     │     │
         │     ┌──────────────────────●                      │     │
         │     │     ┌────────────────┴────────────────┐     │     │
         │     │     │ v_centaines = libellé centaines │     │     │
         │     │     └────────────────┬────────────────┘     │     │
         │     └─────────────────────►│                      │     │
         │           ┌────────────────┴────────────────┐     │     │
         │           │        v_euros = dizaines       │     │     │
         │           │        v_euros >= 20 ?          │     │     │
         │      non  └────────────────┬────────────────┘     │     │
         │     ┌──────────────────────●                      │     │
         │     │     ┌────────────────┴────────────────┐     │     │
         │     │     │  v_dizaines = libellé dizaines  │     │     │
         │     │     └────────────────┬────────────────┘     │     │
         │     └─────────────────────►│                      │     │
         │           ┌────────────────┴────────────────┐     │     │
         │           │        v_euros = unités         │     │     │
         │           │        v_euros >= 1 ?           │     │     │
         │      non  └────────────────┬────────────────┘     │     │
         │     ┌──────────────────────●                      │     │
         │     │     ┌────────────────┴────────────────┐     │     │
         │     │     │    v_unites = libellé unites    │     │     │
         │     │     └────────────────┬────────────────┘     │     │
         │     └─────────────────────►│                      │     │
         │           ┌────────────────┴────────────────┐     │     │
         │           │ v_total = v_total + v_centaines │     │     │
         │           │                   + v_dizaines  │     │     │
         │           │                   + v_unites    │     │     │
         │           │          J = J + 1              │     │     │
         │           │             J :: 2              │     │     │
         │           └────────────────┬────────────────┘     │     │
         └────────────────────────────┼──────────────────────┘  =  │
                                      ●────────────────────────────┘
         ┌────────────────────────────┼──────────────────────┐
 F-PROG  │           ┌────────────────┴────────────────┐     │
         │F-EUROS    │           PRINT v_total         │     │
         │           ├─────────────────────────────────┤     │
         │D-CENTIMES │        v_total  = ""            │     │
         │           │      v_dizaines = ""            │     │
         │           │      v_unites   = ""            │     │
         │           │     v_centimes  = dizaines      │     │
         │           │     v_centimes >= 20 ?          │     │
         │      non  └────────────────┬────────────────┘     │
         │     ┌──────────────────────●                      │
         │     │     ┌────────────────┴────────────────┐     │
         │     │     │  v_dizaines = libellé dizaines  │     │
         │     │     └────────────────┬────────────────┘     │
         │     └─────────────────────►│                      │
         │           ┌────────────────┴────────────────┐     │
         │           │     v_centimes = unites         │     │
         │           │     v_centimes > 1 ?            │     │
         │      non  └────────────────┬────────────────┘     │
         │     ┌──────────────────────●                      │
         │     │     ┌────────────────┴────────────────┐     │
         │     │     │    v_unites = libellé unites    │     │
         │     │     └────────────────┬────────────────┘     │
         │     └─────────────────────►│                      │
         │           ┌────────────────┴────────────────┐     │
         │F-CENTIMES │ v_total = v_total + v_dizaines  │     │
         │           │                   + v_unites    │     │
         │           │  PRINT v_total                  │     │
         │           └─────────────────────────────────┘     │
         └───────────────────────────────────────────────────┘


§ 4. L'Algorithme

Le code source est extrait d’un développement réel datant de février 1995. Le langage « ace » utilisé (compilateur de programmes d’édition du SGBD Informix ISQL) est un langage de gestion proche du SQL, aussi compréhensible qu’un pseudo-langage.

Adapté à des montants inférieurs au million d’Euros, l’algorithme doit d’abord traduire textuellement les milliers d’Euros (s’il y en a), puis les Euros de 1 à 999 (s’il y en a) et traduire enfin les Centimes (s’il y en a).

Je ne garantie pas le respect de la règle des traits d’union que j’ignorais à l’époque. J’ai essayé de la prendre en compte à postériori sans possibilité de tester.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
Extrait du programme d’édition d’un Certificat Administratif : 

{================================}  DEFINE  {==================================}
{}                                                                            {}
{}    PARAM[1] p_n_ca          INTEGER                                        {}
{}                                                                            {}
{}    VARIABLE v_total_net     DECIMAL(10,2)                                  {}
{}    VARIABLE v_integer       INTEGER                                        {}
{}    VARIABLE v_euros         INTEGER                                        {}
{}    VARIABLE v_centimes      INTEGER                                        {}
{}                                                                            {}
{}    VARIABLE v_centaines     CHAR(20)                                       {}
{}    VARIABLE v_dizaines      CHAR(20)                                       {}
{}    VARIABLE v_unites        CHAR(20)                                       {}
{}    VARIABLE v_total         CHAR(100)                                      {}
{}                                                                            {}
{}    VARIABLE j_loop          SMALLINT                                       {}
{}                                                                            {}
{==================================}  END  {===================================}

                            {======================}
{===========================} DATABASE mabase  END {===========================}
                            {======================}

{==================================} SELECT {==================================}

            ca.n_ca          ca_n_ca,
            ca.montant       ca_montant,

FROM        ca

WHERE       ca.n_ca        = $p_n_ca

GROUP BY    ca.n_ca

===============================}  ORDER  BY  {================================}

            ca_n_ca
            
{==================================}  END  {===================================}

{=================================}  FORMAT  {=================================}

{---------------------- TRADUCTION TEXTUELLE D’UN MONTANT ---------------------}

{ TRADUCTION TEXTUELLE DES EUROS ----------------------------------------------}

LET v_total_net = ca_montant 
LET v_total     = ""

PRINT ESC, "&a425H"; { Positionnement du curseur dans la page }

FOR j_loop = 1 TO 2 STEP 1
DO BEGIN
{}
{} LET v_centaines = ""
{} LET v_dizaines  = ""
{} LET v_unites    = ""
{}
{} IF  j_loop = 1     { Traduction textuelle des milliers d’Euros }
{} THEN BEGIN
{}      LET v_euros   = v_total_net
{}      LET v_integer = v_euros  / 1000
{}      LET v_euros   = v_integer
{}      END
{}
{} IF  j_loop = 2     { Traduction textuelle des Euros entre 1 et 999 }
{} THEN BEGIN
{}      LET v_euros   = v_total_net
{}      LET v_integer = v_euros  / 1000
{}      LET v_euros   = v_euros  - (v_integer * 1000)
{}      END
{}
{ TRADUCTION TEXTUELLE DES CENTAINES D’EUROS ----------------------------------}
{}
{} IF v_euros >= 100 THEN LET v_centaines = "CENT"
{} IF v_euros >= 200 THEN LET v_centaines = "DEUX-CENT"
{} IF v_euros >= 300 THEN LET v_centaines = "TROIS-CENT"
{} IF v_euros >= 400 THEN LET v_centaines = "QUATRE-CENT"
{} IF v_euros >= 500 THEN LET v_centaines = "CINQ-CENT"
{} IF v_euros >= 600 THEN LET v_centaines = "SIX-CENT"
{} IF v_euros >= 700 THEN LET v_centaines = "SEPT-CENT"
{} IF v_euros >= 800 THEN LET v_centaines = "HUIT-CENT"
{} IF v_euros >= 900 THEN LET v_centaines = "NEUF-CENT"
{} 
{} IF v_euros >= 100
{} THEN BEGIN
{}      LET v_integer = v_euros  / 100
{}      LET v_euros   = v_euros  - (v_integer * 100)
{}      END
{}
{} IF  j_loop = 2
{} AND v_centaines IS NOT NULL
{} AND v_centaines <> "CENT"
{} AND v_euros  = 0
{} THEN LET v_centaines = v_centaines CLIPPED, "S"
{}
{ TRADUCTION TEXTUELLE DES DIZAINES D’EUROS -----------------------------------}
{}
{} IF v_euros >= 20 THEN LET v_dizaines = "VINGT"
{} IF v_euros >= 30 THEN LET v_dizaines = "TRENTE"
{} IF v_euros >= 40 THEN LET v_dizaines = "QUARANTE"
{} IF v_euros >= 50 THEN LET v_dizaines = "CINQUANTE"
{} IF v_euros >= 60 THEN LET v_dizaines = "SOIXANTE"
{} IF v_euros >= 70 THEN LET v_dizaines = "SOIXANTE"
{} IF v_euros >= 80 THEN LET v_dizaines = "QUATRE-VINGT"
{}
{ TRADUCTION TEXTUELLE DES UNITES D’EUROS -------------------------------------}
{}
{} LET v_integer = v_euros   / 10
{} LET v_integer = v_integer * 10
{}
{} IF (v_euros  >= 10 AND v_euros  < 20)
{} OR (v_euros  >= 70 AND v_euros  < 80)
{} OR (v_euros  >= 90)
{} THEN LET v_euros = v_euros - v_integer + 10
{} ELSE LET v_euros = v_euros - v_integer
{}
{} IF  v_dizaines  = "QUATRE-VINGT"
{} AND v_euros     =  0 THEN LET v_dizaines = "QUATRE-VINGTS"
{}
{} IF  v_dizaines IS NOT NULL
{} AND v_dizaines <> "QUATRE-VINGTS"
{} AND v_euros     >  0 THEN LET v_dizaines = v_dizaines CLIPPED,"-"
{}
{} IF  v_euros     =  1 THEN LET v_unites   = "UN"
{}
{} IF (v_dizaines <> "QUATRE-VINGT" AND v_dizaines IS NOT NULL)
{} AND v_euros     =  1 THEN LET v_unites   = "ET UN"
{}
{} IF  v_euros     =  2 THEN LET v_unites   = "DEUX"
{} IF  v_euros     =  3 THEN LET v_unites   = "TROIS"
{} IF  v_euros     =  4 THEN LET v_unites   = "QUATRE"
{} IF  v_euros     =  5 THEN LET v_unites   = "CINQ"
{} IF  v_euros     =  6 THEN LET v_unites   = "SIX"
{} IF  v_euros     =  7 THEN LET v_unites   = "SEPT"
{} IF  v_euros     =  8 THEN LET v_unites   = "HUIT"
{} IF  v_euros     =  9 THEN LET v_unites   = "NEUF"
{} IF  v_euros     = 10 THEN LET v_unites   = "DIX"
{} IF  v_euros     = 11 THEN LET v_unites   = "ONZE"
{} IF  v_euros     = 11 AND v_dizaines = "SOIXANTE"
{}                      THEN LET v_unites = "ET ONZE"
{} IF  v_euros     = 12 THEN LET v_unites = "DOUZE"
{} IF  v_euros     = 13 THEN LET v_unites = "TREIZE"
{} IF  v_euros     = 14 THEN LET v_unites = "QUATORZE"
{} IF  v_euros     = 15 THEN LET v_unites = "QUINZE"
{} IF  v_euros     = 16 THEN LET v_unites = "SEIZE"
{} IF  v_euros     = 17 THEN LET v_unites = "DIX-SEPT"
{} IF  v_euros     = 18 THEN LET v_unites = "DIX-HUIT"
{} IF  v_euros     = 19 THEN LET v_unites = "DIX-NEUF"
{}
{}                           LET v_euros  =  0
{}
{ MISE EN FORME DU LIBELLE DES EUROS ------------------------------------------}
{}
{} IF v_centaines IS NOT NULL
{} THEN LET v_total = v_centaines CLIPPED
{}
{} IF v_dizaines IS NOT NULL
{} THEN IF v_total IS NULL
{}      THEN LET v_total = v_dizaines CLIPPED
{}      ELSE LET v_total = v_total CLIPPED, "-", v_dizaines CLIPPED
{}
{} IF  v_unites IS NOT NULL
{} AND v_total  IS     NULL
{}      THEN LET v_total = v_unites CLIPPED
{}
{} IF  v_unites IS NOT NULL
{} AND v_total  IS NOT NULL
{} THEN IF v_unites = "ET UN"
{}      OR v_unites = "ET ONZE"
{}      THEN LET v_total = v_total CLIPPED, 1 SPACE, v_unites CLIPPED
{}      ELSE LET v_total = v_total CLIPPED,     "-", v_unites CLIPPED
{} 
{} IF  j_loop       = 1
{} AND v_total_net >= 2000
{} THEN LET v_total = v_total CLIPPED, 1 SPACE, "MILLE"
{}
{} IF  j_loop       = 1
{} AND v_total_net >= 1000
{} AND v_total_net  < 2000
{} THEN LET v_total = "MILLE"
{}
{} END {DO}

{ IMPRESSION DU LIBELLE DES EUROS ---------------------------------------------}

LET v_euros    =  v_total_net
LET v_centimes = (v_total_net  * 100) - (v_euros * 100)

IF  v_total[51,100] = " "
OR (v_total[61,100] = " " AND v_centimes = 0)
THEN PRINT ESC, "(s1p10v0s0b4101T";
ELSE PRINT ESC, "(s1p9v0s0b4101T";

PRINT v_total CLIPPED, " EUROS ";
LET v_total = ""

{ TRADUCTION TEXTUELLE DES DIZAINES DE CENTIMES -------------------------------}

LET v_euros    =  v_total_net
LET v_centimes = (v_total_net  * 100) - (v_euros * 100)

LET v_dizaines = ""
LET v_unites   = ""

IF v_centimes >= 20 THEN LET v_dizaines = "VINGT"
IF v_centimes >= 30 THEN LET v_dizaines = "TRENTE"
IF v_centimes >= 40 THEN LET v_dizaines = "QUARANTE"
IF v_centimes >= 50 THEN LET v_dizaines = "CINQUANTE"
IF v_centimes >= 60 THEN LET v_dizaines = "SOIXANTE"
IF v_centimes >= 70 THEN LET v_dizaines = "SOIXANTE"
IF v_centimes >= 80 THEN LET v_dizaines = "QUATRE-VINGT"

LET v_integer = v_centimes / 10
LET v_integer = v_integer  * 10

IF (v_centimes >= 10 AND v_centimes < 20)
OR (v_centimes >= 70 AND v_centimes < 80)
OR (v_centimes >= 90)
THEN LET v_centimes  = v_centimes - v_integer + 10
ELSE LET v_centimes  = v_centimes - v_integer

IF  v_dizaines = "QUATRE-VINGT"
AND v_centimes = 0 THEN LET v_dizaines = "QUATRE-VINGTS"

{ TRADUCTION TEXTUELLE DES UNITES DE CENTIMES ---------------------------------}

IF  v_dizaines IS NULL
AND v_centimes =  0 THEN LET v_unites = "ZERO"

IF  v_centimes =  1 THEN LET v_unites = "UN"

IF (v_dizaines <> "QUATRE-VINGT" AND v_dizaines IS NOT NULL)
AND v_centimes =  1 THEN LET v_unites = "ET UN"

IF  v_centimes =  2 THEN LET v_unites = "DEUX"
IF  v_centimes =  3 THEN LET v_unites = "TROIS"
IF  v_centimes =  4 THEN LET v_unites = "QUATRE"
IF  v_centimes =  5 THEN LET v_unites = "CINQ"
IF  v_centimes =  6 THEN LET v_unites = "SIX"
IF  v_centimes =  7 THEN LET v_unites = "SEPT"
IF  v_centimes =  8 THEN LET v_unites = "HUIT"
IF  v_centimes =  9 THEN LET v_unites = "NEUF"
IF  v_centimes = 10 THEN LET v_unites = "DIX"
IF  v_centimes = 11 THEN LET v_unites = "ONZE"
IF  v_centimes = 11 AND v_dizaines = "SOIXANTE"
                    THEN LET v_unites = "ET ONZE"
IF  v_centimes = 12 THEN LET v_unites = "DOUZE"
IF  v_centimes = 13 THEN LET v_unites = "TREIZE"
IF  v_centimes = 14 THEN LET v_unites = "QUATORZE"
IF  v_centimes = 15 THEN LET v_unites = "QUINZE"
IF  v_centimes = 16 THEN LET v_unites = "SEIZE"
IF  v_centimes = 17 THEN LET v_unites = "DIX-SEPT"
IF  v_centimes = 18 THEN LET v_unites = "DIX-HUIT"
IF  v_centimes = 19 THEN LET v_unites = "DIX-NEUF"
LET v_centimes =  0

{ MISE EN FORME ET IMPRESSION DU LIBELLE DES CENTIMES -------------------------}

IF v_total_net < 200000
THEN BEGIN
     IF  v_total IS NOT NULL
     THEN PRINT "EUROS ";

     LET v_total = ""

     IF v_dizaines IS NOT NULL
     THEN LET v_total = v_dizaines CLIPPED

     IF  v_unites IS NOT NULL
     AND v_total  IS     NULL
          THEN LET v_total = v_unites CLIPPED

     IF  v_unites IS NOT NULL
     AND v_total  IS NOT NULL
     THEN IF v_unites = "ET UN"
          OR v_unites = "ET ONZE"
          THEN LET v_total = v_total CLIPPED, 1 SPACE, v_unites CLIPPED
          ELSE LET v_total = v_total CLIPPED,     "-", v_unites CLIPPED

     PRINT v_total CLIPPED;

     IF   v_dizaines IS NULL
     AND (v_unites    = "ZERO" OR v_unites = "UN")
     THEN PRINT " CENTIME",  ESC, "(s0B"
     ELSE PRINT " CENTIMES", ESC, "(s0B"
     END
ELSE PRINT ESC, "(s0B"

{===================================}  END  {==================================}



§ 5. Exercice pratique de refactoring

L’algorithme ne respecte pas rigoureusement l’algorigramme. À l’époque, pour ne pas froisser la susceptibilité du compilateur, simplifier la compilation en optimisant le nombre d’instructions était plus important que le respect de l’éthique méthodologique et la recherche de performance.

Il peut être intéressant :

  • De transcrire l’algorithme dans le langage que vous pratiquez.

    La démarche s’apparente à une intervention de maintenance qui oblige à comprendre, à s’approprier la programmation de quelqu’un d’autre.

  • De remplacer la lecture du montant depuis une table BDD par une saisie du montant depuis un écran.

  • De remplacer la sortie imprimante par un affichage écran.

  • De revisiter l’algorithme pour le rendre performant et cohérent avec l’algorigramme.

    Ainsi, la première itération de la boucle DO peut être évitée dans le cas où le montant à traduire est inférieur à 1000 Euros. De même qu’il est possible d’éviter la traduction des centaines s’il n’y en a pas, et/ou des dizaines s’il n’y en a pas, et/ou des unités s’il n’y en a pas.

    Peut-être même révélerez-vous quel qu’erreur bien que l’algorithme ait tourné pendant près de 15 ans. Cela dit, je doute que les traitements réels aient permis de tester des montants supérieurs à mille Euros ou même à mille Francs en 1995 lorsque le programme à été développé.




§ 6. ANNEXES

§ 6.1. Divagations méthodologiques

Nom : Logo CORIG.jpg
Affichages : 63
Taille : 16,7 Ko Nom : Logo LCP.jpg
Affichages : 68
Taille : 18,5 Ko Nom : Logo PS.jpg
Affichages : 68
Taille : 12,5 Ko

L’originalité de l’algorithme "Traduction textuelle d’un montant numérique" consiste à associer les méthodologies LCP de Jean-Dominique Warnier et CORIG de Robert Mallet, conçues dans les années 1960-70.

Revenir à ces basiques permet bien souvent, au-delà de toute méthode particulière, de retrouver une démarche saine, simple, humaine et maîtrisée pour la résolution des problèmes, même les plus complexes ayant trait aux systèmes d'information.

Ces hypothèses de travail s'avèrent souvent utiles et précieuses à rappeler et peuvent constituer la base d'un enseignement initial et permanent des systèmes d'information et de l'informatique.

Refaire les greniers n'est pas forcément une perte de temps.

Il n’est pas nécessaire de reproduire ici l’intégralité d’un Billet de blog que je consacre au sujet. Ceux que cela intéresse peuvent consulter ce billet de blog :


■ ■ ■ SOMMAIRE ■ ■ ■

  • Algorigramme
  • CORIG - COnception et Réalisation de l’Informatique de Gestion
  • LCP - Logique de Construction de Programme
  • PS - Programmation Structurée
  • Conclusion


§ 6.2. De l'instruction PRINT FILE

Certains programmes d’édition peuvent être très complexes en termes de traitement d’informations fixes (tableaux, texte aligné/justifié, par exemple) et d’informations variables. L’instruction "PRINT FILE" simplifie la programmation en traitant l’ensemble des informations fixes d’un état sous forme d’un fichier-formulaire imprimable. Cette instruction n’existe pas forcément dans tous les langages. Lorsqu’elle existe, la difficulté consiste toutefois à créer le formulaire.

Un simple traitement de texte mode caractère des années 80, SPRINT de Borland, permet de créer sous MS/DOS un tel formulaire de qualité bureautique très convenable qui peut d’ailleurs éviter dans certains cas l’utilisation de pré-imprimés. Imprimer avec Informix des tableaux complexes, du texte aligné/justifié en différentes polices de tailles différentes, en variant l’interligne… devient facile.

SPRINT permet soit de sauvegarder le formulaire créé en tant que fichier .prn (PCL 5), soit de l’envoyer à l’imprimante. Il suffit d’ouvrir ce fichier .prn produit avec SPRINT et d’y apporter quelques modifications rudimentaires en début et en fin de fichier :

  1. Sous MS/DOS : Tout d’abord, il faut ajouter un Carriage-return à la fin de chaque ligne du fichier .prn car sinon le fichier transféré sous Unix ne fera qu’un seul item. Il peut alors dépasser la taille maxi et surtout il devient ingérable sous Vi. L’opération peut se faire de différentes façons, soit avec le traitement de texte lui-même qui joue alors le rôle d’un excellent éditeur de texte, soit en convertissant le fichier MS/DOS en fichier Unix (en deux clics avec Notepad++).

  2. Sous MS/DOS ou Unix : Il convient d’intervenir en début de fichier pour dire à l’imprimante de mémoriser la position du curseur « [Esc]&f0S » et lui signifier un interligne nul « [Esc]&l0C » de façon à annihiler les Carriage-return ajoutés qui se traduiraient par des sauts de ligne. Les sauts de ligne sont déjà assurés par des commandes PCL de mouvement de l’index vertical « [Esc]&a+nnV ».

  3. Toujours sous MS/DOS ou Unix : Il reste en fin de fichier à remplacer les commandes PCL de saut de page et réinitialisation de l’imprimante (générées par le traitement de texte) par la commande « Rappel de la position du curseur ([Esc]&f1S) ».

Peut-être bien le seul à avoir utilisé cette instruction, j’ai fait part de mon expérience sur le sujet dans cette discussion :

De l'instruction PRINT FILE



§ 6.3. Discussions similaires

  1. convertir un montant en toutes lettres
    Par lido dans le forum Forms

  2. Cherche un code qui me permet de convertir un montant chiffre en lettre
    Par aminem99 dans le forum VB.NET

  3. Convertir un montant en chiffre en montant en toute lettre
    Par graymatter dans le forum WinDev

  4. Convertir un montant en lettre dans un état Crystal reports
    Par gopal dans le forum SAP Crystal Reports

  5. ?Convertir le montant de ma facture en lettres?
    Par Redhouane dans le forum Bases de données

  6. [VB.NET]Convertir un montant numérique en lettres
    Par kinganasius dans le forum Windows Forms

  7. [Mail] Convertir une somme en toute lettres
    Par mijean dans le forum Langage

  8. Exprimer "textuellement" un montant financier
    Par Krashtest dans le forum SQL




FIN - Travaux Pratiques d'algorithmique (Force 3/7)


Traduction textuelle d’un montant numérique


Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Viadeo Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Twitter Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Google Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Facebook Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Digg Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Delicious Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog MySpace Envoyer le billet « [TUTORIEL] Traduction textuelle d’un montant numérique » dans le blog Yahoo

Mis à jour 24/02/2024 à 08h16 par APL-AML

Catégories
Programmation , ■ ALGORITHMIQUE