Skip to content

Commit

Permalink
Python 3 compatibility (#1405)
Browse files Browse the repository at this point in the history
* cleanup hashing so hashvalue can be copied
* deterministic sweep ordering
* copy on write for keydict
  • Loading branch information
bqpd authored Jun 20, 2019
1 parent f7b4107 commit df532f7
Show file tree
Hide file tree
Showing 67 changed files with 391 additions and 569 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2018 Edward Burnell
Copyright (c) 2019 Edward Burnell

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
37 changes: 17 additions & 20 deletions MANIFEST
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
gpkit/__init__.py
gpkit/_cvxopt.py
gpkit/_mosek/__init__.py
gpkit/_mosek/cli_expopt.py
gpkit/_mosek/expopt.py
gpkit/build.py
gpkit/_pint/__init__.py
gpkit/_pint/usd_cpi.txt
gpkit/constraints/__init__.py
gpkit/constraints/array.py
gpkit/constraints/bounded.py
gpkit/constraints/costed.py
gpkit/constraints/gp.py
gpkit/constraints/model.py
gpkit/constraints/loose.py
gpkit/constraints/model.py
gpkit/constraints/prog_factories.py
gpkit/constraints/relax.py
gpkit/constraints/set.py
gpkit/constraints/sigeq.py
gpkit/constraints/sgp.py
gpkit/constraints/sigeq.py
gpkit/constraints/single_equation.py
gpkit/constraints/tight.py
gpkit/exceptions.py
gpkit/interactive/__init__.py
gpkit/interactive/chartjs.py
gpkit/interactive/sankey.py
gpkit/interactive/plotting.py
gpkit/interactive/plot_sweep.py
gpkit/interactive/ractor.py
gpkit/interactive/plotting.py
gpkit/interactive/sankey.py
gpkit/interactive/widgets.py
gpkit/keydict.py
gpkit/modified_ctypesgen.py
gpkit/nomials/__init__.py
gpkit/nomials/array.py
gpkit/nomials/data.py
Expand All @@ -36,13 +30,6 @@ gpkit/nomials/math.py
gpkit/nomials/map.py
gpkit/nomials/substitution.py
gpkit/nomials/variables.py
gpkit/_pint/__init__.py
gpkit/_pint/usd_cpi.txt
gpkit/globals.py
gpkit/repr_conventions.py
gpkit/small_classes.py
gpkit/small_scripts.py
gpkit/solution_array.py
gpkit/tests/__init__.py
gpkit/tests/from_paths.py
gpkit/tests/helpers.py
Expand All @@ -62,7 +49,17 @@ gpkit/tests/test_repo.py
gpkit/tools/__init__.py
gpkit/tools/autosweep.py
gpkit/tools/docstring.py
gpkit/tools/spdata.py
gpkit/tools/tools.py
gpkit/__init__.py
gpkit/_cvxopt.py
gpkit/build.py
gpkit/exceptions.py
gpkit/globals.py
gpkit/keydict.py
gpkit/modified_ctypesgen.py
gpkit/repr_conventions.py
gpkit/small_classes.py
gpkit/small_scripts.py
gpkit/solution_array.py
gpkit/varkey.py
setup.py
6 changes: 4 additions & 2 deletions checkpy3.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cp gpkit/env/settings .
sed -i '1s/.*/installed_solvers : mosek_cli/' gpkit/env/settings
sed -i '1s/.*/installed_solvers : mosek, cvxopt/' gpkit/env/settings
cat gpkit/env/settings
python3 docs/source/examples/simpleflight.py
python3 gpkit/tests/run_tests.py
mv settings gpkit/env
rm *.pkl
rm solution.*
4 changes: 2 additions & 2 deletions docs/source/citinggpkit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ If you use GPkit, please cite it with the following bibtex::
author={Edward Burnell and Warren Hoburg},
title={GPkit software for geometric programming},
howpublished={\url{https://github.com/convexengineering/gpkit}},
year={2018},
note={Version 0.8.0}
year={2014},
note={Version 0.9.0}
}
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@

# General information about the project.
project = u'gpkit'
copyright = u'2018 Edward Burnell'
copyright = u'2019 Edward Burnell'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.8'
version = '0.9'
# The full version, including alpha/beta/rc tags.
release = '0.8.0'
release = '0.9.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
22 changes: 11 additions & 11 deletions docs/source/examples/autosweep.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"Show autosweep_1d functionality"
import cPickle as pickle
import pickle
import numpy as np
import gpkit
from gpkit import units, Variable, Model
Expand All @@ -12,17 +12,17 @@
m1 = Model(A**2, [A >= l**2 + units.m**2])
tol1 = 1e-3
bst1 = autosweep_1d(m1, tol1, l, [1, 10], verbosity=0)
print "Solved after %2i passes, cost logtol +/-%.3g" % (bst1.nsols, bst1.tol)
print("Solved after %2i passes, cost logtol +/-%.3g" % (bst1.nsols, bst1.tol))
# autosweep solution accessing
l_vals = np.linspace(1, 10, 10)
sol1 = bst1.sample_at(l_vals)
print "values of l:", l_vals
print "values of A:", sol1("A")
print("values of l: %s" % l_vals)
print("values of A: %s" % sol1("A"))
cost_estimate = sol1["cost"]
cost_lb, cost_ub = sol1.cost_lb(), sol1.cost_ub()
print "cost lower bound:", cost_lb
print "cost estimate: ", cost_estimate
print "cost upper bound:", cost_ub
print("cost lower bound: %s" % cost_lb)
print("cost estimate: %s" % cost_estimate)
print("cost upper bound: %s" % cost_ub)
# you can evaluate arbitrary posynomials
np.testing.assert_allclose(mag(2*sol1(A)), mag(sol1(2*A)))
assert (sol1["cost"] == sol1(A**2)).all()
Expand All @@ -31,7 +31,7 @@
np.log(mag(cost_estimate)))
# save autosweep to a file and retrieve it
bst1.save("autosweep.pkl")
bst1_loaded = pickle.load(open("autosweep.pkl"))
bst1_loaded = pickle.load(open("autosweep.pkl", "rb"))

# this problem is two intersecting lines in logspace
m2 = Model(A**2, [A >= (l/3)**2, A >= (l/3)**0.5 * units.m**1.5])
Expand All @@ -40,6 +40,6 @@
# test Model method
sol2 = m2.autosweep({l: [1, 10]}, tol2, verbosity=0)
bst2 = sol2.bst
print "Solved after %2i passes, cost logtol +/-%.3g" % (bst2.nsols, bst2.tol)
print "Table of solutions used in the autosweep:"
print bst2.solarray.table()
print("Solved after %2i passes, cost logtol +/-%.3g" % (bst2.nsols, bst2.tol))
print("Table of solutions used in the autosweep:")
print(bst2.solarray.table())
4 changes: 2 additions & 2 deletions docs/source/examples/beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Beam(Model):
"""
def setup(self, N=4):
exec parse_variables(self.__doc__)
exec(parse_variables(self.__doc__))
# minimize tip displacement (the last w)
self.cost = self.w_tip = w[-1]
return {
Expand Down Expand Up @@ -68,7 +68,7 @@ def setup(self, N=4):

b = Beam(N=6, substitutions={"L": 6, "EI": 1.1e4, "q": 110*np.ones(6)})
sol = b.solve(verbosity=0)
print sol.summary(maxcolumns=6)
print(sol.summary(maxcolumns=6))
w_gp = sol("w") # deflection along beam

L, EI, q = sol("L"), sol("EI"), sol("q")
Expand Down
4 changes: 2 additions & 2 deletions docs/source/examples/boundschecking.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class BoundsChecking(Model):
"""
def setup(self):
exec parse_variables(BoundsChecking.__doc__)
exec(parse_variables(BoundsChecking.__doc__))
self.cost = F
return [
F >= D + T,
Expand All @@ -43,7 +43,7 @@ def setup(self):


m = BoundsChecking()
print m.str_without(["lineage"])
print(m.str_without(["lineage"]))
try:
m.solve()
except ValueError:
Expand Down
5 changes: 2 additions & 3 deletions docs/source/examples/debug.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"Debug examples"

from gpkit import Variable, Model, units

x = Variable("x", "ft")
Expand All @@ -10,11 +9,11 @@
m = Model(x/y, [x <= x_max, x >= x_min])
m.debug()

print "# Now let's try a model unsolvable with relaxed constants\n"
print("# Now let's try a model unsolvable with relaxed constants\n")

Model(x, [x <= units("inch"), x >= units("yard")]).debug()

print "# And one that's only unbounded\n"
print("# And one that's only unbounded\n")

# the value of x_min was used up in the previous model!
x_min = Variable("x_min", 2, "ft")
Expand Down
6 changes: 3 additions & 3 deletions docs/source/examples/docstringparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ class Cube(Model):
way that makes the most sense to someone else reading your model.
"""
def setup(self):
exec parse_variables(Cube.__doc__)
exec(parse_variables(Cube.__doc__))

return [A >= 2*(s[0]*s[1] + s[1]*s[2] + s[2]*s[0]),
s.prod() >= V,
s[2] >= h]


print parse_variables(Cube.__doc__)
print(parse_variables(Cube.__doc__))
c = Cube()
c.cost = c.A
print c.solve(verbosity=0).table()
print(c.solve(verbosity=0).table())
8 changes: 4 additions & 4 deletions docs/source/examples/docstringparsing_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ from gpkit import Variable, VectorVariable

try:
A = self.A = Variable('A', 'm^2', 'surface area')
except Exception, e:
except Exception as e:
raise ValueError("`"+e.__class__.__name__+": "+str(e)+"` was raised"
" while executing the parsed line `A = self.A = Variable('A', 'm^2', 'surface area')`. Is this line following the format `Name (optional Value) [Units] (Optional Description)` without any whitespace in the Name or Value fields?")

try:
V = self.V = Variable('V', 100, 'L', 'minimum volume')
except Exception, e:
except Exception as e:
raise ValueError("`"+e.__class__.__name__+": "+str(e)+"` was raised"
" while executing the parsed line `V = self.V = Variable('V', 100, 'L', 'minimum volume')`. Is this line following the format `Name (optional Value) [Units] (Optional Description)` without any whitespace in the Name or Value fields?")

try:
h = self.h = Variable('h', 1, 'm', 'minimum height')
except Exception, e:
except Exception as e:
raise ValueError("`"+e.__class__.__name__+": "+str(e)+"` was raised"
" while executing the parsed line `h = self.h = Variable('h', 1, 'm', 'minimum height')`. Is this line following the format `Name (optional Value) [Units] (Optional Description)` without any whitespace in the Name or Value fields?")

try:
s = self.s = VectorVariable(3, 's', 'm', 'side length')
except Exception, e:
except Exception as e:
raise ValueError("`"+e.__class__.__name__+": "+str(e)+"` was raised"
" while executing the parsed line `s = self.s = VectorVariable(3, 's', 'm', 'side length')`. Is this line following the format `Name (optional Value) [Units] (Optional Description)` without any whitespace in the Name or Value fields?")

Expand Down
3 changes: 1 addition & 2 deletions docs/source/examples/external_sp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"Can be found in gpkit/docs/source/examples/external_sp.py"

import numpy as np
from gpkit import Variable, Model
from external_constraint import ExternalConstraint
Expand All @@ -15,4 +14,4 @@
]

m = Model(objective, constraints)
print m.localsolve(verbosity=0).summary()
print(m.localsolve(verbosity=0).summary())
2 changes: 1 addition & 1 deletion docs/source/examples/external_sp2.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ def y_ext(self, x0):
y = Variable("y", externalfn=y_ext)

m = Model(y, [np.pi/4 <= x, x <= np.pi/2])
print m.localsolve(verbosity=0).summary()
print(m.localsolve(verbosity=0).summary())
6 changes: 3 additions & 3 deletions docs/source/examples/model_var_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ def setup(self):
m >= sum(comp.m for comp in components)]

PS = PowerSystem()
print "Getting the only var 'E': ", PS["E"]
print "The top-level var 'm': ", PS.m
print "All the variables 'm': ", PS.variables_byname("m")
print("Getting the only var 'E': %s" % PS["E"])
print("The top-level var 'm': %s" % PS.m)
print("All the variables 'm': %s" % PS.variables_byname("m"))
6 changes: 3 additions & 3 deletions docs/source/examples/model_var_access_output.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Getting the only var 'E': E_PowerSystem/Battery [MJ]
The top-level var 'm': m_PowerSystem [lb]
All the variables 'm': [gpkit.Variable(m_PowerSystem [lb]), gpkit.Variable(m_PowerSystem/Battery [lb]), gpkit.Variable(m_PowerSystem/Motor [lb])]
Getting the only var 'E': E_PowerSystem/Battery [MJ]
The top-level var 'm': m_PowerSystem [lb]
All the variables 'm': [gpkit.Variable(m_PowerSystem [lb]), gpkit.Variable(m_PowerSystem/Battery [lb]), gpkit.Variable(m_PowerSystem/Motor [lb])]
18 changes: 9 additions & 9 deletions docs/source/examples/performance_modeling.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Modular aircraft concept"""
import cPickle as pickle
import pickle
import numpy as np
from gpkit import Model, Vectorize, parse_variables

Expand All @@ -24,7 +24,7 @@ class AircraftP(Model):
def setup(self, aircraft, state):
self.aircraft = aircraft
self.state = state
exec parse_variables(AircraftP.__doc__)
exec(parse_variables(AircraftP.__doc__))

self.wing_aero = aircraft.wing.dynamic(aircraft.wing, state)
self.perf_models = [self.wing_aero]
Expand Down Expand Up @@ -63,7 +63,7 @@ class Aircraft(Model):
wing.c, wing.S
"""
def setup(self):
exec parse_variables(Aircraft.__doc__)
exec(parse_variables(Aircraft.__doc__))
self.fuse = Fuselage()
self.wing = Wing()
self.components = [self.fuse, self.wing]
Expand All @@ -88,7 +88,7 @@ class FlightState(Model):
"""
def setup(self):
exec parse_variables(FlightState.__doc__)
exec(parse_variables(FlightState.__doc__))


class FlightSegment(Model):
Expand Down Expand Up @@ -168,7 +168,7 @@ class WingAero(Model):
def setup(self, wing, state):
self.wing = wing
self.state = state
exec parse_variables(WingAero.__doc__)
exec(parse_variables(WingAero.__doc__))

c = wing.c
A = wing.A
Expand Down Expand Up @@ -206,7 +206,7 @@ class Wing(Model):
c, S
"""
def setup(self):
exec parse_variables(Wing.__doc__)
exec(parse_variables(Wing.__doc__))
return {"parametrization of wing weight":
W >= S*rho,
"definition of mean chord":
Expand All @@ -226,7 +226,7 @@ class Fuselage(Model):
"""
def setup(self):
exec parse_variables(Fuselage.__doc__)
exec(parse_variables(Fuselage.__doc__))


AC = Aircraft()
Expand All @@ -247,8 +247,8 @@ def setup(self):
is MISSION.fs.aircraftp)
vars_of_interest.update(MISSION.fs.aircraftp.unique_varkeys)
vars_of_interest.add(M["D"])
print sol.summary(vars_of_interest)
print sol.table(tables=["loose constraints"])
print(sol.summary(vars_of_interest))
print(sol.table(tables=["loose constraints"]))

MISSION["flight segment"]["aircraft performance"]["fuel burn rate"] = (
MISSION.fs.aircraftp.Wburn >= 0.2*MISSION.fs.aircraftp.wing_aero.D)
Expand Down
Loading

0 comments on commit df532f7

Please sign in to comment.