Лучшие студенты
Часть раздела Логика и управление потоком путешествия по Ruby на Coddy — урок 53 из 56.
Последний метод: найти всех студентов, чей средний балл выше определенного порога.
Это ваш конвейер данных на полную мощность: итерируйте, фильтруйте по производному значению, возвращайте имена.
Задание
СреднеДобавьте метод top_students(threshold), который возвращает массив имен, чей средний балл выше threshold. Используйте average_grade внутри метода, не выполняйте вычисления повторно. Пропускайте студентов без оценок (их средний балл равен 0 и не пройдет ни один положительный порог).
Имена должны появляться в порядке добавления; если никто не подходит под критерии, верните [].
Замените тестовый блок на:
add_student("Alice", 20, ["Math"])
add_student("Bob", 22, ["Biology"])
add_student("Cara", 19, ["Physics"])
add_grade("Alice", 90)
add_grade("Alice", 85)
add_grade("Bob", 70)
add_grade("Cara", 60)
puts top_students(80).inspect
puts top_students(50).inspect
puts top_students(100).inspectОжидаемый вывод заканчивается на:
["Alice"]
["Alice", "Bob", "Cara"]
[]Шпаргалка
Используйте top_students(threshold) для фильтрации студентов по среднему баллу, повторно используя average_grade:
def top_students(threshold)
$students
.select { |s| average_grade(s[:name]) > threshold }
.map { |s| s[:name] }
endСтуденты без оценок возвращают 0 из average_grade и естественным образом исключаются любым положительным пороговым значением.
Попробуйте сами
$student_records = {}
def add_student(name, age, courses)
if $student_records.key?(name)
puts "Student '#{name}' already exists."
return
end
$student_records[name] = { age: age, grades: [], courses: courses }
puts "Student '#{name}' added."
end
def add_grade(name, grade)
unless $student_records.key?(name)
puts "Student '#{name}' not found."
return
end
$student_records[name][:grades] << grade
puts "Grade #{grade} added for '#{name}'."
end
def average_grade(name)
unless $student_records.key?(name)
puts "Student '#{name}' not found."
return nil
end
grades = $student_records[name][:grades]
return 0 if grades.empty?
grades.sum.to_f / grades.length
end
def list_by_course(course)
$student_records.select { |_, info| info[:courses].include?(course) }.keys
end
# TODO: def top_students(threshold), имена тех, чей average_grade > threshold
add_student("Alice", 20, ["Math"])
add_student("Bob", 22, ["Biology"])
add_student("Cara", 19, ["Physics"])
add_grade("Alice", 90)
add_grade("Alice", 85)
add_grade("Bob", 70)
add_grade("Cara", 60)
puts top_students(80).inspect
puts top_students(50).inspect
puts top_students(100).inspect
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Обзор методов строкИнтерполяция строкИтерация по строкамSplit и JoinИтоги — String Weaver4Блоки, Proc и лямбды
Что такое блок?do..end против фигурных скобокКлючевое слово yieldПараметры блокаProc и лямбдыИтоги: пользовательский итератор7Хеши. Часть 2
Hash.new со значениями по умолчаниюИтерация по хешамВложенные хешиСлияние и преобразованиеИтоги — счетчик частоты10Проект — Учёт студентов
Обзор проектаДобавить студента2Диапазоны
Что такое диапазон?Методы диапазоновДиапазоны в Case / WhenПовторение — практика по диапазонам5Мощь Enumerable
Select и RejectЦепочки MapReduce / Injectcount, all?, any?, none?group_by и partitionsort_by, min_by, max_byИтоги — Data Pipeline8Продвинутые условные конструкции
Case с классами и RegexМножественные значения в whenТернарный операторОднострочные if / unlessПовторение: Классификатор оценок