1

I'm using gw-basic to determine a person's weight on another planet.

I need to form a comparison between the weight factor on a planet to the planet that the user inputs. I have defined my planets so far but I'm not sure how to get perform the match of the two variables without an if statement. My code is below:

10 Let jupiter=2.54:let mercury=0.38
20 input weight
30 input "planet to determine weight on"; planet
40 let weight2=0
50 if planet="jupiter" then let weight2=2.54*weight else if planet="mercury" then let weight2=0.38*weight
60 print "your weight on" planet "is" weight2

I want to take out the if statements. Is there a way to do this?

6
  • 1
    You should not change an already answered question, because that invalidates the already given answers. Commented Dec 4 at 22:26
  • The current best answer to (all the previous versions) of this question can be found here: How do I learn BASIC Commented Dec 4 at 22:30
  • @SepRoland: But the version of BASIC, which question asker is using is still unknown. And GWBASIC is out of support, or can you tell if that runs on any Windows version from the last 10 years ? Commented Dec 5 at 16:26
  • @Luuk The OP states they are already using gw-basic. I myself can run gw-basic 3.10 on an old pentium computer, and I suspect that's also how other people would do it these days. Many programming languages from the past are out of support today, but that should not stop people from using them and occasionally running into trouble... Commented Dec 5 at 16:56
  • 1
    @StephenC "The literal answer is No ... since you can't do tests in Basic without using IF" But you can! If I were allowed to write an answer on this question (for which I had cast an now-aged-away reopen vote) it would solve the matter in no more than 6 statements and without using IF at all. Commented Dec 13 at 16:41

5 Answers 5

1

GW-Basic doesn't contain built-in tools for working with KEY-VALUE data. You need to write them yourself. The simplest implementation is a linear search. However, if a large number of other space objects are expected to be added to your spacecraft's computer, then more efficient algorithms will be required. Below are 3 algorithms that differ in time and space complexity.


1. Linear search (time complexity O(n))

100 TRUE=-1
110 '
200 'main loop
210 LOOP=TRUE
220 WHILE LOOP
230   INPUT "your weight"; WEIGHT
240   INPUT "planet to determine weight on"; PLANET$
250   RESTORE 1000 'Restore initial position of data
260   READ P$
270   FOUND=FALSE
280   WHILE P$<>"" AND NOT FOUND
290     IF P$=PLANET$ THEN FOUND=TRUE
300     READ G, P$
310   WEND
320   IF FOUND THEN PRINT "your weight on "PLANET$" is "WEIGHT*G
330   LOOP=PLANET$<>""
340 WEND
350 END
1000 '    NAME       GRAV
1001 DATA "mercury", 0.38
1002 DATA "venus",   0.91
1003 DATA "earth",   1.00
1004 DATA "mars",    0.41
1005 DATA "jupiter", 2.54
1006 DATA "saturn",  0.92
1007 DATA "uranus",  0.91
1008 DATA "neptune", 1.14
1100 DATA "", 'end of data

2. Binary search in ordered data (time complexity O(log n))

100 DEF FNLESS(X$,Y$)=X$<Y$       'less function
110 DIM PLNAME$(100), PLGRAV(100) 'large size in advance
120 TRUE=-1
130 '
200 'filling
210 READ P$
220 WHILE P$<>""
230   CNT=CNT+1
240   PLNAME$(CNT)=P$
250   READ PLGRAV(CNT), P$
260 WEND
270 '
300 'ordering
310 FOR I=1 TO CNT-1
320   FOR J=I+1 TO CNT
330     IF FNLESS(PLNAME$(J), PLNAME$(I)) THEN SWAP PLNAME$(I), PLNAME$(J) : SWAP PLGRAV(I), PLGRAV(J)
340   NEXT
350 NEXT
360 '
400 'displaying container contents
410 PRINT "ORDERED ITEMS:"
420 PRINT " # NAME","GRAV"
430 FOR I=1 TO CNT
440   PRINT USING "##";I; : PRINT " ";PLNAME$(I), : PRINT USING "#.##";PLGRAV(I)
450 NEXT
460 PRINT
470 '
500 'main loop
510 LOOP=TRUE
520 WHILE LOOP
530   INPUT "your weight"; WEIGHT
540   INPUT "planet to determine weight on"; PLANET$
550   '
560   'binary search
570   S=1 : E=CNT
580   WHILE S<E
590     HALF=(S+E)\2
600     IF FNLESS(PLNAME$(HALF), PLANET$) THEN S=HALF+1 ELSE E=HALF
610   WEND
620   '
630   IF PLNAME$(S)=PLANET$ THEN PRINT "your weight on "PLANET$" is "WEIGHT*PLGRAV(S)
640   LOOP=PLANET$<>""
650 WEND
660 END
1000 '    NAME       GRAV
1001 DATA "mercury", 0.38
1002 DATA "venus",   0.91
1003 DATA "earth",   1.00
1004 DATA "mars",    0.41
1005 DATA "jupiter", 2.54
1006 DATA "saturn",  0.92
1007 DATA "uranus",  0.91
1008 DATA "neptune", 1.14
1100 DATA "", 'end of data

GW-BASIC 3.23

ORDERED ITEMS:
 # NAME       GRAV
 1 earth      1.00
 2 jupiter    2.54
 3 mars       0.41
 4 mercury    0.38
 5 neptune    1.14
 6 saturn     0.92
 7 uranus     0.91
 8 venus      0.91

3. Hash table (time complexity O(1))

100 'For clarity, the hash function calculates the hash
101 'based on only the first character of name,
102 'so that if name starts with 'a', hash will be 1,
103 'for 'b' -> 2, ..., for 'z' -> 26.
104 'The number of buckets is also 26.
105 'Thus, the hash table is similar to an alphabetical index.
110 '
120 DEF FNHASH(X$)=ASC(X$)+7               'hash function
130 DEF FNBUCKET(X$)=(FNHASH(X$) MOD 26)+1 'bucket index function
140 TRUE=-1
150 DIM PLNAME$(100), PLGRAV(100)          'large size in advance
160 DIM BUCKET(26)                         'first item index   (0 - end of data)
170 DIM PLNEXT(100)                        'next items indexes (0 - end of data)
180 '
200 'filling
210 READ P$
220 WHILE P$<>""
230   CNT=CNT+1
240   PLNAME$(CNT)=P$
250   I=FNBUCKET(P$)
260   NXT=BUCKET(I)
270   IF NXT THEN WHILE NXT : PRV=NXT : NXT=PLNEXT(NXT) : WEND : PLNEXT(PRV)=CNT ELSE BUCKET(I)=CNT
280   READ PLGRAV(CNT), P$
290 WEND
300 '
400 'displaying container contents
410 PRINT "HASH BUCKETS:"
420 PRINT " # NAMES"
430 FOR I=1 TO 26
440   NXT=BUCKET(I)
450   IF NXT THEN PRINT USING "##";I; : WHILE NXT : PRINT " ";PLNAME$(NXT); : NXT=PLNEXT(NXT) : WEND : PRINT
460 NEXT
470 PRINT
480 '
500 'main loop
510 LOOP=TRUE
520 WHILE LOOP
530   INPUT "your weight"; WEIGHT
540   INPUT "planet to determine weight on"; PLANET$
550   '
560   'bucket search
570   IF PLANET$<>"" THEN NXT=BUCKET(FNBUCKET(PLANET$)) ELSE NXT=0
580   FI=0
590   WHILE NXT AND FI=0
600     IF PLNAME$(NXT)=PLANET$ THEN FI=NXT
610     NXT=PLNEXT(NXT)
620   WEND
630   '
640   IF FI THEN PRINT "your weight on "PLANET$" is "WEIGHT*PLGRAV(FI)
650   LOOP=PLANET$<>""
660 WEND
670 END
1000 '    NAME       GRAV
1001 DATA "mercury", 0.38
1002 DATA "venus",   0.91
1003 DATA "earth",   1.00
1004 DATA "mars",    0.41
1005 DATA "jupiter", 2.54
1006 DATA "saturn",  0.92
1007 DATA "uranus",  0.91
1008 DATA "neptune", 1.14
1100 DATA "", 'end of data

GW-BASIC 3.23

HASH BUCKETS:
 # NAMES
 5 earth
10 jupiter
13 mercury mars
14 neptune
19 saturn
21 uranus
22 venus
Sign up to request clarification or add additional context in comments.

3 Comments

I noticed you put vbnet at the top. Is this recommendation for gw-basic? It looks like gw basic code but I wasn't sure about the vb at the top.
VBNet (Visual Basic .NET) is the only dialect of the Basic language whose syntax highlighting is supported here. Direct operators for working with the console are no longer available (PRINT, INPUT). The WHILE .. WEND block has changed. Numeric labels must be followed by colon. But all kinds of comments remained the same.
Previously, the name of the language was hidden, but now it is always displayed above the code, and there is no way to hide it. And it can be misleading. I fixed everything.
1

Next 4 statements solve the problem of connecting a planet's name to its gravitational constant and without using the IF statement:

1 INPUT "Weight on earth and name of other planet : ",W,P$
2 D$="1.00earth0.38mercury0.91venus0.41mars2.54jupiter0.92saturn0.91uranus1.14neptune"
3 I%=INSTR(D$,P$)
4 PRINT "Weight on ";P$;" is";W*VAL(MID$(D$,I%+(I%>0)*5+1,4))

The difficult part here is to avoid a string indexing error if ever INSTR should return 0 (for not having found the substring). In GW-BASIC (and other BASICs) a comparison like (I%>0) produces FALSE (0) or TRUE (-1). In my expression I%+(I%>0)*5+1 this translates to the following:

P$          I% (INSTR)                                      I% (MID$)
==          ==                                              ==
earth        5     5 + ( 5 > 0)*5 + 1 ->  5 + (-1)*5 + 1 ->  1
mercury     14    14 + (14 > 0)*5 + 1 -> 14 + (-1)*5 + 1 -> 10
venus       25    25 + (25 > 0)*5 + 1 -> 25 + (-1)*5 + 1 -> 21
mars        34    34 + (34 > 0)*5 + 1 -> 34 + (-1)*5 + 1 -> 30
jupiter     42    42 + (42 > 0)*5 + 1 -> 42 + (-1)*5 + 1 -> 38
saturn      53    53 + (53 > 0)*5 + 1 -> 53 + (-1)*5 + 1 -> 49
uranus      63    63 + (63 > 0)*5 + 1 -> 63 + (-1)*5 + 1 -> 59
neptune     73    73 + (73 > 0)*5 + 1 -> 73 + (-1)*5 + 1 -> 69
pluto        0     0 + ( 0 > 0)*5 + 1 ->  0 + ( 0)*5 + 1 ->  1

So, if INSTR found the planet then the index that got returned gets decremented by 4. On the other hand if the planet was not found the zero-returned index gets incremented by 1 so that MID$ can fetch a default conversion factor (one that doesn't change the weight).

Don't feel compelled to put everything in just 4 lines. You can use two different INPUT statements, and introduce several intermediate steps instead of using the compound expression...

1 Comment

The lack of input validation, makes input like "1,terra" and/or "1,us" behave like those are valid inputs...
0

I would split the if-statement into multiple statements:

50 if planet="jupiter" then let weight2=2.54*weight 
55 if planet="mercury" then let weight2=0.38*weight

This will result in better readable code than having one, very long, line of if .. else if ...

Comments

0

Nothing wrong. You can prevent repetition as follows:

20 input weight
30 input "planet$ to determine weight on"; planet
40 let gravity=1.0
50 if planet$="jupiter" then let gravity=2.54 else if planet$="mercury" then let gravity=0.38
55 let weight2 = gravity * weight
60 print "your weight on" planet "is" weight2

Some Basic dialects allow nicer mapping of planet name to gravity factor.

What is - I think - what you would like to know. Should you want to offer a menu of all planets and such, then arrays, DATA and READ might be helpfull.


Using arrays:

Filling two arrays p$() (planets) and g() for gravity factors

10 READ N
11 DIM p$(N)
12 DIM g(N)
13 FOR i=1 TO N
14 READ p$(i)
15 READ g(i)
16 NEXT i
17 DATA 3
18 DATA "jupiter",2.54
19 DATA "mercury",0.38
20 DATA "earth",1.0

Asking the weight

21 input "weight"; weight

Asking for the planet

22 FOR i=1 TO N
23 PRINT "planet " p$(i)
24 NEXT i
30 input "planet to determine weight on"; planet$

Determine the gravity factor

40 let gravity=1.0
42 FOR i=1 TO N
50 if planet$=p$(i) then let gravity=g(i)
51 NEXT i

Results

55 let weight2=gravity*weight
60 print "your weight on" planet$ "is" weight2

(My knowledge of GW-Basic is very "basic.")

12 Comments

I thought about using arrays. But then when the user inputs the planet name, how do I match that string they input to the array value?
FOR i=1 TO 2 : IF p$(i) = planet$ THEN gravity = g(i) ....
@SamH Use two arrays, one with planet names, the other with gravity. Search the first array for the planet, then use the index to get the corresponding gravity in the second array.
But then I've still got the issue of trying to match up the planet name someone inputs to the array value
Oh nm. I see what you mean logically. But how would that look in code? I've never searched an array before.
@SamH You do that with a FOR loop that checks each element of the planet array.
@SamH See Joop's comment above for the basic idea. I haven't written BASIC in over 40 years.
Some other answers also use FOR NEXT loops. I'll try adding the code to the answer.
|
-1

If I understand the problem correctly the object is to use the variables.

Smallest change:

50 if planet="jupiter" then let weight2=jupiter*weight else if planet="mercury" then let weight2=mercury*weight

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.