From 5316fabc6dea5903ef55dbde78bfe222c03de820 Mon Sep 17 00:00:00 2001 From: Vincent Cui Date: Sun, 27 Nov 2016 01:48:24 +0800 Subject: [PATCH 1/4] GPH SUPPORT ADDED --- lib/PlanPrinter.py | 69 ++++++++++++++++++++++++++++++++++++---------- maxfield.py | 20 ++++++++++---- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/lib/PlanPrinter.py b/lib/PlanPrinter.py index 9a1df32..6e4f5e8 100644 --- a/lib/PlanPrinter.py +++ b/lib/PlanPrinter.py @@ -31,7 +31,7 @@ import networkx as nx import electricSpring import time - +import re # returns the points in a shrunken toward their centroid def shrink(a): centroid = a.mean(1).reshape([2,1]) @@ -141,11 +141,11 @@ def agentKeys(self): fout.write('Map# Keys Name\n') for portal in self.nameOrder: - + keys = self.agentkeyneeds[agent,portal] if self.agentkeyneeds[agent,portal] == 0: keys = '' - + fout.write(rowFormat%(\ self.nslabel[portal],\ keys,\ @@ -249,7 +249,7 @@ def planMap(self): va = 'bottom' else: va = 'top' - + plt.text(self.xy[i,0],self.xy[i,1],str(j),ha=ha,va=va) @@ -278,7 +278,6 @@ def planMap(self): # plt.clf() def agentLinks(self): - # Total distance traveled by each agent agentdists = np.zeros(self.nagents) # Total number of links, fields for each agent @@ -309,7 +308,7 @@ def agentLinks(self): # plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n {5:4d} {6:s}\n\n' plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s} -> {5:d} {6:s}\n' hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n {5:4d} {6:s}\n\n' - + totalTime = self.a.walktime+self.a.linktime+self.a.commtime for agent in range(self.nagents): @@ -319,7 +318,7 @@ def agentLinks(self): fout.write('Complete link schedule issued to agent %s of %s %s\n\n'\ %(agent+1,self.nagents,time.strftime('%Y-%m-%d %H:%M:%S %Z'))) fout.write('\nLinks marked with * can be made EARLY\n') - + fout.write('----------- PLAN DATA ------------\n') fout.write('Minutes: %s minutes\n'%int(totalTime/60+.5)) fout.write('Total Distance: %s meter\n'%int(totalDist)) @@ -341,11 +340,11 @@ def agentLinks(self): fout.write(' Link Destination\n') fout.write('----------------------------------\n') # 1234112345612345 name - + last_link_from_other_agent = 0 for i in xrange(self.m): p,q = self.orderedEdges[i] - + linkagent = self.link2agent[i] # Put a star by links that can be completed early since they complete no fields @@ -374,6 +373,7 @@ def agentLinks(self): if last_link_from_other_agent: fout.write('\n') last_link_from_other_agent = 0 + fout.write(hilitStr.format(\ i,\ star,\ @@ -396,7 +396,7 @@ def animate(self): INVISIBLE = ( 0.0 , 0.0 , 0.0 , 0.0 ) portals = np.array([self.a.node[i]['xy'] for i in self.a.nodes_iter()]).T - + # Plot all edges lightly def dashAllEdges(): for p,q in self.a.edges_iter(): @@ -441,7 +441,7 @@ def dashAllEdges(): # newPatches.append(Polygon(shrink(coords.T).T,facecolor=GREEN,\ # edgecolor=INVISIBLE)) # print '%s new patches'%len(newPatches) - + aptotal += 313+1250*len(newPatches) newEdge = np.array([self.a.node[p]['xy'],self.a.node[q]['xy']]).T @@ -455,7 +455,7 @@ def dashAllEdges(): # newEdge[0,1]-newEdge[0,0],\ # newEdge[1,1]-newEdge[1,0],\ # fc="k", ec="k")#,head_width=0.0005,head_length=0.001 ) - + plt.plot(newEdge[0],newEdge[1],'k-',lw=2) # plt.plot(newEdge[0],newEdge[1],'g-') @@ -488,7 +488,7 @@ def dashAllEdges(): def split3instruct(self): portals = np.array([self.a.node[i]['xy'] for i in self.a.nodes_iter()]).T - + gen1 = self.a.triangulation oldedges = [] @@ -512,7 +512,7 @@ def split3instruct(self): if len(newedges) == 0: break - + plt.plot(portals[0],portals[1],'go') for edge in oldedges: @@ -520,7 +520,7 @@ def split3instruct(self): for edge in newedges: plt.plot(edge[0],edge[1],'r-') - + oldedges += newedges plt.axis('off') @@ -538,3 +538,42 @@ def split3instruct(self): plt.savefig(self.outputDir+'depth_%s.png'%depth) plt.clf() + def gph(self, gphFile): + input_file = open(gphFile, "r") + new_content = ["digraph PortalLinks {"] + max_input = [] + for line in input_file: + # N1[label="23.1197,113.175007", pos="(16.659203,0.0)"] + gphpat = re.compile('^(.*?)\[label="(.*?),(.*?)",\s+pos="\((.*?),(.*?)\)"') + m = gphpat.match(line) + if m == None: + continue + g = m.groups() + name = g[0] + label1 = g[1] + label2 = g[2] + pos1 = round(float(g[3]), 5) + pos2 = round(float(g[4]), 5) + + new_content.append( + '{}[label="{},{}", pos="({},{})"]'.format( + name, label1, label2, pos1, pos2 + )) + max_input.append( + "{};https://ingress.com/intel?ll={},{}&&z=17&&pll={},{};".format(name, + label1, label2, label1, label2)) + input_file.close() + + for i in range(0, self.m): + (poFrom, poTo) = self.orderedEdges[i] + new_content.append( + "{} -> {}".format(self.names[poFrom], self.names[poTo])) + new_content.append("}\r\n") + result = "\r\n".join(new_content) + output_file = open(self.outputDir + "result.gph", "w") + output_file.write(result) + output_file.close() + + max_file = open(self.outputDir + "max.csv", "w") + max_file.write("\n".join(max_input)) + max_file.close diff --git a/maxfield.py b/maxfield.py index 065330f..41dafc5 100644 --- a/maxfield.py +++ b/maxfield.py @@ -45,7 +45,7 @@ input_file: One of two types of files: - .csv formatted as - + portal name ; lat ; lng [; keys] OR portal name ; Intel map URL [;keys] @@ -93,6 +93,9 @@ def main(): output_directory = args[''] if output_directory[-1] != '/': output_directory += '/' + else: + output_directory = "output/" + output_file = 'lastPlan.pkl' if not args[''] is None: @@ -116,6 +119,10 @@ def main(): urlpat = re.compile('^([^;]*);.*ll=([-0-9\.]+),([-0-9\.]+)\s*;?\s*(\d+)?') # name ; lat ; lng ; keys cvspat = re.compile('^([^;]*);\s*([-0-9\.]+)\s*;\s*([-0-9\.]+)\s*;?\s*(\d+)?') + # gph file input: name[label="lat,lng", pos="(0,164.84227554585027)"] + gphpat = re.compile('^(.*?)\[label="(.*?),(.*?)",.*?(\d+)?') + + i = 0 # each line should be id,name,lat,long,keys with open(input_file,'r') as fin: @@ -123,10 +130,11 @@ def main(): m = urlpat.match(line) if m is None: m = cvspat.match(line) + if m is None: + m = gphpat.match(line) if m is None: continue g = m.groups() -# print g a.add_node(i) a.node[i]['name'] = g[0] @@ -154,7 +162,7 @@ def main(): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] - + makeFields.maxFields(a) ''' @@ -185,7 +193,7 @@ def main(): TK += keylack if keylack > MK: MK = keylack - + weightedlack = TK+2*MK if weightedlack < bestlack: @@ -242,6 +250,9 @@ def main(): PP.agentKeys() PP.planMap() PP.agentLinks() + print input_file[-3:] == "gph" + if (input_file[-3:] == "gph"): + PP.gph(input_file) # These make step-by-step instructional images #PP.animate() @@ -249,4 +260,3 @@ def main(): if __name__ == "__main__": sys.exit(main()) - From e29b6b4dacbe136ebe5e9dea7416f0a4a2986b7a Mon Sep 17 00:00:00 2001 From: Vincent Cui Date: Mon, 28 Nov 2016 00:49:36 +0800 Subject: [PATCH 2/4] Added: inplan.py --- README.maxfield.md | 140 +++++++++++++++++++++++++++++++++++++++++++ README.md | 146 ++++++++++----------------------------------- inplan.py | 119 ++++++++++++++++++++++++++++++++++++ maxfield.py | 0 4 files changed, 290 insertions(+), 115 deletions(-) create mode 100644 README.maxfield.md create mode 100755 inplan.py mode change 100644 => 100755 maxfield.py diff --git a/README.maxfield.md b/README.maxfield.md new file mode 100644 index 0000000..a516b12 --- /dev/null +++ b/README.maxfield.md @@ -0,0 +1,140 @@ +# Introduction + +This code is designed to make a plan for linking a given set of portals in the +way (and the order) that creates the most fields. This is harder than it sounds. +If you're working on more than a dozen portals, learning to use this code may +be faster than planning by hand. + +This code follows the procedure in my [YouTube video][0]. + +# Prerequisites + +You'll need [Python][2] (I've got 2.7) as well as networkx, numpy, and matplotlib. + +You can get these setup easily with the [Enthought Python Distribution][1]. + +You can use [pip][3] to install the dependencies via: + + pip install -r requirements.txt + +# Example + +I'll be distributing this code with a file EXAMPLE.csv. Try running + + python maxfield.py -n 4 EXAMPLE.csv output/ output.pkl + +This will put a bunch of files into the "output/" directory (see OUTPUT FILE LIST) + +Now try running + + python maxfield.py -n 3 output/output.pkl + +This uses the plan stored in output.pkl instead of calculating a new one. It will create files for 3 agents instead of 4. + +### OUTPUT FILE LIST + + keyPrep.txt + List of portals, their numbers on the map, and how many keys are needed + + keys_for_agent_M_of_N.txt + List of keys agent number M will need (if N agents are participating) + + links_for_agent_M_of_N.txt + List of ALL the links + Total distance traveled and AP earned by agent number M + * Except for the links marked with a star (*), the links should be made IN THE ORDER LISTED + * Links with a star can be made out of order, but only EARLY i.e. BEFORE their position in the list (this can save you time) + * The links that agent number M makes are marked with underscores__ + * The first portal listed is the origin portal (where the agent must be) + * The second portal listed is the destination portal (for which the agent must have a key) + + portalMap.png + A map showing the locations of the portals + linkMap.png + A map showing the locations of portals and links + * Up is north + * Portal numbers increase from north to south + * Portal numbers match "keyPrep.txt" and "linkes_for_agent_M_of_N.txt" + * Link numbers match those in the link schedules "links_for_agent_M_of_N.txt" + + ownershipPrep.txt + List of portals whose first link is incoming + * These portals need to be captured and fully powered before the linking operation + List of portals whose first link is outgoing + * You may be able to save time by capturing and fully powering these portals DURING the linking operation + + lastPlan.pkl + A Python pickle file containing all portal and plan information + * The default name is "lastPlan.pkl" + * In the examples above, this is called "output.pkl" + +# Usage + + python maxfield.py [-b] [-n agent_count] input_file [output_directory] [output_file] + + -b: Include this option if you like your maps blue instead of green for any reason + + agent_count: Number of agents for which to make a plan + + input_file: One of two types of files: + .csv + a semicolon-delimited file + the actual file extension does not matter as long as it is not ".pkl" + + two acceptable formats: + + portal name ; lat ; lng [;keys] + OR + portal name ; Intel URL [;keys] + + To get the Intel URL: + * Click on the portal at ingress.com/intel + * Click on "Link" near the top right of the screen + * Copy and paste the URL from the box that appears + Example of an Intel URL: + https://www.ingress.com/intel?ll=29.719016,-95.397893&z=19&pll=29.719011,-95.397881 + + portal name should not contain a semicolon + lat and lng should be the portal's global coordinates + e.g. the Big Ben portal is at 51.500775,-0.124466 + keys (optional parameter) is the number of keys you have for the portal + If you leave this blank, the program assumes you have no keys + + .pkl an output from a previous run of this program + this can be used to make the same plan with a different number of agents + + output_directory: directory in which to put all output + default is the working directory + + output_file: name for a .pkl file containing information on the plan + if you later use this for the input file, the same plan will be + produced with the number of agents you specify (default: "lastPlan.pkl") + +# Warranty and Copyright + +Copyright (C) 2015 by Jonathan Baker: babamots@gmail.com + +Maxfield is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Maxfield is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Maxfield in a file called COPYING.txt. If not, see +. + +# Notes + +The space of possible field-maximizing plans is large. Rather than trying every +possibility, Maxfield randomly tries some plans and presents you with one. + +[0]: https://www.youtube.com/watch?v=priezq6Dm4Y +[1]: https://www.enthought.com/downloads/ +[2]: https://www.python.org/download/releases/2.7 +[3]: https://pypi.python.org/pypi/pip + diff --git a/README.md b/README.md index a516b12..7b33e2c 100644 --- a/README.md +++ b/README.md @@ -1,140 +1,56 @@ -# Introduction +# Maxfield and others -This code is designed to make a plan for linking a given set of portals in the -way (and the order) that creates the most fields. This is harder than it sounds. -If you're working on more than a dozen portals, learning to use this code may -be faster than planning by hand. +## Introduction -This code follows the procedure in my [YouTube video][0]. +**Forks from [maxfield](https://github.com/jpeterbaker/maxfield), Thank you** -# Prerequisites +I'm using Ingress Planner + InGraph. +but it seems that maxfield is better than Ingraph, and the most important is +that it's built by python. -You'll need [Python][2] (I've got 2.7) as well as networkx, numpy, and matplotlib. +Added some feature **(only valid for single agent)** to the original maxfield. -You can get these setup easily with the [Enthought Python Distribution][1]. +## Prerequisites (from maxfield) -You can use [pip][3] to install the dependencies via: +You'll need [Python] (I've got 2.7) as well as networkx, numpy, and matplotlib. - pip install -r requirements.txt +You can use [pip] to install the dependencies via: -# Example + `pip install -r requirements.txt` -I'll be distributing this code with a file EXAMPLE.csv. Try running +## Features - python maxfield.py -n 4 EXAMPLE.csv output/ output.pkl +### Support for '.gph' files -This will put a bunch of files into the "output/" directory (see OUTPUT FILE LIST) +You can get '.gph' files from [ingressplanner](www.ingressplanner.net). And use +it as a common '.csv' file. -Now try running +After the plan is generated, in the output dir, you can find a file named +'result.gph', it can be imported into ingressplanner. - python maxfield.py -n 3 output/output.pkl +### Support for [ingress-maxfield](http://www.ingress-maxfield.com/) -This uses the plan stored in output.pkl instead of calculating a new one. It will create files for 3 agents instead of 4. +We will also generate a file named 'max.csv' for the site mentioned above. -### OUTPUT FILE LIST +## Inplan.py - keyPrep.txt - List of portals, their numbers on the map, and how many keys are needed +Usage: `python inplan.py [input_file] [output_path] [plan_count]` - keys_for_agent_M_of_N.txt - List of keys agent number M will need (if N agents are participating) +Input file and output path is the same as `maxfield.py`. - links_for_agent_M_of_N.txt - List of ALL the links - Total distance traveled and AP earned by agent number M - * Except for the links marked with a star (*), the links should be made IN THE ORDER LISTED - * Links with a star can be made out of order, but only EARLY i.e. BEFORE their position in the list (this can save you time) - * The links that agent number M makes are marked with underscores__ - * The first portal listed is the origin portal (where the agent must be) - * The second portal listed is the destination portal (for which the agent must have a key) +`plan_count` here to tell maxfield that how many plans to create. - portalMap.png - A map showing the locations of the portals - linkMap.png - A map showing the locations of portals and links - * Up is north - * Portal numbers increase from north to south - * Portal numbers match "keyPrep.txt" and "linkes_for_agent_M_of_N.txt" - * Link numbers match those in the link schedules "links_for_agent_M_of_N.txt" +After all plans had been created. you can find many plans folder in `output_path`. - ownershipPrep.txt - List of portals whose first link is incoming - * These portals need to be captured and fully powered before the linking operation - List of portals whose first link is outgoing - * You may be able to save time by capturing and fully powering these portals DURING the linking operation +And two files. - lastPlan.pkl - A Python pickle file containing all portal and plan information - * The default name is "lastPlan.pkl" - * In the examples above, this is called "output.pkl" +### key.csv -# Usage +Every line is a record of a plan. +Each cell will show you keys needed of a portal in this plan. +stddev? you know it. - python maxfield.py [-b] [-n agent_count] input_file [output_directory] [output_file] - -b: Include this option if you like your maps blue instead of green for any reason - - agent_count: Number of agents for which to make a plan - - input_file: One of two types of files: - .csv - a semicolon-delimited file - the actual file extension does not matter as long as it is not ".pkl" - - two acceptable formats: - - portal name ; lat ; lng [;keys] - OR - portal name ; Intel URL [;keys] - - To get the Intel URL: - * Click on the portal at ingress.com/intel - * Click on "Link" near the top right of the screen - * Copy and paste the URL from the box that appears - Example of an Intel URL: - https://www.ingress.com/intel?ll=29.719016,-95.397893&z=19&pll=29.719011,-95.397881 - - portal name should not contain a semicolon - lat and lng should be the portal's global coordinates - e.g. the Big Ben portal is at 51.500775,-0.124466 - keys (optional parameter) is the number of keys you have for the portal - If you leave this blank, the program assumes you have no keys - - .pkl an output from a previous run of this program - this can be used to make the same plan with a different number of agents - - output_directory: directory in which to put all output - default is the working directory - - output_file: name for a .pkl file containing information on the plan - if you later use this for the input file, the same plan will be - produced with the number of agents you specify (default: "lastPlan.pkl") - -# Warranty and Copyright - -Copyright (C) 2015 by Jonathan Baker: babamots@gmail.com - -Maxfield is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Maxfield is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Maxfield in a file called COPYING.txt. If not, see -. - -# Notes - -The space of possible field-maximizing plans is large. Rather than trying every -possibility, Maxfield randomly tries some plans and presents you with one. - -[0]: https://www.youtube.com/watch?v=priezq6Dm4Y -[1]: https://www.enthought.com/downloads/ -[2]: https://www.python.org/download/releases/2.7 -[3]: https://pypi.python.org/pypi/pip +### summary.csv +Here you can find walking distance and move count of each plan. diff --git a/inplan.py b/inplan.py new file mode 100755 index 0000000..bae17e2 --- /dev/null +++ b/inplan.py @@ -0,0 +1,119 @@ +#! /usr/bin/env python +import subprocess +import re +import sys +import os +import multiprocessing +import numpy + + +def worker(plan_number): + output_dir = os.path.join(output_path, "plan" + str(plan_number)) + os.makedirs(output_dir) + cmd = ["maxfield", input_file, output_dir] + subprocess.check_output(cmd) + print "Plan {} finished.".format(plan_number) + +def summarize(plan_count): + print "Making the summarized table." + summarized_content = ["{},{},{},{},{}".format("Plan", "Links", + "Fields", "Distance", "Changed")] + keys_content = [] + for i in range(0, plan_count): + plan_path = os.path.join(output_path, "plan" + str(i)) + data_file = open( + os.path.join(plan_path,"links_for_agent_1_of_1.txt"), + "r") + r_distance = re.compile("Total Distance:\s+(\d+)\s+meter") + r_links = re.compile("Links made:\s+(\d+)") + r_fields = re.compile("Fields completed:\s+(\d+)") + r_link_desc = re.compile("^(.*?)\s?->\s?(.*?)$") + # 2 | 2 | N1 + r_key = re.compile("\s+(\d+)\s+\|\s+(\d+)\s+\|\s+(.*?)$") + for line in data_file: + m_distance = r_distance.match(line) + m_links = r_links.match(line) + m_fields = r_fields.match(line) + if m_distance: + distance = m_distance.groups()[0] + if m_links: + links = m_links.groups()[0] + if m_fields: + fields = m_fields.groups()[0] + data_file.close() + # How many times do we change the "Start" Portal? + data_file = open( + os.path.join(plan_path,"result.gph"), + "r") + changed_count = 0 + current_start = "" + for line in data_file: + if r_link_desc.match(line): + g = r_link_desc.match(line).groups() + if g[0] != current_start: + current_start = g[0] + changed_count = changed_count + 1 + data_file.close() + + # keys + data_file = open( + os.path.join(plan_path,"keyPrep.txt"), + "r") + key_total = 0; + key_plan = {} + for lines in data_file: + m_keys = r_key.match(lines) + if m_keys == None: + continue + g_keys = m_keys.groups() + key_name = g_keys[2] + key_count = g_keys[0] + key_plan[key_name] = key_count + data_file.close() + if (len(keys_content) == 0): + first_line = "" + for key_name in sorted(key_plan.keys()): + first_line = first_line + key_name + "," + first_line = first_line + "stddev" + keys_content.append("plan," + first_line) + key_line = str(i) + "," + key_list = [] + for key_name in sorted(key_plan.keys()): + key_line = key_line + str(key_plan[key_name]) + "," + key_list.append(int(key_plan[key_name])) + stddev = numpy.std(key_list) + keys_content.append(key_line + str(stddev)) + + summary_line = "{},{},{},{},{}".format(i, + links, fields, distance, changed_count) + summarized_content.append(summary_line) + + summary_file = open(os.path.join(output_path, "summary.csv"), "w") + summary_file.write("\n".join(summarized_content)) + summary_file.close() + key_file = open(os.path.join(output_path, "key.csv"), "w") + key_file.write("\n".join(keys_content)) + key_file.close(); + + + +def main(plan_count): + # for i in range(0, int(plan_count)): + # output_dir = os.path.join(output_path, "plan" + str(i)) + # print output_dir + # os.makedirs(output_dir) + # cmd = ["maxfield", input_file, output_dir] + # subprocess.check_output(cmd) + # return 0 + count = multiprocessing.cpu_count() + pool = multiprocessing.Pool(processes=count) + pool.map(worker, range(0, int(plan_count))) + summarize(int(plan_count)) + +if __name__ == "__main__": + if len(sys.argv) != 4: + print "Usage: {} [input_file] [output_path] [plan_count]".format(sys.argv[0]) + else: + input_file = sys.argv[1] + output_path = sys.argv[2] + main(sys.argv[3]) diff --git a/maxfield.py b/maxfield.py old mode 100644 new mode 100755 From 161e1332716ef51ee171191d1813f0e5cce3ca25 Mon Sep 17 00:00:00 2001 From: Vincent Cui Date: Mon, 28 Nov 2016 01:07:29 +0800 Subject: [PATCH 3/4] summary only worked for gph --- inplan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inplan.py b/inplan.py index bae17e2..cc0660e 100755 --- a/inplan.py +++ b/inplan.py @@ -108,7 +108,8 @@ def main(plan_count): count = multiprocessing.cpu_count() pool = multiprocessing.Pool(processes=count) pool.map(worker, range(0, int(plan_count))) - summarize(int(plan_count)) + if (input_file[-3] == "gph"): + summarize(int(plan_count)) if __name__ == "__main__": if len(sys.argv) != 4: From 5b4e2be81abf64b69525d3ca33725c5482e16399 Mon Sep 17 00:00:00 2001 From: Vincent Cui Date: Mon, 28 Nov 2016 01:23:33 +0800 Subject: [PATCH 4/4] bug --- inplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inplan.py b/inplan.py index cc0660e..a98b139 100755 --- a/inplan.py +++ b/inplan.py @@ -108,7 +108,7 @@ def main(plan_count): count = multiprocessing.cpu_count() pool = multiprocessing.Pool(processes=count) pool.map(worker, range(0, int(plan_count))) - if (input_file[-3] == "gph"): + if (input_file[-3:] == "gph"): summarize(int(plan_count)) if __name__ == "__main__":