Qbasicnews.com

QbasicNews.Com => Challenges => Topic started by: Moneo on May 09, 2004, 04:45:08 PM



Title: Challenge: International version of PRINT USING
Post by: Moneo on May 09, 2004, 04:45:08 PM
It just dawned on me that the PRINT USING statement is designed only for USA formatted numbers; that is, using the decimal point to delimit fractional values, and commas to separate thousands. Also, the statement only uses the dollar sign.

Other countries use a comma instead of a decimal point to delimit fractional values, periods (decimal points) to separate thousands, and their own currency symbol instead of the dollar sign.

CHALLENGE: Write a replacement function, sub-program, or subroutine that allows for specifying:

1) The delimiter (comma or decimal point) for fractional values. Example: The number 123.45 in the USA is printed as 123.45 and in other countries (like Spain) as 123,45

2) The separator character for thousands.
Example: The number 12345 is printed as 12,345 in the USA and in other countries as 12.345

3) The currency symbol to use. Example: $ or

FORMATTING CHARACTERS: The formatstring for the PRINT USING specifies 12 formatting characters for formatting strings and numbers (check your manual). For this challenge we will only use the following formatting characters for numbers only:
(#) for each digit position.
(Specified delimiter for fractional values) decimal pt  or comma.
(+) causes sign of the number to be printed before the number.
(-) causes negative number to be printed with a trailing minus sign.
(**) Asterisk protection: causes leading spaces in numeric field to be filled with asterisks.
($$) Floating dollar sign: we will continue to use $$ to specify this feature, but it should actually print the currency symbol defined.
(**$) Floating dollar sign with asterisk protection. A combination of the two above.
(specified separator character for thousands) comma or decimal pt.

PLEASE: when you submit the code for your solutions, please preface the code with a brief explanation of your method or idea for the solution.

NOTE: There are several ways of doing this, some relatively simple, others very complicated. For the most part, I will not get into your code, I'll just compile it and test some results. I'll try to keep up with your entries.

I will request that the winner's code be posted in the tutorials section.
*****


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 11, 2004, 11:21:17 PM
Hey some of you guys outside of the USA, I'm sure you must have encountered incompatibility problems with the PRINT USING statement in your country. Tell us about how you handled this problem. I can't believe you have a local-country, translated version of QB or QuickBASIC.
*****


Title: Challenge: International version of PRINT USING
Post by: SCM on May 13, 2004, 02:51:44 AM
Moneo,

What character is supposed to be used for the Euro?  We're using a program that predates it by a couple of decades.  CHR$(238) looks close.


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 14, 2004, 12:33:55 AM
SCM,

That's a really good question. I really don't know because I have a new keyboard which comes with the Euro symbol. That's how I printed it in point (3) above.

The symbol displays fine in Windows, but if you transfer the character to a text file to look at it with a hex editor in MSDOS, it converts the character to a capital French C, the one with the hook at the bottom.

Is there such a thing as a hex editor that runs in Windows?
*****


Title: Challenge: International version of PRINT USING
Post by: Plasma on May 14, 2004, 12:52:14 AM
My favorite is Hex Workshop (http://www.hexworkshop.com/)


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 15, 2004, 08:24:47 PM
Thanks, Plasma, checked out the Hex Workshop site and it sounds great except for the $50 price. A bit much for the once in a blue moon that I might need it. But thanks anyway.

BTW, if you have it, please tell SCM what the hex (or decimal) character code is for the following Euro symbol:
*****


Title: Challenge: International version of PRINT USING
Post by: Plasma on May 16, 2004, 12:42:31 AM
The Euro is D5h (213) on codepage 858.


Title: Challenge: International version of PRINT USING
Post by: Jonathan Simpson on May 16, 2004, 09:33:40 AM
It's possible to modify characters in the ascii table... maybe thats an option to make the euro available.


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 18, 2004, 10:29:36 PM
Hey you guys outside the USA where you use a comma instead of a decimal point.

Have you ever had problems with PRINT USING? Have any of you written any check printing, invoice or statement printing programs in your country and tried to use PRINT USING?

If this was not a problem, tell me how you did it.
*****


Title: Challenge: International version of PRINT USING
Post by: na_th_an on May 19, 2004, 01:48:16 AM
I find it an interesting challenge, and I would enter if I had the time. It involves parsing and using FSMs, two things that I love... But I have 0 time :(

As for having needed it, I have never. For business applications I've always used Visual Basic, in every assignment or job I've had running QB was a problem, and using Visual Basic is so easy that it hurts :P

Seriously, I think I never wrote "PRINT USING" in a proggie. In QB all I've done is games, scripting systems, DOS utils and interpreters.


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 21, 2004, 12:33:08 AM
Nathan,

What's are FSM's?

If you've never used PRINT USING, then the vast majority of our QB friends here probably haven't used it either. Oh well.....
*****


Title: Challenge: International version of PRINT USING
Post by: SCM on May 21, 2004, 01:13:08 AM
Some of us use it.  I just recently learned from another members code that you can format more than one data type within the same string.  That makes it pretty flexible.
Code:
j% = 10
Sum# = 3.83105945587#
PRINT USING "####) ##.######"; j%; Sum#

Output:
  10)  3.831059
I've thought about writing my own version from time to time, to have it do things I want it to do, but now is not a good time for me.  It would be nice to see someone take this on.


Title: Challenge: International version of PRINT USING
Post by: oracle on May 21, 2004, 02:10:26 AM
Quote from: "Moneo"
What's are FSM's?


Finite State Machines (http://www.google.com/search?q=Finite+State+Machines).


Title: Challenge: International version of PRINT USING
Post by: na_th_an on May 21, 2004, 08:15:20 AM
Quote from: "Moneo"
Nathan,

What's are FSM's?


Woah! Deja vu! :D

http://forum.qbasicnews.com/viewtopic.php?t=4882&start=25

;)

FSMs are very suited for interpreters. And many other things. I love them. They saved my life 2000 times.

A PRINT USING replacement would be extremely complex to code, so I have to admit it is a great idea for a challenge, 'cause I find it terribly challenging... If only I could put 20 minutes together...


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 23, 2004, 01:23:42 AM
Nathan,

Thanks for the flashback on the FSM issue.

To do a PRINT USING replacement is going to take you more than 20 minutes. There's too many tricky things like floating dollar sign, asterisk protection and negative sign on the right of the number.

The replacement routine of this challenge says to be able to specify (1) the decimal or comma delimeter (2) the comma or decimal separator for thousand (3) the currency symbol.

You don't need to write the entire PRINT USING logic to accomplish the above 3 steps. (This is a hint). The solution that I have in mind should take about 10 minutes to write and another 10 minutes to debug.
*****
*****


Title: Challenge: International version of PRINT USING
Post by: na_th_an on May 23, 2004, 10:10:44 AM
I know it will take longer... But I currently can't put together even 20 minutes... imagine a longer period of time! :(

Anyhow using a FSM it would be easier, at least the first interpretation part.


Title: Challenge: International version of PRINT USING
Post by: Plasma on May 23, 2004, 05:46:27 PM
Here's my solution. It simply changes the required symbols in QB's internal routine. This works with PRINT USING, PRINT # USING and LPRINT USING.

Code:
'===============================================================
' SetUsing by Plasma
'---------------------------------------------------------------
' International support for PRINT USING, PRINT # USING and
' LPRINT USING. Created for Moneo's challenge.
'===============================================================

DECLARE SUB SetUsing (Currency$, Thousand$, Fractional$)

' Example...
CLS
' European (if you use cp858, you can use CHR$(213) for the real Euro)
SetUsing "E", ".", ","
PRINT USING "$$#.#######,##"; 1983745.34
' USA
SetUsing "$", ",", "."
PRINT USING "$$#,#######.##"; 1983745.34


DEFINT A-Z
SUB SetUsing (Currency$, Thousand$, Fractional$)

  '===============================================================
  ' SetUsing by Plasma
  '---------------------------------------------------------------
  ' International support for PRINT USING, PRINT # USING and
  ' LPRINT USING. Created for Moneo's challenge.
  '---------------------------------------------------------------
  ' Currency$ - New currency symbol, null to keep old symbol
  '             (default is "$")
  '
  ' Thousand$ - New separator character for thousands, null to
  '             keep old character (default is ",")
  '
  ' Fractional$ - New delimiter for fractional values, null to
  '               keep old delimiter (default is ".")
  '---------------------------------------------------------------
  ' * Compatible with:      QBasic 1.x
  '                     QuickBasic 4.x (IDE & compiled)
  '                         QB PDS 7.x (IDE & compiled)
  '                          VBDOS 1.0 (IDE & compiled)
  '
  '   Note: If you compile your program, it must be compiled as
  '         a stand-alone EXE!
  '===============================================================

  ' Due to Moneo's challenge rules, $ needs to be used in the
  ' format string no matter what you set the currency symbol
  ' to. If you would like to use your specified currency symbol
  ' in the format string, change the constant below to 1.
  CONST FormatCurrency = 0

  STATIC UsingSeg1&, UsingOff1
  STATIC UsingSeg2&, UsingOff2
  STATIC Version

  ' Find the segment and offset of the symbols in B$PUFOUT
  IF UsingSeg1& = 0 THEN
    UsingSeg1& = VARSEG(DefSeg$) - &H400
    DO WHILE UsingSeg1& > 0
      DEF SEG = UsingSeg1&
      FOR i = &H0 TO &H3FF4
        IF PEEK(i) = &HB0 AND PEEK(i + 2) = &HAA THEN
        IF PEEK(i + 3) = &H8A AND PEEK(i + 4) = &HCE THEN
        IF PEEK(i + 5) = &HF6 AND PEEK(i + 6) = &HDE THEN
        IF PEEK(i + 7) = &H7C AND PEEK(i + 8) = &H12 THEN
        IF PEEK(i + 9) = &HFE AND PEEK(i + 10) = &HCF THEN
        IF PEEK(i + 11) = &H75 THEN
          UsingOff1 = i
          EXIT DO
        END IF
        END IF
        END IF
        END IF
        END IF
        END IF
      NEXT
      UsingSeg1& = UsingSeg1& - &H3F0
    LOOP
    IF i = &H3FF5 THEN ERROR 5
  END IF

  ' Find the segment and offset of the symbols in PUSCAN
  IF UsingSeg2& = 0 THEN
    UsingSeg2& = UsingSeg1&
    DO WHILE UsingSeg2& > 0
      DEF SEG = UsingSeg2&
      FOR i = &H0 TO &H3FF4
        IF PEEK(i) = &H3C AND PEEK(i + 2) = &H74 THEN
          IF PEEK(i + 3) = &H45 THEN
            IF PEEK(i + 4) = &H3C AND PEEK(i + 5) = &H5F THEN
            IF PEEK(i + 6) = &H74 AND PEEK(i + 7) = &H94 THEN
            IF PEEK(i + 8) = &H3C AND PEEK(i + 9) = &H5C THEN
            IF PEEK(i + 10) = &H74 AND PEEK(i + 11) = &HB1 THEN
              UsingOff2 = i
              Version = 45
              EXIT DO
            END IF
            END IF
            END IF
            END IF
          ELSEIF PEEK(i + 3) = &H48 THEN
            IF PEEK(i + 4) = &H3C AND PEEK(i + 5) = &H5F THEN
            IF PEEK(i + 6) = &H74 AND PEEK(i + 7) = &H8C THEN
            IF PEEK(i + 8) = &H3C AND PEEK(i + 9) = &H5C THEN
            IF PEEK(i + 10) = &H74 AND PEEK(i + 11) = &HAC THEN
              UsingOff2 = i
              Version = 71
              EXIT DO
            END IF
            END IF
            END IF
            END IF
          END IF
        END IF
      NEXT
      UsingSeg2& = UsingSeg2& - &H3F0
    LOOP
    IF i = &H3FF5 THEN ERROR 5
  END IF

  ' Change the symbols in B$PUFOUT
  DEF SEG = UsingSeg1&
  IF Currency$ <> "" THEN POKE UsingOff1 + &H1, ASC(Currency$)
  IF Thousand$ <> "" THEN POKE UsingOff1 + &H17, ASC(Thousand$)
  IF Fractional$ <> "" THEN POKE UsingOff1 + &H2D, ASC(Fractional$)

  ' Change the symbols in PUSCAN
  DEF SEG = UsingSeg2&
  IF Version = 45 THEN
    IF FormatCurrency AND Currency$ <> "" THEN
      POKE UsingOff2 + &H11, ASC(Currency$)
      POKE UsingOff2 + &H24, ASC(Currency$)
    END IF
    IF Thousand$ <> "" THEN POKE UsingOff2 + &H41, ASC(Thousand$)
    IF Fractional$ <> "" THEN
      POKE UsingOff2 + &H1, ASC(Fractional$)
      POKE UsingOff2 + &H39, ASC(Fractional$)
      POKE UsingOff2 + &H4E, ASC(Fractional$)
    END IF
  ELSE
    IF FormatCurrency AND Currency$ <> "" THEN
      POKE UsingOff2 + &H12, ASC(Currency$)
      POKE UsingOff2 + &H26, ASC(Currency$)
    END IF
    IF Thousand$ <> "" THEN POKE UsingOff2 + &H44, ASC(Thousand$)
    IF Fractional$ <> "" THEN
      POKE UsingOff2 + &H1, ASC(Fractional$)
      POKE UsingOff2 + &H3C, ASC(Fractional$)
      POKE UsingOff2 + &H52, ASC(Fractional$)
    END IF
  END IF

  EXIT SUB
  PRINT USING ""; 0   ' Force the compiler to include PRINT USING

END SUB


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 23, 2004, 08:57:19 PM
Plasma, utterly amazing! Except for the business of specifying the currency symbol which is a bit shaky, all the rest works just fine.

I can't figure out what you're doing because I've never used peek and poke. How do you figure out where the data is in memory in order to get in and modify it?

Unless we have a miracle entry at the last minute which performs better than yours, you will be the winner. At the end, I'll post my simplistic solution.

Thanks.
*****


Title: Challenge: International version of PRINT USING
Post by: Plasma on May 23, 2004, 10:51:38 PM
Hrmm...how is the currency symbol shaky? It'll use whatever character you pass to it. Neither codepage 437 nor 850 have a euro symbol, so there's not much I can do there.

About modifying the memory...well, it helps to have the source code to QBasic. :)


Title: Challenge: International version of PRINT USING
Post by: relsoft on May 24, 2004, 08:33:40 AM
All 7 MB of it. :*(

Lucky you. :*)


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 25, 2004, 11:16:44 PM
Plasma, you're too much! "It helps to have the source code to Qbasic" :rotfl:

About the currency symbol shakiness, I can't remember now what it was.
*****


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 27, 2004, 11:48:47 PM
*Well, this challenge is getting as cold as yesterday's mashed potatoes.

Except for Plasma, no one really gives a diddley about the problem.

So, I'm naming Plasma the winner for a brilliant, though different, solution.

Now I'm going to post my simplistic solution.
I'm tired so I'll just walk you through the logic.

I got the idea from a function in Ethan Winer's QuickPak library which allows you to assign the results of a PRINT USING to a variable. So, without using this QuickPak function:

OPEN A WORK FILE FOR OUTPUT TO #2.
USING USING A NORMAL MASK, DO A PRINT USING #2.
Now on file 2 you have the result formatted according to the normal mask.
CLOSE THE WORK FILE, AND READ IN THE FORMATTED RESULT.

NOW, IF YOU WANT TO CONVERT THE RESULT TO EUROPEAN FORMAT,  CONTINUE.
USE AN INSTR TO CONVERT THE DECIMAL POINT TO AN "X" CHARACTER, AND USE AN INSTR TO CONVERT THE COMMAS TO A "Y".
This is to distinguish original decimal point and commas.
THEN CONVERT THE X'S TO COMMAS AND THE Y'S TO DECIMAL POINTS.
THEN IF YOU WANT TO DISPLAY SOME OTHER CURRENCY CHARACTER, CONVERT THE DOLLAR-SIGN TO THAT CHARACTER.

Simple, yes. Elegant, well that's a matter of opinion. Many people don't like to use work files. In this case, the work file is 95% of the solution.

Opinions?
*****


Title: Challenge: International version of PRINT USING
Post by: SCM on May 28, 2004, 01:33:21 AM
Moneo,
It isn't that no one was interested in the challenge, we just weren't looking at it as having a simple solution.  nath and I were both considering it as a rewrite of the PRINT USING function.  

I like yours.  An output and an input isn't real fast, but most of the time it wouldn't be noticable.


Title: Challenge: International version of PRINT USING
Post by: Moneo on May 29, 2004, 12:52:30 AM
Thanks, SCM, those are exactly my feelings too.
*****