\documentclass[10pt]{article}

\setlength{\oddsidemargin}{-0.5in}
\setlength{\evensidemargin}{-0.5in}
\setlength{\topmargin}{0.0in}
\setlength{\headheight}{0in}
\setlength{\headsep}{0in}
\setlength{\textwidth}{7.0in}
\setlength{\textheight}{9.5in}
\setlength{\parindent}{0in}
\setlength{\parskip}{0.05in}
\setlength{\columnseprule}{0.3pt}
\usepackage{fancyvrb}
\usepackage{relsize}

\begin{document}

Name: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

\textbf{Directions: Work only on this sheet (on both sides, if needed); do not
turn in any supplementary sheets of paper. There is actually plenty of room
for your answers, as long as you organize yourself BEFORE starting
writing.}

{\bf Do not use any Python or Perl constructs which were not introduced
either in lecture, discussion section or our written materials.}

{\bf 1.} (10) Give Python analogs of the following Perl items:
{\bf shift @z}, {\bf unshift @z,\$x} (prepends), {\bf \$ARGV[3]},
{\bf @z[9:12]}.

{\bf 2.} (15) Add code to {\bf kill()} in our PLN program {\bf psax.py},
which will display a confirmation query message, ``Kill this process
(y,n)?'', on the line which is highlighted at the time the user hits the
k key.  The message will overwrite the first part of that line.  If the
next key hit is not y, the function will simply return (the user can
then hit u etc. as a means of restoring the line); otherwise the
original line will be restored and the process will be killed.  In the
latter case, change the State column ($16^{th}$ character position in
the line) to `K'.  You are allowed to add a total of nine lines maximum.

{\bf 3.}  Consider a package {\bf RadixNum.pm} whose objects will store
nonnegative numbers in base-r form internally but will present a scalar
version of the numbers to the ``outside world.'' For example, consider
this code (ignore the three blank lines at the end for now):

\begin{Verbatim}[fontsize=\relsize{-2}]
use RadixNum;

tie $x,'RadixNum',3,0;  # base 3
tie $y,'RadixNum',3,0;  # base 3
$x = 5;
$y = $x + 20;
print $x,$y, "\n";
________________________
________________________
________________________
\end{Verbatim}

This will print out 5 and 25, but internally {\bf \$y}, for instance,
will also be associated with a reference to an anonymous array (2,2,1),
since the base-3 representation of 25 is ${\mathbf 2} \cdot 3^2 +
{\mathbf 2} \cdot 3^1 + {\mathbf 1} \cdot 3^0$.  Note that the fancy
name used for base is {\it radix}, so in this example the radix is 3.

The object created by {\bf TIESCALAR()} (not shown) is an anonymous hash
which consists of an integer {\bf Radix}, a reference {\bf Digits} to
the anonymous array, and an integer {\bf Value} containing the numeric
value.  

Part of the code in {\bf RadixNum.pm} will be a subroutine {\bf
torad()}.  It has as arguments the radix and value, and returns a
reference to the corresponding radix form of the value.  For instance, 
the call {\bf torad(3,25}) will return $\backslash$(2,2,1).

\begin{itemize}

\item [(a)] (15) Fill in the blanks in {\bf torad()}:

\begin{Verbatim}[fontsize=\relsize{-2}]
sub torad {
   my $rad = shift;
   my $vl = shift;
   my @ary = ();
   if ($vl == 0) {@ary = (0);}
   else {
      while ($vl > 0) {
         $t = $vl % $rad;
         $vl = int($vl/$rad);
         ______________
      }
   }
   return ______________;
}
\end{Verbatim}

\item [(b)] (15) An instance method {\bf printrad()} will print out the
radix form of the stored number.  For instance, if {\bf \$y} is storing
25, this function will print out 221.  Fill in the blanks in the test
code above (following the line printing {\bf \$x} and {\bf \$y}), so
that the radix form of {\bf \$y} is printed out, and the blanks in the
function itself below.  For full credit, use no loops. 

\begin{Verbatim}[fontsize=\relsize{-2}]
sub printrad {
   ________________________
   ________________________
   ________________________
}
\end{Verbatim}

\end{itemize}

{\bf 4.} (15) In this problem you will write a class similar to Python's
built-in {\bf Queue} class, but for use with {\bf pth}.  The {\bf get()}
function returns with the head of the work queue; this occurs
immediately if the queue is nonempty, but otherwise the call blocks
until work is available.  Fill in the gaps with at most a total of eight
lines:

\begin{Verbatim}[fontsize=\relsize{-2}]
class pthqueue:
   def __init__(self,qid):
      self.qid = qid
      pth.newevent(qid)
      self.queue = []
   def get(self):
      (insert lines here)
   def put(self,work):
      (insert lines here)
\end{Verbatim}

{\bf 5.} (15) When they added OOP to Perl, the Perl development people
made just two changes.  First, they added the {\bf bless} operation.
Second, they changed the interpreter to allow functions in a package to
be called via the object that had been blessed or the package itself,
such as {\bf \$w1-$>$printworker} and {\bf Worker-$>$newworker()} in our
{\bf Worker} example.  However, show how to modify the calls to {\bf
newworker()} and {\bf printworker()} in our example so as to avoid using
either of those new Perl constructs; replace the existing four lines of
code with four new lines of code.  No changes are to be made to {\bf
Worker.pm} (other than removing the {\bf bless}). 

{\bf Solutions:}

{\bf 1.}  

\begin{Verbatim}[fontsize=\relsize{-2}]
x = z.pop(0)
z.insert(0,x)
sys.argv[4]
z[9:13]
\end{Verbatim}

{\bf 2.} 

\begin{Verbatim}[fontsize=\relsize{-2}]
gb.scrn.addstr(gb.winrow,0,'kill this process?')
c = chr(gb.scrn.getch())
if c != 'y': return
pid = int(ln.split()[0])
os.kill(pid,9)
ln = ln[:15] + 'k' + ln[16:]  # can't change a tuple
gb.cmdoutlines[gb.startrow+gb.winrow)] = ln
gb.scrn.addstr(gb.winrow,0,ln,curses.A_BOLD) 
\end{Verbatim}

{\bf 3.a} 

\begin{Verbatim}[fontsize=\relsize{-2}]
unshift @ary,$k;
\@ary;
\end{Verbatim}

{\bf 3.b}

\begin{Verbatim}[fontsize=\relsize{-2}]
my $r = shift;
my $aryref = $r->{Digits};
print @$aryref;
...
$ry = tied $y;
$ry->printrad();
\end{Verbatim}

{\bf 4.}

\begin{Verbatim}[fontsize=\relsize{-2}]
def get():
   if self.queue == []:
      yield '','wait',self.qid
   return self.queue.pop(0)

def put():

   self.queue.append(work)
   if len(self.queue) == 1:
      yield '','set leave',self.qid
\end{Verbatim}

{\bf 5.}

\begin{Verbatim}[fontsize=\relsize{-2}]
$w1 = Worker::newworker('Worker','Cassius',12,50000)
$w2 = Worker::newworker('Worker','Penelope',5,90000)
...
Worker::printworker($w1) 
Worker::printworker($w2) 
\end{Verbatim}

\end{document}


