Проблема с сортировкой зависимостей сложных модулей Python
У меня есть набор "модулей" с зависимостями.
модуль B зависит от A модуль C зависит от A и B модуль D зависит от C
Я могу представить каждый модуль как объект, а их зависимости как свойство:
class Module():
def __init__(self, name):
self.dependencies = []
self.name = name
def __repr__(self):
return self.name
A = Module("A")
A.dependencies = []
B = Module("B")
B.dependencies = [A]
C = Module("C")
C.dependencies = [A, B]
D = Module("D")
D.dependencies = [C]
modules = [C, D, B, A]
Предположим, у меня есть список модулей в произвольном порядке, например, [C, D, B, A]
Нужно написать функцию, которая будет принимать этот входной список и возвращать список всех этих модулей в порядке зависимости:
Например, [A, B, C, D], начиная с A, потому что у него нет зависимостей, затем B, потому что он зависит только от A, затем C, D по тем же причинам. Я застрял в этом, пожалуйста, помогите с кодом, псевдокодом
"""
class Module():
def __init__(self, name):
self.dependencies = []
self.name = name
def __repr__(self):
return self.name
# normal modules
A = Module("A")
B = Module("B")
C = Module("C")
D = Module("D")
E = Module("E")
F = Module("F")
A.dependencies = []
B.dependencies = [A]
C.dependencies = [B]
D.dependencies = [A, C]
E.dependencies = []
F.dependencies = [B]
# modules that do not follow alphabetical order, so that just sorting modules don't work either
M = Module("M")
N = Module("N")
M.dependencies = [N]
N.dependencies = []
#simple circular dependency
X = Module("X")
Y = Module("Y")
X.dependencies = [Y]
Y.dependencies = [X]
# advanced circular dependency
P = Module("P")
Q = Module("Q")
R = Module("R")
S = Module("S")
P.dependencies = [S]
Q.dependencies = [P]
R.dependencies = [Q]
S.dependencies = [R]
def is_answer_valid(the_input):
# don't worry about changing this method. Just believe me: it works!
answer = sort_modules(list(the_input))
answer_temp = list(answer)
if len(answer) != len(the_input):
print("{} is not a valid answer for {}".format(answer, the_input))
return False
# print("------------")
# print(answer_temp)
loaded_modules = []
while len(answer_temp) > 0:
module = answer_temp.pop(0)
if module in loaded_modules:
print("{} is not a valid answer for {}".format(answer, the_input))
return False
for dep in module.dependencies:
if dep not in loaded_modules:
print("{} is not a valid answer for {}".format(answer, the_input))
return False
loaded_modules.append(module)
# print("-- {}-{}".format(answer_temp, loaded_modules))
# print("{}->{}".format(the_input, answer))
return True
def answer_is_circular(the_list):
# don't worry about changing this method either. Just believe me: it works!
result = None
try:
result = sort_modules(the_list)
except:
return True
msg = "You code did not detect circular dependencies for {}. It returned {} instead of raising an exception."
print(msg.format(the_list, result))
##################################################################
def sort_modules(modules):
#this is the method that needs to be implemented. Feel free to add submethods if you want. It may or may not be necessary.
return list()
##################################################################
print("Tests will run below. Only errors will be shown. If nothing is shown, its fine!")
is_answer_valid([C, D, B, A])
is_answer_valid([A, B, C, D, E])
is_answer_valid([A, B, D, C, E])
is_answer_valid([A, E, D, C, B])
is_answer_valid([A, B, D, C, E])
is_answer_valid([B, A, E, C, D])
is_answer_valid([C, B, A, D, E])
is_answer_valid([D, C, E, B, A])
is_answer_valid([D, C, B, A])
is_answer_valid([A, C, B, D])
is_answer_valid([])
is_answer_valid([E])
is_answer_valid([A])
is_answer_valid([A, E])
is_answer_valid([B, A])
is_answer_valid([A, B])
is_answer_valid([A, B, C])
is_answer_valid([A, C, B])
is_answer_valid([B, A, C])
is_answer_valid([B, C, A])
is_answer_valid([C, B, A])
is_answer_valid([C, A, B])
is_answer_valid([M, N])
is_answer_valid([N, M])
is_answer_valid([C, B, A, D, M, E, N])
is_answer_valid([C, N, B, A, D, M, E])
answer_is_circular([A, C, X, B, Y, D])
answer_is_circular([X, Y])
answer_is_circular([P, Q, R, S])
answer_is_circular([A, P, C, X, R, B, S, Q, Y, D])
answer_is_circular([A, P, C, R, B, S, Q, D])