owlplanner 2025.11.3__tar.gz → 2025.11.5__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.
Files changed (117) hide show
  1. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/INSTALL.md +1 -1
  2. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/PKG-INFO +2 -2
  3. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/README.md +1 -1
  4. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/RELEASE_NOTES.md +6 -0
  5. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/USER_GUIDE.md +1 -1
  6. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/README.md +1 -1
  7. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/pyproject.toml +1 -1
  8. owlplanner-2025.11.5/src/owlplanner/version.py +1 -0
  9. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/About_Owl.py +1 -1
  10. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Documentation.py +1 -0
  11. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Monte_Carlo.py +1 -1
  12. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Quick_Start.py +1 -1
  13. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Settings.py +11 -5
  14. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/owlbridge.py +2 -1
  15. owlplanner-2025.11.3/src/owlplanner/version.py +0 -1
  16. owlplanner-2025.11.3/ui/.owlbridge.py.swo +0 -0
  17. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.devcontainer/devcontainer.json +0 -0
  18. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.flake8 +0 -0
  19. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.gitattributes +0 -0
  20. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.github/workflows/github-actions-runtests.yml +0 -0
  21. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.gitignore +0 -0
  22. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.streamlit/config.toml +0 -0
  23. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/.streamlit/fullconfig.toml +0 -0
  24. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/LICENSE +0 -0
  25. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/Dockerfile.bare +0 -0
  26. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/Dockerfile.static +0 -0
  27. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/buildentrypoint.sh +0 -0
  28. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/docker-compose.yml +0 -0
  29. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docker/runentrypoint.sh +0 -0
  30. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/AD-taxDef.png +0 -0
  31. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/AD-taxFree.png +0 -0
  32. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/AD-taxable.png +0 -0
  33. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/Hist_Bequest.png +0 -0
  34. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/Hist_Spending.png +0 -0
  35. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/MC-tutorial2a.png +0 -0
  36. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/MC-tutorial2b.png +0 -0
  37. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/OwlUI.png +0 -0
  38. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/allocations.png +0 -0
  39. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/owl.png +0 -0
  40. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/piecewiseConstant.png +0 -0
  41. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/profile.png +0 -0
  42. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/ratesCorrelations.png +0 -0
  43. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/ratesPlot.png +0 -0
  44. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/savingsPlot.png +0 -0
  45. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/sourcesPlot.png +0 -0
  46. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/spendingPlot.png +0 -0
  47. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/taxIncomePlot.png +0 -0
  48. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/images/taxesPlot.png +0 -0
  49. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/owl.pdf +0 -0
  50. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/docs/owl.tex +0 -0
  51. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_drawdowncalc-comparison-1.toml +0 -0
  52. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_jack+jill.toml +0 -0
  53. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_joe.toml +0 -0
  54. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_john+sally.toml +0 -0
  55. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_jon+jane.toml +0 -0
  56. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_kim+sam-bequest.toml +0 -0
  57. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/case_kim+sam-spending.toml +0 -0
  58. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/jack+jill.xlsx +0 -0
  59. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/joe.xlsx +0 -0
  60. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/john+sally.xlsx +0 -0
  61. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/jon+jane.xlsx +0 -0
  62. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/kim+sam.xlsx +0 -0
  63. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/examples/template.xlsx +0 -0
  64. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/john+sally.ipynb +0 -0
  65. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/kim+sam.ipynb +0 -0
  66. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/template.ipynb +0 -0
  67. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/tutorial_1.ipynb +0 -0
  68. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/tutorial_2.ipynb +0 -0
  69. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/notebooks/tutorial_3.ipynb +0 -0
  70. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/owlplanner.cmd +0 -0
  71. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/owlplanner.sh +0 -0
  72. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/pytest.ini +0 -0
  73. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/requirements.txt +0 -0
  74. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/__init__.py +0 -0
  75. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/abcapi.py +0 -0
  76. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/config.py +0 -0
  77. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/data/__init__.py +0 -0
  78. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/data/rates.csv +0 -0
  79. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/mylogging.py +0 -0
  80. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plan.py +0 -0
  81. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plotting/__init__.py +0 -0
  82. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plotting/base.py +0 -0
  83. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plotting/factory.py +0 -0
  84. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plotting/matplotlib_backend.py +0 -0
  85. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/plotting/plotly_backend.py +0 -0
  86. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/progress.py +0 -0
  87. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/rates.py +0 -0
  88. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/tax2025.py +0 -0
  89. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/tax2026.py +0 -0
  90. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/timelists.py +0 -0
  91. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/src/owlplanner/utils.py +0 -0
  92. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_logger.py +0 -0
  93. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_regressions.py +0 -0
  94. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_repro.py +0 -0
  95. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_toml_cases.py +0 -0
  96. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_ui_asset_allocation.py +0 -0
  97. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_ui_compare_summaries.py +0 -0
  98. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_ui_sskeys.py +0 -0
  99. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/tests/test_units.py +0 -0
  100. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Asset_Allocation.py +0 -0
  101. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Create_Case.py +0 -0
  102. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Current_Assets.py +0 -0
  103. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Fixed_Income.py +0 -0
  104. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Graphs.py +0 -0
  105. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Historical_Range.py +0 -0
  106. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Logs.py +0 -0
  107. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Optimization_Parameters.py +0 -0
  108. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Output_Files.py +0 -0
  109. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/README.md +0 -0
  110. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Rates_Selection.py +0 -0
  111. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Wages_and_Contributions.py +0 -0
  112. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/Worksheets.py +0 -0
  113. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/__init__.py +0 -0
  114. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/main.py +0 -0
  115. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/progress.py +0 -0
  116. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/sskeys.py +0 -0
  117. {owlplanner-2025.11.3 → owlplanner-2025.11.5}/ui/tomlexamples.py +0 -0
@@ -1,4 +1,4 @@
1
- # Owl
1
+ # Owl - Optimal Wealth Lab
2
2
 
3
3
  ## A retirement exploration tool based on linear programming
4
4
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: owlplanner
3
- Version: 2025.11.3
3
+ Version: 2025.11.5
4
4
  Summary: Owl: Retirement planner with great wisdom
5
5
  Project-URL: HomePage, https://github.com/mdlacasse/owl
6
6
  Project-URL: Repository, https://github.com/mdlacasse/owl
@@ -705,7 +705,7 @@ Requires-Dist: toml
705
705
  Description-Content-Type: text/markdown
706
706
 
707
707
 
708
- # Owl
708
+ # Owl - Optimal Wealth Lab
709
709
 
710
710
  ## A retirement exploration tool based on linear programming
711
711
 
@@ -1,5 +1,5 @@
1
1
 
2
- # Owl
2
+ # Owl - Optimal Wealth Lab
3
3
 
4
4
  ## A retirement exploration tool based on linear programming
5
5
 
@@ -1,3 +1,9 @@
1
+ ### Version 2025.11.05
2
+ - Mentioning Owl as Optimal Wealth Lab
3
+ - Port to Streamlit 1.50 which broke many widgets
4
+ - Rework backprojection of assets to beginning of the year
5
+ - Rework Docker to smaller Alpine image and fix docs
6
+
1
7
  ### Version 2025.07.01
2
8
 
3
9
  Added:
@@ -1,4 +1,4 @@
1
- # Owl
1
+ # Owl - Optimal Wealth Lab
2
2
 
3
3
  ## A retirement exploration tool based on linear programming
4
4
 
@@ -1,4 +1,4 @@
1
- # Owl
1
+ # Owl - Optimal Wealth Lab
2
2
 
3
3
  ## A retirement exploration tool based on linear programming
4
4
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "owlplanner"
7
- version = "2025.11.03"
7
+ version = "2025.11.05"
8
8
  authors = [
9
9
  { name="Martin-D. Lacasse", email="martin.d.lacasse@gmail.com" },
10
10
  ]
@@ -0,0 +1 @@
1
+ __version__ = "2025.11.05"
@@ -4,7 +4,7 @@ import sskeys as kz
4
4
  import owlbridge as owb
5
5
 
6
6
 
7
- st.write("# :material/info: About Owl 🦉")
7
+ st.write("# :material/info: About Owl - Optimal Wealth Lab🦉")
8
8
  kz.divider("orange")
9
9
 
10
10
  st.write(f"This is Owl version {owb.version()} running on Streamlit {st.__version__}.")
@@ -14,6 +14,7 @@ with col3:
14
14
  col1, col2 = st.columns([0.80, 0.20], gap="large")
15
15
  with col1:
16
16
  st.markdown("""
17
+ ### Owl - Optimal Wealth Lab
17
18
  #### A retirement financial exploration tool based on linear programming
18
19
 
19
20
  The goal of Owl is to provide a free and open-source ecosystem that has cutting-edge
@@ -17,7 +17,7 @@ else:
17
17
  st.write("Generate a histogram of results obtained from running mutliple scenarios with stochastic rates.")
18
18
  col1, col2, col3, col4 = st.columns(4, gap="large", vertical_alignment="bottom")
19
19
  with col1:
20
- kz.initKey("MC_cases", 100)
20
+ kz.initCaseKey("MC_cases", 100)
21
21
  kz.getIntNum("Number of random instances", "MC_cases", step=10, max_value=10000)
22
22
  with col4:
23
23
  st.button("Run Simulation", on_click=owb.runMC, disabled=kz.caseIsNotMCReady())
@@ -7,7 +7,7 @@ with col3:
7
7
  st.image("http://github.com/mdlacasse/Owl/blob/main/docs/images/owl.png?raw=true")
8
8
  st.caption("Retirement planner with great wisdom")
9
9
  with col1:
10
- st.write("# :orange[Owl Retirement Planner]\nA retirement financial exploration tool based on linear programming")
10
+ st.write("# :orange[Owl - Optimal Wealth Lab]\nA retirement financial exploration tool based on linear programming")
11
11
  kz.divider("orange")
12
12
  st.write("### :material/campaign: News")
13
13
  st.markdown("""
@@ -4,6 +4,12 @@ import sskeys as kz
4
4
  import owlbridge as owb
5
5
 
6
6
 
7
+ def setKey(key):
8
+ val = kz.getGlobalKey("_"+key)
9
+ if val is not None:
10
+ kz.storeGlobalKey(key, val)
11
+
12
+
7
13
  st.write("# :material/settings: Settings")
8
14
  kz.divider("orange")
9
15
 
@@ -17,7 +23,7 @@ with col1:
17
23
  helpmsg = "Select the plotting library to use."
18
24
  index = choices.index(kz.getGlobalKey(gkey))
19
25
  ret = st.radio("Plotting backend", options=choices, index=index, args=[gkey],
20
- key=gkey, on_change=owb.setGlobalPlotBackend, help=helpmsg, horizontal=True)
26
+ key="_"+gkey, on_change=owb.setGlobalPlotBackend, help=helpmsg, horizontal=True)
21
27
 
22
28
  with col2:
23
29
  choices = ("sidebar", "top")
@@ -26,8 +32,8 @@ with col2:
26
32
  st.write("#### :orange[Menu]")
27
33
  helpmsg = "Select menu appearance."
28
34
  index = choices.index(kz.getGlobalKey(mkey))
29
- ret = st.radio("Menu location", options=choices, index=index,
30
- key=mkey, help=helpmsg, horizontal=True)
35
+ ret = st.radio("Menu location", options=choices, index=index, args=[mkey],
36
+ key="_"+mkey, on_change=setKey, help=helpmsg, horizontal=True)
31
37
 
32
38
  with col3:
33
39
  choices = ("sticky", "static")
@@ -36,8 +42,8 @@ with col3:
36
42
  st.write("#### :orange[Header]")
37
43
  helpmsg = "Select header behavior."
38
44
  index = choices.index(kz.getGlobalKey(pkey))
39
- ret = st.radio("Header behavior", options=choices, index=index,
40
- key=pkey, help=helpmsg, horizontal=True)
45
+ ret = st.radio("Header behavior", options=choices, index=index, args=[pkey],
46
+ key="_"+pkey, on_change=setKey, help=helpmsg, horizontal=True)
41
47
 
42
48
  st.divider()
43
49
  st.write("""
@@ -511,7 +511,8 @@ def setDefaultPlots(plan, key):
511
511
 
512
512
 
513
513
  def setGlobalPlotBackend(key):
514
- val = kz.getGlobalKey(key)
514
+ val = kz.getGlobalKey("_"+key)
515
+ kz.storeGlobalKey(key, val)
515
516
  # Apply to all existing cases.
516
517
  for casename in kz.onlyCaseNames():
517
518
  plan = kz.getKeyInCase("plan", casename)
@@ -1 +0,0 @@
1
- __version__ = "2025.11.03"
Binary file
File without changes
File without changes