Coverage for gpkit/globals.py: 100%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

48 statements  

1"global mutable variables" 

2import os 

3from collections import defaultdict 

4from . import build 

5 

6 

7def load_settings(path=None, trybuild=True): 

8 "Load the settings file at SETTINGS_PATH; return settings dict" 

9 if path is None: 

10 path = os.sep.join([os.path.dirname(__file__), "env", "settings"]) 

11 try: # if the settings file already exists, read it 

12 with open(path) as settingsfile: 

13 lines = [line[:-1].split(" : ") for line in settingsfile 

14 if len(line.split(" : ")) == 2] 

15 settings_ = {name: value.split(", ") for name, value in lines} 

16 for name, value in settings_.items(): 

17 # flatten 1-element lists unless they're the solver list 

18 if len(value) == 1 and name != "installed_solvers": 

19 settings_[name], = value 

20 except IOError: # pragma: no cover 

21 settings_ = {"installed_solvers": [""]} 

22 if settings_["installed_solvers"] == [""] and trybuild: # pragma: no cover 

23 print("Found no installed solvers, beginning a build.") 

24 build() 

25 settings_ = load_settings(path, trybuild=False) 

26 if settings_["installed_solvers"] != [""]: 

27 settings_["just built!"] = True 

28 else: 

29 print(""" 

30============= 

31Build failed! :( 

32============= 

33You may need to install a solver and then `import gpkit` again; 

34see https://gpkit.readthedocs.io/en/latest/installation.html 

35for troubleshooting details. 

36 

37But before you go, please post the output above 

38(starting from "Found no installed solvers, beginning a build.") 

39to gpkit@mit.edu or https://github.com/convexengineering/gpkit/issues/new 

40so we can prevent others from having to see this message. 

41 

42 Thanks! :) 

43""") 

44 settings_["default_solver"] = settings_["installed_solvers"][0] 

45 return settings_ 

46 

47 

48settings = load_settings() 

49 

50 

51class SignomialsEnabledMeta(type): 

52 "Metaclass to implement falsiness for SignomialsEnabled" 

53 def __bool__(cls): return cls._true # pylint: disable=multiple-statements 

54 

55class SignomialsEnabled(metaclass=SignomialsEnabledMeta): # pylint: disable=no-init 

56 """Class to put up and tear down signomial support in an instance of GPkit. 

57 

58 Example 

59 ------- 

60 >>> import gpkit 

61 >>> x = gpkit.Variable("x") 

62 >>> y = gpkit.Variable("y", 0.1) 

63 >>> with SignomialsEnabled(): 

64 >>> constraints = [x >= 1-y] 

65 >>> gpkit.Model(x, constraints).localsolve() 

66 """ 

67 _true = False # default signomial permissions 

68 # pylint: disable=multiple-statements 

69 def __enter__(self): SignomialsEnabled._true = True 

70 def __exit__(self, type_, val, traceback): SignomialsEnabled._true = False 

71 

72 

73class Vectorize: 

74 """Creates an environment in which all variables are 

75 exended in an additional dimension. 

76 """ 

77 vectorization = () # the current vectorization shape 

78 

79 def __init__(self, dimension_length): 

80 self.dimension_length = dimension_length 

81 

82 def __enter__(self): 

83 "Enters a vectorized environment." 

84 Vectorize.vectorization = (self.dimension_length,) + self.vectorization 

85 

86 def __exit__(self, type_, val, traceback): 

87 "Leaves a vectorized environment." 

88 Vectorize.vectorization = self.vectorization[1:] 

89 

90 

91class NamedVariables: 

92 """Creates an environment in which all variables have 

93 a model name and num appended to their varkeys. 

94 """ 

95 lineage = () # the current model nesting 

96 modelnums = defaultdict(int) # the number of models of each lineage 

97 namedvars = defaultdict(list) # variables created in the current nesting 

98 

99 @classmethod 

100 def reset_modelnumbers(cls): 

101 "Clear all model number counters" 

102 for key in list(cls.modelnums): 

103 del cls.modelnums[key] 

104 

105 def __init__(self, name): 

106 self.name = name 

107 

108 def __enter__(self): 

109 "Enters a named environment." 

110 num = self.modelnums[(self.lineage, self.name)] 

111 self.modelnums[(self.lineage, self.name)] += 1 

112 NamedVariables.lineage += ((self.name, num),) # NOTE: Side effects 

113 return self.lineage, self.namedvars[self.lineage] 

114 

115 def __exit__(self, type_, val, traceback): 

116 "Leaves a named environment." 

117 del self.namedvars[self.lineage] 

118 NamedVariables.lineage = self.lineage[:-1] # NOTE: Side effects