diff --git a/Graph.py b/Graph.py new file mode 100644 index 0000000..49f0378 --- /dev/null +++ b/Graph.py @@ -0,0 +1,121 @@ +import math +import random +import pygame +from parse import parse_input +from Node import Node +from globals import * + +def createColorFromString(s): + i = hash(s) + r = (i & 0xFF0000) >> 16 + g = (i & 0x00FF00) >> 8 + b = (i & 0x0000FF) + 125; + return (r,g,b%125 + 100) + +def generateRandomVelocity(): + dx = random.uniform(NODE_MIN_VEL, NODE_MAX_VEL) + dy = random.uniform(NODE_MIN_VEL, NODE_MAX_VEL) + randomVelocity = (dx, dy) + return randomVelocity + +class Graph(object): + # A directed graph which contains nodes + def __init__(self, surface, nodes=[], links=[], file=""): + self.surface = surface + self.nodes = nodes + self.links = links + self.hashLink= {} # This will provide faster access to links + self.file = file + self.font = pygame.font.SysFont(None, 15) + + self.nodesUnderMouse = [] + + def fromFile(self, initializeWithRandomVels=True): + # Parse from file + self.nodes, self.links = parse_input(self.file) + + # Set the position of each node + square = math.ceil(math.sqrt(len(self.nodes))) + for i in range(square): + for j in range(square): + if (i*square + j < len(self.nodes)): + self.nodes[i*square + j].pos = (int((WIDTH)/(square) * i + 20), int((HEIGHT)/(square) * j + 20)) + if (initializeWithRandomVels): + self.nodes[i*square + j].vel = generateRandomVelocity() + else: + self.nodes[i*square + j].vel = (0, 0) + self.nodes[i*square + j].color = createColorFromString(self.nodes[square*i + j].text) + + + def updateNodePositions(self, dt): + for i in self.nodes: + i.update(dt) # Update the position for velocity + + def randomNodes(self): + # Populate nodes with random ones + for i in range(10): + for j in range(10): + position = (20 + i * 80, 20 + j * 80) + color=random.choice([RED,GREEN,BLUE]) + radius=random.randint(5, 15) + text=random.choice(list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) + self.nodes.append(Node(position, generateRandomVelocity(), color, radius, text)) + + def randomLinks(self): + for i in range(random.randint(1, 1000)): + # Each link is (source, destination, weight) + self.links.append((random.choice(self.nodes), random.choice(self.nodes), 1, "BRUH")) + + def updateHashLinks(self): + # This will also calculate the radius for each node + for i in self.links: + # Hash links appear in the dictionary as: + # source_node : [(node1, weight1, description1), (node2, weight2, description2)] + if (i[0] not in self.hashLink.keys()): + self.hashLink[i[0]] = [] + self.hashLink[i[0]].append((i[1], i[2], i[3])) + for i in self.nodes: + if (i in self.hashLink.keys()): + i.radius = max(min(len(self.hashLink[i]), NODE_MAX_RADIUS), NODE_MIN_RADIUS) + else: + # The node has no outer links + i.radius = NODE_MIN_RADIUS + + def drawLinks(self, node): + # Draw all of the links from one node to all of its neighbors + if (node in self.hashLink.keys()): + for i in self.hashLink[node]: + pygame.gfxdraw.line(self.surface, int(node.pos[0]), int(node.pos[1]), int(i[0].pos[0]), int(i[0].pos[1]), RED) + midPoint = ((i[0].pos[0] + node.pos[0])/2, (i[0].pos[1] + node.pos[1])/2) + render=self.font.render(i[0].text, True, WHITE) + self.surface.blit(render, midPoint) + render=self.font.render(i[2], True, WHITE) + self.surface.blit(render, (midPoint[0] + 10, midPoint[1]+10)) + else: + for i in self.links: + if i[0] == node: + pygame.gfxdraw.line(self.surface, int(node.pos[0]), int(node.pos[1]), int(i[1].pos[0]), int(i[1].pos[1]), RED) + midPoint = (abs(i[1].pos[0] + node.pos[0])/2, abs(i[1].pos[1] + node.pos[1])/2) + render=self.font.render(i[1].text, True, WHITE) + self.surface.blit(render, midPoint) + render=self.font.render(i[3], True, WHITE) + self.surface.blit(render, (midPoint[0] + 10, midPoint[1]+10)) + + def draw(self): + # Draw the graph for i in nodes: + mouseX = pygame.mouse.get_pos()[0] + mouseY = pygame.mouse.get_pos()[1] + + if (self.nodesUnderMouse): + # If the node is under the mouse draw the links and the node + # content + for i in self.nodesUnderMouse: + self.drawLinks(i) + node=i + render=self.font.render(node.text, True, WHITE) + self.surface.blit(render, (node.pos[0]+node.radius, node.pos[1]+node.radius)) + + # Now we can finally draw the nodes! + for i in self.nodes: + i.draw(self.surface) + diff --git a/Node.py b/Node.py new file mode 100644 index 0000000..f85dab2 --- /dev/null +++ b/Node.py @@ -0,0 +1,43 @@ +import random +import pygame +from pygame import gfxdraw +from globals import * + +class Node(object): + # A node object contains data for each node + def __init__(self, pos=(1,1), vel=(1,1), color=RED, radius=10, text="A"): + self.pos = pos # This position is the center of the node + self.vel = vel # Velocity vector + self.color = color + self.radius = radius + self.text = text + self.updateB= True + self.font = pygame.font.SysFont(None, int(self.radius * 2.4)) + + def update(self, dt): + if (self.updateB): + if (self.pos[0] <= 0): + self.vel = (random.uniform(NODE_MIN_VEL, NODE_MAX_VEL), self.vel[1]) + if (self.pos[0] >= WIDTH): + self.vel = (-random.uniform(NODE_MIN_VEL, NODE_MAX_VEL), self.vel[1]) + if (self.pos[1] <= 0): + self.vel = (self.vel[0], random.uniform(NODE_MIN_VEL, NODE_MAX_VEL)) + if (self.pos[1] >= HEIGHT): + self.vel = (self.vel[0], -random.uniform(NODE_MIN_VEL, NODE_MAX_VEL)) + + x = self.pos[0] + self.vel[0] * dt + y = self.pos[1] + self.vel[1] * dt + self.pos = (x,y) + + def draw(self, surface): + # Draw the node + gfxdraw.aacircle(surface, int(self.pos[0]), int(self.pos[1]), self.radius, self.color) + gfxdraw.filled_circle(surface, int(self.pos[0]), int(self.pos[1]), self.radius, self.color) + + # Draw the text at the center of the node + textItem = self.font.render(self.text[0], True, BLACK) + textWidth = textItem.get_rect().width + textHeight = textItem.get_rect().height + surface.blit(textItem, (int(self.pos[0] - textWidth/2), int(self.pos[1] - textHeight/2))) + + diff --git a/builder.py b/builder.py new file mode 100644 index 0000000..0bc0444 --- /dev/null +++ b/builder.py @@ -0,0 +1,76 @@ +import pygame +from Graph import Graph +from Node import Node +from globals import * + +def main(): + pygame.init() + screen = pygame.display.set_mode((WIDTH, HEIGHT)) + clock = pygame.time.Clock() + + running = True + graph = Graph(screen, file="finalGraph.txt") + graph.fromFile(False) + isNodeUnderMouse = False + node1 = None + node2 = None + + while (running): + isNodeUnderMouse = False + for event in pygame.event.get(): + if event.type == pygame.QUIT: + file = open(input("Where would you like to save the graph: "),"w") + for i in graph.links: + file.write(i[0].text + " " + i[1].text + " " + str(i[2]) + " " + i[3] + "\n") + file.close() + running = False + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + find = input("Name of node: ") + for i in graph.nodes: + if i.text == find: + i.color = BLUE + if event.type == pygame.MOUSEBUTTONUP: + mouseX, mouseY = pygame.mouse.get_pos() + for i in graph.nodes: + if(mouseX > i.pos[0] - i.radius and \ + mouseY > i.pos[1] - i.radius and \ + mouseX < i.pos[0] + i.radius and \ + mouseY < i.pos[1] + i.radius): + graph.drawLinks(i) + if (node1): + node2 = i + description = input("Description of link: ") + if (description != "no"): + graph.links.append([node1, node2, 1.0, description]) + node2 = None + node1 = None + elif (not node1 and not node2): + node1 = i + isNodeUnderMouse = True + if (not isNodeUnderMouse): + newNode = Node(pos=(mouseX, mouseY), vel=(0,0), text = input("New node text: ")) + graph.nodes.append(newNode) + node1 , node2 = (None, None) + screen.fill(BLACK) + + graph.draw() + mouseX, mouseY = pygame.mouse.get_pos() + for i in graph.nodes: + if(mouseX > i.pos[0] - i.radius and \ + mouseY > i.pos[1] - i.radius and \ + mouseX < i.pos[0] + i.radius and \ + mouseY < i.pos[1] + i.radius): + i.color = GREEN + if (i not in graph.nodesUnderMouse): + graph.nodesUnderMouse.append(i) + graph.drawLinks(i) + else: + if i in graph.nodesUnderMouse: + graph.nodesUnderMouse.remove(i) + if (i.color != BLUE): + i.color = RED + pygame.display.flip() + clock.tick(60) +if __name__ == "__main__": + main() diff --git a/finalGraph.txt b/finalGraph.txt new file mode 100644 index 0000000..3105bee --- /dev/null +++ b/finalGraph.txt @@ -0,0 +1,308 @@ +Set Cartesian_Product 0.7 Is an operand of +Cartesian_Product Product 0.9 Is a type of +Product Operation 1.0 Is an +Set Ordered 1.0 Can be +Ordered Unordered 1.0 Is opposite to +Unordered Ordered 1.0 Is opposite to +Set Unordered 1.0 Can be +Set Element 1.0 Contain many +Element Set 1.0 Is the smallest unit of +Sets Relation 0.6 Can describe +Relation Function 1.0 Is another word for +Function Mapping 1.0 Is another word for +Mapping Relation 1.0 Is another word for +Relation Function 1.0 Is another word for +Function Onto 0.7 Can be +Onto Function 0.7 Describes a property of +Function One_To_One 0.7 Can be +One_To_One Function 0.7 Describes a property of +Injective One_To_One 1.0 Is another word for +One_To_One Injective 1.0 Is another word for +Onto Bijective 0.5 Is half of requirements for +Onto Surjective 1.0 Is another word for +Surjective Onto 1.0 Is another word for +One_To_One Bijective 0.5 Is half of requirements for +Bijective Function 1.0 Is a type of +Bijective Onto 0.5 Requires +Bijective One_To_One 0.5 Requires +Function Quantifier 0.6 Can be bounded by +Quantifier Predicates 0.9 Can describe +Quantifier For_All 1.0 Includes +For_All Quantifier 1.0 Is a +For_All all() 1.0 Is the same as Python +Quantifier For_Each 1.0 Includes +For_Each Quantifier 1.0 Is a +For_Each any() 1.0 Is the same as Python +Quantifier DeMorgan_Laws 0.6 Is negated by +DeMorgan DeMorgan_Laws 1.0 Created +DeMorgan_Laws Logic_Gate 1.0 Describe negation of +DeMorgan_Laws Quantifier 1.0 Describe negation of +Relation Binary 0.4 Can be +Binary Function 0.8 Has 2 inputs for +Binary Number_System 0.9 Is a base 2 +Binary Tree 0.9 Can be a +Relation And 1.0 Can be +And Logic_Gate 1.0 Is a +Logic_Gate Truth_Table 1.0 Determines output in +Truth_Table Boolean 1.0 Is represented in computer by a +Boolean Binary 1.0 Is represented by +Relation Or 0.7 Can be +Relation Xor 0.7 Can be +Relation Not 0.7 Can be +Relation Symmetric 1.0 Can be +Symmetric Undirected 1.0 Describes graph type +Relation Transitive 1.0 Can be +Relation Reflexive 1.0 Can be +Relation Equivalence 1.0 Can be type +Equivalence Binary 0.6 Requires type +Equivalence Modular_Arithmetic 0.8 Describes +Modular_Arithmetic Chinese_Remainder_Theorem 1.0 Soves linear systems by +Modular_Arithmetic Modulus 1.0 Is described by +Equivalence Congruence 0.8 +Congruence Equivalence 0.8 +Modulus Modular_Arithmetic 1.0 Describes +Sets Element 0.8 Is a combination of +Element Combination 0.6 Can be rearranged by +Combination Element 0.6 Rearrange +Combination Combinatorics_Probability 1.0 Is studied in +Element Permutation 0.6 Are rearranged by +Permutation Element 0.6 Rearrange +Permutation Combinatorics_Probability 1.0 Is Studied in +Permutation Factorial 0.8 Is calculated by +Combination Factorial 0.8 Is calculated by +Factorial Product 1.0 Is a +Permutation Seating 1.0 Can be represented by +Combination N_Choose_K 1.0 Is represented by +Set Subsets 1.0 Contain +Set Intersection 1.0 Is an operand for +Set Union 1.0 Is an operand for +Intersection Operation 1.0 Is an +Union Operation 1.0 Is an +Complex_Numbers Real_Numbers 1.0 Has subset of +Real_Numbers Complex_Numbers 1.0 Is a subset of +Real_Numbers Countable 0.6 Are not +Countable Cardinality 1.0 Has the same _ as N +Natural_Numbers Real_Numbers 1.0 Is a subset of +Real_Numbers Natural_Numbers 1.0 Contains +Natural_Numbers Integers 1.0 Is a subset of +Integers Real_Numbers 1.0 Is a subset of +Integers Number_Theory 1.0 Studies +Real_Numbers Real_Analysis 1.0 Is the study of +Supremum Real_Analysis 1.0 Is the greatest upper bound +Infimum Real_Analysis 1.0 Is the lowest lower bound +Complex_Numbers e^(i*pi) 0.7 Describe the relation +e^(i*pi) Eulers_Formula 1.0 Can be proved by +Eulers_Formula Euler 1.0 Was created by +Complex_Numbers Eigenvalues 1.0 Can be +Number_Theory Primes 1.0 Conjectures about +Primes log(n) 0.6 Below n is a ratio of +Number_Theory Alternate_Base_Repr 0.8 Deals with +Alternate_Base_Repr Binary 1.0 Can be +Binary Alternate_Base_Repr 1.0 Is a +Number_Theory Coprime 1.0 Two number can be +Coprime GCD 1.0 The GCD is 1 +GCD Euclidean_GCD 1.0 Can be calculated by +Euclidean_GCD GCD 1.0 Calculates +Euclidean_GCD Modulus 1.0 Is calculated by +Number_Theory RSA 1.0 Describes +RSA Public_Key_Encryption 1.0 Is a type of +RSA Primes 1.0 Is a product of +Number_Theory Residue_Number_Systems 1.0 Studies +Residue_Number_Systems Modulus 1.0 Determined by +Modulus MMI 1.0 Is inverted by +Modulus Congruence_Relation 1.0 Is an example of a +Real_Analysis Real_Numbers 1.0 Is the study of +Real_Analysis Irrationality 1.0 Describes +Real_Analysis Cardinaility 1.0 Defines +Real_Analysis Set 1.0 Defines cardinality of +Set Bijective_Function 1.0 Has same cardinality when _ exists +Bijective_Function Bijective 1.0 Is +Cardinality Countable 1.0 Defines +Tree Graph 1.0 Is a more constrained version of +Graph Complete 1.0 Can be +Graph Wheel 1.0 Can be +Graph Bipartite 1.0 Can be +Bipartite Complete 1.0 Can be +Graph Cube 1.0 Can be a +Cube 2^n 1.0 Contains nodes +Graph Nodes 1.0 Contain +Nodes Vertices 1.0 Another word for +Vertices Nodes 1.0 Another word for +Nodes Degree 1.0 Has property +Degree Out_Degree 1.0 Can be type +Degree In_Degree 1.0 Can be type +Graph Undirected 1.0 Can be +Undirected Symmetric 1.0 Describes relation that is +Graph Directed 1.0 Can be +Graph Paths 1.0 Are explored by +Paths DFS 1.0 Can be generated by +Paths BFS 1.0 Can be generated by +BFS Stack 1.0 Uses +Stack Push 1.0 Has operation +Stack Pop 1.0 Has operation +Graph Cycles 1.0 Can contain +Graph Psuedo 1.0 Can be type +Psuedo Loops 1.0 Can contain +Graph Planar 1.0 Can be +Planar Intersection 1.0 Can be rewritten with no +Graph Non-Planar 1.0 Can be +Non-Planar Intersection 1.0 Cannot be rewritten without +Graph Multigraph 1.0 Can be type +Multigraph Edge 1.0 Has multiple +Graph Digraph 1.0 Can be type +Digraph Binary 1.0 Can be represented with relation of type +Graph Adjacency_Matrix 1.0 Can be represented by +Graph Incidence_Matrix 1.0 Can be represented by +Graph Subgraphs 1.0 Can have +Subgraph Subset 1.0 Is a _ of the original graph +Graph Intersection 1.0 Can be operand of +Graph Union 1.0 Can be operand +Graph Complement 1.0 Has property +Complement Complete 1.0 Contains non-present nodes in +Tree Rooted 1.0 Can be +Tree Branches 1.0 Contain +Branches Paths 1.0 Are explored by +Branches Leaves 1.0 Can extend to +Branches Arc 1.0 Is also known as +Branches Edge 1.0 Is also known as +Tree Perfect 1.0 Can be +Perfect 2^n 1.0 Has _ leaves +Tree Balanced 1.0 Can be +Tree Recursion 1.0 Can be explored by +Recursion log(n) 1.0 Generally bounded by +Tree AVL 1.0 Can be +Tree Parsing 1.0 Can describe +Parsing Language 1.0 Is a problem of +Parsing Finite_Automata 1.0 Determined by +Finite_Automata Nondeterministic_FA 1.0 Are constrained types of +Finite_Automata State_Machine 1.0 Is a type of +State_Machine Accepting 1.0 Has state +Accepting Boolean 1.0 Is a +State_Machine Rejecting 1.0 Has state +Rejectinve Boolean 1.0 Is a +Parsing Grammar 1.0 string is accepted by +Grammar Production 1.0 Is defined by many +Production Nonterminal 1.0 Contains +Production Terminal 1.0 Contains +Production Regular_Expression 1.0 Can be identified with +Regular_Expression Union 1.0 Is operand of +Regular_Expression Concatenation 1.0 Is operand of +Regular_Expression Star 1.0 Is operand of +Tree Permutation_Tree 1.0 Produces +Permuation_Tree Permutations 1.0 Explores all +Tree Binary 1.0 Can be +Tree Huffman_Tree 1.0 Can be a +Huffman_Tree Compression 1.0 Explores +Huffman_Tree Compression_Ratio 1.0 Has +Compression_Ratio Encoding 1.0 Determined by a fixed length +Huffman_Tree Balanced 1.0 Is better when not +Huffman_Tree Bottom_Up 1.0 Is built with +Tree Full 1.0 Can be +Tree Complete 1.0 Can be +Set Graph 1.0 Can describe the edges in a +Chinese_Remainder_Theorem Modular_Arithmetic 1.0 Uses +Incidence_Matrix Matrix 1.0 Is a +Bottom_Up Parsing 1.0 Is algorithm for +Full Tree 1.0 Describes a +Matrix Eigenvalues 1.0 If square contains +Combinatorics_Probability Combination 1.0 Studies +Combinatorics_Probability Permutation 1.0 Studies +Primes Coprime 1.0 Are always +Sets Set 1.0 Is the plural form +all() Function 1.0 Is a +any() Function 1.0 Is a +Seating Permutation 1.0 Is a problem good for +Permutations Permutation 1.0 Is the plural form of +Permutation Permutations 1.0 Is singular +Permutations Permuation_Tree 1.0 Are explored by +Permuation_Tree Tree 1.0 Is a type of +Permutation_Tree Permuation_Tree 1.0 Is a duplicate of +Nonterminal Production 1.0 Is part of a +Language Alphabet 1.0 Contains a +Alphabet Element 1.0 Is made up of +Production Grammar 1.0 Defines a +Arc Edge 1.0 Is synonymous to +Edge Arc 1.0 Is synonymous to +Edge Paths 1.0 Describes +Paths Edge 1.0 Follow +Directed Graph 1.0 Is a type of +Eigenvalues Matrix 1.0 Are properties of a square +log(n) Function 1.0 Is a +Subset Subsets 1.0 Is singular of +Subsets Subset 1.0 Is plural of +Subsets Set 1.0 Are contained in +Subset Set 1.0 Is a smaller part of +Adjacency_Matrix Matrix 1.0 Is a +Adjacency_Matrix Graph 1.0 Represents +AVL Tree 1.0 Is a type of +Subgraphs Graph 1.0 Are smaller parts of a +Xor Logic_Gate 1.0 Is a +Or Logic_Gate 1.0 Is a +Pop Stack 1.0 Is an operation of +Push Stack 1.0 Is an operation of +Push Operation 1.0 Is an +Pop Operation 1.0 Is an +Nondeterministic_FA Finite_Automata 1.0 Is an ambiguous form of +Balanced Tree 1.0 Describes +Transitive Relation 1.0 Describes a +Stars_And_Bars N_Multichoose_K 1.0 Are described by +Stars_And_Bars Combinatorics_Probability 1.0 Are studied in +N_Multichoose_K Stars_And_Bars 1.0 Describe +Combinatorics_Probability N_Multichoose_K 1.0 Studies +N_Choose_K Combination 1.0 Describe +Alphabet Language 1.0 Describe elements in a +Alphabet Terminal 1.0 Can be made of many +Alphabet Nonterminal 1.0 Can be made of many +Irrationality Real_Analysis 1.0 Is explored in +Not Logic_Gate 1.0 Is a +Alternate_Base_Repr Primes 1.0 Can be made of +Natural_Numbers Primes 1.0 Are products of +2^n Function 1.0 Is an exponential +Loops Python 1.0 Are in +Python Language 1.0 Is a +all() Python 1.0 Is in +any() Python 1.0 Is in +Complete Graph 1.0 Describes +Node Subgraphs 1.0 Is the smallest +Node Nodes 1.0 Is singular version of +Nodes Node 1.0 Is plural of +Out_Degree Nodes 1.0 Is property of +In_Degree Nodes 1.0 Is property of +Out_Degree Directed 1.0 Is not equal to in degree when +In_Degree Directed 1.0 Is not equal to out degree when graph is +Directed Edge 1.0 Describes property of +Edge Directed 1.0 Can be +Cardinaility Cardinality 1.0 Is a duplicate of +Wheel Graph 1.0 Descibes +Bipartite Graph 1.0 Describes +Bipartite Onto 1.0 Describes a graph that is +Cube Graph 1.0 Describes +Cycles Graph 1.0 Can be found in +Cycles DFS 1.0 Are found via +DFS Paths 1.0 Explores +Cycles Paths 1.0 Are types of +Rooted Tree 1.0 Describes a type of +Star Regular_Expression 1.0 Is an operation that forms +Concatenation Regular_Expression 1.0 Is an operation that forms +Concatenation Alphabet 1.0 Requires +None Python 1.0 Is in +Modulus Congruence 1.0 Is a type of +And Python 1.0 Is in +Function Python 1.0 Can be defined in +Terminal Alphabet 1.0 Can be part of +Function Codomain 1.0 Contain +Range Python 1.0 Is in +Function Range 1.0 Contain +Domain Function 1.0 Describes a +Codomain Function 1.0 Describes a +Range Codomain 1.0 Is a subset of +Codomain Range 1.0 Is a superset of +Real_Numbers Codomain 1.0 Is the _ for real-valued functions +Leaves Tree 1.0 Are the bottom of a +Psuedo Graph 1.0 Is a type of +Relation Graph 1.0 Describe the relations in +MMI Modulus 1.0 Finds the identity of a _ operation +Compression Encoding 1.0 Studies the best type of +Compression Huffman_Tree 1.0 Is explored by +Recursion Binary 1.0 Is used in binary search +Recursion Tree 1.0 Is the best way to explore a diff --git a/globals.py b/globals.py new file mode 100644 index 0000000..d8406e5 --- /dev/null +++ b/globals.py @@ -0,0 +1,15 @@ +WIDTH =800 +HEIGHT=800 + +WHITE=(255 , 255 , 255) +BLACK=(0 , 0 , 0 ) +RED =(255 , 0 , 0 ) +GREEN=(0 , 255 , 0 ) +BLUE =(0 , 0 , 255) + +NODE_MIN_VEL = 1.0 +NODE_MAX_VEL = 2.0 + +NODE_MIN_RADIUS = 8 +NODE_MAX_RADIUS = 30 + diff --git a/main.py b/main.py new file mode 100644 index 0000000..9e86ae1 --- /dev/null +++ b/main.py @@ -0,0 +1,73 @@ +# Author: Logan Hunt + +import pygame +from Graph import Graph +from Node import Node +from globals import * # Global variables + +pygame.init() + +def main(): + screen = pygame.display.set_mode((WIDTH,HEIGHT)) + clock = pygame.time.Clock() + + running = True + update = True + graph = Graph(screen, file="finalGraph.txt") + graph.fromFile() + graph.updateHashLinks() + + nodeUnderMouse = None + + while(running): + # Main loop + for event in pygame.event.get(): + if event.type == pygame.QUIT: + # If the user closed the window + running = False + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_f: + searchTerm = input("What would you like to search for? ") + for i in graph.nodes: + if searchTerm in i.text: + graph.nodesUnderMouse.append(i) + if event.key == pygame.K_c: + graph.nodesUnderMouse = [] + if event.key == pygame.K_SPACE: + if (update): + update = False + else: + update = True + if event.key == pygame.K_p: + for i in graph.nodes: + if (i not in graph.nodesUnderMouse): + graph.nodesUnderMouse.append(i) + + if event.type == pygame.MOUSEBUTTONUP: + mouseX, mouseY = pygame.mouse.get_pos() + for i in graph.nodes: + if(mouseX > i.pos[0] - i.radius and \ + mouseY > i.pos[1] - i.radius and \ + mouseX < i.pos[0] + i.radius and \ + mouseY < i.pos[1] + i.radius): + i.updateB = False + if (i not in graph.nodesUnderMouse): + graph.nodesUnderMouse.append(i) + else: + if i in graph.nodesUnderMouse: + graph.nodesUnderMouse.remove(i) + i.updateB = True + + screen.fill(BLACK) + + if (update): + graph.updateNodePositions(1) + graph.draw() + + pygame.display.flip() + clock.tick(60) + + pygame.quit() + +if __name__ == "__main__": + main() diff --git a/parse.py b/parse.py new file mode 100644 index 0000000..e92743f --- /dev/null +++ b/parse.py @@ -0,0 +1,46 @@ +from globals import * +from Node import Node + +def findNode(node, listOfNodes): + for i in range(len(listOfNodes)): + if node.text == listOfNodes[i].text: + return i + return len(listOfNodes) + +# Each file is in the form +# +def parse_input(filename): + nodes = [] + links = [] + + lines = open(filename, "r").readlines() + + for line in lines: + # Parse each line and add to links array + if (not line == "\n"): # Line isn't empty + line_split = line.split(" ") + currSrc = Node(text=line_split[0]) + currDest = Node(text=line_split[1]) + + currSrc_index, currDest_index = (findNode(currSrc, nodes), findNode(currDest, nodes)) + appendSrc, appendDest = (False, False) + if (currSrc_index == len(nodes)): + appendSrc = True + if (currDest_index == len(nodes)): + appendDest = True + if (appendSrc): + nodes.append(currSrc) + currSrc_index = len(nodes)-1 + if (appendDest): + nodes.append(currDest) + currDest_index = len(nodes)-1 + + if (len(line_split) > 2): + connection_description = "".join([str(x).strip() + " " for x in line_split[3::]]) + else: + connection_description = "" + # Append the connection to links + links.append((nodes[currSrc_index], nodes[currDest_index], float(line_split[2]), connection_description)) + + return [nodes, links] +