【问题标题】:Class-Array Interaction Ruby类数组交互 Ruby
【发布时间】:2023-04-11 09:20:02
【问题描述】:

我正在尝试设置一个程序来帮助我为班级中的学生评分。我已经将它设置为创建一个学生类,然后通过数组从文件中读取(我在 Ruby 中不太熟悉的东西)。我的编程经验是在 java 中,所以如果有可以解释的错误,我深表歉意。提前感谢您的帮助。

class Student
  def initialize(str_LastName, str_FirstName, arr_Score)
    @str_LastName = str_LastName
    @str_FirstName = str_FirstName
    @arr_Score = arr_Score
    str_Grade = ""
    int_OutOf = 415
  end

  def get_LastName
    str_LastName
  end

  def get_FirstName
    str_FirstName
  end

  def get_Grade
    str_Grade
  end

  def set_TotalScore()
    sum = 0
    arr_Score.each do |item|
      sum += item
    end
    arr_Score[12] = sum
  end

  def set_Grade
    if arr_Score[12]/int_OutOf >= 0.9
      str_Grade = "A"
    elsif arr_Score[12]/int_OutOf >= 0.8
      str_Grade = "B"
    elsif arr_Score[12]/int_OutOf >= 0.7
      str_Grade = "C"
    elsif arr_Score[12]/int_OutOf >= 0.6
      str_Grade = "D"
    else
      str_Grade = "F"
    end
  end
end

def main
  file_name = "Grades"
  arr_students = Array.new(31)
  arr_scores = Array.new(12)
  int_i = 0
  file_io = open(file_name).readlines.each do |line|
    array = line.split(",").map(&:strip)
    student = Student.new(array[0],array[1],array[2..-2]) #the final element in the array is for the final score
    arr_students[int_i] = student
    puts "read #{arr_students[int_i]}"
  end
  file_name = "Graded"
  file_io = open(file_name,"a+")
  arr_students.each do |student|
    set_TotalScore
    set_Grade
    file.io_write(student)
    puts "write #{student}"
  end
end

main if __FILE__==$0

【问题讨论】:

  • 忘了提一下,Grades 文本文件的格式是每行 1 个学生,分数后面跟着名字,我将最后的数组槽保留为 0,以便我可以将其设置为最终得分。
  • 问题是什么?

标签: arrays ruby class


【解决方案1】:

这是我的尝试。我试图在大体上忠实于您的代码的初衷,同时引入了更多的 Rubyish 做事方式。

class Student
  def initialize(firstname, lastname, *scores)
    @firstname, @lastname, @scores = firstname, lastname, scores
  end

  def total_score
    @scores.map(&:to_i).inject(:+)
  end

  def grade
    raise "TOO HIGH!" if total_score > MAX_SCORE

    case total_score / MAX_SCORE
    when 0.9..1.0;  "A"
    when 0.8...0.9; "B"
    when 0.7...0.8; "C"
    when 0.6...0.7; "D"
    else            "F"
    end
  end

  def to_s
    "#{@lastname}, #{@firstname}: #{total_score}, #{grade}"
  end
end

MAX_SCORE = 415.0
DATA.each_line do |line|
  arr = line.split(",").map(&:strip)
  student = Student.new *arr
  puts student
end

__END__
Herb,Goldberg,22,99,44,22,88,88
Mark,Sullivan,77,88,88,44,33

您可以像这样读写文件(未测试):

outfile = File.open("Graded", "a+")
File.open("Grades").each_line do |line|
  ...
  outfile.puts student
end
outfile.close

【讨论】:

    【解决方案2】:

    我们无法轻易复制您的代码,因为您打开了一个名为“Grades”的文件,而我们不知道也不知道它的内容。

    您还应该添加一些代码来首先检查您的文件是否存在,然后再继续 - 现在您的脚本以 Errno::ENOENT 退出。

    我还建议将 main 中的逻辑放入您的班级 - 让您的班级处理所有事情。

    在部分:

    if __FILE__ == $PROGRAM_NAME
    
    end
    

    然后您可以通过简单的调用来简单地初始化您的类,例如:

    Foobar.new(ARGV)
    

    您描述了“成绩”文件,但我不明白您写的内容 - 如果您可以链接到示例,例如通过粘贴或要点,然后链接它会更容易;并且还要说是什么部分不起作用,这也不清楚。

    样式问题是次要的,我认为您的代码还可以 - 这里的其他海报没有。

    【讨论】:

    • 评分系统的格式类似于以下 Smith, John, 1, 2, 3, 4, 5, 6...(代表作业分数的数字)
    【解决方案3】:

    您应该通过 codecademy 来了解您的 ruby​​ 语法。

    要访问您初始化的实例变量(@str_LastName(应该是@last_name)等),您需要使用“attr_reader :str_LastName”,最好在类的顶部。这将确定你的 getter(setter 是 attr_writer,两者都是 attr_accessor)。

    你也可以像这样对数组求和:[1,4,6,7].inject(:+)。

    Java 不允许 case 语句吗?您应该在 set_grade 中使用它。您也不需要初始化 str_Grade。在设置等级中,您可以执行@grade_letter ||= "A",然后调用 set_grade 将在每次调用时返回该值。

    我没有看透你的主要方法。虽然很丑。 Ruby 方法的长度可能不应超过 5 行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-27
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多