Во-первых, ваша while int(min_credit_allowed) > credits_for_semester
строка ведет к бесконечному l oop. Его нужно изменить на
while len(classes_done) != len(class_list) and int(min_credit_allowed) > credits_for_semester: # Remove the second while loop
Во-вторых, вы добавляете список в список, поэтому вы получаете двумерный список для classes_done
с classes_done.append(classes_for_semester)
This должно быть
classes_done += classes_for_semester
, чтобы вы добавляли элементы из classes_for_semester
в classes_done
вместо добавления списка.
Ваш новый код должен выглядеть следующим образом:
def generator(max_credit_allowed, min_credit_allowed, classes_done, class_list):
classes_for_semester = []
credits_for_semester = 0
semester = 0
full_plan = []
# class_list = [['MA 241 ', '4', '', '', ''], ['PS 150 ', '3', 'MA 241 ', '', ''], ['UNIV 101', '1', '', '', ''], ['COM 122', '3', '', '', ''], ...]
# max_credit_allowed = 16
# min_credit_allowed = 12
# classes_done=['UNIV 101']
while len(classes_done) != len(class_list) and int(min_credit_allowed) > credits_for_semester: # keep going until at least the minimum credits are in the semester
semester += 1
for i in range(len(class_list)): # looping over the class list
if int(class_list[i][1]) + credits_for_semester < max_credit_allowed: #if this class was to be added would it go over the max credit for semester if yes go to next class
if (class_list[i][3] == '' or class_list[i][3] in classes_done) and (class_list[i][2] in classes_for_semester or class_list[i][2] in classes_done or class_list[i][2] == '') and (class_list[i][0] not in classes_done):
classes_for_semester.append(class_list[i][0])
credits_for_semester += int(class_list[i][1])
print('classes for semester', classes_for_semester)
print('semester credits', credits_for_semester)
classes_done += classes_for_semester
full_plan.append(semester)
full_plan.append(classes_for_semester)
print('full plan', full_plan)
classes_for_semester = []
credits_for_semester = 0
print('done')
print(full_plan)
Я бы настоятельно рекомендовал использовать None
вместо ''
для несуществующих значений, чтобы вы могли выполнить простую проверку value is None
вместо проверки на равенство для пустой строки.
Для списков передаваемой информации о классах я бы изменил их на классы, словари или именованные кортежи (узнайте больше о них здесь ), чтобы вы могли легко ссылаться на значения по имени а не цифры. class_list[i].class_name
или class_list[i]['class_name']
намного легче отлаживать в будущем, чем индексы magi c. Вы даже можете изменить for
l oop, чтобы использовать фактические данные класса в качестве переменной вместо i in range(len(class_list))
, например, так:
for c in class_list:
if int(c.credits) .... # Using a class or namedtuple approach as suggested above
И еще одна незначительная вещь, которая, вероятно, не является большой проблемой но может стать проблемой, если эти списки будут расти долго: рассмотрите возможность использования sets
вместо lists
для хранения таких вещей, как classes_done
и classes_for_semester
. Он также предотвращает сохранение дубликатов (при условии, что вы не хотите хранить один и тот же класс более одного раза).
Чтобы привести конкретный пример предложения namedtuple
, вы можете сделать следующее :
from collections import namedtuple
ClassList = namedtuple('ClassList', ['class_name', 'credits', 'coreq', 'prereq'])
class_list = [
ClassList(class_name='MA 241', credits=4, coreq=None, prereq=None),
ClassList(class_name='PS 150', credits=3, coreq='MA 241', prereq=None),
# ...
]
Так что твой для л oop становится
for c in class_list:
if c.credits + credits_for_semester < max_credits_allowed:
if (c.prereq is None or c.prereq in classes_done) and \
(c.coreq in classes_for_semester or c.coreq in classes_done or c.coreq is None) and \
(c.class_name not in classes_done):
classes_for_semester.append(c.class_name)
credits_for_semester += c.credits
classes_done += classes_for_semester
full_plan.append(semester)
full_plan.append(classes_for_semester)
classes_for_semester = []
credits_for_semester = 0