From 0ea46a3d721bdefab70f24c4c5573ff568a56cab Mon Sep 17 00:00:00 2001 From: Simponic Date: Thu, 10 Dec 2020 18:10:51 -0700 Subject: Added files --- Graph.py | 121 --------------------- Node.py | 43 -------- README.md | 39 ++++++- builder.py | 76 ------------- finalGraph.txt | 308 ----------------------------------------------------- globals.py | 15 --- main.py | 73 ------------- parse.py | 46 -------- src/Graph.py | 121 +++++++++++++++++++++ src/Node.py | 43 ++++++++ src/builder.py | 77 ++++++++++++++ src/finalGraph.txt | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/globals.py | 15 +++ src/main.py | 73 +++++++++++++ src/parse.py | 46 ++++++++ 15 files changed, 721 insertions(+), 683 deletions(-) delete mode 100644 Graph.py delete mode 100644 Node.py delete mode 100644 builder.py delete mode 100644 finalGraph.txt delete mode 100644 globals.py delete mode 100644 main.py delete mode 100644 parse.py create mode 100644 src/Graph.py create mode 100644 src/Node.py create mode 100644 src/builder.py create mode 100644 src/finalGraph.txt create mode 100644 src/globals.py create mode 100644 src/main.py create mode 100644 src/parse.py diff --git a/Graph.py b/Graph.py deleted file mode 100644 index 49f0378..0000000 --- a/Graph.py +++ /dev/null @@ -1,121 +0,0 @@ -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 deleted file mode 100644 index f85dab2..0000000 --- a/Node.py +++ /dev/null @@ -1,43 +0,0 @@ -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/README.md b/README.md index b0fb7d5..f35c33f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,39 @@ -# graph-explorer +# Graph Explorer This is a WOK (wealth of knowledge) explorer that I made for fun and profit for CSE280. + +## Installation + +All you need is pygame! + +```bash +pip install pygame +``` + +## Usage +```bash +python3 main.py +``` +Select a node by clicking it; this will focus the links that are directed out of that node. + +Press "P" to select all nodes. + +Press "F" to find a node (this is done as a prompt in the shell). + +Press "Space" to pause the visualization. + +Press "C" to clear all the selected nodes. + + +## Using the WOK Builder + +```bash +python3 builder.py +``` + +The builder is a simple one; click anywhere where there is not a node to create a new one (prompted in terminal). + +You can add links between nodes by selecting first the source node and then the directed node. A description for the link will be prompted in the terminal. + +If you accidentally link two nodes, you can cancel the link by typing "no" in the description. + +Press "F" to search for a node. If found, this node will turn blue. diff --git a/builder.py b/builder.py deleted file mode 100644 index 0bc0444..0000000 --- a/builder.py +++ /dev/null @@ -1,76 +0,0 @@ -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 deleted file mode 100644 index 3105bee..0000000 --- a/finalGraph.txt +++ /dev/null @@ -1,308 +0,0 @@ -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 deleted file mode 100644 index d8406e5..0000000 --- a/globals.py +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 9e86ae1..0000000 --- a/main.py +++ /dev/null @@ -1,73 +0,0 @@ -# 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 deleted file mode 100644 index e92743f..0000000 --- a/parse.py +++ /dev/null @@ -1,46 +0,0 @@ -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] - diff --git a/src/Graph.py b/src/Graph.py new file mode 100644 index 0000000..49f0378 --- /dev/null +++ b/src/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/src/Node.py b/src/Node.py new file mode 100644 index 0000000..f85dab2 --- /dev/null +++ b/src/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/src/builder.py b/src/builder.py new file mode 100644 index 0000000..3c79d1b --- /dev/null +++ b/src/builder.py @@ -0,0 +1,77 @@ +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="copy.txt") +# graph.fromFile(False) + graph = Graph(screen) + 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_f: + 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 between " + node1.text + " and " + node2.text + ": ") + 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/src/finalGraph.txt b/src/finalGraph.txt new file mode 100644 index 0000000..3105bee --- /dev/null +++ b/src/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/src/globals.py b/src/globals.py new file mode 100644 index 0000000..d8406e5 --- /dev/null +++ b/src/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/src/main.py b/src/main.py new file mode 100644 index 0000000..9e86ae1 --- /dev/null +++ b/src/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/src/parse.py b/src/parse.py new file mode 100644 index 0000000..e92743f --- /dev/null +++ b/src/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] + -- cgit v1.2.3-70-g09d2