Megha becomes the third time winner: June Programming Challenge now is finished
The top three contenders are Kalyani Chilukuri from Clinovo, Jiangtang Hu from Sanofi Pasteur, and Megha Agarwal from Clinovo. Thank you all for excellent work! The winner is Megha: Her code is the closest to beat the benchmark when tested on a version of CDISC Express. Congratulation!
Benchmark code
%let _=%sysfunc(time());
filename _ temp;
data _null_;
infile 'dir/s/b "C:\CDISC Express\*.sas"|findstr/v "sas7 sas~"' pipe end=EOF;input;
if _n_=1 then call execute('proc printto log=_ new;');
call execute('data _null_; infile "'||_infile_||'"; input;');
if EOF then call execute('proc printto log=log;');
data _null_;retain s;
x=prxparse('/(\d+) records were read from the infile/');
infile _ end=EOF;input;
if prxmatch(x,_infile_) then s+input(prxposn(x,1,_infile_),best.);
if EOF then put s=;
run;
%put %sysevalf(%sysfunc(time())-&_);
Nuance The next two solutions:
i) A terser and faster sas approach by deploying more sophisticated shell command:
data _null_; infile 'for /f "tokens=* usebackq" %f in (`dir/s/b "C:\CDISC Express\*.sas"^|findstr /i /v "sas7 sas~"`) do @type "%f"' pipe;input;run;
The total number of lines can be found in the log file.
ii) If you have Cygwin or MinGW minimal system installed on your Windows machine then you can pipe the unix command “wc -l” into sas to get the line counting of each program.
However, either approach encounters a systematic error rooted in the fact that CDISC Express originally is developed on Solaris, a Unix platform. For example, apply the unix command “cat -v” on the macro “attrn.sas” (the “v” switch lets this utility print nonprinting characters) and you will get something like this:
/*******************************************************************************^M
* PROGRAM NAME: attrn.sas^M
* DESCRIPTION: ^M
* - Open a dataset and get one of its attributes^M
*^M
* PROGRAMMER: Ale Gicqueau^M
*******************************************************************************/^M
^M
%macro attrn(ds,attrib);^M
^M
%local dsid rc;^M
^M
%let dsid=%sysfunc(open(&ds,is));^M
%if &dsid EQ 0 %then %do;^M
%put ERROR: (attrn) Dataset &ds not opened due to the following reason:;^M
%put %sysfunc(sysmsg());^M
%end;^M
%else %do;^M
%sysfunc(attrn(&dsid,&attrib))^M
%let rc=%sysfunc(close(&dsid));^M
%end;^M
^M
%mend;
“^M” is carriage return, which is missed in the last line. The above-mentioned two approaches do not count the last line in this and similar case.
Powershell We discussed the issue of “zero installation programming” before (see here and here). If you are using Windows 7 then the following one-liner script is ready to go:
$c=0;foreach ($x in ls -r | where {$_.extension -eq ".sas"} ){
$c=$c+$(get-content $x.FullName|measure).Count
}; $c
File System Iterator by JScript
One way to test your mastery of a programming language is to write a file system iterator. Basically the input is a path of a folder and then the program you write with a particular programming language iterates recursively into this folder. The SAS example can be found here and the VBScript example here
Here I show the iterator in JScript, id est, Microsoft JavaScript. Call the following code “traverse.js”:
function prt(Str){
// Print a string
WScript.Echo(Str);
}
function prtFile(f){
// Print the path of a file
prt(f.Path+", "+f.DateLastModified);
}
function prtFolder(d){
// Print the path of a folder
prt(d.Path+"\\");
}
function Iter(fldrPth,fso,ActionOnFile,ActionOnFolder){
if (fso.FolderExists(fldrPth)){
var fldr=fso.GetFolder(fldrPth);
var fl=new Enumerator(fldr.Files);
for (fl.moveFirst();!fl.atEnd();fl.moveNext()){
ActionOnFile(fl.item());
}
var d=new Enumerator(fldr.SubFolders);
for (d.moveFirst();!d.atEnd();d.moveNext()){
ActionOnFolder(d.item());
Iter(d.item().Path,fso,ActionOnFile,ActionOnFolder);
}
}
}
objFSO=new ActiveXObject("Scripting.FileSystemObject");
Iter(WScript.Arguments(0),objFSO,prtFile,prtFolder);
To test, run a CMD shell in windows and type something like
traverse "C:\Windows"
The program lists all the subfolders and files together with the file’s last modified time recursively.
Categories
- Best Practices (3)
- Best-Practices (16)
- BioNews (3)
- Business Best Practices (5)
- Case studies (2)
- CDISC (11)
- Clinical Data Management (6)
- Clinical Stories (1)
- Code (13)
- EDC (7)
- Event (3)
- Events (7)
- Menu (3)
- Monthly Contest (12)
- New Technologies (15)
- OpenClinica (2)
- SAS Library (4)
- Scripting (2)
- Tips & Techniques (14)
- Trends (11)




Posted under: 