invocation-tree 0.0.11__tar.gz → 0.0.13__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 (168) hide show
  1. {invocation_tree-0.0.11/invocation_tree.egg-info → invocation_tree-0.0.13}/PKG-INFO +21 -20
  2. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/README.md +20 -19
  3. invocation_tree-0.0.13/images/#generator_function.py# +13 -0
  4. invocation_tree-0.0.13/images/compute.py +22 -0
  5. invocation_tree-0.0.11/images/compute.py → invocation_tree-0.0.13/images/compute.py~ +3 -3
  6. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute1.png +0 -0
  7. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute2.png +0 -0
  8. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute3.png +0 -0
  9. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute4.png +0 -0
  10. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute5.png +0 -0
  11. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute6.png +0 -0
  12. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute7.png +0 -0
  13. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute8.png +0 -0
  14. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute9.png +0 -0
  15. invocation_tree-0.0.13/images/create_images.sh~ +4 -0
  16. invocation_tree-0.0.13/images/eager_pipeline.py~ +28 -0
  17. invocation_tree-0.0.13/images/eager_pipeline1.png +0 -0
  18. invocation_tree-0.0.13/images/eager_pipeline2.png +0 -0
  19. invocation_tree-0.0.13/images/eager_pipeline3.png +0 -0
  20. invocation_tree-0.0.13/images/eager_pipeline4.png +0 -0
  21. invocation_tree-0.0.13/images/eager_pipeline5.png +0 -0
  22. invocation_tree-0.0.13/images/eager_pipeline6.png +0 -0
  23. invocation_tree-0.0.13/images/eager_pipeline7.png +0 -0
  24. invocation_tree-0.0.13/images/factorial.gif +0 -0
  25. invocation_tree-0.0.13/images/factorial.py +10 -0
  26. invocation_tree-0.0.13/images/factorial.py~ +11 -0
  27. invocation_tree-0.0.13/images/factorial1.png +0 -0
  28. invocation_tree-0.0.13/images/factorial2.png +0 -0
  29. invocation_tree-0.0.13/images/factorial3.png +0 -0
  30. invocation_tree-0.0.13/images/factorial4.png +0 -0
  31. invocation_tree-0.0.13/images/factorial5.png +0 -0
  32. invocation_tree-0.0.13/images/factorial6.png +0 -0
  33. invocation_tree-0.0.13/images/factorial7.png +0 -0
  34. invocation_tree-0.0.13/images/generator_expression.py~ +9 -0
  35. invocation_tree-0.0.13/images/generator_expression1.png +0 -0
  36. invocation_tree-0.0.13/images/generator_expression2.png +0 -0
  37. invocation_tree-0.0.13/images/generator_expression3.png +0 -0
  38. invocation_tree-0.0.13/images/generator_expression4.png +0 -0
  39. invocation_tree-0.0.13/images/generator_expression5.png +0 -0
  40. invocation_tree-0.0.13/images/generator_expression6.png +0 -0
  41. invocation_tree-0.0.13/images/generator_expression7.png +0 -0
  42. invocation_tree-0.0.13/images/generator_expression8.png +0 -0
  43. invocation_tree-0.0.13/images/generator_expression9.png +0 -0
  44. invocation_tree-0.0.13/images/generator_function1.png +0 -0
  45. invocation_tree-0.0.13/images/generator_function2.png +0 -0
  46. invocation_tree-0.0.13/images/generator_function3.png +0 -0
  47. invocation_tree-0.0.13/images/generator_function4.png +0 -0
  48. invocation_tree-0.0.13/images/generator_function5.png +0 -0
  49. invocation_tree-0.0.13/images/generator_function6.png +0 -0
  50. invocation_tree-0.0.13/images/generator_function7.png +0 -0
  51. invocation_tree-0.0.13/images/generator_function8.png +0 -0
  52. invocation_tree-0.0.13/images/generator_function9.png +0 -0
  53. invocation_tree-0.0.13/images/generator_pipeline.py~ +26 -0
  54. invocation_tree-0.0.13/images/generator_pipeline1.png +0 -0
  55. invocation_tree-0.0.13/images/generator_pipeline10.png +0 -0
  56. invocation_tree-0.0.13/images/generator_pipeline11.png +0 -0
  57. invocation_tree-0.0.13/images/generator_pipeline12.png +0 -0
  58. invocation_tree-0.0.13/images/generator_pipeline13.png +0 -0
  59. invocation_tree-0.0.13/images/generator_pipeline14.png +0 -0
  60. invocation_tree-0.0.13/images/generator_pipeline15.png +0 -0
  61. invocation_tree-0.0.13/images/generator_pipeline16.png +0 -0
  62. invocation_tree-0.0.13/images/generator_pipeline17.png +0 -0
  63. invocation_tree-0.0.13/images/generator_pipeline18.png +0 -0
  64. invocation_tree-0.0.13/images/generator_pipeline19.png +0 -0
  65. invocation_tree-0.0.13/images/generator_pipeline2.png +0 -0
  66. invocation_tree-0.0.13/images/generator_pipeline20.png +0 -0
  67. invocation_tree-0.0.13/images/generator_pipeline21.png +0 -0
  68. invocation_tree-0.0.13/images/generator_pipeline22.png +0 -0
  69. invocation_tree-0.0.13/images/generator_pipeline23.png +0 -0
  70. invocation_tree-0.0.13/images/generator_pipeline24.png +0 -0
  71. invocation_tree-0.0.13/images/generator_pipeline25.png +0 -0
  72. invocation_tree-0.0.13/images/generator_pipeline26.png +0 -0
  73. invocation_tree-0.0.13/images/generator_pipeline27.png +0 -0
  74. invocation_tree-0.0.13/images/generator_pipeline3.png +0 -0
  75. invocation_tree-0.0.13/images/generator_pipeline4.png +0 -0
  76. invocation_tree-0.0.13/images/generator_pipeline5.png +0 -0
  77. invocation_tree-0.0.13/images/generator_pipeline6.png +0 -0
  78. invocation_tree-0.0.13/images/generator_pipeline7.png +0 -0
  79. invocation_tree-0.0.13/images/generator_pipeline8.png +0 -0
  80. invocation_tree-0.0.13/images/generator_pipeline9.png +0 -0
  81. invocation_tree-0.0.13/images/invocation_tree.pdf +0 -0
  82. invocation_tree-0.0.13/images/invocation_tree0.pdf +0 -0
  83. invocation_tree-0.0.13/images/iterable.py +44 -0
  84. invocation_tree-0.0.13/images/iterable.py~ +31 -0
  85. invocation_tree-0.0.13/images/my_list.py +20 -0
  86. invocation_tree-0.0.13/images/my_list.py~ +4 -0
  87. invocation_tree-0.0.13/images/my_range.py~ +14 -0
  88. invocation_tree-0.0.13/images/my_range0.png +0 -0
  89. invocation_tree-0.0.13/images/my_range1.png +0 -0
  90. invocation_tree-0.0.13/images/my_range10.png +0 -0
  91. invocation_tree-0.0.13/images/my_range11.png +0 -0
  92. invocation_tree-0.0.13/images/my_range12.png +0 -0
  93. invocation_tree-0.0.13/images/my_range13.png +0 -0
  94. invocation_tree-0.0.13/images/my_range14.png +0 -0
  95. invocation_tree-0.0.13/images/my_range15.png +0 -0
  96. invocation_tree-0.0.13/images/my_range2.png +0 -0
  97. invocation_tree-0.0.13/images/my_range3.png +0 -0
  98. invocation_tree-0.0.13/images/my_range4.png +0 -0
  99. invocation_tree-0.0.13/images/my_range5.png +0 -0
  100. invocation_tree-0.0.13/images/my_range6.png +0 -0
  101. invocation_tree-0.0.13/images/my_range7.png +0 -0
  102. invocation_tree-0.0.13/images/my_range8.png +0 -0
  103. invocation_tree-0.0.13/images/my_range9.png +0 -0
  104. invocation_tree-0.0.13/images/out.txt +8 -0
  105. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations.py +2 -2
  106. invocation_tree-0.0.13/images/permutations.py~ +8 -0
  107. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations1.png +0 -0
  108. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations10.png +0 -0
  109. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations11.png +0 -0
  110. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations12.png +0 -0
  111. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations13.png +0 -0
  112. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations2.png +0 -0
  113. invocation_tree-0.0.13/images/permutations22.png~ +0 -0
  114. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations3.png +0 -0
  115. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations4.png +0 -0
  116. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations5.png +0 -0
  117. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations6.png +0 -0
  118. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations7.png +0 -0
  119. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations8.png +0 -0
  120. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations9.png +0 -0
  121. invocation_tree-0.0.13/images/student.gif +0 -0
  122. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students.py +2 -2
  123. invocation_tree-0.0.13/images/students.py~ +30 -0
  124. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students1.png +0 -0
  125. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students10.png +0 -0
  126. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students11.png +0 -0
  127. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students12.png +0 -0
  128. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students13.png +0 -0
  129. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students14.png +0 -0
  130. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students15.png +0 -0
  131. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students2.png +0 -0
  132. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students3.png +0 -0
  133. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students4.png +0 -0
  134. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students5.png +0 -0
  135. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students6.png +0 -0
  136. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students7.png +0 -0
  137. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students8.png +0 -0
  138. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students9.png +0 -0
  139. invocation_tree-0.0.13/images/test.py +15 -0
  140. invocation_tree-0.0.13/images/tree.gv~ +22 -0
  141. invocation_tree-0.0.13/images/tree.pdf +0 -0
  142. invocation_tree-0.0.13/install.txt +31 -0
  143. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/invocation_tree/__init__.py +1 -1
  144. {invocation_tree-0.0.11 → invocation_tree-0.0.13/invocation_tree.egg-info}/PKG-INFO +21 -20
  145. invocation_tree-0.0.13/invocation_tree.egg-info/SOURCES.txt +156 -0
  146. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/setup.py +1 -1
  147. invocation_tree-0.0.11/images/factorial.gif +0 -0
  148. invocation_tree-0.0.11/images/factorial.py +0 -9
  149. invocation_tree-0.0.11/images/factorial1.png +0 -0
  150. invocation_tree-0.0.11/images/factorial2.png +0 -0
  151. invocation_tree-0.0.11/images/factorial3.png +0 -0
  152. invocation_tree-0.0.11/images/factorial4.png +0 -0
  153. invocation_tree-0.0.11/images/factorial5.png +0 -0
  154. invocation_tree-0.0.11/images/factorial6.png +0 -0
  155. invocation_tree-0.0.11/images/factorial7.png +0 -0
  156. invocation_tree-0.0.11/invocation_tree.egg-info/SOURCES.txt +0 -65
  157. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/LICENSE.txt +0 -0
  158. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/MANIFEST.in +0 -0
  159. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/compute.gif +0 -0
  160. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/create_gif.sh +0 -0
  161. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/create_images.sh +0 -0
  162. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/permutations.gif +0 -0
  163. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/students.gif +0 -0
  164. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/images/vscode.png +0 -0
  165. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/invocation_tree.egg-info/dependency_links.txt +0 -0
  166. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/invocation_tree.egg-info/requires.txt +0 -0
  167. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/invocation_tree.egg-info/top_level.txt +0 -0
  168. {invocation_tree-0.0.11 → invocation_tree-0.0.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: invocation_tree
3
- Version: 0.0.11
3
+ Version: 0.0.13
4
4
  Summary: Generate an invocation tree of functions calls.
5
5
  Home-page: https://github.com/bterwijn/invocation_tree
6
6
  Author: Bas Terwijn
@@ -32,7 +32,7 @@ The [invocation_tree](https://pypi.org/project/invocation-tree/) package is desi
32
32
  ```
33
33
 
34
34
  ```python
35
- import invocation_tree as invo_tree
35
+ import invocation_tree as ivt
36
36
 
37
37
  def main():
38
38
  a = 1
@@ -52,7 +52,7 @@ def add(a, b):
52
52
  def multiply(a, b):
53
53
  return a * b
54
54
 
55
- tree = invo_tree.blocking()
55
+ tree = ivt.blocking()
56
56
  print( tree(main) ) # show invocation tree starting at main
57
57
  ```
58
58
  Running the program and pressing <Enter> a number of times results in:
@@ -96,7 +96,7 @@ ___
96
96
  In this more interesting example we compute which students pass a course by using list and dictionary comprehensions.
97
97
 
98
98
  ```python
99
- import invocation_tree as invo_tree
99
+ import invocation_tree as ivt
100
100
  from decimal import Decimal, ROUND_HALF_UP
101
101
 
102
102
  def main():
@@ -123,7 +123,7 @@ def passing_students(averages):
123
123
  if average >= 5.5]
124
124
 
125
125
  if __name__ == '__main__':
126
- tree = invo_tree.blocking()
126
+ tree = ivt.blocking()
127
127
  tree(main)
128
128
  ```
129
129
  ![students](https://raw.githubusercontent.com/bterwijn/invocation_tree/main/images/students.gif)
@@ -135,14 +135,14 @@ if __name__ == '__main__':
135
135
  The program blocks execution at every function call and return statement, printing the current location in the source code. Press the <Enter> key to continue execution. To block at every line of the program (like in a debugger tool) and only where a change of value occured, use instead:
136
136
 
137
137
  ```python
138
- tree = invo_tree.blocking_each_change()
138
+ tree = ivt.blocking_each_change()
139
139
  ```
140
140
 
141
141
  # Debugger #
142
142
  To visualize the invocation tree in a debugger tool, such as the integrated debugger in Visual Studio Code, use instead:
143
143
 
144
144
  ```python
145
- tree = invo_tree.debugger()
145
+ tree = ivt.debugger()
146
146
  ```
147
147
 
148
148
  and open the 'tree.pdf' file manually.
@@ -152,14 +152,15 @@ and open the 'tree.pdf' file manually.
152
152
  An invocation tree is particularly helpful to better understand recursion. A simple `factorial()` example:
153
153
 
154
154
  ```python
155
- import invocation_tree as invo_tree
155
+ import invocation_tree as ivt
156
156
 
157
157
  def factorial(n):
158
158
  if n <= 1:
159
159
  return 1
160
- return n * factorial(n - 1)
160
+ prev_result = factorial(n - 1)
161
+ return n * prev_result
161
162
 
162
- tree = invo_tree.blocking()
163
+ tree = ivt.blocking()
163
164
  print( tree(factorial, 4) ) # show invocation tree of calling factorial(4)
164
165
  ```
165
166
  ![factorial](https://raw.githubusercontent.com/bterwijn/invocation_tree/main/images/factorial.gif)
@@ -170,7 +171,7 @@ print( tree(factorial, 4) ) # show invocation tree of calling factorial(4)
170
171
  This `permutations()` example shows the depth-first nature of recursive execution:
171
172
 
172
173
  ```python
173
- import invocation_tree as invo_tree
174
+ import invocation_tree as ivt
174
175
 
175
176
  def permutations(elements, perm, n):
176
177
  if n==0:
@@ -180,7 +181,7 @@ def permutations(elements, perm, n):
180
181
  all_perms.extend(permutations(elements, perm + element, n-1))
181
182
  return all_perms
182
183
 
183
- tree = invo_tree.blocking()
184
+ tree = ivt.blocking()
184
185
  result = tree(permutations, ['L','R'], '', 2)
185
186
  print(result) # all permutations of going Left or Right of length 2
186
187
  ```
@@ -193,7 +194,7 @@ print(result) # all permutations of going Left or Right of length 2
193
194
  In an educational context it can be useful to hide certian variables to avoid unnecessary complexity. This can for example be done with:
194
195
 
195
196
  ```python
196
- tree = invo_tree.blocking()
197
+ tree = ivt.blocking()
197
198
  tree.hide.add('permutations.elements')
198
199
  tree.hide.add('permutations.element')
199
200
  tree.hide.add('permutations.all_perms')
@@ -203,7 +204,7 @@ tree.hide.add('permutations.all_perms')
203
204
  These invocation_tree configurations are available for an `Invocation_Tree` objects:
204
205
 
205
206
  ```python
206
- tree = invo_tree.Invocation_Tree()
207
+ tree = ivt.Invocation_Tree()
207
208
  ```
208
209
 
209
210
  - **tree.filename** : str
@@ -235,12 +236,12 @@ tree = invo_tree.Invocation_Tree()
235
236
 
236
237
  For convenience we provide these functions to set common configurations:
237
238
 
238
- - **invo_tree.blocking(filename)**, blocks on function call and return
239
- - **invo_tree.blocking_each_change(filename)**, blocks on each change of value
240
- - **invo_tree.debugger(filename)**, non-blocking for use in debugger tool (open &lt;filename&gt; manually)
241
- - **invo_tree.gif(filename)**, generates many output files on function call and return for gif creation
242
- - **invo_tree.gif_each_change(filename)**, generates many output files on each change of value for gif creation
243
- - **invo_tree.non_blocking(filename)**, non-blocking on each function call and return
239
+ - **ivt.blocking(filename)**, blocks on function call and return
240
+ - **ivt.blocking_each_change(filename)**, blocks on each change of value
241
+ - **ivt.debugger(filename)**, non-blocking for use in debugger tool (open &lt;filename&gt; manually)
242
+ - **ivt.gif(filename)**, generates many output files on function call and return for gif creation
243
+ - **ivt.gif_each_change(filename)**, generates many output files on each change of value for gif creation
244
+ - **ivt.non_blocking(filename)**, non-blocking on each function call and return
244
245
 
245
246
  # Troubleshooting #
246
247
  - Adobe Acrobat Reader [doesn't refresh a PDF file](https://superuser.com/questions/337011/windows-pdf-viewer-that-auto-refreshes-pdf-when-compiling-with-pdflatex) when it changes on disk and blocks updates which results in an `Could not open 'somefile.pdf' for writing : Permission denied` error. One solution is to install a PDF reader that does refresh ([Evince](https://www.fosshub.com/Evince.html), [Okular](https://okular.kde.org/), [SumatraPDF](https://www.sumatrapdfreader.org/), ...) and set it as the default PDF reader. Another solution is to save the tree to a different [Graphviz Output Format](https://graphviz.org/docs/outputs/).
@@ -13,7 +13,7 @@ The [invocation_tree](https://pypi.org/project/invocation-tree/) package is desi
13
13
  ```
14
14
 
15
15
  ```python
16
- import invocation_tree as invo_tree
16
+ import invocation_tree as ivt
17
17
 
18
18
  def main():
19
19
  a = 1
@@ -33,7 +33,7 @@ def add(a, b):
33
33
  def multiply(a, b):
34
34
  return a * b
35
35
 
36
- tree = invo_tree.blocking()
36
+ tree = ivt.blocking()
37
37
  print( tree(main) ) # show invocation tree starting at main
38
38
  ```
39
39
  Running the program and pressing &lt;Enter&gt; a number of times results in:
@@ -77,7 +77,7 @@ ___
77
77
  In this more interesting example we compute which students pass a course by using list and dictionary comprehensions.
78
78
 
79
79
  ```python
80
- import invocation_tree as invo_tree
80
+ import invocation_tree as ivt
81
81
  from decimal import Decimal, ROUND_HALF_UP
82
82
 
83
83
  def main():
@@ -104,7 +104,7 @@ def passing_students(averages):
104
104
  if average >= 5.5]
105
105
 
106
106
  if __name__ == '__main__':
107
- tree = invo_tree.blocking()
107
+ tree = ivt.blocking()
108
108
  tree(main)
109
109
  ```
110
110
  ![students](https://raw.githubusercontent.com/bterwijn/invocation_tree/main/images/students.gif)
@@ -116,14 +116,14 @@ if __name__ == '__main__':
116
116
  The program blocks execution at every function call and return statement, printing the current location in the source code. Press the &lt;Enter&gt; key to continue execution. To block at every line of the program (like in a debugger tool) and only where a change of value occured, use instead:
117
117
 
118
118
  ```python
119
- tree = invo_tree.blocking_each_change()
119
+ tree = ivt.blocking_each_change()
120
120
  ```
121
121
 
122
122
  # Debugger #
123
123
  To visualize the invocation tree in a debugger tool, such as the integrated debugger in Visual Studio Code, use instead:
124
124
 
125
125
  ```python
126
- tree = invo_tree.debugger()
126
+ tree = ivt.debugger()
127
127
  ```
128
128
 
129
129
  and open the 'tree.pdf' file manually.
@@ -133,14 +133,15 @@ and open the 'tree.pdf' file manually.
133
133
  An invocation tree is particularly helpful to better understand recursion. A simple `factorial()` example:
134
134
 
135
135
  ```python
136
- import invocation_tree as invo_tree
136
+ import invocation_tree as ivt
137
137
 
138
138
  def factorial(n):
139
139
  if n <= 1:
140
140
  return 1
141
- return n * factorial(n - 1)
141
+ prev_result = factorial(n - 1)
142
+ return n * prev_result
142
143
 
143
- tree = invo_tree.blocking()
144
+ tree = ivt.blocking()
144
145
  print( tree(factorial, 4) ) # show invocation tree of calling factorial(4)
145
146
  ```
146
147
  ![factorial](https://raw.githubusercontent.com/bterwijn/invocation_tree/main/images/factorial.gif)
@@ -151,7 +152,7 @@ print( tree(factorial, 4) ) # show invocation tree of calling factorial(4)
151
152
  This `permutations()` example shows the depth-first nature of recursive execution:
152
153
 
153
154
  ```python
154
- import invocation_tree as invo_tree
155
+ import invocation_tree as ivt
155
156
 
156
157
  def permutations(elements, perm, n):
157
158
  if n==0:
@@ -161,7 +162,7 @@ def permutations(elements, perm, n):
161
162
  all_perms.extend(permutations(elements, perm + element, n-1))
162
163
  return all_perms
163
164
 
164
- tree = invo_tree.blocking()
165
+ tree = ivt.blocking()
165
166
  result = tree(permutations, ['L','R'], '', 2)
166
167
  print(result) # all permutations of going Left or Right of length 2
167
168
  ```
@@ -174,7 +175,7 @@ print(result) # all permutations of going Left or Right of length 2
174
175
  In an educational context it can be useful to hide certian variables to avoid unnecessary complexity. This can for example be done with:
175
176
 
176
177
  ```python
177
- tree = invo_tree.blocking()
178
+ tree = ivt.blocking()
178
179
  tree.hide.add('permutations.elements')
179
180
  tree.hide.add('permutations.element')
180
181
  tree.hide.add('permutations.all_perms')
@@ -184,7 +185,7 @@ tree.hide.add('permutations.all_perms')
184
185
  These invocation_tree configurations are available for an `Invocation_Tree` objects:
185
186
 
186
187
  ```python
187
- tree = invo_tree.Invocation_Tree()
188
+ tree = ivt.Invocation_Tree()
188
189
  ```
189
190
 
190
191
  - **tree.filename** : str
@@ -216,12 +217,12 @@ tree = invo_tree.Invocation_Tree()
216
217
 
217
218
  For convenience we provide these functions to set common configurations:
218
219
 
219
- - **invo_tree.blocking(filename)**, blocks on function call and return
220
- - **invo_tree.blocking_each_change(filename)**, blocks on each change of value
221
- - **invo_tree.debugger(filename)**, non-blocking for use in debugger tool (open &lt;filename&gt; manually)
222
- - **invo_tree.gif(filename)**, generates many output files on function call and return for gif creation
223
- - **invo_tree.gif_each_change(filename)**, generates many output files on each change of value for gif creation
224
- - **invo_tree.non_blocking(filename)**, non-blocking on each function call and return
220
+ - **ivt.blocking(filename)**, blocks on function call and return
221
+ - **ivt.blocking_each_change(filename)**, blocks on each change of value
222
+ - **ivt.debugger(filename)**, non-blocking for use in debugger tool (open &lt;filename&gt; manually)
223
+ - **ivt.gif(filename)**, generates many output files on function call and return for gif creation
224
+ - **ivt.gif_each_change(filename)**, generates many output files on each change of value for gif creation
225
+ - **ivt.non_blocking(filename)**, non-blocking on each function call and return
225
226
 
226
227
  # Troubleshooting #
227
228
  - Adobe Acrobat Reader [doesn't refresh a PDF file](https://superuser.com/questions/337011/windows-pdf-viewer-that-auto-refreshes-pdf-when-compiling-with-pdflatex) when it changes on disk and blocks updates which results in an `Could not open 'somefile.pdf' for writing : Permission denied` error. One solution is to install a PDF reader that does refresh ([Evince](https://www.fosshub.com/Evince.html), [Okular](https://okular.kde.org/), [SumatraPDF](https://www.sumatrapdfreader.org/), ...) and set it as the default PDF reader. Another solution is to save the tree to a different [Graphviz Output Format](https://graphviz.org/docs/outputs/).
@@ -0,0 +1,13 @@
1
+ import invocation_tree as invo_tree
2
+
3
+ def my_generator():
4
+ yield 1
5
+ yield 2
6
+ yield 3
7
+
8
+ def main():
9
+ result = list(my_generator())
10
+ print('result:', result)
11
+
12
+ tree = invo_tree.gif('generator_function.png')
13
+ tree(main)
@@ -0,0 +1,22 @@
1
+ import invocation_tree as ivt
2
+
3
+ def main():
4
+ a = 1
5
+ a = expression(a)
6
+ return multiply(a, 6)
7
+
8
+ def expression(a):
9
+ a = subtract(a, 3)
10
+ return add(a, 9)
11
+
12
+ def subtract(a, b):
13
+ return a - b
14
+
15
+ def add(a, b):
16
+ return a + b
17
+
18
+ def multiply(a, b):
19
+ return a * b
20
+
21
+ tree = ivt.gif('compute.png')
22
+ print( tree(main) )
@@ -1,13 +1,13 @@
1
1
  import invocation_tree as invo_tree
2
2
 
3
3
  def main():
4
- a = 1
4
+ a = 10
5
5
  a = expression(a)
6
6
  return multiply(a, 6)
7
7
 
8
8
  def expression(a):
9
- a = subtract(a, 3)
10
- return add(a, 9)
9
+ a = subtract(a, 5)
10
+ return add(a, 2)
11
11
 
12
12
  def subtract(a, b):
13
13
  return a - b
@@ -0,0 +1,4 @@
1
+
2
+ python students.py
3
+ rm students0.png
4
+ bash create_gif.sh students
@@ -0,0 +1,28 @@
1
+ import invocation_tree as invo_tree
2
+
3
+ def subtract(pipeline):
4
+ for a in pipeline:
5
+ yield a - 3
6
+
7
+ def multiply(pipeline):
8
+ for a in pipeline:
9
+ yield a * 6
10
+
11
+ def my_sum(pipeline):
12
+ total = 0
13
+ for i in pipeline:
14
+ total += i
15
+ return total # return not yield, so not lazy
16
+
17
+ def main():
18
+ pipeline = range(1,4)
19
+ pipeline = subtract(pipeline)
20
+ pipeline = (a + 9 for a in pipeline)
21
+ pipeline = multiply(pipeline)
22
+ return my_sum(pipeline)
23
+
24
+ tree = invo_tree.blocking()
25
+ import types
26
+ tree.to_string[types.GeneratorType] = lambda x: 'generator' # short name for generators
27
+ tree.to_string[type(iter(range(0)))] = lambda x: 'iterator' # short name for iterator
28
+ print( tree(main) )
@@ -0,0 +1,10 @@
1
+ import invocation_tree as ivt
2
+
3
+ def factorial(n):
4
+ if n <= 1:
5
+ return 1
6
+ prev_result = factorial(n - 1)
7
+ return n * prev_result
8
+
9
+ tree = ivt.gif('factorial.png')
10
+ tree(factorial, 4)
@@ -0,0 +1,11 @@
1
+ import invocation_tree
2
+
3
+ def factorial(n):
4
+ if n <= 0:
5
+ return 1
6
+ return n * factorial(n - 1)
7
+
8
+ invocation_tree = invocation_tree.Invocation_Tree()
9
+ invocation_tree.block = False
10
+
11
+ print( invocation_tree(factorial, 4) )
@@ -0,0 +1,9 @@
1
+ import invocation_tree as invo_tree
2
+
3
+ def main():
4
+ iterable_in = range(1,4)
5
+ iterable_out = (i*10 for i in iterable_in) # generator expression
6
+ print(list(iterable_out))
7
+
8
+ tree = invo_tree.gif('generator_function.png')
9
+ tree(main)
@@ -0,0 +1,26 @@
1
+ import invocation_tree as invo_tree
2
+
3
+ def subtract(pipeline):
4
+ for a in pipeline:
5
+ yield a - 7
6
+
7
+ def add(pipeline):
8
+ for a in pipeline:
9
+ yield a + 2
10
+
11
+ def multiply(pipeline):
12
+ for a in pipeline:
13
+ yield a * 6
14
+
15
+ def main():
16
+ pipeline = range(1,4)
17
+ pipeline = subtract(pipeline)
18
+ pipeline = (a+2 for a in pipeline)
19
+ pipeline = multiply(pipeline)
20
+ return list(pipeline)
21
+
22
+ tree = invo_tree.blocking() # gif('generator_pipeline.png')
23
+ import types
24
+ tree.to_string[types.GeneratorType] = lambda x: 'generator' # short name for generators
25
+ tree.to_string[type(iter(range(0)))] = lambda x: 'range_iterator' # short name for range_iterator
26
+ print( tree(main) )
@@ -0,0 +1,44 @@
1
+ import invocation_tree as ivt
2
+
3
+ class My_Iterator:
4
+
5
+ def __init__(self, my_iterable):
6
+ self.value = my_iterable.start
7
+ self.my_iterable = my_iterable
8
+
9
+ def __repr__(self):
10
+ return f'My_Iterator value:{self.value}'
11
+
12
+ def __next__(self):
13
+ prev = self.value
14
+ self.value += self.my_iterable.step
15
+ if prev < self.my_iterable.stop:
16
+ return prev
17
+ raise StopIteration()
18
+
19
+ class My_Iterable:
20
+
21
+ def __init__(self, stop, start=0, step=1):
22
+ self.stop = stop
23
+ self.step = step
24
+ self.start = start
25
+ print('self:',self)
26
+
27
+ def __repr__(self):
28
+ return f'My_Iterable start:{self.start} stop:{self.stop} step:{self.step}'
29
+
30
+ def __iter__(self):
31
+ return My_Iterator(self)
32
+
33
+
34
+ def main():
35
+ iterable = My_Iterable(start=1, stop=3)
36
+ for i in iterable:
37
+ print(i)
38
+
39
+ tree = ivt.blocking() # gif('genexp.png')
40
+ #tree.to_string[type(iter(range(0)))] = lambda ri: 'iterator' # short name for iterator
41
+ #tree.to_string[types.GeneratorType] = lambda gen: 'generator' # short name for generators
42
+ tree.cleanup = False
43
+ print('sum:', tree(main))
44
+ #print('sum:', main())