Qbasicnews.com
September 28, 2021, 02:49:28 PM
 Pages: [1]
 Author Topic: Newbie needs help  (Read 3568 times)
azagthothe
New Member

Posts: 2

 « on: June 23, 2006, 11:24:25 AM »

I have a few questions concerning the following code.

1.  Is there a way to store my cost array as currency or would it be better to store it as a double?  What is the code for double?

2.  Is there a good way to have an idiot proof input?  I want to be able to respond with custom message if the user enters a letter or word instead of a number.

Code:

DIM n AS INTEGER
DIM day AS STRING

DIM items\$(12)
items\$(1) = "1 Partridge in a pear tree"
items\$(2) = "2 Turtledoves"
items\$(3) = "3 French hens"
items\$(4) = "4 Calling birds"
items\$(5) = "5 Gold rings"
items\$(6) = "6 Geese-a-laying"
items\$(7) = "7 Swans-a-swimming"
items\$(8) = "8 Maids-a-milking"
items\$(10) = "10 Lords-a-leaping"
items\$(11) = "11 Pipers piping"
items\$(12) = "12 Drummers drumming"

DIM cost(12)
cost(1) = 27.5
cost(2) = 25!
cost(3) = 5!
cost(4) = 70!
cost(5) = 60!
cost(6) = 25!
cost(7) = 1000!
cost(8) = 4.25
cost(9) = 289.5
cost(10) = 292.5
cost(11) = 95.75
cost(12) = 95!

CLS
1 INPUT "Enter a day from 1 to 12: ", day
day = CINT(day\$)

IF day < 1 THEN
PRINT "Surely you can afford 1 day!"
SLEEP 7
GOTO 1
ELSEIF day > 12 THEN
PRINT "Don't be greedy!"
SLEEP 7
GOTO 1
END IF

FOR n = 1 TO day
PRINT items\$(n), cost(n)

NEXT

END
 Logged
Anonymous
Guest
 « Reply #1 on: June 23, 2006, 04:29:38 PM »

Quote from: "azagthothe"
I have a few questions concerning the following code.

Quote
1.  Is there a way to store my cost array as currency or would it be better to store it as a double?  What is the code for double?

Try storing it as a double, then when you want to display it, multiply it by 100 and store it in an integer. Or use PRINT USING (which i'm not familiar with)

Quote
2.  Is there a good way to have an idiot proof input?  I want to be able to respond with custom message if the user enters a letter or word instead of a number.

Not really. You can check ascii value of the firts char using

Code:
? ASC( LEFT\$( day, 1 ) )
, and see if it's in bounds.
 Logged
Agamemnus
x/ \z

Posts: 3491

 « Reply #2 on: June 24, 2006, 01:35:20 PM »

You can either check the string itself so it only has numbers and then check the value of said numbers, OR you can limit the choices by using a menu where they are controlled with arrow keys and enter key..

This is code to check that the numbers a string "testString\$" has correspond to an upper and lower range of integers. The max (so as not to cause an error) in this example, if you are using an integer, is a 4 digit value from -9999 to 9999. If it's bigger, you need to do an integer check first to make sure it's not something like 99999. QB Integers are between:
-32768 and 32767.

Code:

DECLARE FUNCTION checkValidity(maxDigits as integer, maxValue as integer, minValue as integer, stringtocheck\$)

testmaxDigits = 2
testmaxValue = 12
testminValue = 1
testString\$ = "12"
test = checkValidity(testmaxDigits, testmaxValue, testminValue, testString\$)
if test =  0 then PRINT "Wrong number." ELSE PRINT "Right number."

SLEEP
SYSTEM

FUNCTION checkValidity(maxDigits as integer, maxValue as integer, minValue as integer, stringtocheck\$)
resultMult = 1
startCount = 0
resultstring\$ = ""
allowedChars\$ = "1234567890"

for i = 1 to LEN(stringtocheck\$)
temp\$ = MID\$(stringtocheck\$, i, 1)
if temp\$ = "-" then resultMult = -resultMult

if INSTR(allowedChars\$, temp\$) THEN

if temp\$ = "0" then
if startCount = 1 then digitCount = digitCount + 1
else
startCount = 1
end if
if startCount = 1 then
resultString\$ = resultString\$ + temp\$
digitCount = digitCount + 1
IF digitCount = maxDigits THEN EXIT FOR
end if
end if
next i

resultNumber = VAL(resultString\$)*resultMult
if resultNumber > maxValue THEN checkValidity = 0: EXIT FUNCTION
if resultNumber < minValue THEN checkValidity = 0: EXIT FUNCTION
checkValidity = 1
END FUNCTION
 Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Moneo
Na_th_an

Posts: 1971

 « Reply #3 on: June 24, 2006, 08:46:48 PM »

Quote from: "azagthothe"

......
2.  Is there a good way to have an idiot proof input?  I want to be able to respond with custom message if the user enters a letter or word instead of a number......

From the code you posted, you are only inputting numbers for DAY. If the user were to enter a letter here, QB would issue the error message "Redo from start".

If you don't like this QB message, then INPUT the day to a string, like D\$, and go validate for numeric with no decimal as follows:
Code:
IF NUMDECIMAL(D\$,0) = 0 then .....(it's not numeric)

Now if it's not numeric, you can print a nice message of your own to the user.

Anyway, the function Aga posted is good, and kiils two birds with one stone by checking for numeric as well as validating that the number is with a range.

I'm posting my NUMDECIMAL function in case you need to input and validate numbers containing a decimal point somewhere. It also checks that you obviously can't have more than one decimal point in the same number.

BTW, I didin't just whip this together. I've been using this function successfully for over 10 years.

My function does not allow a leading minus sign siince I have found that you rarely ask the user for negative numbers. Allowing a minus for any number could cause problems. If any of your numbers can contain a minus sign, you will need to strip it off the number, then use the function to validate it, and put the sign back afterwards.

Also, my function does not validate the range of the numbers. I feel that this is easier to do in the main program.
Note that the function issues:
0 = False, that is, not numeric
-1 = True, it is numeric

Code:

FUNCTION NumDecimal (Z\$,DecimalPlaces)

REM *
REM *** CHECK FOR STRICTLY NUMERIC, NO NULL, ALLOW A DECIMAL POINT.
REM *
NumDecimal=0         'Init to False

W\$=Z\$
IF W\$="" THEN EXIT FUNCTION

ZZP=INSTR(W\$,".")
IF ZZP>0 THEN
MID\$(W\$,ZZP,1)="0"
IF ZZP < LEN(W\$)-DecimalPlaces OR INSTR(W\$,".") THEN EXIT FUNCTION
ELSE
FOR ZZ = 1 TO LEN(W\$)
A=ASC(MID\$(W\$,ZZ,1))
IF A<48 OR A>57 THEN RETURN
NEXT ZZ
END IF

NumDecimal = -1          'True

END FUNCTION
 Logged
Ralph
Ancient Guru

Posts: 544

 « Reply #4 on: June 24, 2006, 09:54:49 PM »

Quote

2. Is there a good way to have an idiot proof input? I want to be able to respond with custom message if the user enters a letter or word instead of a number.

try this code:
Code:

1
CLS
INPUT " Enter a number from 1 to 12: ", a\$
a = VAL(a\$)

IF a <1 OR a > 12 THEN
PRINT " "; a\$ ; "is NOT a proper entry.  Press <Ener> to continue"
WHILE INKEY\$ = "": WEND
GOTO 1
ELSE
PRINT " "; a\$ " is a VALID number.  Press <Enter> to continue"
WHILE INKEY\$ = "": WEND
GOTO 1
END IF

END
 Logged

Ralph, using QuickBASIC 4.5 and Windows XP Home Edition and Service Pack 2, with HP LaserJet 4L printer.
Moneo
Na_th_an

Posts: 1971

 « Reply #5 on: June 25, 2006, 08:41:23 PM »

Ralph,

Your validation for a valid range of numbers between 1 and 12 is relying on the fact that you do an INPUT to the string A\$ and then do a VAL of A\$ to the variable A.

This is not a strong validation. It only protects the program and not what the user intended to enter. For example, if he intends to enter 12 and by mistake enters 1w, the VAL will strip and ignore the "w" giving you a "1" into the variable A. Any other invalid letters or characters will be ignored by the VAL, thus giving numeric results that were not intended by the user.

The only complete way to validate the input number is to validate it in its entirety as was entered. Leading or trailing blanks should also be considered as invalid characters, since they could have been intended to be a valid numeric digit. (See my validation function in previous post.)

BTW, it is not good practice to use the same variable name with different "types", like A\$ and A. Some versions of QuickBASIC and QBasic will not allow this.

Also, in my opinion, echoing the input number back to the user for visual confirmation with a pause after it has been validated, is overkill. After you have validated it correctly, print it if you like, but just proceed to process the number.

*****
 Logged
Ralph
Ancient Guru

Posts: 544

 « Reply #6 on: June 25, 2006, 10:56:24 PM »

Moneo:

I see your point, now that you have explained it so well.  I also see that my solution's test for a valid entry can fail.  About the only validation I can see, is that printing the input, at least, can warn the user about an erroneous answer.  Other than that out, I'm with you on the rest.  Thank you for your time and patience.
 Logged

Ralph, using QuickBASIC 4.5 and Windows XP Home Edition and Service Pack 2, with HP LaserJet 4L printer.
Agamemnus
x/ \z

Posts: 3491

 « Reply #7 on: June 26, 2006, 01:37:29 AM »

Ah, well in that case my code would also make "1w" as "1". To fix it, one would need an ELSE in that IF statement, ending the sub as soon as it found a non valid character.
 Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Moneo
Na_th_an

Posts: 1971

 « Reply #8 on: June 27, 2006, 04:05:28 PM »

Quote from: "Ralph"
.
...... About the only validation I can see, is that printing the input, at least, can warn the user about an erroneous answer.......

Yes, in the code you posted, the user gets warned, but all he can do is press enter to continue. If he didn't agree with the number shown, he would have to abort the program somehow, like with a Ctrl-C. Perhaps when you display the number to be processed, it would need a Yes/No to proceed or not.

Regarding my time and patience, you're quite welcome. Data validation is one of my pet peeves.
*****
 Logged
Moneo
Na_th_an

Posts: 1971

 « Reply #9 on: June 27, 2006, 04:08:11 PM »

Quote from: "Agamemnus"
Ah, well in that case my code would also make "1w" as "1". To fix it, one would need an ELSE in that IF statement, ending the sub as soon as it found a non valid character.

Sorry, Aga, but I can't find the sub that you refer to.
*****
 Logged
Agamemnus
x/ \z

Posts: 3491

 « Reply #10 on: June 28, 2006, 03:08:36 PM »

Function, I mean..  :-?
 Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
 Pages: [1]