I have this variable declarations on my program:
X="MAGENTA"
Y="CYAN"
Z="TAN"
A="KHAKI"
Now what I want is to randomly choose one of these and PRINT it. But how to do this?
My BASIC is pretty rusty but you should just be able to use something like:
10 X$ = "MAGENTA"
20 Y$ = "CYAN"
30 Z$ = "TAN"
40 A$ = "KHAKI"
50 N = INT(RND(1) * 4)
60 IF N = 0 THEN PRINT X$
70 IF N = 1 THEN PRINT Y$
80 IF N = 2 THEN PRINT Z$
90 IF N = 3 THEN PRINT A$
or, putting it in a subroutine for code re-use:
10 X$ = "MAGENTA"
20 Y$ = "CYAN"
30 Z$ = "TAN"
40 A$ = "KHAKI"
50 GOSUB 1000
60 PRINT RC$
70 END
1000 TV = INT(RND(1) * 4)
1010 IF TV = 0 THEN RC$ = X$
1020 IF TV = 1 THEN RC$ = Y$
1030 IF TV = 2 THEN RC$ = Z$
1040 IF TV = 3 THEN RC$ = A$
1050 RETURN
Of course, you probably should be using arrays for that sort of thing so you can just use:
10 DIM A$(3)
10 A$(0) = "MAGENTA"
20 A$(1) = "CYAN"
30 A$(2) = "TAN"
40 A$(3) = "KHAKI"
50 PRINT A$(INT(RND(1)*4))
The above answer is correct and comprehensive.
This answer, on the other hand, is not, but I was actually doing a little bit of Commodore BASIC last month and decided that string indexing CAN be useful, sometimes, so here's a non-answer that sort of reframes your problem.
100 X$ = "MAGENTACYAN TAN KHAKI "
110 PRINT MID$(X$,INT(RND(1)*4)*7, 7)
This code gets a random int from 0 to 3, then uses that to find the start index into a single string that contains all four entries, each of which is padded out (where necessary) to 7 characters. That padding is needed because the final parameter to MID$ is the length of the substring to be extracted.
WHY BOTHER?
When to consider indexing over an array:
(1) when your string data is near-uniform length, and
(2) when you have a LOT of little strings.
If those two conditions are true, then the full code, including the data, is more compact, and takes less memory due to allocating fewer pointers.
P.S. Bonus point if you find that I've made an off-by-one error!
Here's another way to do it, using one variable for the output and ON..GOSUB to set it based on a random number in the range [1..4].
10 ON INT(RND(1)*4+1) GOSUB 100,110,120,130
20 PRINT A$
30 END
100 A$ = "MAGENTA":RETURN
110 A$ = "CYAN":RETURN
120 A$ = "TAN":RETURN
130 A$ = "KHAKI":RETURN
Related
Problem:
The circle commands result in a same size binary string as the original, with a Right Circle taking the rightmost bits and circling them to the other side, and likewise for the Left Circle, taking the leftmost digits and circling them to the other side. For example, the command RC 3 81 will take the binary value for 81, or 1010001 in binary, take the
three right most digits, 001, and circle them to the front of the string resulting in 0011010, which is 26 in decimal. So some examples given
RC 3 81 = 26 OK
LC 5 119 = 125 OK
RC 5 181 = 1389 //I get 173
LC 8 999 = 1017 OK
RC 10 1200 = 361648 //I get 353
LC 10 1200 = 600 OK
When I do RC 5 181
181 binary = 101 10101
RC 10110101 = 10101 101 = 173
And
RC 10 1200
1200 binary = 1 0010110000
RC 10 10010110000 = 00101100001 = 353
When I check with a C++ program I wrote I get
Enter the command: LC 5 119
The base ten value is: 125
Run again (Y/N): y
Enter the command: LC 8 999
The base ten value is: 1017
Run again (Y/N): y
Enter the command: LC 10 1200
The base ten value is: 600
Run again (Y/N): y
Enter the command: RC 3 81
The base ten value is: 26
Run again (Y/N): y
Enter the command: RC 5 181
The base ten value is: 173
Run again (Y/N): Y
Enter the command: RC 10 1200
The base ten value is: 353
Run again (Y/N): n
Am I crazy and did these wrong- I have no clue how the author got those two values for the Right Circle answers. Your all thoughts please.
Is there an way to split an string and save it into an table like this:
str = "23 = John, 45 = Karl, 6 = Chloe, 34 = Sarah"
--[[ 23 John
45 Karl
6 Chloe
34 Sarah]]
I want the numbers to be the keys and the Names to be the values.
Adapt this code:
for k,v in str:gmatch("(%d+)%s*=%s*(%a+)") do
print(k,v)
end
This assumes that the names are composed of letters only.
Have a couple million records with a string like
"00 00 01 00 00 01 00 01 00 00 00 00 01 01 00 01 00 00 00 00 01"
String has a length of 56. All positions are filled with either a 0 or a 1.
My job is parse the string of each record every two positions
(there are no spaces, that is just for clarification).
If there is a 1 in position two that means increment var1 +1
If there is ALSO a 1 in position four, (don't care about leading "0"'s
in position 1/3/5/9...55, etc.) increment var2 + 1, up to 28 variables.
The entire 56 len string must be parsed every two characters. Potentially
there could be 28 variables that have to be incremented, (but not realistic,
most likely there is only five or six) which could be found in any part of the
string, beginning to end (as long as they are in position 2/4/6/8 up to 56, etc.)
This is what my boss gave me:
if substr(BigString,2,1)='1' then var1+1;
OK. Fine.
A) There are 27 more places to evaluate in the string.
B) there are a couple million records.
28 nested if then do loops doesn't sound like an answer (all I could think of). At least not to me.
Thanx.
I think the author is trying to look for an do-loop method. So my suggest is macro %do or array statment in data step.
data _null_;
text = '000001000001000100000000010100010000000001';
y = length(text);
array Var[28];
do i = 1 to dim(Var);
Var[i] + (substrn(text,i*2,1)='1');
put i = Var[i]=;
end;
run;
Kind of easy, isn't is?
Array the variables that are to be potentially incremented according to string. A DO loop can examine each part of the string and conditionally apply the needed increment.
The SUM statement <variable>+<expression> means the variable's value is automatically retained from row to row.
Due to the nature of retained variables, you might want only the final var1-var28 values at the last row in the data. The question does not have enough info regarding what is to be done with the var<n> variables.
Example:
Presume string is named op_string (op for operation). Utilize logical evaluation result True is 1 and False is 0
data want(keep=var1-var28);
set have end=done;
array var var1-var28;
do index = 1 to 28;
var(index) + substr(op_string, 2 * index) = '1'; * Add 0 or 1 according to logic eval;
end;
if done; * output one row at the end of the data set;
run;
Use COUNTC() to count the number of 1's in the string then.
data want;
set have;
value = countc(op_string, '1');
run;
if I understood the problem well, this could be the solution:
EDITED 2. solution:
/* example with same row*/
data test;
a="00000100000100010000000001010001000000000100000000011110";output;
a="10000100000100010000000001010001000000000100011100011101";output;
a="01000100000100010000000001010001000000000100000001000000";output;
a="10100100000100010000000001010001000000000111111111111110";output;
a="01100100000100010000000001010001000000000101010101010101";output;
a="00000100000100010000000001010001000000000100001100101010";output;
run;
/* work by rows*/
%macro x;
%let i=1;
data test_output(drop=i);
set test;
i=1;
%do %while (&i<=56);
var&i.=0;
var&i.=var&i.+input(substr(a,&i,1), best8.);
%let i=%eval(&i.+1);
%end;
run;
%mend;
%x;
/* results:
a var1 var2 var3 var4 var5 var6 var7 . .
00000100000100010000000001010001000000000100000000011110 0 0 0 0 0 1 0 .......
10000100000100010000000001010001000000000100011100011101 1 0 0 0 0 1 0 .......
01000100000100010000000001010001000000000100000001000000 0 1 0 0 0 1 0 .......
10100100000100010000000001010001000000000111111111111110 1 0 1 0 0 1 0 .......
01100100000100010000000001010001000000000101010101010101 0 1 1 0 0 1 0 .......
00000100000100010000000001010001000000000100001100101010 0 0 0 0 0 1 0 .......
*/
In my file, I have in each line numbers that are between 0 and 256:
20
123
125
109
175
108
210
74
127
86
172
128
187
131
183
230
132
77
30
177
64
60
211
112
79
45
I would like to compute how many each number is repeated in this file:
with open('file', 'w') as f_sb_out:
for i in range(256):
total = sum(str(i))
print('Numre of repetition of '+str(i)+'is', str(total))
This is certainly not the best way of doing it in terms of error handling, but it meets your basic requirements.
# Declare dict for counts
numCount = dict()
with open('file.txt', 'r') as f_sb_out: # Need to change the form to read, not write
line = f_sb_out.readline() # Read the first line
while line: # Loop through each line
line = f_sb_out.readline()
line = line.strip() # Strip any whitespace on either end
if line == '': # Skip any whitespace lines
continue
if line in numCount:
numCount[line] = numCount[line] + 1 # Increment the counter
else:
numCount[line] = 1 # Start a new counter
# Print the counts
for num in numCount:
print "The number " + num + " appeared "+ str(numCount[num]) + " time(s)."
Given your file, it produces:
The number 210 appeared 1 times.
The number 211 appeared 1 times.
The number 60 appeared 1 times.
The number 132 appeared 1 times.
The number 131 appeared 1 times.
The number 64 appeared 1 times.
The number 112 appeared 1 times.
The number 177 appeared 1 times.
The number 175 appeared 1 times.
The number 230 appeared 1 times.
The number 172 appeared 1 times.
The number 79 appeared 1 times.
The number 86 appeared 1 times.
The number 45 appeared 1 times.
The number 183 appeared 1 times.
The number 187 appeared 1 times.
The number 77 appeared 1 times.
The number 108 appeared 1 times.
The number 109 appeared 1 times.
The number 125 appeared 1 times.
The number 127 appeared 1 times.
The number 128 appeared 1 times.
The number 74 appeared 1 times.
The number 30 appeared 1 times.
The number 123 appeared 1 times.
Create a counter dictionary and append the lines to it as you read over them. Once you finished you can access the key/values using counter.items()
from collections import Counter
cntr = Counter()
with open('numbers.txt', 'r') as file_in:
for line in file_in:
cntr[line.rstrip()] += 1
for k, v in cntr.items():
print('Numre of repetitions of %s: is %s' % (k, v))
> Numre of repetitions of 1: is 4
> Numre of repetitions of 3: is 3
> Numre of repetitions of 2: is 2
The input numbers.txt file contains:
1
2
3
2
3
3
1
1
1
Checking the counts of your numbers is super easy if you use the collections module. In it, there is a class named Counter that can count any hashable object you can throw at it. In this case, you can give it strings or numbers without a problem. You will need the latest version of Python to use the f strings demonstrated here:
#! /usr/bin/env python3
import collections
def main():
with open('numbers.txt', 'rt') as file:
counts = collections.Counter(map(int, file))
for key, value in sorted(counts.items()):
print(f'{key!r} repeats {value!s} times.')
if __name__ == '__main__':
main()
I'm having trouble with printing a board of dots in Commodore Basic 6502.
This is what I have to far: (it's a subroutine)
10 INPUT "Please enter a number:", X
20 DIM A$(X, X)
30 FOR I = 0 TO X
40 FOR J = 0 TO X
50 A$(I, J) = "."
60 NEXT
70 NEXT
80 PRINT A$
END
Can anyone help me out with it because when I paste it into the emulator, type END, and press enter literally nothing happens?
Any help is much appreciated. I'm trying to build a word search game.
Just for laughs, here is some code that does what I think you want to do:
Just type RUN and hit enter!
Snip to fill an array with dots and print it:
10 INPUT "Please enter a number:", X
20 DIM A$(X, X)
21 REM make the array
30 FOR I = 0 TO X
40 FOR J = 0 TO X
50 A$(I, J) = "."
60 NEXT
70 NEXT
80 REM print the array
90 FOR I = 0 TO X
91 FOR J = 0 TO X
92 PRINT A$(I, J);
93 NEXT
94 PRINT
95 NEXT
99 END