modelflowib 2.76__tar.gz → 2.77__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modelflowib-2.76 → modelflowib-2.77}/PKG-INFO +1 -1
- {modelflowib-2.76 → modelflowib-2.77}/modelclass.py +51 -31
- {modelflowib-2.76 → modelflowib-2.77}/modelconstruct_estimation.py +10 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelflowib.egg-info/PKG-INFO +1 -1
- {modelflowib-2.76 → modelflowib-2.77}/modeljupytermagic.py +5 -1
- {modelflowib-2.76 → modelflowib-2.77}/modelnormalize.py +31 -11
- {modelflowib-2.76 → modelflowib-2.77}/modelsolver_ng.py +3652 -3652
- {modelflowib-2.76 → modelflowib-2.77}/pyproject.toml +1 -1
- {modelflowib-2.76 → modelflowib-2.77}/README.md +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/license.md +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelBLfunk.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_Excel.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_cvx.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_dynare.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_financial_stability.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_latex.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_latex_class.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/model_parquet_mixin.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelconstruct.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldash.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldashboot.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldashsidebar.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldekom.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldiff.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeldisplay.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelestimation.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelestimator_new.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelflowib.egg-info/SOURCES.txt +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelflowib.egg-info/dependency_links.txt +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelflowib.egg-info/requires.txt +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelflowib.egg-info/top_level.txt +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelgrab.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelgrabgdx.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelgrabwf2.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelhelp.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelhtml.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelinvert.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeljupyter.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelmacrograb.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelmanipulation.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelmf.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelnet.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelnewton.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelpattern.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelreport.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modeluserfunk.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelvis.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelwidget.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/modelwidget_input.py +0 -0
- {modelflowib-2.76 → modelflowib-2.77}/setup.cfg +0 -0
|
@@ -3188,7 +3188,7 @@ class Modify_Mixin():
|
|
|
3188
3188
|
newnormalisation = [l.split() for l in lines]
|
|
3189
3189
|
vars_before_normalization = {beforeendo.upper() for beforeendo,afterendo in newnormalisation }
|
|
3190
3190
|
frml_normalize_strip = {(beforeendo.upper(),afterendo.upper()) : self.allvar[beforeendo]['frml'].replace('$','').split(' ',2) for beforeendo,afterendo in newnormalisation }
|
|
3191
|
-
frml_normalize_gross = {(beforeendo,afterendo) : (fname ,normal(expression,the_endo = afterendo,endo_lhs=False,
|
|
3191
|
+
frml_normalize_gross = {(beforeendo,afterendo) : (fname ,normal(expression,the_endo = afterendo,endo_lhs=False,add_add_factor=False)) for (beforeendo,afterendo),(frml,fname,expression) in frml_normalize_strip.items() }
|
|
3192
3192
|
frmldict_normalized = {afterendo : f'FRML {fname} {nexpression.normalized}$'
|
|
3193
3193
|
for (beforeendo,afterendo),(fname,nexpression) in frml_normalize_gross.items() }
|
|
3194
3194
|
# breakpoint()
|
|
@@ -3282,8 +3282,10 @@ class Modify_Mixin():
|
|
|
3282
3282
|
|
|
3283
3283
|
Parameters
|
|
3284
3284
|
----------
|
|
3285
|
-
updateeq :
|
|
3286
|
-
new equations seperated by newline
|
|
3285
|
+
updateeq : str or Makemodel
|
|
3286
|
+
new equations seperated by newline, or a Makemodel instance whose
|
|
3287
|
+
normalized equations (including per-equation add factors and
|
|
3288
|
+
fitted equations, when present) are used as the update.
|
|
3287
3289
|
newfunks : TYPE, optional
|
|
3288
3290
|
Additional userspecified functions. The default is [].
|
|
3289
3291
|
calc_add : bool, optional
|
|
@@ -3297,32 +3299,50 @@ class Modify_Mixin():
|
|
|
3297
3299
|
a dataframe with calculated add factors. Origin is the original models lastdf.
|
|
3298
3300
|
|
|
3299
3301
|
'''
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
updatefunks=list(set(self.funks+newfunks) ) #
|
|
3303
|
-
|
|
3304
|
-
newmodelname = newname if newname else self.name+' Updated'
|
|
3305
|
-
|
|
3306
|
-
dfvars = set(self.lastdf.columns)
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
frmldict_calc_add = {nexpression.endo_var: f'{frml}
|
|
3323
|
-
frml,fname,nexpression in frml2_normal
|
|
3324
|
-
|
|
3325
|
-
|
|
3302
|
+
from modelconstruct_estimation import Makemodel # local to avoid circular import
|
|
3303
|
+
|
|
3304
|
+
updatefunks=list(set(self.funks+newfunks) ) #
|
|
3305
|
+
|
|
3306
|
+
newmodelname = newname if newname else self.name+' Updated'
|
|
3307
|
+
|
|
3308
|
+
dfvars = set(self.lastdf.columns)
|
|
3309
|
+
new_var_description = self.var_description
|
|
3310
|
+
|
|
3311
|
+
if isinstance(updateeq, Makemodel):
|
|
3312
|
+
# the Makemodel has already expanded, optionally estimated and normalized the
|
|
3313
|
+
# equations, and decided add factor/fixable/fitted per equation from its flags
|
|
3314
|
+
updatefunks = list(set(updatefunks + updateeq.funks))
|
|
3315
|
+
new_var_description = {**self.var_description, **updateeq.var_description}
|
|
3316
|
+
frml2_normal = [['FRML', fname, nexpression]
|
|
3317
|
+
for fname, (parts, nexpression)
|
|
3318
|
+
in zip(updateeq.normal_output_frmlnames, updateeq.normal)]
|
|
3319
|
+
frmldict_update = {nexpression.endo_var: f'{frml} {fname} {nexpression.normalized}$' for
|
|
3320
|
+
frml,fname,nexpression in frml2_normal}
|
|
3321
|
+
frmldict_update = {**frmldict_update,
|
|
3322
|
+
**{f'{nexpression.endo_var}_FITTED': f'FRML <FIT> {nexpression.fitted}$'
|
|
3323
|
+
for frml,fname,nexpression in frml2_normal if len(nexpression.fitted)}}
|
|
3324
|
+
frmldict_calc_add = {nexpression.endo_var: f'{frml} <CALC_ADD_FACTOR> {nexpression.calc_add_factor}$' for
|
|
3325
|
+
frml,fname,nexpression in frml2_normal
|
|
3326
|
+
if len(nexpression.calc_add_factor) and nexpression.endo_var in self.endogene|self.exogene|dfvars }
|
|
3327
|
+
else:
|
|
3328
|
+
updatemodel = mp.tofrml(updateeq) # create the moedl with the usual processing of frml's
|
|
3329
|
+
while ' ' in updatemodel:
|
|
3330
|
+
updatemodel = updatemodel.replace(' ', ' ')
|
|
3331
|
+
frml2 = updatemodel.split('$')
|
|
3332
|
+
frml2_strip = [mp.split_frml(f+'$') for f in frml2 if len(f)>2]
|
|
3333
|
+
frml2_normal = [[frml,fname,
|
|
3334
|
+
normal(expression[:-1],do_preprocess=do_preprocess,add_add_factor=add_add_factor,
|
|
3335
|
+
make_fixable = pt.kw_frml_name(fname.upper(),'FIXABLE'))]
|
|
3336
|
+
for allfrml,frml,fname,expression in frml2_strip]
|
|
3337
|
+
frmldict_update = {nexpression.endo_var: f'{frml} {fname} {nexpression.normalized}$' for
|
|
3338
|
+
frml,fname,nexpression in frml2_normal}
|
|
3339
|
+
|
|
3340
|
+
|
|
3341
|
+
if add_add_factor:
|
|
3342
|
+
frmldict_calc_add = {nexpression.endo_var: f'{frml} {fname} {nexpression.calc_add_factor}$' for
|
|
3343
|
+
frml,fname,nexpression in frml2_normal if nexpression.endo_var in self.endogene|self.exogene|dfvars }
|
|
3344
|
+
else:
|
|
3345
|
+
frmldict_calc_add={}
|
|
3326
3346
|
# breakpoint()
|
|
3327
3347
|
|
|
3328
3348
|
frmldict = {k: v['frml'] for (k,v) in self.allvar.items() if k in self.endogene } # frml's in the existing model
|
|
@@ -3331,8 +3351,8 @@ class Modify_Mixin():
|
|
|
3331
3351
|
newfrml = '\n'.join([f for f in newfrmldict.values()])
|
|
3332
3352
|
newmodel = self.__class__(newfrml,modelname = f'updated {self.name}',
|
|
3333
3353
|
funks=updatefunks,
|
|
3334
|
-
var_description=
|
|
3335
|
-
model_description = self.model_description,
|
|
3354
|
+
var_description=new_var_description,
|
|
3355
|
+
model_description = self.model_description,
|
|
3336
3356
|
var_groups = self.var_groups ,
|
|
3337
3357
|
reports = self.reports ,
|
|
3338
3358
|
substitution = self.substitution,
|
|
@@ -982,6 +982,16 @@ from IPython.display import display, Markdown, Math
|
|
|
982
982
|
import re
|
|
983
983
|
from IPython.display import display, Markdown, Math
|
|
984
984
|
|
|
985
|
+
class Markdown(Markdown):
|
|
986
|
+
"""IPython Markdown, but with the markdown source as the text/plain fallback.
|
|
987
|
+
|
|
988
|
+
The stock class reprs as '<IPython.core.display.Markdown object>', and that
|
|
989
|
+
string is what latex/pdf exporters show, as they can not render the
|
|
990
|
+
text/markdown mime type and fall back to text/plain. With the source as
|
|
991
|
+
repr, exported documents show the model text instead."""
|
|
992
|
+
def __repr__(self):
|
|
993
|
+
return str(self.data)
|
|
994
|
+
|
|
985
995
|
def display_model(cell: str, spec: str = "markdown"):
|
|
986
996
|
"""
|
|
987
997
|
Display a model specification.
|
|
@@ -27,6 +27,10 @@ from modelclass import model
|
|
|
27
27
|
from modelmanipulation import explode
|
|
28
28
|
from model_latex_class import a_latex_model
|
|
29
29
|
from modelconstruct_estimation import Makemodel, display_model
|
|
30
|
+
# Markdown subclass whose text/plain fallback is the markdown source itself,
|
|
31
|
+
# so latex/pdf exports show the model text instead of
|
|
32
|
+
# '<IPython.core.display.Markdown object>'. Shadows the IPython import above.
|
|
33
|
+
from modelconstruct_estimation import Markdown
|
|
30
34
|
from modelhelp import debug_var
|
|
31
35
|
from modelreport import LatexRepo
|
|
32
36
|
|
|
@@ -589,7 +593,7 @@ try:
|
|
|
589
593
|
if dict_name in user_ns:
|
|
590
594
|
segs = list(user_ns[dict_name].keys())
|
|
591
595
|
print(f"Model `{name}` built from segments: {', '.join(segs)}")
|
|
592
|
-
print(f"✅ Created
|
|
596
|
+
print(f"✅ Created Makemodel: {name}")
|
|
593
597
|
print(emodel)
|
|
594
598
|
|
|
595
599
|
return emodel
|
|
@@ -129,8 +129,19 @@ def funk_find_arg(funk_match, streng):
|
|
|
129
129
|
return streng[:start], match[1:index], match[index + 1:]
|
|
130
130
|
assert 1==2,f'Parantese mismatch in {streng}'
|
|
131
131
|
|
|
132
|
+
def funk_check_arg(funk,arg,udtryk,udtryk_up):
|
|
133
|
+
'''Guards against variables named like a function.
|
|
134
|
+
|
|
135
|
+
A lagged variable with a function name, fx DIFF(-1), matches DIFF( and would
|
|
136
|
+
silently be swallowed as a function call. If the argument is a pure signed
|
|
137
|
+
integer it must be such a lag, so raise an informative error instead.'''
|
|
138
|
+
if re.fullmatch(r'[+-]?\d+',arg.replace(' ','')):
|
|
139
|
+
raise Exception(f"A variable can not be named {funk}, as {funk}( is a function in the business language.\n"
|
|
140
|
+
f"{funk}({arg}) looks like a lagged variable {funk}. Rename the variable.\n"
|
|
141
|
+
f"Original expression: {udtryk}\n"
|
|
142
|
+
f"Processed so far : {udtryk_up}")
|
|
143
|
+
|
|
132
144
|
|
|
133
|
-
|
|
134
145
|
def preprocess(udtryk,funks=[]):
|
|
135
146
|
'''
|
|
136
147
|
test processing expanding dlog,diff,movavg,pct,logit functions
|
|
@@ -146,16 +157,21 @@ def preprocess(udtryk,funks=[]):
|
|
|
146
157
|
|
|
147
158
|
'''
|
|
148
159
|
udtryk_up = udtryk.upper().replace(' ','')
|
|
160
|
+
udtryk_up = funk_replace('PCT','PCT_GROWTH',udtryk_up)
|
|
161
|
+
|
|
149
162
|
while dlog_match := funk_in('DLOG',udtryk_up):
|
|
150
163
|
fordlog,dlogudtryk_up,efterdlog=funk_find_arg(dlog_match,udtryk_up)
|
|
151
|
-
|
|
152
|
-
|
|
164
|
+
funk_check_arg('DLOG',dlogudtryk_up,udtryk,udtryk_up)
|
|
165
|
+
udtryk_up=fordlog+'DIFF(LOG('+dlogudtryk_up+'))'+efterdlog
|
|
166
|
+
|
|
153
167
|
while logit_match := funk_in('LOGIT',udtryk_up):
|
|
154
168
|
forlogit,logitudtryk_up,efterlogit=funk_find_arg(logit_match,udtryk_up)
|
|
155
|
-
|
|
156
|
-
|
|
169
|
+
funk_check_arg('LOGIT',logitudtryk_up,udtryk,udtryk_up)
|
|
170
|
+
udtryk_up=forlogit+'(LOG('+logitudtryk_up+'/(1.0 -'+logitudtryk_up+')))'+efterlogit
|
|
171
|
+
|
|
157
172
|
while movavg_match := funk_in('MOVAVG', udtryk_up):
|
|
158
173
|
forkaede,kaedeudtryk,efterkaede=funk_find_arg(movavg_match,udtryk_up)
|
|
174
|
+
funk_check_arg('MOVAVG',kaedeudtryk,udtryk,udtryk_up)
|
|
159
175
|
arg=kaedeudtryk.split(',',1)
|
|
160
176
|
avg='(('
|
|
161
177
|
term=arg[0]
|
|
@@ -168,19 +184,23 @@ def preprocess(udtryk,funks=[]):
|
|
|
168
184
|
|
|
169
185
|
while pct_match := funk_in('PCT_GROWTH',udtryk_up):
|
|
170
186
|
forpc,pcudtryk,efterpc=funk_find_arg(pct_match,udtryk_up)
|
|
171
|
-
|
|
187
|
+
funk_check_arg('PCT_GROWTH',pcudtryk,udtryk,udtryk_up)
|
|
188
|
+
udtryk_up=f'{forpc} (100 * ( ({pcudtryk}) / ({lagone(pcudtryk,funks=funks)}) -1)) {efterpc}'
|
|
172
189
|
|
|
173
190
|
while pct_match := funk_in('PCY',udtryk_up):
|
|
174
191
|
forpc,pcudtryk,efterpc=funk_find_arg(pct_match,udtryk_up)
|
|
175
|
-
|
|
176
|
-
|
|
192
|
+
funk_check_arg('PCY',pcudtryk,udtryk,udtryk_up)
|
|
193
|
+
udtryk_up=f'{forpc} (100 * ( ({pcudtryk}) / ({lagone(pcudtryk,funks=funks,laglead=-4)}) -1)) {efterpc}'
|
|
194
|
+
|
|
177
195
|
while diff_match := funk_in('DIFF' , udtryk_up):
|
|
178
196
|
fordif,difudtryk_up,efterdif=funk_find_arg(diff_match,udtryk_up)
|
|
179
|
-
|
|
180
|
-
|
|
197
|
+
funk_check_arg('DIFF',difudtryk_up,udtryk,udtryk_up)
|
|
198
|
+
udtryk_up=fordif+'(('+difudtryk_up+')-('+lagone(difudtryk_up+'',funks=funks)+'))'+efterdif
|
|
199
|
+
|
|
181
200
|
while diff_match := funk_in('D' , udtryk_up):
|
|
182
201
|
# print(f'{udtryk_up} on D')
|
|
183
202
|
fordif,difudtryk_up,efterdif=funk_find_arg(diff_match,udtryk_up)
|
|
203
|
+
funk_check_arg('D',difudtryk_up,udtryk,udtryk_up)
|
|
184
204
|
difudtryk_up = difudtryk_up.replace(' ','').replace(',0,1','') if difudtryk_up.endswith(',0,1') else difudtryk_up
|
|
185
205
|
udtryk_up=fordif+'(('+difudtryk_up+')-('+lagone(difudtryk_up+'',funks=funks)+'))'+efterdif
|
|
186
206
|
|
|
@@ -407,7 +427,7 @@ if __name__ == '__main__':
|
|
|
407
427
|
normal('a+b = c',add_add_factor=1,make_fitted=1).fprint
|
|
408
428
|
normal('PCT_growth(a) = n(-1)',add_add_factor=0).fprint
|
|
409
429
|
normal('a = movavg(pct(b),2)',add_add_factor=0).fprint
|
|
410
|
-
normal('pct_growth(c) = pct_growth(
|
|
430
|
+
normal('pct_growth(c) = pct_growth(dd)',add_add_factor=0).fprint
|
|
411
431
|
normal('pct_growth(c) = z+pct(b) + pct(e)').fprint
|
|
412
432
|
normal('pct_growth(c) = z+pct(b) + pct(e)').fprint
|
|
413
433
|
normal('a = pct_growth(b)',add_add_factor=0).fprint
|