Skip to content

Instantly share code, notes, and snippets.

@faizaanshamsi
Last active December 30, 2015 01:49
Show Gist options
  • Save faizaanshamsi/7758132 to your computer and use it in GitHub Desktop.
Save faizaanshamsi/7758132 to your computer and use it in GitHub Desktop.
A OO program that reads in a csv of students and grades, and allows a report to be generated for student and classroom grade averages.
# Grade, contains the name of the assignment and the score
class AssignmentGrade
attr_accessor :numeric_grade, :assignment
def initialize(assignment, grade)
@assignment = assignment
@numeric_grade = grade.to_f
end
end
# Letter grade
class FinalGrade
attr_reader :letter
def initialize(letter)
@letter = letter
end
end
# Reads in grade data and instantiates assignment_grades
class GradeReader
def initialize(file_name)
@file_name = file_name
end
def read_data
grade_data = []
CSV.foreach(@file_name, headers: true) do |row|
grade = row.to_hash.select { |k, v| k != 'name' }
pupil = []
grade.each do |k, v|
pupil << AssignmentGrade.new(k, v)
end
grade_data << pupil
end
grade_data
end
end
# Classroom level data and methods
class GradeSummary
attr_accessor :average, :min_score, :max_score, :standard_deviation
def initialize(students)
@students = students
end
def total
@students.map(&:average).reduce(:+)
end
def class_average
@class_average ||= (total / @students.length)
end
def min_score
@min_score = @students.map(&:average).sort.first.round(2)
end
def max_score
@min_score = @students.map(&:average).sort.last.round(2)
end
def variance
@variance ||= @students.map(&:average).inject(0.0) { |sum, average| (sum + (average - class_average)**2) } / (@students.length)
end
def standard_deviation
@standard_deviation = Math.sqrt(variance).round(2)
end
end
name assignment_1 assignment_2 assignment_3 assignment_4 assignment_5
Johnny Smith 100 80 75 78 60
Sally Strong 100 100 90 95 85
Jimmy Fallon 95 97 85 40 85
Chris Botsworth 98 86 85 82 80
Brian Boyd 50 60 65 70 75
def prompt(question)
puts "#{question}"
gets.chomp
end
def grade_assign(students, grade_data)
students.each_with_index do |student, i|
student.grades = []
grade_data[i].each do |grades|
student.grades << grades
end
end
end
def teacher_load(students)
students.each do |pupil|
print "#{pupil.name}'s grades:"
puts "#{pupil.grades.map(&:numeric_grade).join(", ")}"
end
end
def teacher_report_out(students)
students.each do |pupil|
puts "#{pupil.name}'s average: #{pupil.average}"
end
end
def teacher_letter(students)
students.each do |pupil|
puts "#{pupil.name}'s letter grade: #{pupil.final_grade.letter}"
end
end
def name_switch(students)
students.each do |pupil|
pupil.name = pupil.name.split(' ').reverse.join(', ')
end
end
def student_sort(students)
students.sort_by(&:name)
end
def teacher_write(students)
write_file = prompt('What file do you want to write to?')
File.open(write_file, 'w') do |file|
students.each do |pupil|
file.write("#{pupil.name}: Average: #{pupil.average}")
file.write(" Grade: #{pupil.final_grade.letter}\n")
end
end
end
def classroom_report(classroom)
puts "The class average was: #{classroom.class_average}"
puts "The lowest average was: #{classroom.min_score}"
puts "The highest average was: #{classroom.max_score}"
puts "The standard deviation was: #{classroom.standard_deviation}"
end
require_relative 'grade_reader.rb'
require_relative 'student.rb'
require_relative 'assingment_grade.rb'
require_relative 'final_grade.rb'
require_relative 'grade_summary.rb'
require_relative 'student_reader.rb'
require_relative 'methods.rb'
require 'csv'
file_name = prompt('What file do you want to read from?')
grade_data = GradeReader.new(file_name).read_data
students = StudentReader.new(file_name).read_data
grade_assign(students, grade_data)
classroom = GradeSummary.new(students)
teacher_load(students)
teacher_report_out(students)
teacher_letter(students)
classroom_report(classroom)
name_switch(students)
student_sort(students)
teacher_write(students)
# Student Class, student requires name, all else optional
class Student
attr_accessor :name, :average, :final_grade, :grades
def initialize(name)
@name = name
end
def total
@grades.map(&:numeric_grade).reduce(:+)
end
def average
@average ||= (total / @grades.length)
end
def final_grade
@final_grade = FinalGrade.new('F') if average < 60
@final_grade = FinalGrade.new('D') if average >= 60 && average < 70
@final_grade = FinalGrade.new('C') if average >= 70 && average < 80
@final_grade = FinalGrade.new('B') if average >= 80 && average < 90
@final_grade = FinalGrade.new('A') if average >= 90
@final_grade
end
end
# Reads in data and instantiates students with name
class StudentReader
def initialize(file_name)
@file_name = file_name
end
def read_data
students = []
CSV.foreach(@file_name, headers: true) do |row|
grad = Student.new(row.to_hash.select { |k, v| k == 'name' }.values.join)
students << grad
end
students
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment