I have tried commenting out each library individually and I have tried to just import decimal, each time it crashes at the line marked below.
<!DOCTYPE html>
<html>
<head>
<title>FindNetProps_Brython_v1</title>
<link rel="stylesheet" href="UIKit/css/uikit.css" />
<script src="jquery.js"></script>
<script src="UIKit/js/uikit.js"></script>
<script src="Brython3.1.3-20150514-095342/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
from browser import document, html, alert
import networkx as nx
import glob
import decimal
import matplotlib.pyplot as plt
import numpy as np
############ will crash before getting here ##########
document <= "imports successful"
def printProperties(filename):
inputFile = open(filename, "r")
myString = ''#initialize string to hold link pairs
myList = inputFile.readlines()#read all lines from inputFile and store each line individually in myList list
length = len(myList)
for i in range(length):
myList[i] = myList[i].replace('\n', ' ')#replace returns with spaces
myList[i] = myList[i].replace(',', ' ')#replace commas with spaces
myString = myString + myList[i]
mySinglesList = myString.split(' ')#remove spaces and store in new list
mySinglesList.remove('')#remove the additional return void that each "_as_link_pairs.txt" file has
G = nx.Graph()#create graph using networkx module
tupleList = zip(*[iter(mySinglesList)]*2)#turn the singles list into a 2-tuple list
G.add_edges_from(tupleList)#add all the edge pairs to graph G <<< will only allow passing of 2-tuples or 3-tuples!
document <= ('\nNumber of NODES in network: ' + str(G.number_of_nodes())) # capable of returning number of nodes after just adding edges
print('\nNumber of distinct EDGES in network: ' + str(G.number_of_edges()) + '\n') # function knows how to handle (0,1) and (1,0) case!
total = 0
degreeDict = nx.degree(G)#returns dictionary of degrees, keys are stored as string(ints)
print("Each node identifer on the left with the corresponding degree on the right: \n")
for i in range(G.number_of_nodes()):#iterate over the number of nodes, zero as first node
print(str(i) + ' : ' + str(degreeDict[str(i)]))
total += degreeDict[str(i)]
#ycoords[i] = degreeDict[str(i)] <<< #used to plot each node with corresponding degree
print()#return for readibility
min_val = min(degreeDict.values())#get min number connectivity
print("Minimum Degree: " + str(min_val))
max_val = max(degreeDict.values())#get max number connectivity
print("Maximum Degree: " + str(max_val))
realAvgConnectivity = float(decimal.Decimal(total/G.number_of_nodes()).quantize(decimal.Decimal('.01')))
print("Average Degree (my function): " + str(realAvgConnectivity))
print()#return for readibility
xcoords = list(range(G.number_of_nodes()))
ycoords = list(range(G.number_of_nodes()))
for i in range(G.number_of_nodes()):
ycoords[i] = 0
for i in range(1, max_val+1):
for j in range(G.number_of_nodes()):
if degreeDict[str(j)] == i:
ycoords[i] = ycoords[i] + 1
print()
print(ycoords)
print()
inputFile.close()
centralityDict = nx.degree_centrality(G)
for i in range(G.number_of_nodes()):
centralityDict[str(i)] = float(decimal.Decimal(centralityDict[str(i)]).quantize(decimal.Decimal('.01')))
print("CENTRALITY (networkx function):\n" + str(centralityDict)) # output also doesnt make sense ??????
print("Degree Assortivity (networkx function): \n" + str(nx.degree_assortativity_coefficient(G)))
#nx.draw(G) # draws graph showing edges and nodes
plt.figure(1) # declares "figure" which allows subplots to be made
ax = plt.subplot(111) # declares which numrows, numcols, fignum where fignum ranges from 1 to numrows*numcols
plt.plot(xcoords, ycoords, '-bo')
plt.xlabel('Degree')
plt.ylabel('Number of Nodes')
plt.title('Degree Distribution of Network')
ax.set_xticks(range(G.number_of_nodes()))
ax.set_yticks(range(G.number_of_nodes()))
plt.grid(True)
plt.savefig('path.png')
plt.show() # show graph
'''
@pre: gets passed two strings. The first string should be of the format 'x,y\n' wher x,y are integers. The second string should be a .txt filename
@post: removes listed edge from passed file and appends '_MODIFIED' to the filename if not already there
@returns: boolean value
'''
def removeEdge(edgeToRemove, filename):
oldFile = open(filename, "r") # open file in read only mode
isModifiedBool = isModified(filename) # checks to see if filname has '_MODIFIED' in it
noExtensionList = filename.split('.') # split off .txt extension
noExtension = noExtensionList[0] # take string without .txt extension
if isModifiedBool:
newName = noExtension + '.txt' # adds .txt extension back on if already modified
else:
newName = noExtension + "_MODIFIED.txt" # append '_MODIFIED' to filename with .txt extension
newFile = open(newName, 'w') # create or open file in write only mode
oldList = oldFile.readlines() # read line by line the old .txt file, CAUTION: each line include '\n' at the end
edgeFound = False
complementEdge = findComplement(edgeToRemove) # find the complement of the passed edge to insure complete removal
for i in range(len(oldList)):
if oldList[i] == edgeToRemove: # check to see if edges match, if they do then do NOT write it to new file
edgeFound = True # boolean to confirm the edge was removed
continue # continue to next for loop iteration
elif oldList[i] == complementEdge: # also take out the complement of the edge >>> example: 'x,y\n' = 'y,x\n'
continue
else:
newFile.write(str(oldList[i]))
oldFile.close()
newFile.close()
if edgeFound:
return True
else:
return False
'''
@pre: takes string, should be name of .txt filename
@post: checks to see if filename has _MODIFIED appended to it, artificially throws an error to accomplish it
@returns: boolean value
'''
def isModified(filename):
isModifiedList = filename.split('_') # file format should be city/location_matrix_as_link_pairs_MODIFIED.txt
try:
if isModifiedList[5] == 'MODIFIED.txt': # throws 'out of bounds' exception if NOT modifed
print("\nis modified") # can be taken out
return True
except Exception as e:
print('\nnot modified') # can be taken out
return False
'''
@pre: takes a string, should be of the format 'x,y\n' where x and y are integers
@post: none
@returns: a string of format 'y,x\n' where x,y are integers
'''
def findComplement(edge):
noReturn = edge.replace('\n', '')
noCommaList = noReturn.split(',')
complementEdge = noCommaList[1] + ',' + noCommaList[0] + '\n' # note that 0 and 1 are switched then , and \n is appended back on
return complementEdge
'''
@pre: takes two strings. The first string should be of the format 'x,y\n' where x,y are integers. The second string should be a .txt filename
@post: adds passed edge and its complement to passed file in format 'x,y\n' where x,y are integers. Note: the edges will be added to the bottom of the file
@returns: boolean value
'''
def addEdge(edgeToAdd, filename):
try:
if edgeAlreadyExists(edgeToAdd, filename):
print("ERROR: edge already exists")
else:
oldFile = open(filename, "r")
oldList = oldFile.readlines()
isModifiedBool = isModified(filename)
noExtensionList = filename.split('.') # split off .txt extension
noExtension = noExtensionList[0] # take string without .txt extension
if isModifiedBool:
newName = noExtension + '.txt'
else:
newName = noExtension + "_MODIFIED.txt" # create new filename with .txt extension
newFile = open(newName, 'w')
complement = findComplement(edgeToAdd)
oldList.append(edgeToAdd)
oldList.append(complement)
for i in range(len(oldList)):
newFile.write(oldList[i])
newFile.close()
oldFile.close()
return True
except Exception as e:
print("\nError when adding edge")
return False
##################### TESTING #########################
printProperties('Aarnet-tz_matrix_as_link_pairs.txt')
#######################################################
'''
@pre: takes two strings. The first string should be of the format 'x,y\n' where x,y are integers. The second string should be a .txt filename
@post: opens passed file and checks it for the passed edge
@returns: boolean value
'''
def edgeAlreadyExists(edge, filename):
oldFile = open(filename, "r")
oldList = oldFile.readlines()
for i in range(len(oldList)):
if edge == oldList[i]:
return True
else:
continue
return False
'''
@pre: takes two strings. The first is of the format 'x' where x is an integer. The second string should be a .txt filename
@post: removes all the edges from the passed file that contains the first passed string.
@returns: none
'''
def removeNode(node, filename):
oldFile = open(filename, "r")
oldList = oldFile.readlines()
isModifiedBool = isModified(filename)
noExtensionList = filename.split('.') # split off .txt extension
noExtension = noExtensionList[0] # take string without .txt extension
if isModifiedBool:
newName = noExtension + '.txt'
else:
newName = noExtension + "_MODIFIED.txt" # create new filename with .txt noExtension
newFile = open(newName, 'w')
for i in range(len(oldList)):
noReturnList = oldList[i].split('\n')
noReturn = noReturnList[0]
noCommaList = noReturn.split(',')
if (node == noCommaList[1]) or (node == noCommaList[0]):
continue
else:
newFile.write(oldList[i])