Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
717bfdf
Interactive Programming Project Proposal
bweissman1 Mar 4, 2018
8e13150
Adding pagetree.py from MP3. This will need to be modified, but shoul…
aidenclpt Mar 6, 2018
85f6889
Adding wiki_functions.py
aidenclpt Mar 6, 2018
a23eba0
First version of classes
bweissman1 Mar 6, 2018
92108d5
Fixed drawing problem by adding 'pygame.display.update()' in Viewer d…
aidenclpt Mar 7, 2018
01337d7
work-in-progress Viewer.draw
bweissman1 Mar 7, 2018
64dd072
Viewer draw work-in-progress 2
bweissman1 Mar 7, 2018
4c49151
Added controller cobject to handle user input, pan and zoom functions…
aidenclpt Mar 8, 2018
3b5b05e
fixed poor behavior in the zoom
aidenclpt Mar 9, 2018
6a04ff6
Clickable text box in progress
bweissman1 Mar 9, 2018
44d9e80
button test file
bweissman1 Mar 9, 2018
e68c20f
fixed merge conflict
bweissman1 Mar 9, 2018
23def05
test button file
bweissman1 Mar 9, 2018
5cd6be4
Fixed mouse dectection within text button
aidenclpt Mar 9, 2018
759ec64
Adding start of fractal generation feature (Node.expand()), still nee…
aidenclpt Mar 12, 2018
e0806c4
Implemented node expansion so that nodes can be made into a fractal o…
aidenclpt Mar 13, 2018
3f928dd
inputbox module
bweissman1 Mar 13, 2018
867f655
inputbox module
bweissman1 Mar 13, 2018
1c844cf
Clickable/unclickable box
bweissman1 Mar 13, 2018
592602c
Now you can enter text in the box
bweissman1 Mar 13, 2018
64a3181
added doc strings and in-line comments for classes and methods
aidenclpt Mar 14, 2018
9d5c888
Merge branch 'master' of https://github.com/bweissman1/InteractivePro…
aidenclpt Mar 14, 2018
d5875c7
Fixed two bugs I introduced while typing in comments so the code runs
aidenclpt Mar 14, 2018
f927c53
look ma no modules
bweissman1 Mar 14, 2018
f8aa9f6
Look ma no module
bweissman1 Mar 14, 2018
4b4f75a
Merge branch 'master' of https://github.com/bweissman1/InteractivePro…
bweissman1 Mar 14, 2018
246f6ee
look ma no module
bweissman1 Mar 14, 2018
5c8f51b
now takes and displays text input
bweissman1 Mar 14, 2018
a185fda
Now responds to backspaces
bweissman1 Mar 14, 2018
2355085
now box changes when clicked
bweissman1 Mar 14, 2018
84bfee6
Combined classes and c3
bweissman1 Mar 14, 2018
802192d
Now, upon return, replaces node1
bweissman1 Mar 15, 2018
49c72ba
final version of ze box
bweissman1 Mar 16, 2018
82b68eb
Testing github merge
aidenclpt Mar 15, 2018
4456d95
c4 merge attempt 1
bweissman1 Mar 16, 2018
006d7fc
adding updated code for screenshots
aidenclpt Mar 15, 2018
02d0492
work-in-progress reflection
bweissman1 Mar 16, 2018
7fd4602
user story
bweissman1 Mar 16, 2018
58aca27
adding final changes to code (save to file) and readme.md
aidenclpt Mar 16, 2018
3c258d8
adding final code with readme.md
aidenclpt Mar 16, 2018
ada3fc9
deleted unneccessary files
aidenclpt Mar 16, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
# InteractiveProgramming
This is the base repo for the interactive programming project for Software Design, Spring 2018 at Olin College.

#Dependencies
You need to install: wikipedia, pygame, bs4
Other libraries used: urllib, math, collections, string
wiki_functions.py was written by Aiden Carley-Clopton as par of MP2

#Use
To run the code, run $ python wikipedia_visualizer.py

Click on the rectangle and type in the title of the article you want ot start at.
Hit enter to generate the first node. Click on it to expand it and find the first
few links (the default value is 3, and can be changed by pressing one of the number
keys). Right click on a node to open the wikipedia page in your browser. Zooming
happens with new node generation and can be done manually by scrolling,panning is
done by dragging with left click held down.

If you want to delete a branch, hover over a node and press the delete key to delete
all of it's children. If you click on the node again, you'll get a new set of links
to explore.

Hitting the 'd' key while not in the search bar will expand every node one layer.
This is good for building a tree, but I should warn you it takes a while (since
the program has to search the internet for results)

Hitting the 's' key while not in the text box will save the current tree to a file.
To load a file, type the name ending in '.txt', and the code will parse it. If the file
doesn't exist, it just won't load anything. I've included the examples 'philosophy.txt',
'metal.txt','box.txt', and 'eigen vector.txt' so you can load them and take a look.
Note that deletion is not fully supported in files generated from saves.

Screenshots of use can be found in /screenshots
6 changes: 6 additions & 0 deletions Untitled.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
33 changes: 33 additions & 0 deletions button.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from pygame.locals import *
import pygame
import pygame_textinput
import time
import math

if __name__ == '__main__':

textinput = pygame_textinput.TextInput()


pygame.init()
screen = pygame.display.set_mode((250,250))

running = True

while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
print(event.pos)
if event.type == pygame.QUIT:
running = False
break
screen.fill(pygame.Color(28, 172, 229))
# Feed it with events every frame
textinput.update(pygame.event.get())
# Blit its surface onto the screen
screen.blit(textinput.get_surface(), (10, 10))

pygame.display.update()


pygame.quit()
251 changes: 251 additions & 0 deletions c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import pygame
import time
import math
import pygame_textinput

class Model(object):

def __init__(self, size, boxes=None):
self.size = size
self.width = size[0]
self.height = size[1]
self.nodes = []
self.nodes.append(Node('title',size[0]/2,size[1]/2))
self.clines = []

self.panning = False
self.mouse_pos = None
self.boxes = []
self.boxes.append(Box(('Main Box'),((size[0]/2)-(size[0]/4)),((size[1]*.33)-(size[1]/30)))),
self.rectangle = pygame.Rect(((size[0]/2)-(size[0]/4),(size[1]*.33)-(size[1]/30),(size[0]/2),(size[1]/10)))
self.scale = 1
self.inputboxes = []

def zoom_in(self,center):
"""Zooms in around the center
center: tuple containing the center about which the screen will
be dilated"""
for node in self.nodes:
node.x = (node.x - center[0])*1.05 + center[0]
node.y = (node.y - center[1])*1.05 + center[1]
for cline in self.clines:
cline.update()
self.scale = self.scale * 1.05

def zoom_out(self,center):
"""Zooms out around the center
center: tuple containing the center about which the screen will
be dilated"""
for node in self.nodes:
node.x = (node.x - center[0])*0.95 + center[0]
node.y = (node.y - center[1])*0.95 + center[1]
for cline in self.clines:
cline.update()
self.scale = self.scale * 0.95

def pan(self,dx,dy):
"""Moves everything on the screen by dx,dy
dx: movement in the x direction
dy: movement in the y direction"""
for node in self.nodes:
node.x = node.x + dx
node.y = node.y + dy
for cline in self.clines:
cline.update()

def inputbox(self):
inputboxes.append(jean)

class Viewer(object):
"""Displays the model"""

def __init__(self,model):
self.model = model
self.screen = pygame.display.set_mode(self.model.size)

def draw(self):
self.screen.fill(pygame.Color(28, 172, 229))
for cline in self.model.clines:
pygame.draw.lines(self.screen, pygame.Color(200, 200, 200), False, cline.points,
ConnectionLine.line_width)
for node in self.model.nodes:
pygame.draw.circle(self.screen, pygame.Color(175,175,175),
(int(node.x), int(node.y)), node.size,0)
for box in self.model.boxes:
pygame.draw.rect(self.screen,pygame.Color(255,255,255),pygame.Rect(((self.model.width/2)-(self.model.width/4),(self.model.height*.33)-(self.model.height/30),(self.model.width/2),(self.model.height/10))))

for inputbox in self.model.inputboxes:
pygame.draw.rect(self.screen,pygame.Color(200,200,200),pygame.Rect(((self.model.width/2)-(self.model.width/4),(self.model.height*.33)-(self.model.height/30),(self.model.width/2),(self.model.height/10))))

pygame.display.update()

class Controler(object):
"""Handles user input into the model"""

def __init__(self, model):
self.model = model

def handle_event(self, event):
"""Updates model according to type of input"""


if model.panning:
dx = pygame.mouse.get_pos()[0] - self.model.mouse_pos[0]
dy = pygame.mouse.get_pos()[1] - self.model.mouse_pos[1]
self.model.pan(dx,dy)
self.model.mouse_pos = pygame.mouse.get_pos()

if event.type == pygame.MOUSEBUTTONDOWN:

if event.button == 5:
m_pos = pygame.mouse.get_pos()
self.model.zoom_in(m_pos)

elif event.button == 4:
m_pos = pygame.mouse.get_pos()
self.model.zoom_out(m_pos)

elif event.button == 1:
m_pos = pygame.mouse.get_pos()
rect = self.model.rectangle
if rect[0] < m_pos[0] < rect[0]+rect[2] and rect[1] < m_pos[1] < rect[1]+rect[3]:
if len(self.model.inputboxes) == 0:
self.model.inputboxes.append(Inputbox(((self.model.width/2)-(self.model.width/4)),((self.model.height*.33)-(self.model.height/30))))
else:
self.model.inputboxes.clear()
for node in self.model.nodes:
if ((m_pos[0]-node.x)**2+(m_pos[1]-node.y)**2)**.5 <= Node.node_size:
self.model.nodes.extend(node.expand(self.model.scale))
self.model.clines.append(ConnectionLine(node, self.model.nodes[-1]))
self.model.clines.append(ConnectionLine(node, self.model.nodes[-2]))
self.model.clines.append(ConnectionLine(node, self.model.nodes[-3]))

if pygame.mouse.get_pressed()[0]:
rect = self.model.rectangle
m_pos = pygame.mouse.get_pos()
if not (rect[0] < m_pos[0] < rect[0]+rect[2] and rect[1] < m_pos[1] < rect[1]+rect[3]):
self.model.panning = True
self.model.mouse_pos = pygame.mouse.get_pos()

elif pygame.mouse.get_pressed()[0] == False:
self.model.panning = False


if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.model.pan(0,10)

if event.key == pygame.K_DOWN:
self.model.pan(0,-10)

if event.key == pygame.K_LEFT:
self.model.pan(10,-0)

if event.key == pygame.K_RIGHT:
self.model.pan(-10,0)

class Inputbox(object):

def __init__(self,x,y):
self.x = x
self.y = y

class Box(object):
"""A clickable box where the user enters the title of the page she/he is
interested in"""

def __init__(self,title='',x=0,y=0):
self.title = title
self.x = x
self.y = y

def __str__(self):
return '%s at (%d,%d)' % (title,x,y)

class Node(object):
"""A clickable node appearing in a web
Attributes: x, y, title, children (list of the titles of nodes linked to
by the node)"""

node_size = 10

def __init__(self,title,x,y, level = 1):
self.children = []
self.x = x
self.y = y
self.title = title
self.size = Node.node_size
self.level = level
self.expanded = False

def __str__(self):
return '%d,%d' % (self.x,self.y)

def expand(self, scale):
r = 100*scale/1.2**(self.level)

first = Node('1', self.x, self.y + r, self.level + 1)
second = Node('2', self.x + r*math.sin(math.pi/3), self.y - r*math.cos(math.pi/3), self.level + 1)
third = Node('3', self.x - r*math.sin(math.pi/3), self.y - r*math.cos(math.pi/3), self.level + 1)

cline1 = ConnectionLine(self, first)
cline2 = ConnectionLine(self, second)
cline3 = ConnectionLine(self, third)

return [first, second, third]

class ConnectionLine(object):

line_length = 10
line_width = 3

def __init__(self,start,end):
"""Start and end are nodes"""
self.start = start
self.end = end
self.x0 = start.x
self.y0 = start.y
self.x1 = end.x
self.y1 = end.y
self.points = [(self.x0,self.y0), (self.x1, self.y1)]

def __str__(self):
return 'Start: %s End: %s' % (str(self.start),str(self.end))

def update(self):
"""Recalculates the line endpoints when nodes are changed"""
self.x0 = self.start.x
self.y0 = self.start.y
self.x1 = self.end.x
self.y1 = self.end.y
self.points = [(self.x0,self.y0), (self.x1, self.y1)]

if __name__ == '__main__':

pygame.init()

node1 = Node('Node1',1,2)
node2 = Node('Node2',3,4)



running = True

model = Model((1000,1000))


view = Viewer(model)
controler = Controler(model)
#view.draw()
k=0
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
controler.handle_event(event)

view.draw()
time.sleep(.001)

pygame.quit()
Loading