Fonction Print Using

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Fonction Print Using

Message 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
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

cool ! j'adopte :D
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Merci ! :D

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

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

Je vais essayer de l'adapter.

A+
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

C'est cool ^^
un peu plus complet que StrF ^^

Dri
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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:
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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... :(
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message 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
Répondre