Skip to content

Commit

Permalink
working parse var for py3, just needs line numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
bqpd committed Aug 5, 2019
1 parent 20d82e3 commit cf61433
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 31 deletions.
60 changes: 32 additions & 28 deletions docs/source/examples/performance_modeling.py
@@ -1,7 +1,7 @@
"""Modular aircraft concept"""
import pickle
import numpy as np
from gpkit import Model, Vectorize, parse_variables
from gpkit import Model, Vectorize, parse_variables, pv_decorater


class AircraftP(Model):
Expand All @@ -21,10 +21,10 @@ class AircraftP(Model):
Wfuel, aircraft.W, state.mu
"""
@pv_decorater(__doc__, globals())
def setup(self, aircraft, state):
self.aircraft = aircraft
self.state = state
exec(parse_variables(AircraftP.__doc__))

self.wing_aero = aircraft.wing.dynamic(aircraft.wing, state)
self.perf_models = [self.wing_aero]
Expand Down Expand Up @@ -62,8 +62,8 @@ class Aircraft(Model):
---------------
wing.c, wing.S
"""
@pv_decorater(__doc__, globals())
def setup(self):
exec(parse_variables(Aircraft.__doc__))
self.fuse = Fuselage()
self.wing = Wing()
self.components = [self.fuse, self.wing]
Expand All @@ -87,8 +87,9 @@ class FlightState(Model):
rho 0.74 [kg/m^3] air density
"""
@pv_decorater(__doc__, globals())
def setup(self):
exec(parse_variables(FlightState.__doc__))
pass


class FlightSegment(Model):
Expand All @@ -103,6 +104,7 @@ class FlightSegment(Model):
Wfuel, aircraft.W
"""
@pv_decorater(__doc__, globals())
def setup(self, aircraft):
self.aircraft = aircraft

Expand Down Expand Up @@ -165,10 +167,11 @@ class WingAero(Model):
---------------
CL, wing.S, state.mu, state.rho, state.V
"""
@pv_decorater(__doc__, globals())
def setup(self, wing, state):
self.wing = wing
self.state = state
exec(parse_variables(WingAero.__doc__))
assert False

c = wing.c
A = wing.A
Expand Down Expand Up @@ -205,8 +208,8 @@ class Wing(Model):
---------------
c, S
"""
@pv_decorater(__doc__, globals())
def setup(self):
exec(parse_variables(Wing.__doc__))
return {"parametrization of wing weight":
W >= S*rho,
"definition of mean chord":
Expand All @@ -225,32 +228,33 @@ class Fuselage(Model):
W 100 [lbf] weight
"""
@pv_decorater(__doc__, globals())
def setup(self):
exec(parse_variables(Fuselage.__doc__))
pass

AC = Aircraft()
MISSION = Mission(AC)
M = Model(MISSION.takeoff_fuel, [MISSION, AC])
print(M)
sol = M.solve(verbosity=0)
# save solution to some files
sol.savemat()
sol.savecsv()
sol.savetxt()
sol.save("solution.pkl")
# retrieve solution from a file
sol_loaded = pickle.load(open("solution.pkl"))

vars_of_interest = set(AC.varkeys)
# note that there's two ways to access submodels
assert (MISSION["flight segment"]["aircraft performance"]
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"]))

MISSION["flight segment"]["aircraft performance"]["fuel burn rate"] = (
MISSION.fs.aircraftp.Wburn >= 0.2*MISSION.fs.aircraftp.wing_aero.D)
sol = M.solve(verbosity=0)
print(sol.diff("solution.pkl", showvars=vars_of_interest, sortbymodel=False))
# # save solution to some files
# sol.savemat()
# sol.savecsv()
# sol.savetxt()
# sol.save("solution.pkl")
# # retrieve solution from a file
# sol_loaded = pickle.load(open("solution.pkl"))
#
# vars_of_interest = set(AC.varkeys)
# # note that there's two ways to access submodels
# assert (MISSION["flight segment"]["aircraft performance"]
# 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"]))
#
# MISSION["flight segment"]["aircraft performance"]["fuel burn rate"] = (
# MISSION.fs.aircraftp.Wburn >= 0.2*MISSION.fs.aircraftp.wing_aero.D)
# sol = M.solve(verbosity=0)
# print(sol.diff("solution.pkl", showvars=vars_of_interest, sortbymodel=False))
3 changes: 3 additions & 0 deletions docs/source/examples/pm_test.py
@@ -0,0 +1,3 @@
from performance_modeling import Wing

print(Wing())
35 changes: 35 additions & 0 deletions gpkit/__init__.py
Expand Up @@ -17,6 +17,41 @@
from .constraints.model import Model
from .tools.docstring import parse_variables

import inspect
import ast


class pv_decorater(object):

def __init__(self, string, globals):
self.string = string
self.globals = globals

def __call__(self, f):
string = self.string
orig_source = inspect.getsource(f)
# print("os\n", orig_source)
orig_lines = orig_source.split("\n")
indent_length = 0
while orig_lines[1][indent_length] in [" ", "\t"]:
indent_length += 1
first_indent_length = indent_length
while orig_lines[2][indent_length] in [" ", "\t"]:
indent_length += 1
second_indent = orig_lines[2][:indent_length]
parse_lines = [second_indent + line for line in parse_variables(string).split("\n")]
# make ast of these new lines, insert it into the original ast
new_lines = [orig_lines[1]] + parse_lines + orig_lines[2:]
new_src = "\n".join([line[first_indent_length:] for line in new_lines])
# print("ns\n%s" % new_src)
new_ast = ast.parse(new_src, "<parse_variables>")
ast.fix_missing_locations(new_ast)
code = compile(new_ast, "<parse_variables>", "exec", dont_inherit=True)
out = {}
exec(code, self.globals, out)
return out[f.__name__]


GPBLU = "#59ade4"
GPCOLORS = ["#59ade4", "#FA3333"]

Expand Down
2 changes: 2 additions & 0 deletions gpkit/constraints/set.py
Expand Up @@ -262,6 +262,8 @@ def process_result(self, result):

def __repr__(self):
"Returns namespaced string."
if not self:
return "<gpkit.%s object>" % self.__class__.__name__
return ("<gpkit.%s object containing %i top-level constraint(s)"
" and %i variable(s)>" % (self.__class__.__name__,
len(self), len(self.varkeys)))
Expand Down
3 changes: 0 additions & 3 deletions gpkit/tools/docstring.py
@@ -1,6 +1,5 @@
"Docstring-parsing methods"
import re
import sys
import numpy as np


Expand Down Expand Up @@ -59,8 +58,6 @@ def expected_unbounded(instance, doc):

def parse_variables(string, errorcatch=True):
"Parses a string to determine what variables to create from it"
if sys.version_info >= (3, 0):
raise FutureWarning("parse_variables is not yet supported in Python 3")
out = "from gpkit import Variable, VectorVariable\n"
out += check_and_parse_flag(string, "Constants\n", errorcatch,
constant_declare)
Expand Down
15 changes: 15 additions & 0 deletions test.py
@@ -0,0 +1,15 @@
from gpkit import *
from gpkit.nomials.array import NomialArray
import numpy as np

t = Variable("t")
u = Variable("u")
v = Variable("v")
w = Variable("w")
x = VectorVariable(3, "x")
y = VectorVariable(3, "y")
z = VectorVariable(3, "z")
a = VectorVariable((3, 2), "a")
b = VectorVariable((3, 2), "b")

print w >= x

0 comments on commit cf61433

Please sign in to comment.