For the following code in HP Time-Shared BASIC, I am wondering about line 2270:
2180 INPUT X
2190 IF X=1 THEN 2210
2200 LET X=2
2210 LET X=X+1
2220 IF X=3 THEN 2260
2230 IF B>39 THEN 2260
[irrelevant code lines removed for clarity]
2260 X1=X1*(-1)
2270 GOTO X OF 2290,2540,2720
Based on other examples in this code base, it seems GOTO [variable] OF [line1,line2,...] seems to be the equivalent of if X == 1 GOTO LINE 1; if X == 2, GOTO LINE 2, etc.
I found the relevant Wikipedia bit "Calculated flow-control via the GOTO/OF and GOSUB/OF statements" but I'd like more clarity.
Can anyone confirm?
Thanks,
Caleb
Thankfully, the Wikipedia page has a link to all the original documentation:
http://www.bitsavers.org/pdf/hp/2000TSB/
This includes a full language reference:
http://www.bitsavers.org/pdf/hp/2000TSB/22687-90001_AccessBasic9-75.pdf
Which says this about GOTO/OF on page 11-40
GO TO numeric expression OF statement number list
...
When the second form of the GO TO statement is used, the numeric expression is evaluated and rounded to an integer "n". Control then is transferred to the "nth" statement number in the statement number list, where statement number list is one or more statement numbers separated by commas. If there is no statement number corresponding to the value of the numeric expression, the GO TO statement is ignored and the statement following the GO TO statement is executed
That appears to confirm your guess
Related
Working with postgres 9.4 and using PGAdmin III: I have a schema with a character field that MAY contain "new lines" (NLs), or MAY contain double spaces, or neither. I need to divide the field into 3 segments by either of the above factors or by 26 characters in length.
If the total length is 26 or less, I just copy it as is.
If it has NLs, then I split it by those.
If no NLs but it has double spaces, I split it by those.
Finally, if none of the above, I want to split it into 3 26 character chunks.
For context; the column is data entered by customers into a 3 line box. anywhere from 4 characters up to 78. Some use NLs, some use spaces to push the text to the next line, some have luck with spacing so use neither.
Here's the part of the query to gather the first line:
CASE WHEN LENGTH(detail) < 27 THEN detail
WHEN detail LIKE E'%\n%' THEN SPLIT_PART(detail,E'\n',1)
WHEN detail LIKE E'% %' THEN SPLIT_PART(detail,E' ',1)
ELSE LEFT(detail, 26)
END AS line1,
When I test this on a sample schema, the first three parts work exactly as I need but the "ELSE" part never does. The LEFT statement workout outside of the CASE statement but not within.
I've tried enclosing it with a SELECT clause, nesting several CASE-WHEN-ELSE statements, and other things to no avail.
Oddly, it DOES work if I take out the "SPLIT_PART" line referring to '% %'.
Short of giving up on the double-space split, is there another solution, or have I just formatted something wrong?
CASE WHEN LENGTH(detail) < 27 THEN detail
WHEN detail LIKE '%\n%' THEN SPLIT_PART(detail,'\n',1)
WHEN position(' ' in detail) > 0 THEN SPLIT_PART(detail,' ',1)
ELSE left(detail,26)
After another bit of time mucking about, I suspected the LIKE E'% %' might be the issue - and it was. Simply changing it to LIKE E' ' allows it to work like I wanted.
Added:
Turns out the best solution is a combination of "position" to determine if the double space exists, and split-part to separate correctly at the location.
I want to write fairly concise, more readable R code.
I try to go to the line each time to avoid having very long codes. I have noticed that I have different results depending on whether I go to the line or not after the OR operator in grepl. And that annoys me
For example with this code. I have:
sigaps$Oncologie<-ifelse(
grepl("Radioth[ée]rapie|Chimioth[ée]rapie|Radiochimioth[ée]rapie|Cancer|Tumeur|Tumoral",
sigaps$Titre.de.l.étude,
ignore.case=TRUE),1,0)
table(sigaps$Oncologie)
0 1
377 157
But when I moved Tumoral to the next line, I have a different result. I dont understand what doesn't
works:
sigaps$Oncologie<-ifelse(
grepl("Radioth[ée]rapie|Chimioth[ée]rapie|Radiochimioth[ée]rapie|Cancer|Tumeur|
Tumoral",
sigaps$Titre.de.l.étude,
ignore.case=TRUE),1,0)
table(sigaps$Oncologie)
0 1
380 154
I have always done this. But I'm wondering, if I can't get the same results with two different ways of coding that I find identical, am I not making a coding mistake for years?
The difference occurs because your are breaking the line and adding spaces into your string by splitting it on to the next line and indenting it. Fix it by a) not doing that or b) creating your string with paste(..., sep="|")
grepl(paste("Radioth[ée]rapie", "Chimioth[ée]rapie",
"Radiochimioth[ée]rapie", "Cancer",
"Tumeur", "Tumoral", sep="|"),
sigaps$Titre.de.l.étude, ignore.case=TRUE)
I attend 1st grade of Highschool. Recently I had an assignment to do in Turbo Pascal and this happened:
var
a,b,x,y,n:integer;
begin
readln(a,b,x,y);
if a<b and x<y then n:=a+y;
if a<b and x>y then n:=a+y;
if a>b and x<y then n:=b+x;
if a>b and x>y then n:=b+x;
writeln(n);
end.
An Error 57 appeared in the second if row between "y" and "<".
Can someone explain why this happened?
A web source indicates that Error 57 is "Then" Expected and because you did not surround your If comparisons with parenthesis brackets the compiler expects that the next word should be a then. Even if the error is not what the source said you still need to enclose your If comparisons with parenthesis brackets if you have more than one comparison in one if
if (a<b) and (x<y) then n:=a+y;
Otherwise the compiler thinks you want the comparison to be
a < b and x
Which will check if a is smaller than the result of b "ANDed" with x
I've got a function that uses readline to ask people to enter in data. But I'm at a loss as to the best method to insure that the data entered meet my criteria. I'm figuring "if" statements may be the best way to go to check for errors, but I'm not sure how to incorporate them. My attempt at using them is obviously flawed (see below).
As a simple example, 2 of the most likely problems I'm going to run into would be I'd like to insure that at least some value is entered in for x (and if a value is entered for x it is a number) and that V1 and V2 contain the same number of values.
fun<-function(){
T<-readline("What is x" )
if(T=="" | typeof(x)!=numeric)
{print("Input non-aceptable")
T<-readline("What is x ")}
else
V<-readline("Enter 4 values" )
V2<-readline("Enter 4 more values ")
if(length(V1)!=length(V2))
{print("V1 & V2 do not contain equal # of values")
V<-readline("Enter 4 values ")
V<-readline("Enter 4 more values ")}
else
T<-as.numeric(T)
V<-as.numeric(V)
V2<-as.numeric(V2)
return(list(x,V1,V2)
}
As you can see, my hope is to try and spot potential errors before they cause an actual error to happen, and then to give the person an opportunity to re-enter the data. If "if" statements are the way to go, can I get some help on using the correctly?
Thanks!
In R the boolean types TRUE and FALSE can also be represented by T and F. So first off try changing the variables that you have named T to something sensible... like x maybe???
Secondly, in your typeof(x) argument, you called the variable T, so that won't work. In addition there were no quotes around numeric. Try if(!(is.numeric(x)))
Thirdly, your variables are inconsistently named, V and V, and then V1 and V2. Aside from hard to read, it also just won't work.
Lastly, your return statement needs a second closing parenthesis, the function code block needs a closing curly brace.
I'm trying to learn how to configure my .vimrc file with my own functions.
I'd like to write a function that traverses every line in a file and counts the total number of characters, but ignores all whitespace. This is for a programming exercise and as a stepping stone to more complex programs (I know there are other ways to get this example value using Vim or external programs).
Here's what I have so far:
function countchars()
let line = 0
let count = 0
while line < line("$")
" update count here, don't count whitespace
let line = getline(".")
return count
endfun
What functional code could I replace that commented line with?
If I understand the question correctly, you're looking to count the number of non-whitespace characters in a line. A fairly simple way to do this is to remove the whitespace and look at the length of the resulting line. Therefore, something like this:
function! Countchars()
let l = 1
let char_count = 0
while l <= line("$")
let char_count += len(substitute(getline(l), '\s', '', 'g'))
let l += 1
endwhile
return char_count
endfunction
The key part of the answer to the question is the use of substitute. The command is:
substitute(expr,pattern,repl,flags)
expr in this case is getline(l) where l is the number of the line being iterated over. getline() returns the content of the line, so this is what is being parsed. The pattern is the regular expression \s which matches any single whitespace character. It is replaced with '', i.e. an empty string. The flag g makes it repeat the substitute as many times as whitespace is found on the line.
Once the substitution is complete, len() gives the number of non-whitespace characters and this is added to the current value of char_count with +=.
A few things that I've changed from your sample:
The function name starts with a capital letter (this is a requirement for user defined functions: see :help user-functions)
I've renamed count to char_count as you can't have a variable with the same name as a function and count() is a built-in function
Likewise for line: I renamed this to l
The first line in a file is line 1, not line 0, so I initialised l to 1
The while loop counted up to but not including the last line, I assume you wanted all the lines in the file (this is probably related to the line numbering starting at 1): I changed your code to use <= instead of <
Blocks aren't based on indentation in vim, so the while needs an endwhile
In your function, you have let line = getline('.')
I added a ! on the function definition as it makes incremental development much easier (everytime you re-source the file, it will override the function with the new version rather than spitting out an error message about it already existing).
Incrementing through the file works slightly differently...
In your function, you had let line = getline('.'). Ignoring the variable name, there are still some problems with this implementation. I think what you meant was let l = line('.'), which gives the line number of the current line. getline('.') gives the contents of the current line, so the comparison on the while line would be comparing the content of the current line with the number of the last line and this would fail. The other problem is that you're not actually moving through the file, so the current line would be whichever line you were on when you called the function and would never change, resulting in an infinite loop. I've replaced this with a simple += 1 to step through the file.
There are ways in which the current line would be a useful way to do this, for example if you were writing a function with that took a range of lines, but I think I've written enough for now and the above will hopefully get you going for now. There are plenty of people on stackoverflow to help with any issues anyway!
Have a look at:
:help usr_41.txt
:help function-list
:help user-functions
:help substitute()
along with the :help followed by the various things I used in the function (getline(), line(), let+= etc).
Hope that was helpful.
This approach uses lists:
function! Countchars()
let n = 0
for line in getline(1,line('$'))
let n += len(split(line,'\zs\s*'))
endfor
return n
endfunction
I suppose you have already found the solution.
Just for info:
I use this to count characters without spaces in Vim:
%s/\S/&/gn