Кто-нибудь знает, как упростить бесконечные, если elif else заявления в этом алгоритме? - PullRequest
0 голосов
/ 17 января 2020

Я пытаюсь написать конвертер оценок, который меняет количественные оценки, такие как 88%, на буквенную оценку (то есть B +), но я чувствую, что есть более простой способ, чем использование бесконечных операторов elif. В идеале я хотел бы иметь одно условие, которое определяет букву на основе диапазона, и другое условие, которое определяет, назначать ли + или - на основе отдельного диапазона. Вот текущий код:

def convert_score_to_grade_w_plus_and_minus(score):
if score in range(98, 101):
    return 'A+'
elif score in range(93, 98):
     return 'A'
elif score in range(90, 93):
    return 'A-'
elif score in range(88, 90):
    return 'B+'
elif score in range(83, 88):
    return 'B'
elif score in range(80, 83):
    return 'B-'
elif score in range(78, 80):
    return 'C+'
elif score in range(73, 78):
    return 'C'
elif score in range(70, 73):
    return 'C-'
elif score in range(68, 70):
    return 'D+'
elif score in range(63, 68):
    return 'D'
elif score in range(60, 63):
    return 'D-'
elif score in range(60):
    return 'F'
else: 
    return 'INVALID SCORE'

Ответы [ 5 ]

5 голосов
/ 17 января 2020

Вы можете сохранить свои оценки в списке кортежей, а затем вернуть результат, для которого оценка соответствует, используя понимание списка.

scores = [('A+', 99, 101), ('A', 93, 98), ('A-', 90, 93)]

score = 91

[result[0] for result in scores if score in range(result[1], result[2])][0]
#'A-'

# without range

[result[0] for result in scores if score > result[1] and score < result[2]][0]

Вы можете расширить список оценок, включив в них столько скобок, сколько вы хотеть.

Немного убрал вышесказанное;

def get_grade(score):
    scores = [('A+', 99, 101), ('A', 93, 98), ('A-', 90, 93)]
    result = [grade for grade, low, high in scores if score > low and score < high]
    return result[0] if result else 'Invalid Score'
2 голосов
/ 17 января 2020

Есть несколько способов сделать это, и ответ L Python является отличным подходом для общего случая, как преобразовать кучу операторов if в структуру данных.

Но обратите внимание что вы также можете изменить исходную реализацию! В вашем конкретном c случае, когда рассматриваемые вами диапазоны хорошо упорядочены и эксклюзивны, вы можете альтернативно думать о том, что оценки представляют не диапазоны, а отсечки. Например:

def convert_score_to_grade_w_plus_and_minus(score):
  if score >= 98:
      return 'A+'
  elif score >= 93:
       return 'A'
  elif score >= 90:
      return 'A-'
  elif score >= 88:
      return 'B+'
  elif score >= 83:
      return 'B'
  elif score >= 80:
      return 'B-'
  elif score >= 78:
      return 'C+'
  elif score >= 73:
      return 'C'
  elif score >= 70:
      return 'C-'
  elif score >= 68:
      return 'D+'
  elif score >= 63:
      return 'D'
  elif score >= 60:
      return 'D-'
  elif score >= 0:
      return 'F'
  else: 
      return 'INVALID SCORE'

Может быть упрощено до:

def convert_score_to_grade_w_plus_and_minus(score):
  grade_cutoffs = (('A+', 98), ('A', 93), ..., ('D', 63), ('D-', 60), ('F', 0))
  for grade, cutoff in grade_cutoffs:
    if score >= cutoff:
      return grade

  return 'INVALID SCORE'
1 голос
/ 17 января 2020
 def convert_score(score):
  if score<=60:
    return 'F'
  first_digit = int(score/10)
  if score%10>=8:
    backgrade = '+'
  elif score%10>=3 and score%10<8:
    backgrade = ''
  else:
    backgrade = '-'
  frontgrade = chr(74-(first_digit))

  return frontgrade + backgrade

аналогично Hamms, но вместо отсечений, рассматривая его как первую и последнюю цифры, влияющие на первый и последний знаки классов соответственно.

0 голосов
/ 17 января 2020
import math
def convert_score_to_grade_w_plus_and_minus(score):
    if score > 100:
        return 'INVALID SCORE'
    score = 99 if score > 99 else score
    letter = chr(9 - math.floor(score / 10) + 65) if score >= 60 else 'F'
    return letter + ('+' if score % 10 >= 8 and not letter == 'F' else ('' if score % 10 >= 3 or letter == 'F' else '-'))

Объяснение:

  1. Оценка клипа выше 99 при 99 (если допустимо).
  2. Найдите письмо с оценкой, зная, что A является 65 в ASCII.
  3. Добавить +, ничего или - в зависимости от остатка score % 10. Если это F, ничего не добавляйте.
0 голосов
/ 17 января 2020

Одна «проблема» с некоторыми другими ответами состоит в том, что она пройдет l oop через range объект, что приведет к большему количеству вычислений, чем необходимо. Вы можете использовать распаковку кортежей и перебирать список. Есть также удобная функция, где вы можете делать такие вещи, как 0 < x < 1, чтобы сделать сравнения в одном кадре.

def convert_score_to_grade_w_plus_and_minus(score):
    grade_ranges = [
        (98, 101, 'A+'), (93, 98, 'A'), (90, 93, 'A-'),
        (88, 90, 'B+'), (83, 88, 'B'), (80, 83, 'B-'),
        (78, 80, 'C+'), (73, 78, 'C'), (70, 73, 'C-'),
        (68, 70, 'D+'), (63, 68, 'D'), (60, 63, 'D-'),
        (0, 60, 'F'),
    ]

    for lower, upper, grade in grade_ranges:
        if lower <= score <= upper:
            return grade

    return "Invalid Score"

for score in [70, 34, 99, 102]:
    print(score, convert_score_to_grade_w_plus_and_minus(score))
# (70, 'C-')
# (34, 'F')
# (99, 'A+')
# (102, 'Invalid Score')
...