Instructions
Objective
Write a program to create scores table in html page using Ruby to read csv file.
Requirements and Specifications
Write a simple Ruby program to create an HTML scores file for posting class scores.
The program should read a comma separated text file (exported form a spreadsheet) containing class scores and create an HTML file for displaying the scores. The program should read command line parameters to:
- determine if just the ID's or the Names and IDs should be displayed.
- command line qualifier: -ids or -names input file name.
- The program should have a main that calls various procedures. You may use global variables.
Additionally, you can use I/O redirection to capture the HTML output.
An example execution might be:
% ruby proj6.rb -ids scores1.csv > scores.html
% ruby proj6.rb -names scores1.csv > names.html
The source file will always be the same format. This includes:
,<class title>
,Assignments, <assignment count>
,Tests,<tests count>
,Assignments weight, <assignments weight>
,Tests Weight, <tests weight>
<titles>
,Possible,<... possible scores ...>
<id>, <name>, <... scores ...>
<id>, <name>, <... scores ...>
<id>, <name>, <... scores ...>
Screenshots of output



Source Code
require 'csv'
def startHTML
puts "<HTML><HEAD><STYLE>"
puts "TABLE, TH, TD { border: 1px solid black; }"
puts "</STYLE></HEAD><BODY BGCOLOR='LightGray'>"
end
def endHTML
puts "</BODY></HTML>"
end
def printTitle (title)
puts "<P><BIG><B> #{title} </BIG>"
puts "<BR> As of: Wednesday, November 2, 2022 </B></P>"
end
def startTable
puts "<TABLE>"
end
def endTable
puts "</TABLE>"
end
def printCell (cell)
puts "<TD> <CENTER> #{cell} </CENTER> </TD>"
end
def startRow
puts "<TR>"
end
def endRow
puts "</TR>"
end
# convert a row (array) of text values to an array of integer values
def getRowValues (row)
arr = []
for e in row do
arr.push(e.to_i)
end
return arr
end
def printTableHeader (titles, idsOrNames)
startRow
if idsOrNames
printCell (titles[0])
else
printCell (titles[1])
end
for i in 2..titles.length-1 do
printCell (titles[i])
end
printCell ("Ave")
endRow
end
def printAverages (averages)
startRow
printCell("<B> Average </B>")
for avg in averages do
printCell ('<B> %.1f </B>' % avg)
end
printCell(" ")
endRow
end
def printPossible (possible)
startRow
printCell("<B>Possible </B>")
for p in possible do
printCell ('<B> %d </B>' % p)
end
printCell(" ")
endRow
end
def csvToHTML (csv, idsOrNames)
title = csv[0][1]
nAssignments = csv[1][2].to_i
nTests = csv[2][2].to_i
aWeight = csv[3][2].to_i
tWeight = csv[4][2].to_i
possible = getRowValues(csv[6][2, csv[6].length])
titles = csv[5]
data = csv[7, csv.length-1]
# remove names or ids depending on selected column
m = data.transpose
if idsOrNames
m.delete_at(1)
m[0] = getRowValues(m[0]) # convert ids to integers
else
m.delete_at(0)
end
data = m.transpose
data = data.sort_by { |d| d.first } # sort by first column
startHTML
printTitle(title)
startTable
printTableHeader(titles, idsOrNames)
nVals = nAssignments + nTests # total number of values
averages = Array.new(nVals, 0.0)
nValid = Array.new(nVals, 0.0)
for i in 0..data.length-1 do
startRow
if idsOrNames
printCell('%04d' % data[i][0])
else
printCell(data[i][0])
end
# print and sum assignments
aSum = 0.0
for j in 0..nAssignments-1 do
cell = data[i][j + 1]
printCell (cell)
if not cell.nil?
aSum += 0.4 * cell.to_f / possible[j].to_f
averages[j] += cell.to_f
nValid[j] += 1.0
end
end
# print and sum tests
tSum = 0.0
for j in 0..nTests-1 do
cell = data[i][j + nAssignments + 1]
printCell (cell)
if not cell.nil?
tSum += 0.6 * cell.to_f / possible[j + nAssignments].to_f
averages[j + nAssignments] += cell.to_f
nValid[j + nAssignments] += 1.0
end
end
avg = 100 * ( aSum / nAssignments.to_f + tSum / nTests.to_f )
if avg == 100.0
printCell (avg)
else
printCell ('%.2f' % avg) # print average number with 2 decimal digits
end
endRow
end
# get total averages
for i in 0..averages.length-1 do
averages[i] = averages[i] / nValid[i]
end
printAverages (averages)
printPossible (possible)
endTable
puts "<P> </P><P><SMALL><B><U>Grading Formula:</U></B>"
puts "<BR>  Grading Formula: [ ( (homework scores/possible) * 0.4) + ( (test scores/possible) * 0.6) ]"
puts "</SMALL></P>"
endHTML
end
# main
if __FILE__ == $PROGRAM_NAME
# check that there are 2 arguments
if ARGV.length != 2
puts "Invalid number of arguments"
exit
end
# select ids or names
idsOrNames = case ARGV[0]
when "-ids"
true
when "-names"
false
else
puts "Invalid argument '#{ARGV[0]}', expected -ids or -names"
exit
end
# verify that file exists
if not File.file? ARGV[1]
puts "File '#{ARGV[1]}' not found"
exit
end
# load the csv
csv = CSV.read(ARGV[1])
# generate the HTML
csvToHTML(csv, idsOrNames)
end