Tagged with " Script"

Megha becomes the third time winner: June Programming Challenge now is finished

Jul 8, 2011 by     2 Comments    Posted under: Code, Monthly Contest, New Technologies, Scripting, Tips & Techniques

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

Nov 19, 2010 by     No Comments    Posted under: New Technologies, Scripting, Tips & Techniques

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.

Auto-update using Windows Powershell

Sep 21, 2010 by     5 Comments    Posted under: Tips & Techniques

Ask yourself this question: without any new installation, what type of programming can you do on a Windows machine (you can do a lot with a Unix/Linux machine or a Mac for sure)? The answer can be found in the first reference. However, the point I want to make in this post is, since the commencement of Windows 7, Powershell is the one!

Here is an example: The following script updates files from a source folder to a target folder by examing the last-modified time of the corresponding files. Also if a new file is added in the source folder, the script copies this file to the target folder. In case the file in source folder is older than the one in the target folder, an error message is fired.

Read more »

Last-modified time comparison

Sep 17, 2010 by     No Comments    Posted under: Tips & Techniques

The following script written in VBS is to compare the last-modified dates of pairs of files with the same name in two different folders. Two types of output are available:

  1. If the file in the first folder is not found in the second …
  2. If the last modified dates are different …

To use the code, substitute “[path1]” and “[path2]” with your own, as well as modifiy the filename matching condition to fit your need.


With CreateObject("Scripting.FileSystemObject") ' Generic part
For Each f In .GetFolder("[path1]").Files ' Get the first folder
' The following filtration condition is flawed in the sense that it is case-sensitive Read more »
Check out the BioNews, a very handy daily recap of the latest industry news!