Midterm 2 Answers


  1. birth.pl: names.txt was used as the test file for grading purposes. # first compare people by year, then month, and finally day. If those # all match, the last comparison is by name. Note that by using an # or (||), that the first non-0 result will be returned. If two # elements are equal, such as the year, then the spaceship operator, # <=>, will return 0 and the function will move on to the next # comparison sub comparePeople { return $$a{year} <=> $$b{year} || $$a{month} <=> $$b{month} || $$a{day} <=> $$b{day}; || $$a{name} cmp $$b{name}; } # the file to open is in the first command line argument open(INPUTFILE, "<", $ARGV[0]); @peopleRecords = (); # for each input line, split it into the name and date fields and then # further split the date field into month, day, and year. Create an # anonymous hash for the person and add it to the peopleRecords array foreach $line (<INPUTFILE>) { @fields = split(/\s+/, $line); $date = pop(@fields); @dates = split(/\//, $date); $name = join(" ", @fields); push(@peopleRecords, { name => $name, month => $dates[0], day => $dates[1], year => $dates[2] }); } # print either all the people or the requested number of people (specified # by command argument 1), whichever is less @peopleRecords = sort comparePeople @peopleRecords; for ($i = 0; @peopleRecords > 0 && $i < $ARGV[1]; $i++) { $ref = shift(@peopleRecords); printf("%s %d/%d/%d\n", $$ref{name}, $$ref{month}, $$ref{day}, $$ref{year}); }
    1. bullets.pl: article1.txt and article2.txt were used as the test files for grading purposes. foreach $line (<>) { if ($line =~ /^\d+\. +/) { print $line; } }
    2. date.pl: The dates in dates.txt were used as the test data for grading purposes. if ($ARGV[0] =~ /^[A-Z][a-z]{2}\. \d{1,2}, \d{4} (AD|BC)/) { print "passed\n"; } else { print "failed\n"; }
    3. substitute.pl: substitute.txt was used as the test file for grading purposes. open(INPUT, "<", $ARGV[0]) or die "Cannot open $ARGV[0]: $!\n"; $string = join("", <INPUT>); $string =~ s/(\d\d):(\d\d):(\d\d)/\1 hours, \2 minutes, and \3 seconds/g; close(INPUT); open(OUTPUT, ">", $ARGV[0]) or die "Cannot open $ARGV[0] for output: $!\n"; print OUTPUT $string;
  2. rename.pl $dir = $ARGV[0]; if (! -d $dir) { exit(1); } chdir $dir; for $file (<*.cc>) { $newfile = $file; $newfile =~ s/\.cc/\.cpp/; rename $file, $newfile; }
  3. airport.dtd: The files airportDTD.xml and errorWeatherDTD.xml were used as test files for grading purposes. <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT weather (airport)+> <!ELEMENT airport (location, elevation, runway+)> <!ELEMENT location (city, (state | country))> <!ELEMENT elevation (quantity, measure)> <!ELEMENT runway (map_coordinates)> <!ELEMENT map_coordinates (latitude, longitude)> <!ELEMENT latitude (degrees, minutes, direction)> <!ELEMENT longitude (degrees, minutes, direction)> <!ELEMENT city (#PCDATA)> <!ELEMENT state (#PCDATA)> <!ELEMENT country (#PCDATA)> <!ELEMENT quantity (#PCDATA)> <!ELEMENT measure (#PCDATA)> <!ELEMENT degrees (#PCDATA)> <!ELEMENT minutes (#PCDATA)> <!ELEMENT direction (#PCDATA)>
  4. airport.xsd: The following files were used as test files for grading purposes. There were a total of 15 errors in the error test files:

    <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://web.eecs.utk.edu/~bvz/airport" xmlns="http://web.eecs.utk.edu/~bvz/airport" elementFormDefault="qualified"> <xs:element name="weather"> <xs:complexType> <xs:sequence maxOccurs="unbounded"> <xs:element ref="airport" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="airport"> <xs:complexType> <xs:sequence> <xs:element ref="location" /> <xs:element ref="elevation" /> <xs:element ref="runway" maxOccurs="10" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="location"> <xs:complexType> <xs:sequence> <xs:element name="city" type="xs:string"/> <xs:choice> <xs:element name="state" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="elevation"> <xs:complexType> <xs:sequence> <xs:element name="quantity"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minExclusive value="-200"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="measure"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="feet"/> <xs:enumeration value="meters"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="runway"> <xs:complexType> <xs:sequence> <xs:element ref="map_coordinates" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="map_coordinates"> <xs:complexType> <xs:sequence> <xs:element ref="latitude" /> <xs:element ref="longitude" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="latitude"> <xs:complexType> <xs:sequence> <xs:element name="degrees"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="-90"/> <xs:maxInclusive value="90"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="minutes" type="minutesType" /> <xs:element name="direction"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="N"/> <xs:enumeration value="S"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="longitude"> <xs:complexType> <xs:sequence> <xs:element name="degrees"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="-180"/> <xs:maxInclusive value="180"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="minutes" type="minutesType" /> <xs:element name="direction"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="E"/> <xs:enumeration value="W"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:simpleType name="minutesType"> <xs:restriction base="xs:decimal"> <xs:minInclusive value="0"/> <xs:maxExclusive value="60"/> <xs:pattern value="\d{1,2}(.\d{1,3})?"/> </xs:restriction> </xs:simpleType> </xs:schema>
  5. XML structure for a recipe
    recipe
         name: string
         citation
           title: string
           publisher: string
           year: restricted integer (e.g., 1900-2010)
           isbn: pattern with alternating digit groups and dashes
         introduction: string
         ingredients
           ingredient+
             quantity: best to use a pattern since the example shows 
               at least three variations, an integer, a fraction (1/4) or
               a range of numbers (3-5).
             measure: string (e.g., T, t, 28-oz can--you might try for an 
                enumerated type but it is probably difficult to enumerate all 
                the possibilities, such as 28-oz can)
             name: string
             processing?: string (e.g., drained, undrained, stemmed, etc)-might
                be omitted
         directions
           direction+: string
         comments? 
           comment+: string
    
    Discussion: It is nice to have an overarching category for ingredients, directions, and comments that group all the elements of that group together. It makes each group seem like a block of related data, which is what they are. It also might make it a little easier for a program to retrieve those elements when using an XML parser. I felt as though comments might be optional, but you may well have concluded, based on the example, that comments are required. Many of you broke citation down into either a web reference or a published reference. That was an excellent distinction.