-
Notifications
You must be signed in to change notification settings - Fork 1
/
cytoscape.py
100 lines (79 loc) · 3.13 KB
/
cytoscape.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from logging import Logger
from frozendict import frozendict
from color import generate_random_hex_colors
from course import Course
def create_compound(subject):
return frozendict({
"data": frozendict({
"id": subject,
"type": "compound",
}),
})
def create_node(course):
data = {
"id": course.get_identifier(),
"description": course.description,
}
parent = course.determine_parent()
if parent != "CROSSLISTED":
data["parent"] = parent
node = {"data": frozendict(data),}
return frozendict(node)
def create_edge(target, source):
return frozendict({
"data": frozendict({
"source": source,
"target": target,
}),
})
def generate_style(parent, color):
return { parent : color }
def get_subgraphs(course: Course, course_ref_to_course: dict[Course.Reference, Course], seen: set[Course], graph_set_1: set[Course], graph_set_2: set[Course]):
if course.get_identifier() in seen:
return
seen.add(course.get_identifier())
to_add = set()
to_add.add(create_node(course))
to_add.add(create_compound(course.determine_parent()))
for reference in course.optimized_prerequisites.course_references:
if reference not in course_ref_to_course:
print(f"Prerequisite not found in courses: {reference}")
continue
edge = create_edge(target=course.get_identifier(), source=reference.get_identifier())
to_add.add(edge)
c: Course = course_ref_to_course[reference]
to_add.add(get_subgraphs(c, course_ref_to_course, seen, graph_set_1, graph_set_2))
for graph_data in to_add:
graph_set_1.add(graph_data)
graph_set_2.add(graph_data)
def build_graphs(course_ref_to_course: dict[Course.Reference, Course], subject_to_courses: dict[str, set[Course]], logger: Logger):
logger.info("Building course graphs...")
graph = set()
subject_to_graph = dict()
for subject, course_set in subject_to_courses.items():
for course in course_set:
if subject not in subject_to_graph:
subject_to_graph[subject] = set()
get_subgraphs(course, course_ref_to_course, set(), graph, subject_to_graph[subject])
return graph, subject_to_graph
def cleanup_graphs(global_graph, subject_to_graph, logger: Logger):
count = 0
if None in global_graph:
count += 1
global_graph.discard(None)
for subject in subject_to_graph:
if None in subject_to_graph[subject]:
count += 1
subject_to_graph[subject].discard(None)
logger.info(f"Removed {count} None graphs")
def generate_style_from_graph(graph):
parents = set()
for el in graph:
if "data" in el:
data = el["data"]
if "parent" in data:
parents.add(data["parent"])
colors = generate_random_hex_colors(len(set(parents)))
return [generate_style(parent, color) for parent, color in zip(set(parents), colors)]
def generate_styles(subject_to_graph):
return { subject: generate_style_from_graph(subject_to_graph[subject]) for subject in subject_to_graph }