330 likes | 338 Views
Learn how to manipulate and generate reports entirely within Perl using the DataPresenter package. This tutorial covers importing, sorting, formatting, and outputting data from a database.
E N D
DataPresenter Manipulating Database Reports Entirely Within Perl James E Keenan
A Hospital Census • CLIENTS - JULY 26, 2001 - C O N F I D E N T I A L PAGE 1 • SHRED WHEN NEW LIST IS RECEIVED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! • NAME C. NO UNIT WARD ADMIT BIRTH • HERNANDEZ HECTOR 456791 SAMSON 0217 2001-07-25 1963-08-01 • JONES TIMOTHY 803092 LAVER 0103 2001-03-19 1969-06-29 • SMITH HAROLD 359962 TRE 0111 2001-07-19 1973-10-02 • SMITH BETTY SUE 698389 SAMSON 0211 1992-01-23 1949-08-12 • VASQUEZ ADALBERTO 786792 LAVER 0104 2001-07-26 1973-08-17 • VASQUEZ ALBERTO 906786 TRE 0111 2001-07-15 1953-02-28 • VASQUEZ JORGE 456787 LAVER 0105 1986-01-17 1956-01-13 • VASQUEZ JOAQUIN 456789 SAMSON 0209 1990-11-14 1970-03-25 • VASQUEZ LEONARDO 456788 LAVER 0107 1990-08-23 1970-15-23 • VAZQUEZ TOMASINA 456790 LAVER 0110 1980-11-14 1960-14-02 • WILSON SYLVESTER 498703 LAVER 0110 1983-04-02 1953-06-22 Perl Seminar New York
Structure of a DataPresenter Object (1) • my %data = ( • 456791 => [ 'HERNANDEZ', • 'HECTOR', • '456791', • 'SAMSON', • '0217', • '2001-07-25', • '1963-08-01' ], • 803092 => [ 'JONES', • 'TIMOTHY', • '803092', • 'LAVER', • '0103', • '2001-03-19', • '1969-06-29' ], • ... • ); Perl Seminar New York
A Hospital Census • CLIENTS - JULY 26, 2001 - C O N F I D E N T I A L PAGE 1 • SHRED WHEN NEW LIST IS RECEIVED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! • NAME C. NO UNIT WARD ADMIT BIRTH • HERNANDEZ HECTOR 456791 SAMSON 0217 2001-07-25 1963-08-01 • JONES TIMOTHY 803092 LAVER 0103 2001-03-19 1969-06-29 • SMITH HAROLD 359962 TRE 0111 2001-07-19 1973-10-02 • SMITH BETTY SUE 698389 SAMSON 0211 1992-01-23 1949-08-12 • VASQUEZ ADALBERTO 786792 LAVER 0104 2001-07-26 1973-08-17 • VASQUEZ ALBERTO 906786 TRE 0111 2001-07-15 1953-02-28 • VASQUEZ JORGE 456787 LAVER 0105 1986-01-17 1956-01-13 • VASQUEZ JOAQUIN 456789 SAMSON 0209 1990-11-14 1970-03-25 • VASQUEZ LEONARDO 456788 LAVER 0107 1990-08-23 1970-15-23 • VAZQUEZ TOMASINA 456790 LAVER 0110 1980-11-14 1960-14-02 • WILSON SYLVESTER 498703 LAVER 0110 1983-04-02 1953-06-22 Perl Seminar New York
Create 1stDataPresenter Object • # Create an object that stores the hospital census keyed by C no • my ($sourcefile, $outputfile); • my @columns_selected = (); • my $sorted_data = ''; • $sourcefile = 'census.txt'; • my $dp1 = DataPresenter->new($sourcefile); • # Select fields for output and • # change the order in which they are sorted • @columns_selected = • ('dateadmission', 'lastname', 'firstname', 'cno', 'datebirth'); • $sorted_data = $dp1->sort_by_column(\@columns_selected); • $outputfile = 'format01.txt'; • $dp1->writeformat($sorted_data, \@columns_selected, $outputfile); • $outputfile = 'census.html'; • $dp1->writeHTML($sorted_data, \@columns_selected, $outputfile); Perl Seminar New York
Output via Perl Format • 1980-11-14 VAZQUEZ TOMASINA 456790 1960-14-02 • 1983-04-02 WILSON SYLVESTER 498703 1953-06-22 • 1986-01-17 VASQUEZ JORGE 456787 1956-01-13 • 1990-08-23 VASQUEZ LEONARDO 456788 1970-15-23 • 1990-11-14 VASQUEZ JOAQUIN 456789 1970-03-25 • 1992-01-23 SMITH BETTY SUE 698389 1949-08-12 • 2001-03-19 JONES TIMOTHY 803092 1969-06-29 • 2001-07-15 VASQUEZ ALBERTO 906786 1953-02-28 • 2001-07-19 SMITH HAROLD 359962 1973-10-02 • 2001-07-25 HERNANDEZ HECTOR 456791 1963-08-01 • 2001-07-26 VASQUEZ ADALBERTO 786792 1973-08-17 Perl Seminar New York
Structure of DataPresenter packages (1) Package main (calling script) DataPresenter.pm new() sort_by_column() writeformat() writeHTML() Perl Seminar New York
Client MedicalInsurance Status • CLIENT MEDICAL INSURANCE STATUS • AS OF JULY 1, 2001 • ALL INFORMATION IS CONFIDENTIAL ! ! ! • NAME C. NO. STATE MEDICARE MD'CAID • ADAMS GEORGIE 392876 2089297 LM84291J • BOUBAKAR ALI 456892 1378742 • CHIN MAO-TSE 399901 990887776C12 • DOVER DILSON 399723 AB82376T • MARESH TIMOTHY 392877 2089200 TS84368G • VASQUEZ JORGE 456787 1163582 990999876A XQ95432K • VASQUEZ JOAQUIN 456789 1056410 990994567C2 • VASQUEZ LEONARDO 456788 1039642 AW45329T • WESTINGHOUSE GEORGE 456600 1894567 990993214M Perl Seminar New York
Create 2ndDataPresenter Object • # Create an object that stores client Medicare and Medicaid • # numbers, keyed by C no • $sourcefile = 'medinsure.txt'; • my $dp2 = DataPresenter->new($sourcefile); • @columns_selected = • ('lastname', 'firstname', 'medicare', 'medinsure', 'cno'); • $sorted_data = $dp2->sort_by_column(\@columns_selected); • $outputfile = 'format02.txt'; • $dp2->writeformat($sorted_data, \@columns_selected, $outputfile); Perl Seminar New York
Output via Perl Format (2) • ADAMS GEORGIE LM84291J 392876 • BOUBAKAR ALI 456892 • CHIN MAO-TSE 990887776C12 399901 • DOVER DILSON AB82376T 399723 • MARESH TIMOTHY TS84368G 392877 • VASQUEZ JOAQUIN 990994567C2 456789 • VASQUEZ JORGE 990999876A XQ95432K 456787 • VASQUEZ LEONARDO AW45329T 456788 • WESTINGHOUSE GEORGE 990993214M 456600 Perl Seminar New York
DataPresenter Constructor (1) • sub new { • my ($class, $source, $self); • ($class, $source) = @_; • # bless a ref to an empty hash into the invoking class • $self = bless {}, ref($class) || $class; • # initialize the database • $self->_init($source); • # return a reference to the initialized object • return $self; • sub _init { • my ($self, $source) = @_; • # Initialization procedure: Details depend on • # characteristics of different source files • } • } Perl Seminar New York
Initialization of Data in DataPresenter::Census • package DataPresenter::Census; • @ISA = qw(DataPresenter); • sub _init { • my ($self, $sourcefile) = @_; • my %data = (); • open(CENSUS, $sourcefile); • while (<CENSUS>) { • # Process $sourcefile one line at a time • # Strip out lines you don't need in new object • # Data munging as needed to get data in uniform format • # $data{'[key]'} = \@values_from_census\; • } • close(CENSUS); • return \%data; • } Perl Seminar New York
Initialization of Data in DataPresenter::Medinsure • package DataPresenter::Medinsure; • @ISA = qw(DataPresenter); • sub _init { • my ($self, $sourcefile) = @_; • my %data = (); • open(MEDINSURE, $sourcefile); • while (<MEDINSURE>) { • # $data{'[key]'} = \@values_from_medinsure\; • } • close(MEDINSURE); • return \%data; • } Perl Seminar New York
Invoke Constructor fromDataPresenter::[Subclass] • $sourcefile = 'census.txt'; • my $dp1 = DataPresenter::Census->new($sourcefile); • $sourcefile = 'medinsure.txt'; • my $dp2 = DataPresenter::Medinsure->new($sourcefile); Perl Seminar New York
Package main (calling script) DataPresenter.pm new() writeformat() sort_by_column() writeHTML() DataPresenter::Census.pm _init() DataPresenter::Medinsure.pm _init() Structure of DataPresenter packages (2) Perl Seminar New York
Construct a DataPresenter::Combo Object • $sourcefile = 'census.txt'; • my $dp1 = DataPresenter::Census->new($sourcefile); • $sourcefile = 'medinsure.txt'; • my $dp2 = DataPresenter::Medinsure->new($sourcefile); • my @objects = ($dp1, $dp2); • my $dpC = DataPresenter::Combo->new(\@objects); Perl Seminar New York
DataPresenter::Combo Sorting and Output Methods • my @objects = ($dp1, $dp2); • my $dpC = DataPresenter::Combo->new(\@objects); • @columns_selected = • ('lastname', 'firstname', 'cno', 'datebirth', • 'Medicare', 'Medicaid'); • $sorted_data = $dpC->sort_by_column(\@columns_selected); • $outputfile = 'format03.txt'; • $dpC->writeformat($sorted_data, \@columns_selected, $outputfile); Perl Seminar New York
Output via Perl Format (3) • VASQUEZ JOAQUIN 456789 1970-03-25 990994567C2 • VASQUEZ JORGE 456787 1956-01-13 990999876A XQ95432K • VASQUEZ LEONARDO 456788 1970-15-23 AW45329T Perl Seminar New York
Construct Combo::Intersect and Combo::Union Objects • my @objects = ($dp1, $dp2); • my $dpI = DataPresenter::Combo::Intersect->new(\@objects); • my $dpU = DataPresenter::Combo::Union->new(\@objects); Perl Seminar New York
Package main (calling script) DataPresenter.pm new() sort_by_column() writeformat() writeHTML() DP::Medinsure.pm _init() DP::Census.pm _init() DataPresenter::Combo.pm _init() DataPresenter::Combo::Intersect.pm _init() DataPresenter::Combo::Intersect.pm _init() Structure of DataPresenter packages (3) Perl Seminar New York
A Closer Look at the Constructor • our @fields = (); • our %parameters = (); • our $index = ''; • my ($sourcefile, $fieldsfile, $outputfile); • my @columns_selected = (); • my $sorted_data = ''; • my @objects = (); • $sourcefile = 'census.txt'; • $fieldsfile = 'fields_census.data'; • do $fieldsfile; • my $dp1 = DataPresenter::Census->new( • $sourcefile, \@fields, \%parameters, $index); Perl Seminar New York
Configuration File:fields_census.data • @fields = qw( • lastname firstname cno unit • ward dateadmission datebirth ); • %parameters = ( • $fields[0] => [14, 'U', 'a', 'Last Name'], • $fields[1] => [10, 'U', 'a', 'First Name'], • $fields[2] => [ 7, 'U', 'n', 'C No.'], • $fields[3] => [ 6, 'U', 'a', 'Unit'], • $fields[4] => [ 4, 'U', 'n', 'Ward'], • $fields[5] => [10, 'U', 'a', 'Date of Admission'], • $fields[6] => [10, 'U', 'a', 'Date of Birth'], • ); • $index = 2; Perl Seminar New York
%parameters: A closer look • %parameters = ( • $fields[0] => [14, 'U', 'a', 'Last Name'], • $fields[1] => [10, 'U', 'a', 'First Name'], • $fields[2] => [ 7, 'U', 'n', 'C No.'], • $fields[3] => [ 6, 'U', 'a', 'Unit'], • $fields[4] => [ 4, 'U', 'n', 'Ward'], • $fields[5] => [10, 'U', 'a', 'Date of Admission'], • $fields[6] => [10, 'U', 'a', 'Date of Birth'], • ); • # ^ ^ ^ ^ • # width of field in output • # U: sort ascending (up); D: sort descending (down) • # a: alphabetical (case-insensitive) • # n: numerical • # s: ASCII-betical (case-sensitive) • # extended titles for format headers Perl Seminar New York
Configuration File:Why Not Just 2 Variables? • %parameters = ( • 'lastname' => [14, 'U', 'a', 'Last Name'], • 'firstname' => [10, 'U', 'a', 'First Name'], • 'cno' => [ 7, 'U', 'n', 'C No.'], • 'unit' => [ 6, 'U', 'a', 'Unit'], • 'ward' => [ 4, 'U', 'n', 'Ward'], • 'dateadmission' => [10, 'U', 'a', 'Date of Admission'], • 'datebirth' => [10, 'U', 'a', 'Date of Birth'], • ); • $index = 2; Perl Seminar New York
DataPresenter Constructor (2) • sub new { • my ($class, $source, $fieldsref, $paramsref, $index) = @_; • my ($self, $dataref); • # apply 3 internal subroutines to validate @fields, %parameters and $index • _validate_fields($fieldsref); • _validate_parameters($fieldsref, $paramsref); • _validate_index($fieldsref, $index); • # bless a ref to an empty hash into the invoking class • $self = bless {}, ref($class) || $class; • # populate the database by building hash of arrays • # and returning a reference to that hash • $dataref = $self->_init($source, $fieldsref, $paramsref, $index); • # add 2 entries to that hash keyed by 'fields' and 'parameters' • _make_labels_params(\@{${$dataref}{'fields'}}, \@{${$dataref}{'parameters'}}); • # initialize the object from the prepared values (Damian, p. 98) • %$self = %$dataref; • return $self; • } Perl Seminar New York
Initialization of Data in DataPresenter::Census (2) • package DataPresenter::Census; • @ISA = qw(DataPresenter); • sub _init { • my ($self, $sourcefile, $fieldsref, $paramsref, $index) = @_; • my %data = (); my @paramvalues = (); • my @fields = @$fieldsref; my %parameters = %$paramsref; • $data{'fields'} = [@fields]; • for (my $i = 0; $i < scalar(@fields); $i++) { • push @paramvalues, \@{$parameters{$fields[$i]}}; • } • $data{'parameters'} = [@paramvalues]; $data{'index'} = [$index]; • open(CENSUS, $sourcefile); • while (<CENSUS>) { • # $data{'[key[$index]]'} = \@values_from_census\; • } • close(CENSUS) || die "cannot close $sourcefile: $!"; return \%data; • } Perl Seminar New York
Structure of a DataPresenter Object (2a) • my %data = ( • 'fields' => ['lastname', • 'firstname', • 'cno', • 'unit', • 'ward', • 'dateadmission', • 'datebirth', ], • 'parameters' => [ • [14, 'U', 'a', 'Last Name'], • [10, 'U', 'a', 'First Name'], • [ 7, 'U', 'n', 'C No.'], • [ 6, 'U', 'a', 'Unit'], • [ 4, 'U', 'n', 'Ward'], • [10, 'U', 'a', 'Date of Admission'], • [10, 'U', 'a', 'Date of Birth'], ], • (continued on next slide) Perl Seminar New York
Structure of a DataPresenter Object (2b) • (continued from previous slide) • 'index' => [2], • 456791 => [ 'HERNANDEZ', • 'HECTOR', • '456791', • 'SAMSON', • '0217', • '2001-07-25', • '1963-08-01', ], • 803092 => [ 'JONES', • 'TIMOTHY', • '803092', • 'LAVER', • '0103', • '2001-03-19', • '1969-06-29' ], • ...,); Perl Seminar New York
Construct Combo::Intersect and Combo::Union Objects • $sourcefile = 'census.txt'; • $fieldsfile = 'fields_census.data'; • do $fieldsfile; • my $dp1 = DataPresenter::Census->new( • $sourcefile, \@fields, \%parameters, $index); • $sourcefile = 'medinsure.txt'; • $fieldsfile = 'fields_medinsure.data'; • do $fieldsfile; • my $dp2 = DataPresenter::Medinsure->new( • $sourcefile, \@fields, \%parameters, $index); • @objects = ($dp1, $dp2); • my $dpI = DataPresenter::Combo::Intersect->new(\@objects); • my $dpU = DataPresenter::Combo::Union->new(\@objects); Perl Seminar New York
Select Entries for Output • my ($column, $relation); • my @choices = (); • @objects = ($dp1, $dp2); • my $dpI = DataPresenter::Combo::Intersect->new(\@objects); • $column = 'lastname'; • $relation = 'is'; • @choices = ('Vasquez'); • print "Got this far!\n"; • $dpI->select_rows($column, $relation, \@choices); Perl Seminar New York
Output via Perl Format (4) • Selected fields from: Census and Insurance Data (Partial) • Date Medicaid • Last Name First Name C No. of Birth Medicare No. No. • ----------------------------------------------------------------- • VASQUEZ JOAQUIN 456789 1970-03-25 990994567C2 • VASQUEZ JORGE 456787 1956-01-13 990999876A XQ95432K • VASQUEZ LEONARDO 456788 1970-15-23 AW45329T Perl Seminar New York
Structure of DataPresenter packages (4) Package main (calling script) DataPresenter.pm Methods callable from package main: new() sort_by_column() select_rows() get_data_count() print_data_count() print_to_screen() print_to_file() full_report() writeformat() writeformat_plus_header() writeHTML() Other subroutines used internally: _validate_fields() _validate_parameters() _validate_index() _make_labels_params() _validate_args() _build_sort_formula() _formula_engine() _key_constructor() _analyze_relation() _strip_non_matches() _count_engine() _format_title() _format_argument_line_top() _format_hyphen_line() _format_picture_line() _format_argument_line() DP::Medinsure.pm _init() _extract_rows() DataPresenter::Combo.pm _init() _extract_rows() _merge_into_base() _augment() DP::Census.pm _init() _extract_rows() DataPresenter::Combo::Intersect.pm _merge_engine() DataPresenter::Combo::Union.pm _merge_engine() Perl Seminar New York
DataPresenter Manipulating Database Reports Entirely Within Perl James E Keenan PODhttp://www.concentric.net/~Jkeen/datapresenter/datapresenter.htmlArchivehttp://www.concentric.net/~Jkeen/datapresenter/datapresenter.zip Perl Seminar New York