Page 1 sur 2

Fonction Print Using

Publié : mer. 12/oct./2005 19:04
par Good07
Bonsoir à tous.

J'ai cherché sur code archive si je trouvais quelque chose pour afficher correctement des nombres avec PureBasic et comme je n'ai rien trouvé à ce sujet je me suis concocté une fonction Print Using en m'inspirant de celle du GFA basic.
Bien sur elle est plus basique, mais je pense qu'on peux sûrement l'améliorer. Pour l'instant elle semble correspondre à ce que je veux en faire.
J'ai pas tester tous les cas de figures. :(
Mais je vous fait confiance pour ça. En fait le problème d'affichage n'est pas simple à résoudre à cause des polices qui sont proportionnelles et de la façon dont Pure traite les nombres converti en chaine de caractères.
Bon je pense que cela va intéresser quelqu'un. Je n'ai pas trouvé d'autre façon que de convertir les nombres en chaine et de toute manière DrawText n'accepte que les chaines alors...
J'ai commenté au maximum la procédure et si vous pensez que l'on peux faire plus simple et mieux, n'hésitez pas à modifier le code, il est là pour ça. Il faudrait rajouter le format d'affichage en notation scientifique.
par exemple(1.27E+03).
Je suis en train de chercher une solution, mais si vous avez une idée...
voici le listing:

Code : Tout sélectionner

;Simulation de Print Using
;Auteur Good07
;Pure Basic version 3.94
;Octobre 2005






Global posx


Procedure.s Using(masque.s,nombre.s)
  posx=TextLength(masque); On récupère la longueur du masque en pixels
  PosDeciMasque=FindString(masque,".",1); position du point décimal du masque
  PosDeciNombre=FindString(nombre,".",1); position du point décimal du nombre (si pas de décimale renvoi zéro)
  MasqueDroite=Len(masque)-PosDeciMasque ; récupère le nombre de chiffre à droite du point décimal du masque
  MasqueGauche=Len(masque)-(MasqueDroite+1); idem à gauche
  PartieEntiere.s=Mid(nombre,1,PosDeciNombre-1); récupère la partie entière du nombre
  PartieDecimale.s=Right(nombre,Len(nombre)-PosDeciNombre); idem pour la partie décimale
  If PosDeciNombre=0
    drnombre.s=LSet(".",MasqueDroite+1,"0"); si le nombre n'est pas décimal, rajoute un point + le nombre de zéro correspondants au masque
  Else  
    drnombre.s="."+Left(PartieDecimale,MasqueDroite); si décimal coupe la partie décimale à afficher en fonction du masque
  EndIf 
  Format$=RSet(Right(PartieEntiere,MasqueGauche),MasqueGauche," ")+drnombre; met le nombre au format
  posx=posx-TextLength(Format$); modifie la position d'affichage qui est différente suivant la police utilisée.
  ProcedureReturn Format$
EndProcedure

If OpenWindow(0, 0, 0, 600, 400, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test Print Using") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf
;-------------------------------------Exemple d'affichage
StartDrawing(WindowOutput())
DrawingMode(1)
Restore nombre
Locate(10,10)
DrawText("Affichage sans Print Using")
For i=1 To 10
  Read n.f
  res.s=StrF(n)
  Locate(10+posx,40+pasy)
  DrawText(res)
  pasy+20
Next i
Locate(300,10)
DrawText("Affichage avec Print Using")
Restore nombre
pasy=0
For i=1 To 10
  Read n.f
  res.s=StrF(n)
  Format$=Using("######.##",res); appel de la procedure: on donne le masque de formatage et le nombre à formater.
  Locate (300+posx,40+pasy)
  DrawText(Format$)
  pasy+20
Next i



StopDrawing()


Repeat
  Event = WaitWindowEvent()  
Until Event = #PB_EventCloseWindow

End

DataSection
nombre:
Data.f 12.56364,1456.23,243676.12,789,18.475,145.89,3.14159265,45,4561,478
; IDE Options = PureBasic v3.94 (Windows - x86)
Voila, j'attend vos suggestions :D

Publié : mer. 12/oct./2005 19:15
par Good07
:oops: Désolé, je me suis trompé de rubrique.
Si le modo veux bien transféré ce post dan la rubrique application ou truc et astuce.
Merci :D

Publié : mer. 12/oct./2005 22:55
par Backup
cool ! j'adopte :D

Publié : jeu. 13/oct./2005 2:58
par Good07
Merci ! :D

En GFA, pour l'affichage scientifique le masque est le suivant:

"###.##^^^^"

Je vais essayer de l'adapter.

A+

Publié : jeu. 13/oct./2005 10:58
par Backup
En GFA, pour l'affichage scientifique le masque est le suivan
comme tu le sais deja j'ai pas mal de bouquin Micro application sur le GFA :D

Publié : jeu. 13/oct./2005 11:22
par Dr. Dri
C'est cool ^^
un peu plus complet que StrF ^^

Dri

Publié : jeu. 13/oct./2005 14:50
par Good07
Dobro:
comme tu le sais deja j'ai pas mal de bouquin Micro application sur le GFA
Ok Merci Dobro, mais depuis je crois que j'ai récupéré toute la collection mais cela ne m'est pas d'une grande utilité puisque c'est une fonction native du GFA. Pour la recréer en Pure, je pense qu'il faut analyser le masque comme le fait une fonction Eval. :?

Dri:
C'est cool ^^
un peu plus complet que StrF ^^
Oui effectivement, mais il faudrait encore l'améliorer et je pense que c'est une fonction qui manque dans Pure. Peut-être avec la version 4... :wink:

Publié : jeu. 13/oct./2005 17:50
par Good07
Bon nouvelle version.
Pas de grands changements, seulement plus simple à utiliser. On transmet à la procedure la position x et y de l'endroit où l'on veut afficher ainsi que le format du masque et le nombre et c'est tout.


Pour le format scientifique, je laisse tomber vu le peu d'utilité qu'il peux avoir avec un basic qui n'affiche que 6 décimales. :D

A+

Code : Tout sélectionner

;Simulation de Print Using
;Auteur Good07
;Pure Basic version 3.94
;Octobre 2005

Procedure Using(PosX,PosY,masque.s,nombre.s)
  PosDeciMasque=FindString(masque,".",1); position du point décimal du masque
  PosDeciNombre=FindString(nombre,".",1); position du point décimal du nombre (si pas de décimale renvoi zéro)
  MasqueDroite=Len(masque)-PosDeciMasque ; récupère le nombre de chiffre à droite du point décimal du masque
  MasqueGauche=Len(masque)-(MasqueDroite+1); idem à gauche
  PartieEntiere.s=Mid(nombre,1,PosDeciNombre-1); récupère la partie entière du nombre
  PartieDecimale.s=Right(nombre,Len(nombre)-PosDeciNombre); idem pour la partie décimale
  If PosDeciNombre=0
    drnombre.s=LSet(".",MasqueDroite+1,"0"); si le nombre n'est pas décimal, rajoute un point + le nombre de zéro correspondants au masque
  Else  
    drnombre.s="."+Left(PartieDecimale,MasqueDroite); si décimal coupe la partie décimale à afficher en fonction du masque
  EndIf 
  Format$=RSet(Right(PartieEntiere,MasqueGauche),MasqueGauche," ")+drnombre; met le nombre au format
  StartDrawing(WindowOutput())
  DrawingMode(1)
  LongMasque=TextLength(masque); On récupère la longueur du masque en pixels
  PosChaine=LongMasque-TextLength(Format$); modifie la position d'affichage qui est différente suivant la police utilisée.
  Locate(PosX+PosChaine,PosY)
  DrawText(Format$)
  StopDrawing()
EndProcedure

If OpenWindow(0, 0, 0, 600, 400, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test Print Using") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf
;-------------------------------------Exemple d'affichage
StartDrawing(WindowOutput())
DrawingMode(1)
Restore nombre
Locate(10,10)
DrawText("Affichage sans Print Using")
For i=1 To 10
  Read n.f
  res.s=StrF(n)
  Locate(10,30+pasy)
  DrawText(res)
  pasy+20
Next i
Locate(300,10)
DrawText("Affichage avec Print Using")
StopDrawing()
Restore nombre
For yy=30 To 210 Step 20
  Read n.f
  res.s=StrF(n)
  Using(300,yy,"######.##",res); appel de la procedure: on donne le masque de formatage et le nombre à formater.
Next yy


Repeat
  Event = WaitWindowEvent()  
Until Event = #PB_EventCloseWindow

End

DataSection
nombre:
Data.f 12.56364,1456.23,243676.12,789,18.475,145.89,3.14159265,45,4561,478
; IDE Options = PureBasic v3.94 (Windows - x86)

Publié : jeu. 13/oct./2005 18:12
par Dr. Dri
Good07 a écrit :Pour le format scientifique, je laisse tomber vu le peu d'utilité qu'il peux avoir avec un basic qui n'affiche que 6 décimales. :D
euh t'as regardé l'aide de StrF ???

Dri

Publié : jeu. 13/oct./2005 20:20
par Good07
euh t'as regardé l'aide de StrF ???
Ben...Oui mais mis à part le nombre de décimales affichées on ne peut pas faire grand chose. De plus à l'affichage pas moyen d'aligner les chiffres. Moi je me sert du masque pour aligner les chiffres sur le point décimal. On peut peut-être faire plus simple... Moi, j'aime les choses compliquées. :D

En Gfa par exemple on écrit:

Print using "####.##^^^^,1231456.4523;

et on obtient 123.15E+04.

En Pure si on fait STRF("1231456.4523",2) on obtient :

12314546.45

Et on a pas le choix du format de sorti... :(

Publié : ven. 14/oct./2005 11:18
par Dr. Dri
c'est juste pour dire que StrF ne se limite pas à 6 décimales... tu peux en mettres moins ou plus mais la fonction gère très bien tout ce qui se passe après la virgule ^^ (ou le point lol)

Dri

Publié : ven. 14/oct./2005 14:26
par Good07
Dri à écrit:

c'est juste pour dire que StrF ne se limite pas à 6 décimales... tu peux en mettres moins ou plus mais la fonction gère très bien tout ce qui se passe après la virgule ^^ (ou le point lol)
Oui, bien sur je me suis trompé de deux décimales. Ce n'est pas 6 mais 8. :D

En fait tout dépend du nombre de chiffre avant la virgule. :(

on peut écrire sans problème:
1.23456789
ou 12.345678
123.4567

et ainsi desuite. Ce qui fait que le nombre 12345678.9 ne peut avoir qu'une seule décimale. :(

C'est dù à la gestion des nombres de Pure. Ce qui explique que l'affichage au format scientifique n'est pas très utiles.

Ma procédure est surtout utile pour aligner les nombres et faciliter la présentation de tableau. Pour le reste, StrF fait la même chose.

Mais avec la version 4... :D

Publié : ven. 14/oct./2005 15:39
par Dr. Dri
essaye ça ;)

Code : Tout sélectionner

Debug StrF(ATan(0.25687), 20)
le probleme c'est juste que PB ne gère que des nombres réels sur 32bits donc avec une précision "faible"

ta fonction est très bien mais elle recoit un masque et une chaine en paramètre alors que StrF recoit un nombre de décimales et un nombre réel.

lionel_om m'avait donné un lien concernant le format des nombres réels en mémoire (selon la norme IEEE) et avec fweil également on a vu comment récupérer les données comme le signe, le nombre (la mantisse) et l'exposant.

Dri ;)

Publié : ven. 14/oct./2005 19:23
par Good07
Wahou !!!! 8O

Mais c'est que je n'avais pas compris que l'on pouvais faire ça...

Merci Dri pour ton explication. Comme je savais que l'on ne pouvais pas afficher + de 8 décimales, pour moi STRf("nnn",2) servait à afficher un nombre raisonnable de décimale, je n'aurai jamais pensé à faire STRF("nnn",20)... :(

Je vais de ce pas voir ce que je peux faire dans ce sens là.

Il faut dire que l'explication de STRF laisse à désirer. Quelques petits exemples auraient été les bienvenus.

Comme je dis toujours il vaux mieu un qui sait que trois qui cherchent :D

Publié : ven. 14/oct./2005 20:28
par Good07
Grace à Dri, je me suis aperçu que j'avais énormément compliqué le problème. :oops:

Voici donc une procédure simplifiée. On conserve le masque puique c'est lui qui va servir au formatage de l'affichage et à récupérer le nombre de décimale du format.

Code : Tout sélectionner

;Simulation de Print Using
;Auteur Good07
;Pure Basic version 3.94
;Octobre 2005

Procedure.f Using(PosX,PosY,masque.s,nombre.f)
  Nbdecimale=Len(masque)-FindString(masque,".",1)
  Format$=RSet(StrF(nombre,Nbdecimale),Len(Masque)," ")
  StartDrawing(WindowOutput())
  DrawingMode(1)
  LongMasque=TextLength(masque)
  PosChaine=LongMasque-TextLength(Format$)
  Locate(PosX+PosChaine,PosY)
  DrawText(Format$)
  StopDrawing()
EndProcedure

If OpenWindow(0, 0, 0, 600, 400, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test Print Using") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf
;-------------------------------------Exemple d'affichage
StartDrawing(WindowOutput())
DrawingMode(1)
Restore nombre
Locate(10,10)
DrawText("Affichage sans Print Using")
For i=1 To 10
  Read n.f
  res.s=StrF(n)
  Locate(10,30+pasy)
  DrawText(res)
  pasy+20
Next i
Locate(300,10)
DrawText("Affichage avec Print Using")
StopDrawing()
Restore nombre
For yy=30 To 210 Step 20
  Read n.f
  Using(300,yy,"######.##",n)
Next yy


Repeat
  Event = WaitWindowEvent()  
Until Event = #PB_EventCloseWindow

End

DataSection
nombre:
Data.f 12.56364,1456.23,243676.12,789,18.475,145.895,3.14159265,45,4561,478
; IDE Options = PureBasic v3.94 (Windows - x86)
Voilà je pense que cela ce passe de commentaires. Plus simple et aussi efficace. :D