getting command line arguments in Scheme using `command-line` function - command-line

This question has definitely been asked before, here. Some of the solutions presented did work(in Windows) except for the command-line function mentioned in Command-line access and exit values in r6rs-lib.
I managed to achieve what I wanted in Gauche(non r6rs compliant implementation) using *argv*:
(display *argv*)
> gosh test.ss first 1 2 3 4 5 6 7 8 9 10 11 12 13
>> (first 1 2 3 4 5 6 7 8 9 10 11 12 13)
I want to do the same with Petite Chez Scheme which is r6rs compliant using the command-line function. I've tried to use the code in that chapter but all I get is a list with the script's name and only the first argument. e.g
#!r6rs
(import (rnrs programs (6)))
(display (command-line))
> petite --script test.ss first second
>> (test.ss first)
Is there some other library import I'm missing that would make it work?

The following 'script' works for me in 'Ikarus Scheme':
#!/usr/bin/env scheme-script
(import (rnrs))
(display (command-line))
(newline)
ebg#ebg$ ./ik.scm a b c
(./ik.scm a b c)
ebg#ebg$ ikarus --r6rs-script ./ik.scm a b c
(./ik.scm a b c)
and for Petite
ebg#ebg$ petite --script ~/ik.scm a b c
(/Users/ebg/ik.scm a b c)
Note that officially (import (rnrs programs (6))) won't import display so as written your code should fail.

Related

SPSS Merging Data with duplicate Keys

I am currently attempting to join 2 datasets using SPSS syntax but am struggling as I have duplicate values on the keys. I would like for the joined data to be duplicated for each instance of the key on the source dataset (or other way round as it doesn't matter which is the source).
The datasets are like the following -
Data1 (3rd column placeholder)
batch
run
date
A
1
1
A
2
1
A
3
1
B
1
1
C
1
1
C
2
1
D
1
1
E
1
1
Data2
batch
Value1
Value2
A
1
21
A
2
22
A
3
23
A
4
24
B
5
25
B
6
26
B
7
27
B
8
28
C
9
29
C
10
30
C
11
31
C
12
32
D
13
33
D
14
34
D
15
35
D
16
36
E
17
37
E
18
38
E
19
39
E
20
40
Current attempt
What I have just now is a method where I CASETOVARS on Data1 before matching it onto Data2 and then VARSTOCASES to expand it out. This works perfectly with my test data but, unfortunately, it requires that I know exactly how many 'runs' there will be. That will not be known in production. It could be 1 or more.
Is there a method to join these datasets while expanding the joined data into the multliple cases in the source?
I am open to using macros but am not able to utilise Python solutions for this (which would probably be easier!).
edit - Unfortunately, extensions are also not possible for me to use.
CASESTOVARS
/ID = batch .
DATASET ACTIVATE data2 .
MATCH FILES
/FILE = *
/TABLE = data1
/BY batch .
EXECUTE .
VARSTOCASES
/MAKE run FROM BATCH_RUN_ID.1 TO BATCH_RUN_ID.3 .
EXECUTE .
If Python and dependent extention command are not availabe, here's an idea how to solve the dynamic list length for the varstocases phase.
What you'll do is basically to create a new dataset with the maximum number of runs possible, attach your read dataset to it, and then set the varstocases to go for that maximum number of runs (blank rows are dropped automatically):
dataset name orig.
data list free/throwthisrow (f1) BATCH_RUN_ID.1 to BATCH_RUN_ID.50 (50F8.2) .
begin data
1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
end data.
add files /file=* /file=orig .
EXECUTE.
select if missing(throwthisrow).
VARSTOCASES
/MAKE run FROM BATCH_RUN_ID.1 TO BATCH_RUN_ID.50 /drop throwthisrow.
EXECUTE .
To complete your present approach you can use spssinc select variables extention command (see examples of use here and here and here). You will use it to automatically create a list of the variables you want to name in your varstocases command, so that the syntax will automatically adapt itself to the number of runs in the data:
So after varstocases and match files:
spssinc select variables macroname="!from" /properties pattern = "BATCH_RUN_ID".
VARSTOCASES /MAKE run FROM !from .

Binary application on scan in KDB?

I'm trying to understand this:
100+\ 1 2 3
101 103 106
Which works fine.
Question 1:
When I wrap this in brackets, I get an error I wasn't expecting:
(100+\) 1 2 3
'Cannot write to handle 100. OS reports: Bad file descriptor
What am I doing wrong here? It doesn't look like I'm writing a file to me.
Question 2:
Given the +[1;2] = 3, I believe this:
+[100;]\ 1 2 3
'
[0] +[100;]\ 1 2 3
(or perhaps +[;100]\ 1 2 3) should also work with projection, but it doesn't. What am I doing wrong here?
Question 1:
Use parse to determine order of execution
q)show pt:parse "(100+\\)1 2 3"; // need to escape \
((\;+);100)
1 2 3
q)eval each pt // should be clearer now
100
1 2 3
q)
q)value eval each pt // attempting to apply 100 to list which cannot be done
'Cannot write to handle 100. OS reports: Bad file descriptor
[0] value eval each pt
^
Question 2:
The projection is unary & is applied to the entire right argument. With unary application, evaluations will (attempt to) continue until convergence - https://code.kx.com/q/ref/accumulators/#unary-values
q)(neg\)1 2 3
1 2 3
-1 -2 -3
q)+[100]\[1 2 3]
'wsfull
m 0 68157440
Question 1
When an iterator (here \) is applied postfix (as is usual) to a function (here +) it derives a function (here +\) that is both variadic (as per #mturkington) and has infix syntax. You can apply it as a unary or as a binary. Your example 100+\1 2 3 applies it as a binary.
The parser needs a clue if you want to apply +\ as a unary. You can apply any function using bracket notation. Or you can parenthesise it: (+\) has noun syntax, as does the list (+;-;*;%). You can apply or index a noun with prefix syntax.
q)100+\1 2 3 / binary application, infix syntax
101 103 106
q)+\[100;1 2 3] / binary application, bracket syntax
101 103 106
q)+\[1 2 3] / unary application, bracket syntax
1 3 6
q)(+\)1 2 3 / unary application, prefix syntax
1 3 6
Question 2
You don’t say what result you expect from using the projection. I’ll assume you’re exploring a different way of getting the same result as in Q1.
The key issue here is that the projection of binary Add on 100 is a unary +[;100] (or +[100] or just 100+), and the accumulators \ and / applied to a unary are the Converge, Do and While iterators.
None of these gives you the Q1 result. For unary f, the derived function f\ just keeps applying f successively.
q)5 +[100]\ 1 2 3 / do 100+ five times
1 2 3
101 102 103
201 202 203
301 302 303
401 402 403
501 502 503
In this case, +\ is the underlying code for the sums keyword. This is one of several keywords that are known as variadic because their rank is not fixed. When you try (100+\) 1 2 3, kdb is actually applying the equivalent of sums to your input list, then trying to write that to handle 100, which of course doesn't exist. So that's why you get the error you get.
As for the syntax in Question 2, the following should work (adapted from this page on the variadic syntax)
q)+\[100;1 2 3]
101 103 106

Unicode characters in Julia: star symbol

I am trying to simplify the notation in a couple of functions using some unicode characters. In one of this function I have tried to use the star symbol (\star) but I've got several errors and warnings.
Please have a look at the following working example:
a = [1 2 3; 4 5 6; 7 8 9]
- Gives: a 3×3 Array{Int64,2}
a⋆ = [1 2 3; 4 5 6; 7 8 9]
- Gives: ERROR: syntax: unexpected "="
Why the star symbol is not working when it is used as above? Does it have a designed functionality in Julia?
The ⋆ symbol parses as an infix operator:
julia> dump(parse("a⋆b"))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol ⋆
2: Symbol a
3: Symbol b
typ: Any
A case could be made for allowing ⋆ as a character in identifier names, but that would be a breaking change and so far we have generally parsed characters that are generally considered to be operator-like in the Unicode standard as operators with the appropriate precedence.

copying every nth line and duplicating it on it's following line

I am trying to make test files for the project, and I figured in order to make a bradycardia test file from an example file of a normal ECG.
Therefore I would need to copy every third line and insert it into the next line.
for example:
a = [
1
2
3
4
5
6
7
8
9
10]
and I want:
b = [
1
2
3
3
4
5
6
6
7
8
9
9
10]
and so on... but since the file is 6000 characters long, obviously i cannot manually copy it. And I need it to be 9000 characters long I've tried looking online on how to do this, and am having no luck.
Any suggestions?
b=zeros(floor(4/3*length(a)),1);
b(1:4:end)=a(1:3:end);
b(2:4:end)=a(2:3:end);
b(3:4:end)=a(3:3:end);
b(4:4:end)=a(3:3:end);
Another way:
b = a(sort([1:numel(a) 3:3:numel(a)]))
And here is a third faster and simpler method
b = a(round(1:0.75:numel(a)))
This only works if length(a) is a multiple of 3, but seems to be faster than the other answers, at least for large vectors:
b = reshape([reshape(a,3,[]); a(3:3:end).'],[],1);

How to extract certain columns from a big Notepad text file?

I have a big text file and the data in it are in 5 columns, but I need just the first and the last column of that.
It will take many days and probably with mistake if I want to enter the data of this two column one-by-one from here to another file.
Is there a fast way to do this?
For example:
1 1.0000000000000000 0.0000000000 S {0}
2 1.5000000000000000 0.3010299957 C {2}
3 1.7500000000000000 0.6020599913 S {0,2}
4 2.0000000000000000 0.7781512504 C {3}
5 2.3333333333333333 1.0791812460 C {3,2}
6 2.5000000000000000 1.3802112417 S {3,0,2}
7 2.5277777777777778 1.5563025008 S {0,3}
8 2.5833333333333333 1.6812412374 S {3,0,0,2}
9 2.8000000000000000 1.7781512504 C {5,2}
10 3.0000000000000000 2.0791812460 C {5,0,2}
I need the first column (numbering) and the last inside { }.
ALT + Left Mouse Click puts you in Column Mode Select. It's quite an useful shortcut that may help you.
in Notepad++, you can use regular expression to do replacement:
the regex for find and replace is:
^( +\d+).+\{([\d,]+)\}$
\1 \2
then can change the:
1 1.0000000000000000 0.0000000000 S {0}
2 1.5000000000000000 0.3010299957 C {2}
3 1.7500000000000000 0.6020599913 S {0,2}
4 2.0000000000000000 0.7781512504 C {3}
5 2.3333333333333333 1.0791812460 C {3,2}
6 2.5000000000000000 1.3802112417 S {3,0,2}
7 2.5277777777777778 1.5563025008 S {0,3}
8 2.5833333333333333 1.6812412374 S {3,0,0,2}
9 2.8000000000000000 1.7781512504 C {5,2}
10 3.0000000000000000 2.0791812460 C {5,0,2}
to:
1 0
2 2
3 0,2
4 3
5 3,2
6 3,0,2
7 0,3
8 3,0,0,2
9 5,2
10 5,0,2
if not want the leading space, then use:
^( +\d+).+\{([\d,]+)\}$
\1 \2
will change to:
1 0
2 2
3 0,2
4 3
5 3,2
6 3,0,2
7 0,3
8 3,0,0,2
9 5,2
10 5,0,2
You should use awk or gawk which is available on windows platform also. Use gawk "{print $1,$5}" inpfile > outfile. I copied your file named it 'one'. You can see the output which consists of 1st and 5th column of your file.
>gawk "{print $1, $5}" one
1 {0}
2 {2}
3 {0,2}
4 {3}
5 {3,2}
6 {3,0,2}
7 {0,3}
8 {3,0,0,2}
9 {5,2}
10 {5,0,2}
You can import it into Excel and manipulate it there.
If you are using .NET, FileHelpers may save you a lot of time. From your post we can't tell what technology you are hoping to use to accomplish this.
Ultraedit has a tool for selecting columns and opens large files (I tried a 900 Mb file on a 2008 desktop and it opened in 3 minutes). I think it has a demo version fully operational.
Excel could work if you do not have too many rows.
Cheers,
One more way is to copy the data to MS word file.
Then use
{Alt + left mouse click}
Then you can drag on the selected column and you can see only a single column is selected.
Copy and paste wherever you want.
There is only one way to convolve ungodly amounts of data. That is with the command prompt.
$cat text.txt | sed 's/{.*,//;s/ */ /g;s/[{}]//g' | awk '{print $1","$5}' > clean_text.csv
This 15 second fix is not available in Windows OS. It will take you less time to download and install Linux on that old dead computer in your closet than it will to get your data in and out of Excel.
Happy coding!