Difference between revisions of "CSC111 Lab 2 2018"

From dftwiki3
Jump to: navigation, search
(Created page with "~~~~ ---- __TOC__ <bluebox> This lab deals with loops in python. You will be assigned a new partner at the beginning of the lab, and you will work in pair on the different ch...")
 
(Moodle Submission)
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 11:36, 4 February 2018 (EST)
 
[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 11:36, 4 February 2018 (EST)
 
----
 
----
__TOC__
+
 
  
 
<bluebox>
 
<bluebox>
Line 7: Line 7:
 
You will be assigned a new partner at the beginning of the lab, and you will work in pair on the different challenges.  Don't hesitate to share insights and help your neighbors during the lab.  This is true of all labs.  Homework assignments have to be done as an individual pair, but for the labs, you are free to talk to other pairs in the classroom.  Feel free to take a short break from time to time.  Water is always good.  A walk in the cold air of the terrace, off Room 340, is also always good!
 
You will be assigned a new partner at the beginning of the lab, and you will work in pair on the different challenges.  Don't hesitate to share insights and help your neighbors during the lab.  This is true of all labs.  Homework assignments have to be done as an individual pair, but for the labs, you are free to talk to other pairs in the classroom.  Feel free to take a short break from time to time.  Water is always good.  A walk in the cold air of the terrace, off Room 340, is also always good!
 
</bluebox>
 
</bluebox>
 +
<br />
 +
<tanbox>
 +
Update regarding Snow Day on 2/7/18: if you don't find a partner today 2/7 to work on this lab, then simply work on it on your own.  Today is an exception to the rule.
 +
</tanbox>
 +
<br />
 +
=Introductory Video for Wednesday's Lab Groups=
 +
<br />
 +
For the Wednesday group, here's a short video introducing you to the lab. 
 +
<center>
 +
<videoflash>FBTSp571rfM</videoflash>
 +
</center>
 +
<br />
 +
__TOC__
  
 
+
<br />
  
 
=Definite for-loops=
 
=Definite for-loops=
Line 107: Line 120:
 
# print the contents of the farm
 
# print the contents of the farm
 
for animal in  [ "dog", "cat", "horse" ]:
 
for animal in  [ "dog", "cat", "horse" ]:
     print animal
+
     print( animal )
 
</source>
 
</source>
 
<br />
 
<br />
Line 135: Line 148:
 
Old MacDonald's farm is a song most American kids learn at one point in their life. I certainly never heard it when I grew up in France, but I think most of you will be familiar with it.  
 
Old MacDonald's farm is a song most American kids learn at one point in their life. I certainly never heard it when I grew up in France, but I think most of you will be familiar with it.  
 
<center>
 
<center>
<videoflash>7_mol6B9z00</videoflash>
+
<videoflash>lWhqORImND0</videoflash>
 
</center>
 
</center>
If you don't know it, this YouTube video will get you acquainted with it. :-)
+
If you don't know it, the first 3 minutes of the YouTube video above will get you acquainted with it. :-)
  
 
The goal of this problem is for you to add a section to the program below so that it prints parts of the lyrics of the famous song using a for-loop.
 
The goal of this problem is for you to add a section to the program below so that it prints parts of the lyrics of the famous song using a for-loop.
Line 146: Line 159:
 
# display the names of the animals
 
# display the names of the animals
 
for animal in  [ "horse", "pig", "dog", "cat" ]:
 
for animal in  [ "horse", "pig", "dog", "cat" ]:
       print animal
+
       print( animal )
 
</source>
 
</source>
 
<br />
 
<br />
Line 244: Line 257:
 
<br />
 
<br />
 
* Same idea as with the previous challenge but after inputing the information from the user, the program outputs it in a half-box!   
 
* Same idea as with the previous challenge but after inputing the information from the user, the program outputs it in a half-box!   
Example (user input in in boldface):
+
::'''Example''' (user input in in boldface):
 
<br />  
 
<br />  
 
  your first name?  '''Mickey'''
 
  your first name?  '''Mickey'''
Line 323: Line 336:
 
* Note 1: <font color="red">'''Very important''': make sure there's a blank line between the part of the program that gets the input from the user, and the actual output of the program (the two columns of number).  This blank line will help the automatic grader to better recognize the output of your program</font>
 
* Note 1: <font color="red">'''Very important''': make sure there's a blank line between the part of the program that gets the input from the user, and the actual output of the program (the two columns of number).  This blank line will help the automatic grader to better recognize the output of your program</font>
 
* Note 2: The space between the temperatures printed on the same line can be created by a simple string of 7 spaces.
 
* Note 2: The space between the temperatures printed on the same line can be created by a simple string of 7 spaces.
* Submit your program to Moodle, in the Lab 2 section.  You have until Friday 9/18 evening to finish this program.
+
* Submit your program to Moodle, in the Lab 2 section.   
  
 
<br />
 
<br />
Line 356: Line 369:
 
<source lang="bash">
 
<source lang="bash">
 
#! /bin/bash
 
#! /bin/bash
 +
# D. Thiebaut
 +
# Smith College
 +
# vpl_run.sh script
 +
# runs the student program and compare the output to the solution
 +
# program and displays some information about the lines that do not
 +
# match
 +
# set -x
 +
 +
# --- pick the right python interpreter ---
 +
if [[ `hostname -s` = "marax" ]]; then
 +
    python=/usr/bin/python3.5
 +
else
 +
    python=/usr/local/bin/python3.4
 +
fi
 +
 +
 +
# create helper script that extracts ints and floats from file
 +
cat > extractFloats.py <<EEOOFF
 +
#! /usr/bin/env $python
 +
import re, sys
 +
for line in sys.stdin:
 +
    out =  " ".join( re.findall(r"[-+]?\d*\.\d+|\d+", line ) )
 +
    if len( out ) <= 1: continue
 +
    print( out )
 +
EEOOFF
 +
chmod +x extractFloats.py
  
cat > vpl_execution <<EOF
+
# create vpl_execution which will be run on the jail server
 +
#
 +
cat > vpl_execution <<EEOOFF
 
#! /bin/bash
 
#! /bin/bash
 +
# Moodle scale
 +
#100.00 %93.00 %A
 +
#92.99 %90.00 %A-
 +
#89.99 %87.00 %B+
 +
#86.99 %83.00 %B
 +
#82.99 %80.00 %B-
 +
#79.99 %77.00 %C+
 +
#76.99 %73.00 %C
 +
#72.99 %70.00 %C-
 +
#69.99 %67.00 %D+
 +
#66.99 %60.00 %D
 +
#59.99 %0.00 %F
 +
 +
 +
# --- program tested (no extension) ---
 +
prog1=lab2
 +
 +
# ---------------------------------------------------------------
 +
# grade given to a program that crashes
 +
# ---------------------------------------------------------------
 +
crashGrade=65  # equivalent to C
 +
 +
# =================================================
 +
# Pick 2 random inputs to test program with
 +
DIFF=\$RANDOM
 +
let "DIFF %= 20"
 +
let "DIFF = DIFF + 2"
 +
TEMP1=\$RANDOM
 +
let "TEMP1 %= 30"
 +
let "TEMP2 = TEMP1 + DIFF"
 +
 +
echo \$TEMP1 > input.dat
 +
echo \$TEMP2 >> input.dat
 +
 +
# ---------------------------------------------------------------
 +
# scale( percentGood )
 +
# transforms inGrade into outGrade
 +
# ---------------------------------------------------------------
 +
function scale {
 +
    percent=\$1
 +
    inGrade=(  95 90 85 80 75 70 65 60 55 50 0 )
 +
    #            A A- B+ B  B- C+ C  C- D+ D  F
 +
    outGrade=( 100 92 92 92 92 92 92 86 86 86 86 )
 +
    #outGrade=( 100 93 87 83 80 77 73 80 67 60 50 )
 +
 +
    # get length of an array
 +
    arraylength=\${#inGrade[@]}
 +
 +
    # loop through all the grades
 +
    for (( i=0; i<\${arraylength}; i++ ));
 +
    do
 +
        if (( \$percent > \${inGrade[\$i]} )) ; then
 +
    return \${outGrade[\$i]}
 +
        fi
 +
    done
 +
    return 50
 +
}
 +
 +
#--- test scale ---
 +
#for j in \`seq 100 -1 0 \` ; do
 +
#    scale \$j
 +
#    echo "\$j --> \$?"
 +
#done
 +
#exit 0
 +
 +
# ---------------------------------------------------------------
 +
# computeMatching( solution, student )
 +
# returns the percentage of matching lines
 +
# ---------------------------------------------------------------
 +
function computeMatching {
 +
    # \$1 = solution output                                       
 +
    # \$2 = student output               
 +
    #echo "computeMatching: solution = \$1"
 +
    #echo "computeMatching: student  = \$2"
 +
    noLinesToMatch=\`cat \$1 | wc -l\`
 +
    noGoodLines=\`grep -Fxf \$2 \$1 | wc -l\`
 +
    #echo "noLinesToMatch = \$noLinesToMatch"                   
 +
    #echo "noGoodLines = \$noGoodLines"                                                         
 +
    percentGood=\$(( \$noGoodLines * 100 / \$noLinesToMatch ))
 +
    #echo "percentGood = \$percentGood"
 +
    return \$percentGood
 +
}
 +
 +
# ---------------------------------------------------------------
 +
# runProgram.  Stop if program crashes
 +
# ---------------------------------------------------------------
 +
function run {
 +
    #echo "python \$1 < \$2"
 +
    $python \$1 < \$2  &> user.out 
 +
   
 +
 +
    errCode=\$?
 +
    if [ \$errCode -ne 0 ]; then
 +
        echo "Error! Unfortunately, your program crashed."
 +
        cat user.out
 +
 +
        echo ""
 +
        echo "Your grade will be  \$crashGrade" 
 +
        echo ""
 +
        exit 0
 +
    fi
 +
}
 +
 +
 +
#--- figure out how to filter the outputs ---
 +
keepOnlyNumbers=true
 +
removeMultipleSpaces=true
 +
removeBlankLines=true
 +
 +
#--- accumulate percentage of good output ---
 +
totalPercent=0
 +
noTests=1
 +
 +
# ---------------------------------------------------------
 +
# --- test the student program against solution program ---
 +
# ---------------------------------------------------------
 +
for i in \$noTests  ; do
 +
  echo "==========="
 +
  echo "TEST # \$i "
 +
  echo "==========="
 +
  echo ""
 +
 +
  # ==============================================
 +
  # TEST 1
 +
  # ==============================================
 +
  echo "Your program was tested with these numbers:"
 +
  cat input.dat
 +
  echo ""
 +
 +
  #-----------------------------------------------------------------
 +
  #--- run studentprogram, capture output, keep  original output ---
 +
  #-----------------------------------------------------------------
 +
  run \${prog1}.py input.dat      # output will &> user.out
 +
  cp user.out user.out.org
 +
 +
  #--- remove non numbers and non minus---
 +
  if [ \$keepOnlyNumbers = true ] ; then
 +
      ./extractFloats.py < user.out > dummy.out
 +
      mv dummy.out user.out
 +
  fi
 +
 +
  #--- remove multiple spaces ---
 +
  if [ \$removeMultipleSpaces = true ] ; then
 +
      cat user.out | sed 's/  */ /g' > dummy.out
 +
      mv dummy.out user.out
 +
  fi
 +
 +
  #--- remove blank lines ---
 +
  if [ \$removeBlankLines = true ] ; then
 +
      cat user.out | sed '/^\s*\$/d' > dummy.out
 +
      mv dummy.out user.out
 +
  fi
 +
 +
  #-----------------------------------------------------------------
 +
  #--- generate output for solution program and treat it same as ---
 +
  #--- output of user.                                          ---
 +
  #-----------------------------------------------------------------
 +
  $python \${prog1}sol.py < input.dat    > expectedOutput\${i}
 +
 +
  #--- remove non numbers and non minus---
 +
  if [ \$keepOnlyNumbers = true ] ; then
 +
      ./extractFloats.py < expectedOutput\${i} > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 +
  fi
 +
 +
  #--- remove multiple spaces ---
 +
  if [ \$removeMultipleSpaces = true ] ; then
 +
      cat expectedOutput\${i} | sed 's/  */ /g' > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 +
  fi
 +
 +
  #--- remove blank lines ---
 +
  if [ \$removeBlankLines = true ] ; then
 +
      cat expectedOutput\${i} | sed '/^\s*\$/d' > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 +
  fi
 +
 +
  #--- compute difference.  Count number of lines that are  ---
 +
  #--- different                                            ---
 +
  diff -y -w --ignore-all-space user.out expectedOutput\${i} > diff.out
 +
 
 +
  #--- reject if different ---
 +
  if ((\$? > 0)); then
 +
      echo "Comment :=>>- Your output is incorrect."
 +
 +
      #--- display test file ---
 +
      #echo "Your program tested with:"
 +
      #echo "./\${prog1} \${data}\${i} "
 +
      #echo "--|>"
 +
 +
      echo "Output from your program:"
 +
      cat user.out.org
 +
      echo ""
 +
      echo "Expected output: "
 +
      cat expectedOutput\${i}
 +
      echo ""
  
prog=lab2.py
+
      #--- accumulate percentages obtained at different tests --- 
python=/usr/local/bin/python3.4
+
      computeMatching expectedOutput\${i} user.out
 +
      percent=\$?
 +
      totalPercent=\$(( \$totalPercent + \$percent ))
  
\$python \$prog
+
  else
 +
      # --------------------- REWARD IF CORRECT OUTPUT -----------------
  
EOF
+
      #--- good output ---
 +
      echo "Congrats, the output of your program is correct!"
 +
      cat user.out.org
 +
      totalPercent=\$(( \$totalPercent + 100 ))
 +
  fi
 +
done
 +
 
 +
#--- compute reported grade in moodle ---
 +
averagePercentGood=\$(( \$totalPercent / \$noTests ))
 +
 
 +
scale \$averagePercentGood
 +
grade=\$?
 +
echo ""
 +
echo "Your grade is \${grade}/100"
 +
 
 +
 
 +
EEOOFF
  
 
chmod +x vpl_execution
 
chmod +x vpl_execution
 +
  
 
</source>
 
</source>
Line 375: Line 632:
 
#! /bin/bash
 
#! /bin/bash
 
# D. Thiebaut
 
# D. Thiebaut
 +
# Smith College
 +
# vpl_run.sh script
 +
# runs the student program and compare the output to the solution
 +
# program and displays some information about the lines that do not
 +
# match
 +
# set -x
 +
 +
# --- pick the right python interpreter ---
 +
if [[ `hostname -s` = "marax" ]]; then
 +
    python=/usr/bin/python3.5
 +
else
 +
    python=/usr/local/bin/python3.4
 +
fi
 +
 +
 +
# create helper script that extracts ints and floats from file
 +
cat > extractFloats.py <<EEOOFF
 +
#! /usr/bin/env $python
 +
import re, sys
 +
for line in sys.stdin:
 +
    out =  " ".join( re.findall(r"[-+]?\d*\.\d+|\d+", line ) )
 +
    if len( out ) <= 1: continue
 +
    print( out )
 +
EEOOFF
 +
chmod +x extractFloats.py
  
 +
# create vpl_execution which will be run on the jail server
 +
#
 
cat > vpl_execution <<EEOOFF
 
cat > vpl_execution <<EEOOFF
 
#! /bin/bash
 
#! /bin/bash
#set -x
+
# Moodle scale
+
#100.00 %93.00 %A
 +
#92.99 %90.00 %A-
 +
#89.99 %87.00 %B+
 +
#86.99 %83.00 %B
 +
#82.99 %80.00 %B-
 +
#79.99 %77.00 %C+
 +
#76.99 %73.00 %C
 +
#72.99 %70.00 %C-
 +
#69.99 %67.00 %D+
 +
#66.99 %60.00 %D
 +
#59.99 %0.00 %F
 +
 
 +
 
 
# --- program tested (no extension) ---
 
# --- program tested (no extension) ---
prog=lab2.py
+
prog1=lab2
solutionProg=lab2sol.py
 
  
# --- Python ----
+
# ---------------------------------------------------------------
#python=/usr/local/bin/python3.4
+
# grade given to a program that crashes
python=/usr/bin/python3.3
+
# ---------------------------------------------------------------
 +
crashGrade=65  # equivalent to C
  
 
# =================================================
 
# =================================================
 
# Pick 2 random inputs to test program with
 
# Pick 2 random inputs to test program with
 +
DIFF=\$RANDOM
 +
let "DIFF %= 20"
 +
let "DIFF = DIFF + 2"
 
TEMP1=\$RANDOM
 
TEMP1=\$RANDOM
 
let "TEMP1 %= 30"
 
let "TEMP1 %= 30"
let "TEMP2 = TEMP1 + 6"
+
let "TEMP2 = TEMP1 + DIFF"
 +
 
 +
echo \$TEMP1 > input.dat
 +
echo \$TEMP2 >> input.dat
  
#echo "TEMP1 = \$TEMP1"
+
# ---------------------------------------------------------------
#echo "TEMP2 = \$TEMP2"
+
# scale( percentGood )
 +
# transforms inGrade into outGrade
 +
# ---------------------------------------------------------------
 +
function scale {
 +
    percent=\$1
 +
    inGrade=(  95 90 85 80 75 70 65 60 55 50 0 )
 +
    #            A A- B+ B  B- C+ C  C- D+ D  F
 +
    outGrade=( 100 92 92 92 92 92 92 86 86 86 86 )
 +
    #outGrade=( 100 93 87 83 80 77 73 80 67 60 50 )
 +
 +
    # get length of an array
 +
    arraylength=\${#inGrade[@]}
  
echo \$TEMP1 > input
+
    # loop through all the grades
echo \$TEMP2 >> input
+
    for (( i=0; i<\${arraylength}; i++ ));
 +
    do
 +
        if (( \$percent > \${inGrade[\$i]} )) ; then
 +
    return \${outGrade[\$i]}
 +
        fi
 +
    done
 +
    return 50
 +
}
  
# =================================================
+
#--- test scale ---
# generate user output and exptect output
+
#for j in \`seq 100 -1 0 \` ; do
\$python \$prog < input > userOut
+
#    scale \$j
\$python \$solutionProg < input > expectedOut
+
#    echo "\$j --> \$?"
 +
#done
 +
#exit 0
  
 +
# ---------------------------------------------------------------
 +
# computeMatching( solution, student )
 +
# returns the percentage of matching lines
 +
# ---------------------------------------------------------------
 +
function computeMatching {
 +
    # \$1 = solution output                                       
 +
    # \$2 = student output               
 +
    #echo "computeMatching: solution = \$1"
 +
    #echo "computeMatching: student  = \$2"
 +
    noLinesToMatch=\`cat \$1 | wc -l\`
 +
    noGoodLines=\`grep -Fxf \$2 \$1 | wc -l\`
 +
    #echo "noLinesToMatch = \$noLinesToMatch"                   
 +
    #echo "noGoodLines = \$noGoodLines"                                                         
 +
    percentGood=\$(( \$noGoodLines * 100 / \$noLinesToMatch ))
 +
    #echo "percentGood = \$percentGood"
 +
    return \$percentGood
 +
}
  
# =================================================
+
# ---------------------------------------------------------------
# function that prints the difference between user and expected output
+
# runProgram. Stop if program crashes
incorrectOutput() {
+
# ---------------------------------------------------------------
        echo "Comment :=>>- Your output is incorrect."
+
function run {
        #--- display test file ---
+
    #echo "python \$1 < \$2"
        echo "<|--"
+
    $python \$1 < \$2  &> user.out 
        echo "Your program tested with"
+
   
        echo "temperatures ranging from"
 
        echo "\$TEMP1 to \$TEMP2"
 
        echo "--|>"
 
  
        echo "Comment :=>> ---------------"
+
    errCode=\$?
        echo "Comment :=>>- Your output:"
+
    if [ \$errCode -ne 0 ]; then
        echo "Comment :=>> ---------------"
+
        echo "Error! Unfortunately, your program crashed."
        echo "<|--"
+
        cat user.out
        cat userOut
 
        echo "--|>"
 
        echo ""
 
        echo "Comment :=>> ---------------"
 
        echo "Comment :=>>- Expected output: "
 
        echo "Comment :=>> ---------------"
 
        echo "<|--"
 
        cat expectedOut
 
        echo "--|>"
 
  
 +
        echo ""
 +
        echo "Your grade will be  \$crashGrade" 
 +
        echo ""
 +
        exit 0
 +
    fi
 
}
 
}
 +
 +
 +
#--- figure out how to filter the outputs ---
 +
keepOnlyNumbers=true
 +
removeMultipleSpaces=true
 +
removeBlankLines=true
 +
 +
#--- accumulate percentage of good output ---
 +
totalPercent=0
 +
noTests=1
 +
 +
# ---------------------------------------------------------
 +
# --- test the student program against solution program ---
 +
# ---------------------------------------------------------
 +
for i in \$noTests  ; do
 +
  echo "==========="
 +
  echo "TEST # \$i "
 +
  echo "==========="
 +
  echo ""
 +
 +
  # ==============================================
 +
  # TEST 1
 +
  # ==============================================
 +
  echo "Your program was tested with these numbers:"
 +
  cat input.dat
 +
  echo ""
 +
 +
  #-----------------------------------------------------------------
 +
  #--- run studentprogram, capture output, keep  original output ---
 +
  #-----------------------------------------------------------------
 +
  run \${prog1}.py input.dat      # output will &> user.out
 +
  cp user.out user.out.org
  
# function that tells user of program crash or infinite loop, and what the test was.
+
  #--- remove non numbers and non minus---
timeoutOutput() {
+
  if [ \$keepOnlyNumbers = true ] ; then
    if [ "\$1" ]; then   # if there's a parameter
+
      ./extractFloats.py < user.out > dummy.out
        i=\$1
+
      mv dummy.out user.out
        echo "Comment :=>>- Your program has timed out or crashed."
+
  fi
  
        #--- display test file ---
+
  #--- remove multiple spaces ---  
        echo "Comment :=>>- Your program tested with:"
+
  if [ \$removeMultipleSpaces = true ] ; then
        echo "<|--"
+
      cat user.out | sed 's/  */ /g' > dummy.out
        cat data\${i}.txt
+
      mv dummy.out user.out
        echo "--|>"
+
  fi
    fi
+
 
}
+
  #--- remove blank lines ---
 +
  if [ \$removeBlankLines = true ] ; then
 +
      cat user.out | sed '/^\s*\$/d' > dummy.out
 +
      mv dummy.out user.out
 +
  fi
  
# function that removes non-digits, extra spaces, and extra blank lines from text file.
+
  #-----------------------------------------------------------------
cleanup () {
+
  #--- generate output for solution program and treat it same as ---
    if [ "\$1" ]; then  # if there's a parameter
+
  #--- output of user.                                           ---
       
+
  #-----------------------------------------------------------------
        #--- remove non numbers and non minus---
+
  $python \${prog1}sol.py < input.dat    > expectedOutput\${i}
        cat \$1 | sed 's/[^0-9*.0-9\ -]*//g' > dummy.out
 
        mv dummy.out \$1
 
 
        #--- remove multiple spaces ---  
 
        cat \$1 | sed 's/  */ /g' > dummy.out
 
        mv dummy.out \$1
 
  
        #--- remove blank lines ---
+
  #--- remove non numbers and non minus---
        cat \$1 | sed '/^\s*\$/d' > dummy.out
+
  if [ \$keepOnlyNumbers = true ] ; then
        mv dummy.out \$1
+
      ./extractFloats.py < expectedOutput\${i} > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 
   fi
 
   fi
}
 
  
cleanup userOut
+
  #--- remove multiple spaces ---
cleanup expectedOut
+
  if [ \$removeMultipleSpaces = true ] ; then
 +
      cat expectedOutput\${i} | sed 's/  */ /g' > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 +
  fi
  
#echo "userOut = "
+
  #--- remove blank lines ---
#cat userOut
+
  if [ \$removeBlankLines = true ] ; then
 +
      cat expectedOutput\${i} | sed '/^\s*\$/d' > dummy.out
 +
      mv dummy.out expectedOutput\${i}
 +
  fi
  
#echo "expectedOut = "
+
  #--- compute difference.  Count number of lines that are  ---
#cat expectedOut
+
  #--- different                                            ---
 +
  diff -y -w --ignore-all-space user.out expectedOutput\${i} > diff.out
 +
 
 +
  #--- reject if different ---
 +
  if ((\$? > 0)); then
 +
      echo "Comment :=>>- Your output is incorrect."
  
#--- compute difference ---  
+
      #--- display test file ---
diff -y -w --ignore-all-space userOut expectedOut > diff.out
+
      #echo "Your program tested with:"
 +
      #echo "./\${prog1} \${data}\${i} "
 +
      #echo "--|>"
  
#--- reject if different ---
+
       echo "Output from your program:"
if ((\$? > 0)); then
+
       cat user.out.org
      incorrectOutput
+
       echo ""
      grade=70
+
       echo "Expected output: "
      # --------------------- REWARD IF CORRECT OUTPUT -----------------
+
       cat expectedOutput\${i}
else
 
      #--- good output ---
 
       echo "Comment :=>>- Congrats, your output is correct."
 
       echo "Comment :=>> --------------------------------."
 
       echo "<|--"                                                                          
 
       echo "Your program tested with"                                                      
 
       echo "temperatures ranging from"                                                     
 
      echo "\$TEMP1 to \$TEMP2"                                                             
 
 
       echo ""
 
       echo ""
      cat userOut
 
      echo "--|>"
 
      grade=100
 
fi
 
  
# =================================================
+
      #--- accumulate percentages obtained at different tests --- 
# Report grade
+
      computeMatching expectedOutput\${i} user.out
if (( grade > 100 )); then
+
      percent=\$?
  grade=100
+
      totalPercent=\$(( \$totalPercent + \$percent ))
fi
 
echo "Grade :=>> \$grade"
 
  
 +
  else
 +
      # --------------------- REWARD IF CORRECT OUTPUT -----------------
  
exit
+
      #--- good output ---
 +
      echo "Congrats, the output of your program is correct!"
 +
      cat user.out.org
 +
      totalPercent=\$(( \$totalPercent + 100 ))
 +
  fi
 +
done
  
 +
#--- compute reported grade in moodle ---
 +
averagePercentGood=\$(( \$totalPercent / \$noTests ))
  
 +
scale \$averagePercentGood
 +
grade=\$?
 +
echo ""
 +
#echo "Your grade is \${grade}/100"
 +
echo "Grade :=>> \$grade"
  
 +
EEOOFF
  
EEOOFF
 
 
 
chmod +x vpl_execution
 
chmod +x vpl_execution
  

Latest revision as of 14:45, 9 February 2018

D. Thiebaut (talk) 11:36, 4 February 2018 (EST)



This lab deals with loops in python. You will be assigned a new partner at the beginning of the lab, and you will work in pair on the different challenges. Don't hesitate to share insights and help your neighbors during the lab. This is true of all labs. Homework assignments have to be done as an individual pair, but for the labs, you are free to talk to other pairs in the classroom. Feel free to take a short break from time to time. Water is always good. A walk in the cold air of the terrace, off Room 340, is also always good!


Update regarding Snow Day on 2/7/18: if you don't find a partner today 2/7 to work on this lab, then simply work on it on your own. Today is an exception to the rule.


Introductory Video for Wednesday's Lab Groups


For the Wednesday group, here's a short video introducing you to the lab.



Definite for-loops


Loops that use the range() function


  • For this section of the lab, open IDLE and create the different program sections below in the Python shell window.


>>> for n in range( 4 ):
	print( n )

>>> for n in range( 1, 4 ):
	print( n )

>>> for n in range( -1, 4 ):
	print( n )

>>> for n in range( 5, 10 ):
	print( n )

>>> for n in range( 0, 10, 2 ):
	print( n )

>>> for n in range( 1, 10, 2 ):
	print( n )

>>> for n in range( 10, 0, -2 ):
	print( n )


  • Do you understand how the range() function works?
    • If you give it only 1 number, it will generate a series of numbers starting at 0 and going up to that number, but not including it, in steps of 1.
    • If you give it 2 numbers, it will use the first one as the start, and the second at the stop, and will generate all the integers between the two, in steps of 1. The stop number is never used.
    • IF you give it 3 numbers, the 3rd one is the step. It can be positive or negative.


Challenge #1: Range-Controlled Loops

QuestionMark1.jpg


Now, your turn:

List of even numbers
write a loop that prints all the even numbers between 4 and 20; 4, and 20 included.
List of odd numbers
write a loop that prints all the odd numbers between -3 and 19, -3, and 19 included.
List odd numbers in reverse order
write a loop that prints all the odd numbers starting at 9 and going down to 1, included.


Definite For-Loops that use Lists


  • We can use explicit lists to generate similar outputs. For example, the output of the first two examples in the previous section could have been generated by the following loops:


>>>for n in [0, 1, 2, 3]:
            print( n )

>>>for n in [1, 2, 3]:
            print( n )



Challenge #2: List-Controlled Loops

QuestionMark2.jpg


Solve the 3 problems of Challenge 1 above, using lists instead of the range() function.








For-Loops ready for modification


  • Create the following python program (we're not working in interactive mode at this point). Don't hesitate to copy and paste to go faster!
# lab2seq.py
# 
 
# print the contents of the farm
for animal in  [ "dog", "cat", "horse" ]:
     print( animal )


  • Add a pig to your list of animals, and make sure it gets listed by the program.


Modification #1
Change the for-loop of your program so that it reads:


       counter = 0
       for animal in  [ "dog", "cat", "horse", "pig" ]:
           print( counter, animal )
           counter = counter + 1


  • Run the program. Observe its output. From this observation, modify the program so that its output now reads something like this (user input is in underlined):
       Your farm contains
       animal # 1 : a sheep
       animal # 2 : a dog
       animal # 3 : a bear
       animal # 4 : a mouse

Old MacDonald's Farm

Old MacDonald's farm is a song most American kids learn at one point in their life. I certainly never heard it when I grew up in France, but I think most of you will be familiar with it.

If you don't know it, the first 3 minutes of the YouTube video above will get you acquainted with it. :-)

The goal of this problem is for you to add a section to the program below so that it prints parts of the lyrics of the famous song using a for-loop.

Here's the beginning program which you have to modify:

     
# display the names of the animals
for animal in  [ "horse", "pig", "dog", "cat" ]:
      print( animal )


Challenge #3: Output Song Lyrics

QuestionMark3.jpg


  • Modify the program above so that it uses the loop, and outputs the lyrics of the song:
    Old MacDonald had a farm, E-I-E-I-O
    And on his farm he had a horse E-I-E-I-O
    Here a horse, there a horse, everywhere a horse !
    
    Old MacDonald had a farm, E-I-E-I-O
    And on his farm he had a pig E-I-E-I-O
    Here a pig, there a pig, everywhere a pig !
    
    Old MacDonald had a farm, E-I-E-I-O
    And on his farm he had a dog E-I-E-I-O
    Here a dog, there a dog, everywhere a dog !
    
    Old MacDonald had a farm, E-I-E-I-O
    And on his farm he had a cat E-I-E-I-O
    Here a cat, there a cat, everywhere a cat !

(don't worry if you get extra spaces in your output)

The input() Function


Try the following statements in the console window. Again, some of these might generate errors. It is important for you to understand why these errors occur.


>>> firstName = input( "Enter your first name: " )
>>> firstName

>>> lastName = input( "Enter your last name: " )
>>> lastName

>>> print( firstName, lastName )

>>> x = input( "enter a number: " )
>>> x

>>> x + 5

>>> x = input( "Enter a number: " )
>>> x

>>> y = eval( x )
>>> y
>>> y + 5

>>> z = eval(  "314.56789" )
>>> z



Challenge #4: Gathering student information

QuestionMark4.jpg


Write a python program that asks the user for her name, box number, 99-Id number, and phone number, and that outputs it back on the screen nicely formatted.

Example (the information entered by the user is in boldface):

your first name? Allie
your last name? Gator
your box number? 1234
your phone number? 413 456 7890
your Smith Id? 990123456


Name:   Allie Gator (990123456)
box #:  1234
phone:  413 456 7890



Challenge #5: Printing the student information it in a (half) box

QuestionMark5.jpg


  • Same idea as with the previous challenge but after inputing the information from the user, the program outputs it in a half-box!
Example (user input in in boldface):


your first name?   Mickey
your last name?    Mouse
your box number?   1234
your phone number? 413 456 7890
your Id number?    990111222

+---------------------------------------
| Name:   Mickey Mouse ( 990111222 )
| Box:     1234
| Phone:  413 456 7890 
+---------------------------------------


  • The length of the bars is unimportant.



Challenge #6: Temperature Converter

QuestionMark8.jpg


  • Write a program that prompts the user for a temperature expressed in Fahrenheit, and outputs the equivalent temperature in Celsius.
  • The equation for temperature conversion is: Celsius = ( Fahrenheit -32 ) * 5 / 9
  • Here is an example of the way your program will work (the user input is in boldface):
Please enter temperature in Fahrenheit: 12
 
12 degrees Fahrenheit is -11.11111111111111 Celsius.

(We will not worry about the extra length of the Celsius number for this lab.)



Moodle Submission


  • Write a program called lab2.py that prompts the user for 2 integer numbers representing a low and a high temperature, expressed in Farhenheit, and outputs all the temperatures in between, with their equivalent Celsius.
  • Below is an example of interaction between the user and her program:


Enter low temperature: 20
Enter high temperature: 40

Fahrenheit Celsius
20         -6.66666666667
21         -6.11111111111
22         -5.55555555556
23         -5.0
24         -4.44444444444
25         -3.88888888889
26         -3.33333333333
27         -2.77777777778
28         -2.22222222222
29         -1.66666666667
30         -1.11111111111
31         -0.555555555556
32         0.0
33         0.555555555556
34         1.11111111111
35         1.66666666667
36         2.22222222222
37         2.77777777778
38         3.33333333333
39         3.88888888889
40         4.44444444444


  • Note 1: Very important: make sure there's a blank line between the part of the program that gets the input from the user, and the actual output of the program (the two columns of number). This blank line will help the automatic grader to better recognize the output of your program
  • Note 2: The space between the temperatures printed on the same line can be created by a simple string of 7 spaces.
  • Submit your program to Moodle, in the Lab 2 section.



<showafterdate after="20180210 00:00" before="20180601 00:00">

Solution Programs


# lab2.py
# D. Thiebaut
# The program prompts the user for 2 integer temperatures
# and outputs a table of all temperatures ranging between the
# two values, last value included.
temp1 = eval( input( "Enter low temperature: " ) )
temp2 = eval( input( "Enter high temperature: " ) )
print()
print( "Fahrenheit Celsius" )
for temp in range( temp1, temp2+1 ):
     print( temp, "       ", (temp-32)*5/9 )


</showafterdate>


...