home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / perl / 5854 < prev    next >
Encoding:
Internet Message Format  |  1992-09-11  |  15.1 KB

  1. Path: sparky!uunet!cs.utexas.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!bu.edu!transfer!ceylon!NewsWatcher!user
  2. From: hhg1@gte.com (Hal German)
  3. Newsgroups: comp.lang.perl
  4. Subject: SAS compared to Perl
  5. Message-ID: <hhg1-110992064042@132.197.14.85>
  6. Date: 11 Sep 92 11:40:35 GMT
  7. Sender: news@ceylon.gte.com
  8. Followup-To: comp.lang.perl
  9. Organization: GTE Labs
  10. Lines: 511
  11.  
  12.  
  13. This is the text version of a paper presented at the Boston Area SAS User's
  14. Group recently. It will also be in the proceedings of the Northeast SAS
  15. Users Group. Enjoy !
  16.  
  17. Report Writing on a Budget: Using Perl
  18.  
  19.  
  20. Hallett  German
  21.  
  22. GTE Laboratories, Inc.
  23.  
  24.  
  25. Introduction
  26. At last year's NESUG, Marge Scerbo presented an
  27. interesting paper showing how a few simple SAS(
  28. datasteps statement could be used to generate
  29. powerful and customizable reports.
  30.  
  31. As I read through the paper, I wondered "Gee, I
  32. could do most of this in Perl. Or can I?" This paper
  33. is a response to that thought.  The following is 
  34. an outline of the paper:
  35.  
  36. 1. What is Perl?
  37. 2. How can I learn more about Perl?
  38. 3. Perl Concepts
  39. 4. Basic Reports -- SAS vs. Perl
  40.         * Input Forms
  41.         * Reports
  42. 5. Conclusions
  43. 6. References
  44.  
  45. After reading the paper, you should have a good 
  46. overview of Perl's reporting capabilities and 
  47. hopefully be encouraged to create your own reports 
  48. with this command language.
  49.  
  50.  What is Perl?
  51. Perl was developed by Larry Wall starting in 1986. It
  52. officially stands for Practical Extraction and Report
  53. Language. [But there are those who say that like 
  54. SAS it is a group of letters with no meaning in itself.
  55. You be the judge.]
  56.  
  57. Perl is a powerful command language that has 
  58. elements of C, UNIX shells, awk, sed, and much
  59. more. The result is a self-contained portable 
  60. language. Perl is now almost a de facto standard with
  61. UNIX system administrators. [It also is used internally
  62. at the SAS Institute.]
  63.  
  64. Perl's appeal is also because it is distributed with 
  65. source and available free as part of GNU public
  66. software.It can be obtained via e-mail or from various 
  67. anonymous ftp sites. Per l can now be found under 
  68. AmigaOS,Atari OS, DOS [it runs fine under MS-
  69. Windows], Macintosh, UNIX, and VMS.
  70.  
  71. Perl contains many different elements:
  72. -- Over 100 built-in functions
  73. -- A  rich built-in library
  74. -- networking capabilities
  75. -- database capabilities
  76. -- C interfaces
  77. -- debugger
  78. -- report capabilities
  79. -- converters (awk, sed, C header libraries to Perl)
  80.  
  81. Many utilities and interfaces have been built with 
  82. Perl. These include interfaces to Oracle, Sybase,
  83. Curse, and X Windows.
  84.  
  85. How can I learn more about Perl?
  86.  
  87. Here are some places to look:
  88.  
  89. * A free man (help) document has over 100 pages on 
  90. Perl. A formatted copy can be obtained from the 
  91. anonymous ftp site chem.bu.edu.
  92.  
  93. * Various conferences give tutorials on Perl. These
  94. include USENIX, SUG (SUN), and DECUS (DEC).
  95.  
  96. * The Usenet group comp.lang.perl is a treasure 
  97. trove of Perl tips. Perl's creator Larry Wall is actively
  98. posting useful messages there.
  99.  
  100. * Once a month, a FAQ (frequently asked questions)
  101. list is posted on comp.lang.perl
  102.  
  103. * The Wall and Schwartz book (see references) is
  104. considered the source on Perl. An advanced Perl
  105. book is planned.
  106.  
  107. * The German book covers Perl portability and has 
  108. a healthy number of Perl references.
  109.  
  110. Perl Concepts
  111.  
  112. Before looking at our first Perl report, it is helpful to 
  113. understand the following:
  114.  
  115. * Perl statements usually are in lowercase except for 
  116. filenames, and subroutines.
  117.  
  118. * Perl statements must end with a semicolon. 
  119. [Making SAS users feel right at home.]
  120.  
  121. * A series of statements may be processed as a 
  122. block. A block is contained within braces. (i.e. {})
  123. *
  124.  Comments begin with a #.
  125.  
  126. * Perl supports a number of data types each with its 
  127. own unique identifier:
  128.  
  129. - $ -- Scalar variables may contain numbers 
  130. (including decimals, characters, or Boolean (1,0). 
  131. Scalars also may hold the elements of simple and 
  132. associative arrays.
  133.  
  134. examples    $a = 1; #Assigned a number
  135.                          $a  = "dog" #Assigned string
  136.  
  137. - @ --  Simple arrays. Can contain elements with 
  138. numbers or characters. Each element is designated
  139. by a  numeric key  marking the position in the array.
  140.  
  141. examples    @array1 #entire array
  142.                           $array1[0] #First element in array
  143.                           $array1[$#array1] #Last element in 
  144.         #array.
  145.  
  146. - % -- Associative arrays. Can contain elements 
  147. with numbers or characters. Each element  is 
  148. designated by a numeric OR character key marking 
  149. the position in the array. Associative arrays are 
  150. beyond the scope of this paper.
  151.  
  152. * The following are some of the functions that are
  153. used in these examples:
  154.  
  155. - CLOSE. Closes an open file.
  156.  
  157. - DIE. If a condition is met then die (end program) with
  158. an optional message. A WARN function is also 
  159. available. 
  160.  
  161. - OPEN. A powerful command. May open a file
  162. for reading (default), writing, or both!  An alias for the 
  163. file is assigned by the user. (Like SAS's libref or 
  164. fileref component in a LIBNAME or FILENAME 
  165. statement.)  Also may be used like SAS's LIBNAME 
  166. PIPE/FILENAME PIPE statements to pipe output 
  167. from a n operating system command to or from a file.
  168.  
  169. Basic Reports -- SAS vs Perl: Input Forms
  170.  
  171. [Do note that all examples shown are "standard Perl" 
  172. and should be portable across operating systems. I 
  173. created these examples on MS-DOS or a Macintosh 
  174. and ran them of UNIX "as is!"]
  175.  
  176. Data may be inputted two different ways. Interactively
  177. and non-interactively:
  178.  
  179. Interactively:
  180. The following is a simple program that takes user 
  181. input and writes it to a file.  The chop function 
  182. removes the newline. 
  183.  
  184.     open(FILE1,">>input.txt");
  185.     $cnt = 1;
  186. un:
  187.       print "Enter the NAME of the University\n";
  188.       $univ=substr(<STDIN>,0,21);
  189.       chop($univ);
  190. cy:
  191.      print "Enter the CITY of the University\n";
  192.      $city=substr(<STDIN>,0,16);
  193.     chop($city);
  194. printit:
  195.      print FILE1 "$univ $city \n";
  196.  print "Do you wish to enter another record? Y/N\n";
  197.      $choice=substr(<STDIN>,0,1);
  198.      if ($choice eq "Y") {$cnt++; goto un;}
  199.      else  {die "$cnt records added\n";}
  200.   
  201.  
  202. This approach is ideal for small databases. A rich 
  203. range of data checking is possible. 
  204.  
  205. Non-interactively:
  206.  
  207. For smaller files, you can pre-build an array that 
  208. contains values:
  209.  
  210. @array1= ("Brown University  Providence",
  211.           "Cornell  Ithaca");
  212.  
  213. For larger files, it is recommended to use 
  214. compressed files or  dbm files.:
  215.  
  216. Compressed  (Binary) Files:  Files with variable-
  217. length records are compressed and uncompressed 
  218. using the pack/unpack functions. This is shown a 
  219. little later in the paper. They can also be set up as 
  220. random-access files
  221.  
  222. DBM files. DBM stands for  Data Base Management. 
  223. DBM is available in some format for all Perl 
  224. interpreters except the Amiga and the Macintosh. 
  225. This is done using associative arrays and is beyond 
  226. the scope of this paper.
  227.  
  228. Basic Reports -- SAS vs Perl: Input Forms
  229.  
  230. Report #1 -- A Simple List
  231.  
  232. The following report should be produced:
  233.  
  234. BROWN UNIVERSITY
  235. PROVIDENCE
  236. CORNELL
  237. ITHACA
  238. UNIV OF MARYLAND
  239. BALTIMORE
  240. UCLA
  241. LOS ANGELES
  242. COLUMBIA
  243. NYC
  244. SYRACUSE UNIV.
  245. SYRACUSE
  246.  
  247. To do this, the program will also: 1) split the "fields"
  248. of the "record" to appear on two lines and 2) convert
  249. the values of these fields to uppercase regardless
  250. whatever was the original case of the value.
  251.  
  252. Here is the program that creates both the input 
  253. record and the report:
  254.  
  255. #Example 1 -- Standard Approach.
  256. #
  257. #########################
  258. # a. Create an array                          #
  259. #########################
  260. $fileo = "ex1.txt";       #Set value for file
  261. @array1= ("Brown University  Providence",
  262.           "Cornell  Ithaca",
  263.           "Univ of Maryland  Baltimore",
  264.           "UCLA  Los Angeles",
  265.           "Columbia  NYC",
  266.           "Syracuse Univ.  Syracuse");
  267. ########################
  268. # b. Open a file for writing             #
  269. ########################
  270. open(EX1,">$fileo");
  271.   foreach $cnt (0 .. $#array1) {
  272. ############################
  273. # c. Split the "record" into two fields   #
  274. ############################
  275.         ($univ,$loc) = split('  ',$array1[$cnt]);
  276. #############################
  277. # d. Translate record to uppercase        #
  278. #############################
  279.         ($university = $univ) =~ tr/a-z/A-Z/; 
  280.         ($location   = $loc)  =~ tr/a-z/A-Z/; 
  281. ############################
  282. # d. Write out record and close file      #
  283. ############################
  284.         print EX1 "$university\n$location\n";
  285.  }
  286. close(EX1);
  287.  
  288.  
  289. Note that a scalar variable contains the value of the
  290. file name. This allows you to easily change a file 
  291. name IN ONE PLACE ONLY when needed.
  292.  
  293. Report #2 -- A Formatted List
  294.  
  295.   
  296. Formatted list like the one below can also be created 
  297. with Perl.
  298.  
  299. BROWN UNIVERSITY          PROVIDENCE 
  300. CORNELL              ITHACA 
  301. UNIV OF MARYLAND    BALTIMORE 
  302.  UCLA     LOS ANGELES
  303. COLUMBIA                                               NYC 
  304. SYRACUSE UNIV    .        SYRACUSE 
  305.                                     
  306.  
  307. Note that it would be easy to add the UNIV text as in
  308. Marge's example.
  309.  
  310. The following part creates the binary file:
  311.  
  312. #Example 2 -- Fixed Records (Use Pack/Unpack) 
  313. Input Part
  314. ####################################
  315. #a. Create an array                #
  316. ####################################
  317.  @univs = ( "Brown University",  "Providence",
  318.              "Cornell",          "Ithaca",
  319.              "Univ of Maryland", "Baltimore",
  320.              "UCLA",             "Los Angeles",
  321.              "Columbia",         "NYC",
  322.              "Syracuse Univ.",   "Syracuse");
  323. ####################################
  324. #b. Open a file for writing        #
  325. ####################################
  326. open (EX2,">ex2.txt")
  327.   || die "Can't open ex2.txt $!\n"; #exception handling
  328. ####################################
  329. #c. Go through array               #
  330. ####################################
  331.   foreach $i (0 .. $#univs) {
  332. ####################################
  333. #d. If university,                 #
  334. #   then assign to $university.    #
  335. ####################################
  336.         if (($i == 0)  || (length($i/2)==1)){   #first record
  337.              $university = $univs[$i];
  338.        }
  339. ####################################
  340. #e. If location,                   #
  341. #   then assign to $location       #
  342. #   write out "packed" record      #
  343. #   close file                     #
  344. ####################################
  345.        if (length($i/2)==3) {  #location
  346.            $location = $univs[$i];
  347.            $line = pack("A20 A15",$university,$location);
  348.           print EX2 $line;
  349.      }
  350.  }
  351.      close(EX2);
  352.  
  353.  
  354. This example is used to retrieve and unpack the 
  355. records from the file and create the report:
  356.  
  357. # Example 2 -- Fixed Records (Use Pack/UnPack) 
  358. Report Part
  359. ##################### 
  360. # a. open file and                      #
  361. #    retrieve packed line          #
  362. #####################
  363. file_part:
  364.           open (EXP2,"ex2.txt")
  365.                || die "Can't open ex2.txt $!\n";
  366.           while (<EXP2>) {
  367.                chop;
  368.                $line = $_;
  369.           }
  370.         close(EXP2);
  371. ###########################
  372. # b. Loop through line:                          #
  373. #    Unpack line                                            #
  374. #    Strip leading characters                 #
  375. #    Rejoin line                                             #
  376. #    Set line to uppercase                    #
  377. #    Print line                                               #
  378. ##########################
  379. rpt_part:
  380.         $len    = length($line);
  381.         
  382. for($offset=0;($offset<$len);$offset=$offset+34) {
  383.               $lin = substr($line,$offset);
  384.              ($univ,$loc) = unpack("A20 A15",$lin);
  385.               @univ=split(' ',$univ); #Trim leading blanks
  386.               @loc=split(' ',$loc);
  387.               $unn = join(' ',$univ[0],$univ[1],$univ[2]);
  388.               ($univ= $unn) =~ tr/a-z/A-Z/;  #Change to 
  389. uppercase
  390.               $lon = join(' ',$loc[0],$loc[1]);
  391.               ($loc= $lon) =~ tr/a-z/A-Z/;
  392.             printf "%20s %15s\n",$univ,$loc; #formatted 
  393. print
  394.          }
  395.  
  396. Example #3 Creating a  formatted report using Perl.
  397.  
  398. Perl has a powerful report facilit that can do pretty 
  399. much anything SAS can with PUT statements. Here 
  400. is a simple example:
  401.  
  402.                           University List                                  
  403. University    State     Zip
  404. BROWN UNIVERSITY               RI    
  405. UNIV. OF MARYLAND                          MD        21201
  406. UCLA              CA    
  407. COLUMBIA    NY       10005
  408. SYRACUSE UNIV                                  NY    13112
  409.  
  410.  
  411. This is the data as stored in the input file: [Note the * 
  412. as a field delimiter]
  413.  
  414. Brown University*ri*
  415. Univ. of Maryland*md*21201
  416. UCLA*CA*
  417. Columbia*ny*10005
  418. Syracuse Univ*ny*13112
  419.  
  420. This is the Perl script that generated it: [Note that you 
  421. first create a template and then use it.]
  422.  
  423. #Example 3 -- Using Formatted Reports
  424. #Create a header format. Period = end of format. 
  425. format  HEAD1=
  426.                        University List
  427.  
  428. University                  State             Zip
  429.  
  430. .
  431. #Define report format. Accent = blank line
  432. format EX3B=
  433. ~
  434. #<<< -- Place holder and left justification
  435. @<<<<<<<<<<<<<<<<<<<       @<<               @<<<<<
  436. #Variables in report
  437. $un,                       $st,              $zip
  438.  
  439. .
  440. open(EX3A,"ex3a.txt") || (die "cant open ex3a.txt 
  441. $!\n");
  442. open(EX3B, ">ex3b.txt") || (die "cant open ex3b.txt 
  443. $!\n");
  444. # System Variables  $^ -- header format name 
  445. # $~ -- report format name
  446. select (EX3B); $^ = "HEAD1"; $~ = "EX3B";
  447. while (<EX3A>) {
  448. chop;
  449. ($unn,$stt,$zipp) = split(/\*/,$_); #Parse fields
  450. ($un= $unn) =~ tr/a-z/A-Z/;         #Set to Uppercase
  451. ($st= $stt) =~ tr/a-z/A-Z/;
  452. ($zip= $zipp) =~ tr/a-z/A-Z/;
  453. write(EX3B);                        #Write out report
  454. }
  455. close(EX3A);
  456. close(EX3B);
  457.  
  458. Here is a list of report variables:
  459.  
  460. $|    0 (default) writes out
  461. buffer every x lines.
  462. >0 Writes out buffer
  463. after a write or print.
  464. $%    Current Page number
  465. $=    Current page length.
  466. Default=60.
  467. $-    Number of lines left on a
  468. page available for
  469. writing.
  470. $~    Current report format
  471. $^    Current header format
  472.  
  473. Many other capabilities are possible such as sorting
  474. records, changing lines per page, and generating
  475. footers. Unfortunately, it would take far more pages 
  476. than I have to cover that material.
  477.  
  478. Conclusions
  479. This can only be the briefest of introduction to Perl's
  480. reporting capabilities. It offers a strong (and free) 
  481. alternative for SAS in doing simple reports. The 
  482. reader is encouraged to try the examples and read 
  483. the suggested references.  Posters in future years 
  484. may discuss  some of Perl's advanced reporting 
  485. capabilities and how to create interactive Perl 
  486. applications.
  487.  
  488. Getting in touch with me/Trademarks
  489.  
  490. Hallett German
  491. GTE Laboratories Inc
  492. 40 Sylvan Road
  493. Waltham, Ma 02254
  494. 617-466-2290
  495. hhg1@bunny.gte.com
  496.  
  497. SAS (  and all other SAS products mentioned are a 
  498. registered trademark of the SAS Institute
  499.  
  500. References [Annotated]
  501. Bates, Douglas "Data Manipulation in Perl" 
  502. Unpublished Paper pp1-6.
  503. [Strongly recommended. Has a good section on 
  504. how to use Perl to clean up datafiles. Some of this
  505. capability was added into the 6.07 release.]
  506.  
  507. German, Hallett  Command Language Cookbook
  508. 1992 Van Nostrand Reinhold pp. 247-305
  509. [Has plenty of Perl references and a good discussion
  510. on Perl portability.]
  511.  
  512. Scerbo, Marge "Data Step Reporting" NESUG 91
  513. Proceedings  1991 pp.  60-66
  514. [If you want to see how to generate the same 
  515. examples using SAS, look at Marge's paper.]
  516.  
  517. Wall, Larry  and Randall L. Schwartz Programming 
  518. Perl 1991 O'Reilly & Associates. pp 1-42, 106-118
  519. [The Perl "bible". Also called the Camel book 
  520. because what is on the cover. A reference, tutorial, 
  521. and code ideas book all in one place. Strongly 
  522. recommended.]
  523.