Page 2 sur 2

Publié : lun. 02/juin/2008 11:08
par djmcg
Merci a Brossden pour ce bout de code.
Pour moi, il est tres tres interressant.

Merci encore.

Publié : mar. 03/juin/2008 0:48
par GeBonet
C'est vrai que c'est infini... Et pour moi, c'est encore plus infini, j'ai a peu prêt arrêter le developpement au moment ou le net prenais vraiment son envol... Résultat : alors que lorsque j'ai commencé, La revue "l'Ordinateur Invividuel" et "Micro-Système" n'existait même pas et la doc en français encore moins... (J'ai le N° 1 de l'OI... d'ici peu, je le vend une fortune :lol: )... Et les "Kb" se comptais en Quelques uns. Alors, imaginez moi, devant ce site de "gens" qui collaborent, et c'est vrai aussi pour des truc immense comme "developpez.com".. Aujourd'hui qui veut... S'installe devant son clavier, choisi...??? Ben, n'importe quoi comme langage et apprend, là chez lui... Et peu à la limite si c'est un fan des "Lego", faire du copier coller et pondre de quoi faire tomber la bourse de NY sans vraiment savoir ce qu'et un algorithme ou que l'IA c'est un morceau de cerveau greffé... :lol: :lol: Non, c'est pas à vous que je parle, ni de vous d'ailleurs :lol: Bon j'exagère un peu, quoi que ? :roll: :wink: Bref pour les chiffres en lettre, je vais vous passer quand j'ai un peu de temps, un code "complet" et en vrai "PB".... Promis, avec Milliard et Milliardième... :P

A+ ET merci d'exister, v'la que maintenant j'en ai encore au moins pour 60 ans avec ce viva PB

Comme promis un Code PB même sujet...

Publié : ven. 13/juin/2008 17:20
par GeBonet
Comme promis voici le Code en PB incluant milliards et Millième s'il le faut.
Ce n'est pas une conversion, mais c'est évidement le même algorithme.

Sous cette forme, peut facilement faire partie d'une LIB... pour qui veux !

L'appel se faisant alors par : Reponse$=Conversion(Nombre)

Code : Tout sélectionner

;---------------------------------------------------------------------------------------------------------
;							CODE de la : Convertir Chiffres en Lettres
;  13-06-2008                                     												   J.G. (GeBonet)
;' ---------------------------------------------------------------------------------------------------------
; Initialisation de la table des nombres     à partir de lecture des DATA....  On..
															    ; Charge dans deux tableaux qui sont :
Global Dim TableEntier.s(90)				; 	<< Les entiers 	  >>	
Global Dim TableDecim.s(14)				;   << Les décimales >>
																
Global Nombre.s									
Global nb.s											
Global Section.s
Global Decode.s 
;---------------------------------------------------------------------------------------------------------------------------
;                     MODULES de lecture dans les tables
;
;   Section.s =  désigne les entiers ou les décimales
;   Cle.s        =  désigne le numéro de la table ou se trouve la repésentation du nombre
;' --------------------------------------------------------------------------------------------------------------------------------
Procedure.s LitDansFichierLettres(Section.s, Cle.s)
	
		Protected strReturn.s ,Indice.b
		Shared TableEntier.s(), TableDecim.s(), EnLettre.s
		
		If Section="Chiffres" : Indice=1: EndIf	; Donne une valeur d'orientation...On pourrait en nettoyant 
		If Section="Decimale": Indice=2:EndIf	; le programmme supprimer ici une partie de code... 
		   strReturn = Space(255)	     				; par une affectation directe selon Section et Cle !  		
		Select Indice											; rechercher la valeur donné par la Clef 
			Case 1
					strReturn=TableEntier.s(Val(Cle))		; C'est la partie entière 	
    		Case 2
    				strReturn=TableDecim.s(Val(Cle))	; C'est la partie décimale 	
        	Default
    			  strReturn="Erreur Table"
    			  Return
  		EndSelect			
  		Position=FindString(strReturn, "=",1)  
		EnLettre.s=Mid(strReturn,Position+1)
		TableDecim.s(12)=EnLettre							; Memo Pour Debug
  		ProcedureReturn  EnLettre
			
EndProcedure 
;' -------------------------------------------------------------------------------------------------------------------------------
;								Decodage et moteur de Conversion a proprement parlé
;---------------------------------------------------------------------------------------------------------------------------
Procedure.s Decodage(nb.s)

    Protected nb1.s
    Shared Decode$
	Repeat 										      		;suppression des zéros à droite de la partie décimale
            If Right(nb, 1) = "0" 
            	nb = Left(nb, Len(nb) - 1)
            EndIf
    Until Right(nb, 1)<>"0"
    ;
    Select Len(nb)
        Case 0
            Decode$ = ""
        Case 1
        	Section.s="Chiffres"
            Decode$ = LitDansFichierLettres(Section.s, nb.s)
        Case 2
            If Val(nb) < 17 
	            Section.s="Chiffres"
            	Decode$ = LitDansFichierLettres(Section.s, nb.s)
            Else
            	nb1=Str(Int(Val(nb)/10)*10) ; prend la partie dizaine
                Section.s="Chiffres"
            	Decode$ = LitDansFichierLettres(Section.s, nb1)
                nb1 = Right(nb, 1)
                Decode$=Decode$+"-"+LitDansFichierLettres(Section.s, nb1)
            EndIf
            If Right(Decode$, 2)="un" And nb > "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et un":EndIf
            If Right(Decode$, 4)="zéro" : Decode$=Left(Decode$, Len(Decode$) - 5):EndIf
        Case 3					    ; <<<   A Partir d'ici on entre dans le domaine de la récursivité   >>>
            	If Left(nb, 1)="1" ;---------------------------------------------------------------------------------------
		                Decode$ = "cent "+Decodage(Mid(nb, 2))
	            Else
		                Decode$ = Decodage(Left(nb, 1))+" cent "+Decodage(Mid(nb, 2))
	                    If Right(Decode$, 6) = " cent " : Decode$ = Left(Decode$, Len(Decode$) - 1)+"s":EndIf
				EndIf	                    
	    Case 4 To 6
                 Decode$ =Decodage(Left(nb, Len(nb) - 3))+" mille "+Decodage(Right(nb, 3))
        	    If Left(Decode$, 2) = "un" : Decode$ = Mid(Decode$, 4):EndIf
        Case 7 To 9
        		Decode$ = Decodage(Left(nb, Len(nb) - 6))+" millions "+Decodage(Right(nb, 6))
            	If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 10)+Mid(Decode$, 12):EndIf
        Case 10 To 12
            Decode$ = Decodage(Left(nb, Len(nb) - 9))+" milliards "+Decodage(Right(nb, 9))
            If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 11)+Mid(Decode$, 13):EndIf
            
    EndSelect
	ProcedureReturn  Decode$
	
EndProcedure
;---------------------------------------------------------------------------------------------------------------------------
;													Conversion de Nb ...
;---------------------------------------------------------------------------------------------------------------------------
Procedure.s Conversion(nb.s) 

	Protected NbDeci.s							; Préserve quelques données 
	Protected Affichage.s						; a usage locale... 
	Protected Entier.s
	Protected Decimal.s
	
    Pos.w=FindString(nb, ",",1)	   			; Au cas ou "nb" c'est un... 
    If Pos.w = 0  										; un entier
        Affichage =Decodage(nb)+" unité ";        OU    
    Else                                 					; un décimal ce qui change tout ...
        Repeat 										    ; suppression des zéros à droite de la partie décimale
            If Right(nb, 1) = "0" : nb = Left(nb, Len(nb) - 1):EndIf
        Until Right(nb, 1)<>"0"
        Entier=Left(nb, FindString(nb, ",",1) - 1)			; Prise de la partie entière 
        Decimal=Mid(nb, FindString(nb, ",",1) + 1)	; Prise de la partie décimale
        ; <<<<<  Décodage de la partie entière >>>>>>> ------------------------------------------------
        Entier = Decodage(Entier)								; Decodage de la partie entière de nb
        If Right(Entier, 2) = "un" : Entier = Entier+"e":EndIf
        If Entier = "une" :Entier = Entier+" unité ": Else :If Entier <> "" : Entier = Entier+" unités ":EndIf: EndIf
        ; <<<<<  Décodage de la partie Decimale >>>>>>> ---------------------------------------------
        NbDeci=Str(Len(Decimal))		
        Decimal = Decodage(Decimal)						; Et enfin, expression du type d'unitée... 
        Affichage = Entier+Decimal+" "
        Affichage = Affichage +LitDansFichierLettres("Decimale", NbDeci)
        If Decimal<>"un" : Affichage = Affichage +"s":EndIf

    EndIf
    ProcedureReturn  Affichage

EndProcedure
;------------------------------------------------------------------------------------------------------
;						Initialisation des tables de la représentation littérale
;										START PROGRAMME 
;------------------------------------------------------------------------------------------------------
Repeat 													; Partie de lecture des DATA qui pourrait -être lus sur disque et donc modifiables
		Read Numero$								; sans entrer dans le programme pour un executable par exemple  ....
		If Numero$<>"FinDecimale"		    ; Mais la forme sur disque devrait respecter strictement l'ordre ci dessous  et 
				Num=Val(Numero$)				; se terminer absolument par "FinEntier" et "FinDecimale"	
				If Entier=0 								; A noter que le mot "unité" peut être rempalcer par ce que l'on veut... 
					If Numero$="FinEntier"		; Exemple : euros ou mètres pour plus d'un...  
						Entier=1
					Else			
						TableEntier(Num)=Numero$:
					EndIf
				Else
					TableDecim(Num)=Numero$
				EndIf	
		EndIf				
Until Numero$="FinDecimale"				; recherche "FinDecimale" qui marque la fin du fichier
;
DataSection
	MesChiffres:
		Data.s "0=zéro","1=un","2=deux","3=trois","4=quatre","5=cinq","6=six","7=sept","8=huit","9=neuf","10=dix","11=onze"
		Data.s "12=douze","13=treize","14=quatorze","15=quinze","16=seize"
		Data.s "20=vingt","30=trente","40=quarante","50=cinquante","60=soixante","70=septante","80=quatre-vingt","90=nonante","FinEntier"
		;[Decimale]
		Data.s "1=dixième","2=centième","3=millième","4=dix-millième","5=cent-millième","6=millionième","7=dix-millionième"
		Data.s "8=cent-millionième","9=milliardième","10=dix-milliardième","11=cent-milliardième","FinDecimale"

EndDataSection
; ****************************************************************************************************************
; 						Début de programme  pour l'utilisateur et prise de la valeur à convertir  
; ****************************************************************************************************************
NbrBase.s="1234,567"
Repeat  	
 	; 																			Entré de la valeur à convertir 
 	Nombre= InputRequester("Transformeur","Donnez votre valeur : ",NbrBase)
 	ReplaceString(Nombre, ".",",",2) 						; Vérifie que les points, s'il y a, deviennent virgules...
	NbrBase=Nombre
    Reponse$=Conversion(Nombre)                    	;    APPEL ICI        et           REPONSE ICI 
    ;																			;    PUIS  <<< Affichage de la conversion !!!!   >>>
    Resultat=MessageRequester("Pour : "+Nombre+" Autre cas ? ",Reponse$,#PB_MessageRequester_YesNo) 
    
Until Resultat = 7
    ;
End
;*******************************************************************************************************************
Voilà, voilà...

Publié : mar. 17/juin/2008 9:30
par brossden
@GeBonet

ton code ne marche pas (teste avec 400, 420)

Par contre le mien fonctionne avec des milliards, des unités etc !

Publié : mar. 17/juin/2008 9:58
par GeBonet
Correct.... Il semble en effet que pour des valeurs entières et inférieur à il ne fonctionne pas... J'ai du oublier qq chose qq part :( Ce qui m'étonne, car avec 25,98 ou 1,qq chose ça fonctionne... Et c'est apparament le saut des centaines entières qui pose problème... Que ce soit, 100,200...1200,2100 etc.. Mais pas 12001,xxx par exemple... :?:

Alors autre chose, je ne fais aucune compétition, et n'ai jamais discuté sur la validité de ton code ou non... J'essaye simplement de mettre en ligne un code qui est me parait ok... A prendre ou à laisser ou a "corriger"... "L'original" à fonctionné pendant 15 ans, c'est sa transposition que j'essaye de faire en PB parce que je reprend la programmation depuis longtemps et avec un langage nouveau en utilisant uniquement l'algorithme... Et pour passer mon temps. Et apparament, je coince quelque part... :wink: Et vais vérifier quelle étape il saute quand il s'agit de centaine entière... Merci de l'info, car j'étais passé a travers avec mes tests... :lol: La procheine fois je le ferais compter pendant une semaine de 0,0000001 à 1.000.000.000.000 pour être certains :lol:
Voilà, voilà...

Correction du module concerné...

Publié : mar. 17/juin/2008 11:10
par GeBonet
Voilà c'était un oubli l'ors d'un coller... Mais m'a permis de trouver un autre oubli qui lui était aussi passé inaperçu... Dans la même partie... Les corrections son faites et les erreurs restés en commentaires...

Code : Tout sélectionner

Procedure.s Decodage(nb.s)

    Protected nb1.s
    Shared Decode$
    ; 													ET CECI N'AVAIS RIEN A FAIRE ICI PUISQUE POUR DECIMALE		
    ;													   et cela transformais 200 en 2 et 12200 en 122 etc... 	
    ;										normal les zéros à droite des décimales c'est comme ceux à gauche des entiers
    ;
	;Repeat 										      		;  suppression des zéros à droite de la partie décimale
    ;        If Right(nb, 1) = "0" 
    ;        	nb = Left(nb, Len(nb) - 1)				<<<	Cruel oubli de recopie d'une partie dans l'autre >>>
    ;        EndIf
    ; Until Right(nb, 1)<>"0"
    ;
    Select Len(nb)
        Case 0
            Decode$ = ""
        Case 1
        	Section.s="Chiffres"
            Decode$ = LitDansFichierLettres(Section.s, nb.s)
        Case 2
            If Val(nb) < 17 
	            Section.s="Chiffres"
            	Decode$ = LitDansFichierLettres(Section.s, nb.s)
            Else
            	nb1=Str(Int(Val(nb)/10)*10) ; prend la partie dizaine
                Section.s="Chiffres"
            	Decode$ = LitDansFichierLettres(Section.s, nb1)
                nb1 = Right(nb, 1)
                Decode$=Decode$+"-"+LitDansFichierLettres(Section.s, nb1)
            EndIf
            If Right(Decode$, 2)="un" And nb > "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et un":EndIf
            ; >> CI-DESSOUS >>  Ajoutée car pour terminaisons par vingt cela doit être "et une" et non "et un"<
            If Right(Decode$, 2)="un" And nb = "20" : Decode$=Left(Decode$, Len(Decode$) - 2)+"et une":EndIf
            If Right(Decode$, 4)="zéro" :Decode$=Left(Decode$, Len(Decode$) - 5):EndIf
            
        Case 3					    ; <<<   A Partir d'ici on entre dans le domaine de la récursivité   >>>
        
        		;If Left(nb, 1)="1"  <<<<===      CECI EST A REMPLACER PAR CI DESSOUS
        		;                      Car cela donnait pour 12021 => douze mille zéro cent ving-et-un					
            	If Left(nb, 1)="1" Or Left(nb, 1)="0" ;------------------------------
		                Decode$ = "cent "+Decodage(Mid(nb, 2))
	            Else
		                Decode$ = Decodage(Left(nb, 1))+" cent "+Decodage(Mid(nb, 2))
	                    If Right(Decode$, 6) = " cent " : Decode$ = Left(Decode$, Len(Decode$) - 1)+"s":EndIf
				EndIf	                    
	    Case 4 To 6
                 Decode$ =Decodage(Left(nb, Len(nb) - 3))+" mille "+Decodage(Right(nb, 3))
        	    If Left(Decode$, 2) = "un" : Decode$ = Mid(Decode$, 4):EndIf
        Case 7 To 9
        		Decode$ = Decodage(Left(nb, Len(nb) - 6))+" millions "+Decodage(Right(nb, 6))
            	If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 10)+Mid(Decode$, 12):EndIf
        Case 10 To 12
            Decode$ = Decodage(Left(nb, Len(nb) - 9))+" milliards "+Decodage(Right(nb, 9))
            If Left(Decode$, 2) = "un" : Decode$ = Left(Decode$, 11)+Mid(Decode$, 13):EndIf
            
    EndSelect
	ProcedureReturn  Decode$
	
EndProcedure
Voilà en remplaçant ce module cela devrait aller maintenant...

Publié : mar. 17/juin/2008 11:24
par brossden
L'orthographe de Unité (s) est mal gérée et tu ne devais pas laisser l'unité en fin de ligne style €, km/h etc ???
En plus il faudrait y ajouter des "Euros" si on parle d'argent, de "telle ou telle autre" expression de mesure que ce soit des quantités, des vitesses, volumes etc... Auxquels cas nous aurions "mille deux cent mètres et 25 centimètres", ou "mille deux cent euros et vingt cinq cents"

Publié : mar. 17/juin/2008 11:43
par Ollivier
Pas mal ce côté récursif de la chose. Je ne l'avais pas vu sous cet angle là...

Publié : mar. 17/juin/2008 11:43
par GeBonet
Encore vrai, d'autant que comme je le disais, il faudrait pour chaque cas adapter les type d'unités traitées !
Mais rien n'empèche de creer une initialisation en rapport au type d'unité traitée... Ce qui règlerais le problème des unités et en même temps cloturerais totalement le sujet...

Voilà, voilà ! et Merci !