Chris Pollett > Old Classes > PIC40 ( Print View ) Lecture Notes-PDF Spring '01 Ad: Enrollment info Course Info:
Practice Exams: PIC: |
HW4 Solutions Page<html> <!-- Filename: p40hw4file1.html Purpose: This file is the main document for our Toy Search Engine site. It gives the opportunity to the user to search the engine for an entry. It also has a link to the add a page document (p40hw4file4.php). --> <head> <title>Toy Search Engine</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="Authors" content="Christopher Pollett" /> <meta name="keywords" content="search engine" /> </head> <body text="#000000" bgcolor="#99FFCC" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <h1 style="text-align:center">Toy Search Engine </h1> <!--The SSI that follows checks if the searchdb directory exists. If not it creates it. In the event that this document was accessed as the action of the add a page document's (p40hw4file4.php's) form, the SSI below adds the URL and description to the appropriate DBMS in the searchdb. It then prints out if this was successful. --> <!--#exec cgi="p40hw4file2.cgi" --> <!-- Now we have the search form described in the purpose of this document. --> <form method="GET" action="http://www.math.ucla.edu/~cpollett/hw4/p40hw4file1.php"> <div style="text-align:center"> <table border="0" cellpadding="0" > <tr> <td valign="center">Search database for a single keyword: </td> <td valign="bottom"> <input type="text" name="searchfield" size="15" maxlength="80" /> </td> <td valign="bottom"> <input type="submit" name="submit1" value="Submit" /> </td> </tr> </table> </form> <!-- If this document was called as the action of the above form, then the next SSI checks the DBMs in the searchdb to see if there are any matches. --> <!--#exec cgi="p40hw4file3.cgi" --> <br /> <a href="p40hw4file4.php" >Add a page to the database.</a> <p> This page was last modified <!--#flastmod file="p40hw4file1.php"-->.</p> </div> </body> </html> #!/usr/local/bin/perl # # Filename: p40hw4file2.cgi # # Purpose: This script is used by the Toy Search Engine to # associate a URL description pair with a list of # keywords. It is also called by the p40hw1file1.php # document to create the searchdb directory if it doesn't exist. # require "subparseform.lib"; Parse_Form(); # # Begin Main Section # print "Content-type: text/html\n\n"; if(!$formdata{submit2}) {CheckDir();} # if submit2 doesn't exist we check if need to create # searchdb else {AddPage();} # add URL description pairs to appropriate DBMs. # # End Main Section # # # Function: CheckDir # # Purpose: creates the searchdb directory if it doesn't exist # sub CheckDir() { if(-d "searchdb") {return;} mkdir("searchdb",0755); } # # Function: AddPage # # Purpose: adds URL description row to a DBM hash for each keyword # passed in the keywords form variable. # sub AddPage() { my @keywords= split(/\s/,$formdata{keywords}); #get list of keywords foreach $word (@keywords) #now add URL description row to #each keyword's DBM. { dbmopen(%urlTable,"searchdb/$word",0755); $urlTable{$formdata{url}}=$formdata{description}; dbmclose(%urlTable); } print "<p>URL added to appropriate DBMs.</p>\n"; } #!/usr/local/bin/perl # # Filename: p40hw4file3.cgi # # Purpose: This script presents the results a Toy Engine Search # on a given keyword. # require "subparseform.lib"; Parse_Form(); print "Content-type: text/html\n\n"; if(!$formdata{searchfield}) {return;} #if the searchfield variable is not set #then we haven't searched for anything yet so stop # # Now we check if the keyword exists as a DBM hash in the searchdb. # If not print no matches. Otherwise, we open that hash and print # the URL description pairs listed there. # if(-e "searchdb/$formdata{searchfield}.dir") { dbmopen(%urlTable,"searchdb/$formdata{searchfield}",0755); print "<table>\n"; # # The next while loop prints out the URL description pairs. # while( ($key, $value) = each(%urlTable)) { print "<tr><td>\n"; print "<a href=\"$key\">$key</a>\n"; print "</td><tr><td>\n"; print "Description:<br />\n$value\n"; print "<br /><br /></td></tr>\n"; } print "</table>\n"; dbmclose(%urlTable); } else { print "<p>Sorry, no matches.</p>\n"; } <html> <!-- Filename: p40hw4file4.php Purpose: This document provides a form that allows the user to associate a new URL description pair to a list of keywords in th Toy Search Engine. --> <head> <title>Toy Search Engine -- add a page</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="Authors" content="Christopher Pollett" /> <meta name="keywords" content="search engine" /> </head> <body text="#000000" bgcolor="#99FFCC" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div style="text-align:center"> <h1>Toy Search Engine -- add a page </h1> <!-- The action of the form on this page is p40hw4file1.html; however, the page is actually added by the cgi script p40hw4file2.cgi which is exec'd as an SSI in p40hw4file1.php --> <form method="GET" action="http://www.math.ucla.edu/~cpollett/hw4/p40hw4file1.php"> <table border="0" cellpadding="0" > <tr> <td>Enter a list of space separated keywords:</td> </tr> <tr> <td> <input type="text" name="keywords" size="40" maxlength="120" /> <br /> <br /> </td> </tr> <tr><td>Enter a URL:</td></tr> <tr> <td> <input type="text" name="url" size="40" maxlength="120" /> <br /> <br /> </td> </tr> <tr><td valign="top">Enter a description:</td></tr> <tr><td><textarea name="description" cols="40" rows="10"> </textarea></td> </tr> </table> <input type="submit" name="submit2" value="Submit" /> <input type="reset" name="Reset" /> </form> <p> This page was last modified <!--#flastmod file="p40hw4file4.php"-->. </p> </div> </body> </html> #!/usr/local/bin/perl # # Name: NClock HW3 Bonus solutions # # Purpose: A simple PERL clock which sync's with the NIST atomic clock # or any internet clock which uses the RFC 867 time protocol. # Command line arguments: timezone, width, height, clockSite, sync frequency # # Example Uses: >NClock --- starts a 150x150 clock on PST using time-a.nist.gov # syncing every 60 seconds. # # >NClock -5 200 300 time-b.nist.gov 30 # --- starts a 200x300 clock on EST using time-b.nist.gov # syncing every 30 seconds # # Author: Chris Pollett # # # includes # use Tk; use Socket; # # Globals # $PI=3.1415926535; # beloved constant $zoneOffset = ($ARGV[0]) ? $ARGV[0] : -8; # timezones from Greenwich Mean Time $clockSizeX = ($ARGV[1]) ? $ARGV[1] : 150; #clock width $clockSizeY = ($ARGV[2]) ? $ARGV[2] : 150; #clock height $syncClock = ($ARGV[3]) ? $ARGV[3] : "time-a.nist.gov"; #atomic clock to connect to $syncFreq = ($ARGV[4]) ? $ARGV[4] : 300; # number of seconds between contacting atomic clock $secCount=0; #counter used to tell when to resync with atomic clock # # Main Loop # $mw = MainWindow->new; $mw->geometry("$clockSizeX"."x"."$clockSizeY"); $menu = $mw->Menu(-tearoff =>'0', -menuitems => [ [ 'command' => "Greenwich", -command=>sub{$zoneOffset = 0; $secCount=0;}], [ 'command' => "Maritime", -command=>sub{$zoneOffset = -4; $secCount=0;}], [ 'command' => "Eastern", -command=>sub{$zoneOffset = -5; $secCount=0;}], [ 'command' => "Central", -command=>sub{$zoneOffset = -6; $secCount=0;}], [ 'command' => "Mountain", -command=>sub{$zoneOffset = -7; $secCount=0;}], [ 'command' => "Pacific", -command=>sub{$zoneOffset = -8; $secCount=0;}] ]); $mw->bind("<Button-3>", sub{ $menu->Popup(-popover =>'cursor');}); $canvas = $mw->Canvas(-background => "white", -height => $clockSizeX, -width => $clockSizeY); $canvas->pack(); #canvas on which clock drawn $mw->repeat(1000,\&ReDraw); MainLoop; # # Name: ReDraw($frame, $canvas); # # Purpose: computes current time (sync'd with atomic clock every $syncFreq seconds) # then draws clock based on this time # sub ReDraw { # #get size of current window and resize clock accordingly # ($clockSizeX,$clockSizeY)=split(/[x|+]/,$mw->geometry()); $canvas->configure(-height => $clockSizeY, -width => $clockSizeX); # # Now either sync with NIST time or assume a second has passed # and update time accordingly # if($secCount== 0) { $time = connectNIST(); ($hour,$minute,$second) =split(/:/,$time); $hour =($hour+$zoneOffset)%24; $ampm = ($hour<12)? "am" : "pm"; $hour %=12; } else { $second = ($second+1)%60; if($second == 0) { $minute = ($minute+1)%60; if($minute == 0) {$hour = ($hour+1)%12;} } } #update title of clock then redraw clock face then sync update counter if (length($second)<2) {$second = "0$second";} if (length($minute)<2) {$minute = "0$minute";} $time = $hour.":".$minute.":".$second.$ampm; $mw->title($time); DrawClock($clockSizeX, $clockSizeY, $hour, $minute, $second); $secCount= ($secCount+1)%$syncFreq; } # # Name: DrawClock($clockSizeX, $clockSizeY, $hour, $minute, $second) # # Purpose: Draws the picture of an analog clock according to the size # and time parameters passed # sub DrawClock { #time to angle conversions $secondAng = $_[4]/30*$PI-$PI/2; $minuteAng = $_[3]/30*$PI+($secondAng+$PI/2)/60-$PI/2; $hourAng = $_[2]/6*$PI+($minuteAng+$PI/2)/12-$PI/2; #calculate border around clock and clock dimensions my $offSetX = $_[0]/15; my $offSetY = $_[1]/15; my $diameterX = $_[0]-2*$offSetX; my $diameterY = $_[1]-2*$offSetY; my $radiusX = $diameterX/2; my $radiusY = $diameterY/2; my $centerX = $radiusX +$offSetX; my $centerY = $radiusY +$offSetY; #starting and ending positions of tick marks my $startTickX; my $startTickY; my $endTickX; my $endTickY; #lengths of ticks and of hands my $tickScaling = .85; my $secScaling = .85; my $minScaling = .75; my $hourScaling = .5; # #Clear screen & draw face # $canvas->delete("all"); $canvas->createOval( $offSetX, $offSetY, $diameterX+$offSetX, $diameterY+$offSetY, -width=>($offSetX+$offSetY)/4, -outline=>"black"); # #Draw Ticks # $tickWidth = ($offSetX+$offSetY)/8; for($theta=0; $theta< 2*$PI; $theta+= $PI/6) { $endTickX= $radiusX*cos($theta); $endTickY= $radiusY*sin($theta); $startTickX= $tickScaling*$endTickX; $startTickY= $tickScaling*$endTickY; $canvas->createLine($centerX+$startTickX, $centerY+$startTickY, $centerX+$endTickX, $centerY+$endTickY, -fill=>"black", -width=>$tickWidth); } # #Draw Hour and Minutes then Seconds # $canvas->createLine($centerX+$hourScaling*$radiusX*cos($hourAng), $centerY+$hourScaling*$radiusY*sin($hourAng), $centerX, $centerY, $centerX+$minScaling*$radiusX*cos($minuteAng), $centerY+$minScaling*$radiusY*sin($minuteAng), -fill=>"blue", -width=>$tickWidth, -joinstyle=>"bevel"); $canvas->createLine($centerX+$secScaling*$radiusX*cos($secondAng), $centerY+$secScaling*$radiusY*sin($secondAng), $centerX, $centerY, -fill=>"red", -width=>$tickWidth/2, -joinstyle=>"bevel"); } # # TCP Stuff # # # Name: openTCP # # Purpose: given a stream, an internet address name, and a port opens a TCP # connection to that port. (Taken essentially from Client Web Programming Perl # book) # sub openTCP { my ($FS, $dest, $port) = @_; my $protocol = getprotobyname('tcp'); socket($FS, PF_INET, SOCK_STREAM, $protocol); my $sin =sockaddr_in($port, inet_aton($dest)); connect($FS,$sin) || return undef; my $old_fh = select($FS); $| =1; select($old_fh); return 1; } # # Name: connectNist # # Purpose: connects to a RFC-867 clock $syncClock grab its time string # and return hour, minute, second substring. # sub connectNIST { my @time; my $timeString; # #connect to nist using RFC-867 protocol #get there time string and close connection # if(openTCP(F,$syncClock, 13) == undef) { print "Error connecting to server.\n"; exit(-1); } $timeString=""; $timeString .= $_ while (<F>); close(F); @time = split(/\s/, $timeString); return $time[3]; # return only hour:minute:second part of string } |