cs_ManChesTer
Messages postés374Date d'inscriptionvendredi 20 octobre 2000StatutModérateurDernière intervention15 janvier 2021
-
3 mai 2003 à 00:47
cs_ManChesTer
Messages postés374Date d'inscriptionvendredi 20 octobre 2000StatutModérateurDernière intervention15 janvier 2021
-
7 mai 2003 à 16:36
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
cs_ManChesTer
Messages postés374Date d'inscriptionvendredi 20 octobre 2000StatutModérateurDernière intervention15 janvier 2021 7 mai 2003 à 16:36
Merci Japee,
Voici un ptit corrigé (sans les règles grammaticales qui ne sont pas utiles pour etablir un cheque valide).
Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','soixante','quatre-vinght','quatre-vingt');
Langage='Francais France';
{const Unite : array[0..9] of string= // pour la belgique
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','septante','quatre-vinght','nonante');
Langage='Francais Belgique';}
var fr : String;
ch : String;
t : String;
begin
fr:='';
ch:=inttostr(value);
while length(ch)>0 do
begin
t:=ch[1];
case length(ch) of
2,5,8:
begin
t:=t+ch[2];
if ((Strtoint(t) in [70..79]) or (Strtoint(t) in [90..99])) and (Langage='Francais France') then
begin
fr:=fr+Dixaine[strtoint(t[1])]+' ';
t:=Inttostr((Strtoint(t)-((strtoint(t[1])*10))+10));
end;
if strtoint(t)<20 then
begin
fr:=fr+unite2[strtoint(t)-10]+' ';
delete(ch,1,1);
end
else
fr:=fr+Dixaine[strtoint(t[1])]+' ';
end;
1,3,4,6,7,9,10:
if not ((length(ch) in [3,6,9]) and(t[1]='1')) then
begin
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliard ';
6 :fr:=fr+'million ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
begin
case length(ch) of
4,5 :Fr:=Fr+'mille';
7,8 :Fr:=Fr+'Million';
10 :Fr:=Fr+'Milliard';
end;
break;
end;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;
Bon coding ....
ManChesTer.
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 6 mai 2003 à 16:04
Tout bien reçu 5 sur 5, Delphiprog.
J'espère néanmoins que je n'ai pas eu l'air de dire "bah, tu vois, c'est trop facile, t'as qu'a rajouter ça et ça marche impec". J'en serais désolé :-{
J'ai fait ce truc plutôt genre "tiens, je fais le point sur ce que je sais faire avec les routines de gestion de chaîne", sans trop savoir au départ si j'arriverais quelque part... d'où un espèce de débordement enthousiaste.
Amitiés Delphistes :-D
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 6 mai 2003 à 14:30
Merci pour cette intéressante proposition.
Mais plutôt que l'enrobage (l'encapsulation a un autre sens), il serait mieux de l'intéger et de déclarer ta fonction à l'intérieur de la fonction Int2Letters, et de n'y faire appel que dans les cas nécessaires.
Mais on peut utiliser d'autres techniques encore plus performantes. Non pas que la tienne ne le soit pas, mais les comparaisons de chaînes de caractères sont toujours consommatrices de temps de traitement.
Rendez-vous dans quelques temps pour une copie corrigée et complétée...
Merci à tous les trois pour vos remarques constructives.
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 6 mai 2003 à 11:17
Merci à toi Delphiprog, pour ce beau bout de code !
Je l'ai tout récemment installé, sous D4, sans trop y croire, ben ça marche du tonnerre de Brest...
Me reste plus qu'à essayer de tout comprendre ;-)
Voilà, je vais passer pour un forcené, mais ça me démangeait :
En réponse à l'inquiétude bien légitime de Nono40 quant au respect strict de certaines règles grammaticales concernant l'accord au pluriel de "vingt" et de "cent", j'ai pondu une petite fonction qui prend ça en charge. J'en ris encore :-)))))
function Ortho(A_Verifier: String): String;
begin
if Pos('quatre vingt', A_Verifier) <> 0 then
begin
if Length(A_Verifier) - Pos('quatre vingt', A_Verifier) = 12 then
Insert('s', A_Verifier, Pos('quatre vingt', A_Verifier) + 12);
end else
if Pos('cent', A_Verifier) > 1 then
begin
if Length(A_Verifier) - Pos('cent', A_Verifier) = 4 then
Insert('s', A_Verifier, Pos('cent', A_Verifier) + 4);
end;
Result := A_Verifier;
end;
Ca fonctionne très bien avec ta fonction, Delphiprog. Il suffit de l'encapsuler ainsi :
Ortho(Int2Letters(LeNombre));
Il faut éventuellement l'adapter pour qu'elle fonctionne avec un autre programme similaire, mais le principe me semble cohérent...
Bonne Prog !
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 5 mai 2003 à 20:40
Merci pour ces précisions Japee.
Si je n'ai pas fait les accords que nous a indiqués Nono40, en revanche les particularités de la langue française que tu mentionnes sont bien prises en compte. C'est surement ce qui explique un code un peu plus long.
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 5 mai 2003 à 18:56
Bonjour, ManChesTer
Elle est superbe, ta fonction, mais elle ne s'adapte pas bien au français.
Je m'explique :
si tu saisis (71..76), tu obtiens Soixante-dix un, Soixante-dix deux, etc..., pareil avec la suite (91..96) où tu obtiens Quatre vingt dix un, Quatre vingt dix trois, etc...
C'est normal, c'est une particularité (tordue, à mon avis...) de la langue française qui fait qu'on dit "60 et 11" pour "71", etc...
Il faudrait, pour que ça fonctionne, utiliser, comme nos amis belges et suisses francophones, les expressions "Septante" pour "Soixante-dix" et "Nonante" pour "Quatre-vingt-dix" (l'équivalent de "Seventy" et de "Ninety").
D'autre part il faudrait remplacer la constante Unite[0] qui est '' par 'zéro', ça évite de planter sur
fr[1] := uppercase(fr[1])[1]
quand on saisit "0", justement.
Enfin, ça n'a pas l'air de bien fonctionner avec les dizaines de milliers, les centaines de milliers, les dizaines de millions, les centaines de millions, quand ils sont terminés parune suite de "0", par exemple "50000", "200000", etc...
Désolé, c'est vrai qu'en plus, le français, c'est pas simple :-(
cs_ManChesTer
Messages postés374Date d'inscriptionvendredi 20 octobre 2000StatutModérateurDernière intervention15 janvier 2021 3 mai 2003 à 21:39
Merci Mono40 pour les regles,
mais la routine que j'ai postèe est a la base multilingue et permet l'impression de cheques dans divers langues .....
C'est donc volontairement q'elles ne sont pas appliquèes, les regles n'etant pas internationales et etant inutiles pour faire un cheque valable.
ps:la version orgignale est capable d'ecrire "-cent vingt trois euros soixante deux cents-" dans 45 langues... (idem en USD,Yen etc....).
Bon coding...
ManChesTer.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 3 mai 2003 à 08:25
Merci à tous les deux.
Merci à Manchester pour avoir étendu les capacités de cette fonction, même si elle n'utilise pas la récursivité. Plus simple ? c'est à chacun d'apprécier.
Merci à Nono40 de nous (me) rappeler les règles grammaticales qui me manquaient lorsque j'ai écrit ce code.
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 3 mai 2003 à 02:48
Extrait : "Vingt et cent prennent la marque du pluriel quand, multipliés par autre adjectif numéral, ils forment le deuxième terme d'un adjectif numéral composé. Mais il est d'usage de ne pas mettre d's s'ils sont suivis d'un autre adjectif numéral"
En clair :
Quatre-vingts
Quatre-vingt deux
Cent
Cent quatre
Deux cents
Deux cent douze
Mille est invariable dans tous les cas.
Que celui qui pense que le Français est simple, relise son livre de grammaire...
cs_ManChesTer
Messages postés374Date d'inscriptionvendredi 20 octobre 2000StatutModérateurDernière intervention15 janvier 2021 3 mai 2003 à 00:47
Voici la meme chose, en + simple...
prend en compte les milliards jusque 99 milliards mais peut facilement etre étendu .....
Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','soixante-dix','quatre vinght','quatre vingt dix');
var fr : String;
ch : String;
t:string;
begin
fr:='';
ch:=inttostr(value);
while length(ch)>0 do
begin
t:=ch[1];
case length(ch) of
2,5,8:begin
t:=t+ch[2];
if strtoint(t)<20 then
begin
fr:=fr+unite2[strtoint(t)-10]+' ';
delete(ch,1,1);
end
else
fr:=fr+Dixaine[strtoint(t[1])]+' ';
end;
1,3,4,6,7,9,10:
if not ((length(ch) in [3,6,9]) and(t[1]='1')) then
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliards ';
6 :fr:=fr+'millions ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
break;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;
7 mai 2003 à 16:36
Voici un ptit corrigé (sans les règles grammaticales qui ne sont pas utiles pour etablir un cheque valide).
Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','soixante','quatre-vinght','quatre-vingt');
Langage='Francais France';
{const Unite : array[0..9] of string= // pour la belgique
('Zero','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','septante','quatre-vinght','nonante');
Langage='Francais Belgique';}
var fr : String;
ch : String;
t : String;
begin
fr:='';
ch:=inttostr(value);
while length(ch)>0 do
begin
t:=ch[1];
case length(ch) of
2,5,8:
begin
t:=t+ch[2];
if ((Strtoint(t) in [70..79]) or (Strtoint(t) in [90..99])) and (Langage='Francais France') then
begin
fr:=fr+Dixaine[strtoint(t[1])]+' ';
t:=Inttostr((Strtoint(t)-((strtoint(t[1])*10))+10));
end;
if strtoint(t)<20 then
begin
fr:=fr+unite2[strtoint(t)-10]+' ';
delete(ch,1,1);
end
else
fr:=fr+Dixaine[strtoint(t[1])]+' ';
end;
1,3,4,6,7,9,10:
if not ((length(ch) in [3,6,9]) and(t[1]='1')) then
begin
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliard ';
6 :fr:=fr+'million ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
begin
case length(ch) of
4,5 :Fr:=Fr+'mille';
7,8 :Fr:=Fr+'Million';
10 :Fr:=Fr+'Milliard';
end;
break;
end;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;
Bon coding ....
ManChesTer.
6 mai 2003 à 16:04
J'espère néanmoins que je n'ai pas eu l'air de dire "bah, tu vois, c'est trop facile, t'as qu'a rajouter ça et ça marche impec". J'en serais désolé :-{
J'ai fait ce truc plutôt genre "tiens, je fais le point sur ce que je sais faire avec les routines de gestion de chaîne", sans trop savoir au départ si j'arriverais quelque part... d'où un espèce de débordement enthousiaste.
Amitiés Delphistes :-D
6 mai 2003 à 14:30
Mais plutôt que l'enrobage (l'encapsulation a un autre sens), il serait mieux de l'intéger et de déclarer ta fonction à l'intérieur de la fonction Int2Letters, et de n'y faire appel que dans les cas nécessaires.
Mais on peut utiliser d'autres techniques encore plus performantes. Non pas que la tienne ne le soit pas, mais les comparaisons de chaînes de caractères sont toujours consommatrices de temps de traitement.
Rendez-vous dans quelques temps pour une copie corrigée et complétée...
Merci à tous les trois pour vos remarques constructives.
6 mai 2003 à 11:17
Je l'ai tout récemment installé, sous D4, sans trop y croire, ben ça marche du tonnerre de Brest...
Me reste plus qu'à essayer de tout comprendre ;-)
Voilà, je vais passer pour un forcené, mais ça me démangeait :
En réponse à l'inquiétude bien légitime de Nono40 quant au respect strict de certaines règles grammaticales concernant l'accord au pluriel de "vingt" et de "cent", j'ai pondu une petite fonction qui prend ça en charge. J'en ris encore :-)))))
function Ortho(A_Verifier: String): String;
begin
if Pos('quatre vingt', A_Verifier) <> 0 then
begin
if Length(A_Verifier) - Pos('quatre vingt', A_Verifier) = 12 then
Insert('s', A_Verifier, Pos('quatre vingt', A_Verifier) + 12);
end else
if Pos('cent', A_Verifier) > 1 then
begin
if Length(A_Verifier) - Pos('cent', A_Verifier) = 4 then
Insert('s', A_Verifier, Pos('cent', A_Verifier) + 4);
end;
Result := A_Verifier;
end;
Ca fonctionne très bien avec ta fonction, Delphiprog. Il suffit de l'encapsuler ainsi :
Ortho(Int2Letters(LeNombre));
Il faut éventuellement l'adapter pour qu'elle fonctionne avec un autre programme similaire, mais le principe me semble cohérent...
Bonne Prog !
5 mai 2003 à 20:40
Si je n'ai pas fait les accords que nous a indiqués Nono40, en revanche les particularités de la langue française que tu mentionnes sont bien prises en compte. C'est surement ce qui explique un code un peu plus long.
5 mai 2003 à 18:56
Elle est superbe, ta fonction, mais elle ne s'adapte pas bien au français.
Je m'explique :
si tu saisis (71..76), tu obtiens Soixante-dix un, Soixante-dix deux, etc..., pareil avec la suite (91..96) où tu obtiens Quatre vingt dix un, Quatre vingt dix trois, etc...
C'est normal, c'est une particularité (tordue, à mon avis...) de la langue française qui fait qu'on dit "60 et 11" pour "71", etc...
Il faudrait, pour que ça fonctionne, utiliser, comme nos amis belges et suisses francophones, les expressions "Septante" pour "Soixante-dix" et "Nonante" pour "Quatre-vingt-dix" (l'équivalent de "Seventy" et de "Ninety").
D'autre part il faudrait remplacer la constante Unite[0] qui est '' par 'zéro', ça évite de planter sur
fr[1] := uppercase(fr[1])[1]
quand on saisit "0", justement.
Enfin, ça n'a pas l'air de bien fonctionner avec les dizaines de milliers, les centaines de milliers, les dizaines de millions, les centaines de millions, quand ils sont terminés parune suite de "0", par exemple "50000", "200000", etc...
Désolé, c'est vrai qu'en plus, le français, c'est pas simple :-(
3 mai 2003 à 21:39
mais la routine que j'ai postèe est a la base multilingue et permet l'impression de cheques dans divers langues .....
C'est donc volontairement q'elles ne sont pas appliquèes, les regles n'etant pas internationales et etant inutiles pour faire un cheque valable.
ps:la version orgignale est capable d'ecrire "-cent vingt trois euros soixante deux cents-" dans 45 langues... (idem en USD,Yen etc....).
Bon coding...
ManChesTer.
3 mai 2003 à 08:25
Merci à Manchester pour avoir étendu les capacités de cette fonction, même si elle n'utilise pas la récursivité. Plus simple ? c'est à chacun d'apprécier.
Merci à Nono40 de nous (me) rappeler les règles grammaticales qui me manquaient lorsque j'ai écrit ce code.
3 mai 2003 à 02:48
En clair :
Quatre-vingts
Quatre-vingt deux
Cent
Cent quatre
Deux cents
Deux cent douze
Mille est invariable dans tous les cas.
Que celui qui pense que le Français est simple, relise son livre de grammaire...
3 mai 2003 à 00:47
prend en compte les milliards jusque 99 milliards mais peut facilement etre étendu .....
Function IntToFrench(value:Longint):string;
const Unite : array[0..9] of string=
('','un','deux','trois','quatre','cinq','six','sept','huit','neuf');
Unite2 : array[0..9] of string=
('dix','onze','douze','treize','quatorze','quinze','seize','dix-sept','dix-huit','dix-neuf');
dixaine:array[2..9] of string=
('vingt','trente','quarante','cinquante','soixante','soixante-dix','quatre vinght','quatre vingt dix');
var fr : String;
ch : String;
t:string;
begin
fr:='';
ch:=inttostr(value);
while length(ch)>0 do
begin
t:=ch[1];
case length(ch) of
2,5,8:begin
t:=t+ch[2];
if strtoint(t)<20 then
begin
fr:=fr+unite2[strtoint(t)-10]+' ';
delete(ch,1,1);
end
else
fr:=fr+Dixaine[strtoint(t[1])]+' ';
end;
1,3,4,6,7,9,10:
if not ((length(ch) in [3,6,9]) and(t[1]='1')) then
if length(ch)=1 then
fr:=fr+unite[strtoint(t)]
else
fr:=fr+unite[strtoint(t)]+' ';
end;
delete(ch,1,1);
if length(ch)=0 then break;
case length(ch) of
9 :fr:=fr+'milliards ';
6 :fr:=fr+'millions ';
3 :fr:=fr+'mille ';
2,5,8 :fr:=fr+'cent ';
end;
if (strtoint(ch)=0) then
break;
end;
fr:=trim(fr);
fr[1]:=uppercase(fr[1])[1];
result:=fr;
end;
Bon Coding....
ManChesTer.