uzoncalc 1.0.1__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.
- uzoncalc-1.0.1/LICENSE +21 -0
- uzoncalc-1.0.1/PKG-INFO +302 -0
- uzoncalc-1.0.1/README.md +280 -0
- uzoncalc-1.0.1/core/__init__.py +5 -0
- uzoncalc-1.0.1/core/context.py +98 -0
- uzoncalc-1.0.1/core/context_options.py +134 -0
- uzoncalc-1.0.1/core/handcalc/__init__.py +0 -0
- uzoncalc-1.0.1/core/handcalc/ast_instrument.py +111 -0
- uzoncalc-1.0.1/core/handcalc/ast_to_ir.py +314 -0
- uzoncalc-1.0.1/core/handcalc/ast_to_step.py +106 -0
- uzoncalc-1.0.1/core/handcalc/ast_validator.py +142 -0
- uzoncalc-1.0.1/core/handcalc/ast_visitor.py +257 -0
- uzoncalc-1.0.1/core/handcalc/exceptions.py +21 -0
- uzoncalc-1.0.1/core/handcalc/field_names.py +14 -0
- uzoncalc-1.0.1/core/handcalc/instrument_cache.py +48 -0
- uzoncalc-1.0.1/core/handcalc/ir.py +411 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/__init__.py +0 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/base_post_handler.py +19 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/parentheses_simplify.py +19 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/post_pipeline.py +25 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/subscriptify.py +48 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/swap_alias.py +47 -0
- uzoncalc-1.0.1/core/handcalc/post_handlers/swap_symbol.py +98 -0
- uzoncalc-1.0.1/core/handcalc/recorder.py +23 -0
- uzoncalc-1.0.1/core/handcalc/recording_injector.py +166 -0
- uzoncalc-1.0.1/core/handcalc/recording_state.py +25 -0
- uzoncalc-1.0.1/core/handcalc/steps.py +542 -0
- uzoncalc-1.0.1/core/handcalc/transformers.py +60 -0
- uzoncalc-1.0.1/core/handcalc/unit_collector.py +173 -0
- uzoncalc-1.0.1/core/logger.py +4 -0
- uzoncalc-1.0.1/core/setup.py +77 -0
- uzoncalc-1.0.1/core/template/__init__.py +0 -0
- uzoncalc-1.0.1/core/template/calc_template.html +278 -0
- uzoncalc-1.0.1/core/template/template.css +376 -0
- uzoncalc-1.0.1/core/template/utils.py +112 -0
- uzoncalc-1.0.1/core/tests/__init__.py +0 -0
- uzoncalc-1.0.1/core/tests/ast_print.py +17 -0
- uzoncalc-1.0.1/core/tests/example.py +28 -0
- uzoncalc-1.0.1/core/units.py +5 -0
- uzoncalc-1.0.1/core/utils/__init__.py +4 -0
- uzoncalc-1.0.1/core/utils/doc.py +105 -0
- uzoncalc-1.0.1/core/utils/elements.py +793 -0
- uzoncalc-1.0.1/core/utils/options.py +96 -0
- uzoncalc-1.0.1/core/utils_extra/__init__.py +0 -0
- uzoncalc-1.0.1/core/utils_extra/excel.py +281 -0
- uzoncalc-1.0.1/pyproject.toml +3 -0
- uzoncalc-1.0.1/setup.cfg +4 -0
- uzoncalc-1.0.1/setup.py +23 -0
- uzoncalc-1.0.1/tests/test_hello.py +2 -0
- uzoncalc-1.0.1/tests/test_pkg.py +14 -0
- uzoncalc-1.0.1/uzoncalc.egg-info/PKG-INFO +302 -0
- uzoncalc-1.0.1/uzoncalc.egg-info/SOURCES.txt +53 -0
- uzoncalc-1.0.1/uzoncalc.egg-info/dependency_links.txt +1 -0
- uzoncalc-1.0.1/uzoncalc.egg-info/requires.txt +2 -0
- uzoncalc-1.0.1/uzoncalc.egg-info/top_level.txt +1 -0
uzoncalc-1.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 uyoufu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
uzoncalc-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: uzoncalc
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: UzonCalc is a tool for writing engineering calculation documents using Python. With it, you can write calculation reports as smoothly as writing Python, and benefit from the full Python ecosystem and AI assistance.
|
|
5
|
+
Home-page: https://github.com/uyoufu/UzonCalc
|
|
6
|
+
Author: uyoufu
|
|
7
|
+
Author-email: uyoufu@uzoncloud.com
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: pint
|
|
12
|
+
Requires-Dist: numpy
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: author-email
|
|
15
|
+
Dynamic: description
|
|
16
|
+
Dynamic: description-content-type
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
Dynamic: requires-dist
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
Dynamic: summary
|
|
22
|
+
|
|
23
|
+
# UzonCalc
|
|
24
|
+
|
|
25
|
+
[中文](README.zh-CN.md)
|
|
26
|
+
|
|
27
|
+
UzonCalc is a tool for writing engineering calculation documents using Python. With it, you can write calculation reports as smoothly as writing Python, and benefit from the full Python ecosystem and AI assistance.
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
1. Write using Python code — no extra syntax to learn
|
|
32
|
+
2. Benefit from the Python ecosystem and AI support
|
|
33
|
+
3. Focus on calculations, not layout
|
|
34
|
+
4. Output beautiful HTML directly; convertible to PDF and Docx
|
|
35
|
+
|
|
36
|
+
## Start
|
|
37
|
+
|
|
38
|
+
**Installation**
|
|
39
|
+
|
|
40
|
+
``` bash
|
|
41
|
+
pip install uzoncalc
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Copy Template**
|
|
45
|
+
|
|
46
|
+
``` Python
|
|
47
|
+
# example.py
|
|
48
|
+
from uzoncalc import *
|
|
49
|
+
|
|
50
|
+
@uzon_calc()
|
|
51
|
+
def sheet():
|
|
52
|
+
doc_title("uzoncalc example")
|
|
53
|
+
|
|
54
|
+
"Hello, UzonCalc!"
|
|
55
|
+
|
|
56
|
+
save()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
sheet()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Execution**
|
|
64
|
+
|
|
65
|
+
``` python
|
|
66
|
+
python example.py
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Example
|
|
70
|
+
|
|
71
|
+
``` python
|
|
72
|
+
from numpy import sqrt
|
|
73
|
+
from pathlib import Path
|
|
74
|
+
import sys
|
|
75
|
+
|
|
76
|
+
# Ensure project root is on sys.path so `import core` works when running
|
|
77
|
+
# this script from the `core` folder.
|
|
78
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
from core.setup import uzon_calc
|
|
82
|
+
from core.utils import *
|
|
83
|
+
from core.utils_extra.excel import get_excel_table
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@uzon_calc()
|
|
87
|
+
def sheet():
|
|
88
|
+
doc_title("UzonCalc Full Example")
|
|
89
|
+
page_size("A4")
|
|
90
|
+
|
|
91
|
+
H1("UzonCalc Full Example")
|
|
92
|
+
|
|
93
|
+
"This is a full example demonstrating various features of UzonCalc."
|
|
94
|
+
|
|
95
|
+
toc()
|
|
96
|
+
|
|
97
|
+
# description:
|
|
98
|
+
# this is a full example of using UzonCalc.
|
|
99
|
+
|
|
100
|
+
H2("Auto Table of Contents")
|
|
101
|
+
"You can automatically generate a table of contents for your document."
|
|
102
|
+
|
|
103
|
+
H2("Basic Constants")
|
|
104
|
+
# number
|
|
105
|
+
H3("Numbers")
|
|
106
|
+
intNumber = 100
|
|
107
|
+
floatNumber = 3.1415
|
|
108
|
+
scientificNumber = 1.2e3
|
|
109
|
+
complexNumber = 2 + 3j
|
|
110
|
+
|
|
111
|
+
H3("Strings")
|
|
112
|
+
helloString = "Hello,"
|
|
113
|
+
uzonCalcString = "UzonCalc!"
|
|
114
|
+
greeting = helloString + uzonCalcString
|
|
115
|
+
|
|
116
|
+
H3("String Output")
|
|
117
|
+
# you can output strings directly
|
|
118
|
+
"This is a string output inline."
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
This is a string output block.
|
|
122
|
+
It can span multiple lines.
|
|
123
|
+
It will be rendered as paragraph.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
H3("String Formatting")
|
|
127
|
+
name = "Uzon"
|
|
128
|
+
f"Hello, {name}! Welcome to UzonCalc."
|
|
129
|
+
pi = 3.1415926535
|
|
130
|
+
f"Value of pi up to 3 decimal places: {pi:.3f}"
|
|
131
|
+
|
|
132
|
+
H3("String Formatting With Equations")
|
|
133
|
+
enable_fstring_equation()
|
|
134
|
+
f"Hello, {name}! Welcome to UzonCalc."
|
|
135
|
+
f"The value of pi is approximately {pi:.3f}, which is useful in calculations."
|
|
136
|
+
disable_fstring_equation()
|
|
137
|
+
|
|
138
|
+
H2("Units and Calculations")
|
|
139
|
+
length = 5 * unit.meter
|
|
140
|
+
time = 2 * unit.second
|
|
141
|
+
speed = length / time
|
|
142
|
+
|
|
143
|
+
H3("Complex Calculation")
|
|
144
|
+
|
|
145
|
+
acceleration = speed / time
|
|
146
|
+
force = 10 * unit.kilogram * acceleration
|
|
147
|
+
stress = force / (length**2)
|
|
148
|
+
|
|
149
|
+
H3("Unit Conversion")
|
|
150
|
+
"Original speed in m/s:"
|
|
151
|
+
speed
|
|
152
|
+
hide()
|
|
153
|
+
speedKmh = speed.to(unit.kilometer / unit.hour)
|
|
154
|
+
show()
|
|
155
|
+
f"Speed in km/h: {speedKmh}"
|
|
156
|
+
|
|
157
|
+
# use matplotlib to plot a sine wave
|
|
158
|
+
H2("Plotting Example")
|
|
159
|
+
"You can use Matplotlib to create plots within UzonCalc."
|
|
160
|
+
hide()
|
|
161
|
+
import numpy as np
|
|
162
|
+
import matplotlib.pyplot as plt
|
|
163
|
+
|
|
164
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
165
|
+
y = np.sin(x)
|
|
166
|
+
plt.plot(x, y)
|
|
167
|
+
plt.title("Sine Wave")
|
|
168
|
+
plt.xlabel("x (radians)")
|
|
169
|
+
plt.ylabel("sin(x)")
|
|
170
|
+
plt.legend(["sin(x)"])
|
|
171
|
+
plt.grid(True)
|
|
172
|
+
show()
|
|
173
|
+
Plot(plt)
|
|
174
|
+
|
|
175
|
+
# sub
|
|
176
|
+
H2("Variable subscription")
|
|
177
|
+
|
|
178
|
+
H3("Default Subscript Rule")
|
|
179
|
+
|
|
180
|
+
"if you want to make a word to be subscript, you can use _ after it. For example, H_2 will be rendered as H₂."
|
|
181
|
+
a_x = 10 * unit.meter / unit.second**2
|
|
182
|
+
speed_2 = a_x * 2 * unit.second
|
|
183
|
+
|
|
184
|
+
H3("complex Subscript")
|
|
185
|
+
|
|
186
|
+
"You can also use other language characters as subscripts, like gamma_混凝土."
|
|
187
|
+
"You can use alias"
|
|
188
|
+
|
|
189
|
+
H3("Array Subscript")
|
|
190
|
+
"You can use array subscript like A[i]."
|
|
191
|
+
|
|
192
|
+
# 希腊字母
|
|
193
|
+
H2("Greek Letters")
|
|
194
|
+
"You can use Greek letters like 'alpha' (α), 'beta' (β), 'gamma' (γ), 'delta' (δ), etc. in your calculations."
|
|
195
|
+
"When you write 'alpha', it will be rendered as α."
|
|
196
|
+
"Capitalized Greek letters like 'Beta' will be rendered as Β."
|
|
197
|
+
|
|
198
|
+
rho_water = 1000 * unit.kilogram / unit.meter**3
|
|
199
|
+
g = 9.81 * unit.meter / unit.second**2
|
|
200
|
+
h = 10 * unit.meter
|
|
201
|
+
pressure = rho_water * g * h
|
|
202
|
+
"Pressure calculated using ρgh:"
|
|
203
|
+
pressure
|
|
204
|
+
|
|
205
|
+
H2("Functions Converter")
|
|
206
|
+
|
|
207
|
+
"Some functions can automatically convert to math style."
|
|
208
|
+
|
|
209
|
+
H3("Square Root")
|
|
210
|
+
"You can use sqrt(x) to represent the square root of x."
|
|
211
|
+
|
|
212
|
+
edge1 = 3 * unit.meter
|
|
213
|
+
edge2 = 4 * unit.meter
|
|
214
|
+
diagonal = sqrt(edge1**2 + edge2**2)
|
|
215
|
+
|
|
216
|
+
H3("Absolute Value")
|
|
217
|
+
"You can use abs(x) to represent the absolute value of x."
|
|
218
|
+
value = -15 * unit.newton
|
|
219
|
+
absValue = abs(value)
|
|
220
|
+
|
|
221
|
+
H2("Tables")
|
|
222
|
+
|
|
223
|
+
"You can create tables to organize data."
|
|
224
|
+
|
|
225
|
+
Table(
|
|
226
|
+
[
|
|
227
|
+
[
|
|
228
|
+
th("Component", rowspan=3),
|
|
229
|
+
th("Material", rowspan=3),
|
|
230
|
+
th("Elastic Modulus (MPa)", colspan=2),
|
|
231
|
+
th("Design Strength (MPa)", colspan=2),
|
|
232
|
+
th("Standard Strength (MPa)", colspan=2),
|
|
233
|
+
],
|
|
234
|
+
[
|
|
235
|
+
"Ec/Es",
|
|
236
|
+
"Compressive",
|
|
237
|
+
"Tensile",
|
|
238
|
+
"Compressive",
|
|
239
|
+
"Tensile",
|
|
240
|
+
],
|
|
241
|
+
],
|
|
242
|
+
[
|
|
243
|
+
["Cap Beam", "C60", 3.6e4, 26.5, 1.96, 38.5, 2.85],
|
|
244
|
+
["Cap Beam 2", "C60", 3.6e4, 26.5, 1.96, 38.5, 2.85],
|
|
245
|
+
],
|
|
246
|
+
title="Sample Table",
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
H2("Call Excel Calculation")
|
|
250
|
+
|
|
251
|
+
"You can update values for Excel calculation and get results table back."
|
|
252
|
+
"This is very useful for re-using of existing Excel calculation."
|
|
253
|
+
|
|
254
|
+
P(
|
|
255
|
+
get_excel_table(
|
|
256
|
+
excel_path="examples/calculation.xlsx",
|
|
257
|
+
values={
|
|
258
|
+
"A3": 6,
|
|
259
|
+
"B3": 10,
|
|
260
|
+
"C3": 2,
|
|
261
|
+
},
|
|
262
|
+
range="A1:D3",
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
"Excel table will be cached for faster rendering next time if cache=True and the input values are not changed."
|
|
267
|
+
|
|
268
|
+
H2("Saving Document")
|
|
269
|
+
|
|
270
|
+
H3("Save as HTML")
|
|
271
|
+
|
|
272
|
+
"You can save the document as an HTML file using the save() function."
|
|
273
|
+
|
|
274
|
+
H3("Export To Word Document")
|
|
275
|
+
|
|
276
|
+
"You can export the html document to a word document by pandoc command."
|
|
277
|
+
|
|
278
|
+
from core.utils.doc import save
|
|
279
|
+
|
|
280
|
+
save("../output/example.en.html")
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
if __name__ == "__main__":
|
|
284
|
+
import time
|
|
285
|
+
|
|
286
|
+
t0 = time.perf_counter()
|
|
287
|
+
sheet() # type: ignore
|
|
288
|
+
t1 = time.perf_counter()
|
|
289
|
+
print(f"Execution time: {t1 - t0} seconds")
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Preview:
|
|
294
|
+
|
|
295
|
+

|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
## Demo
|
|
299
|
+
|
|
300
|
+
Source: [example.en.py](https://github.com/uyoufu/UzonCalc/blob/master/examples/example.en.py)
|
|
301
|
+
|
|
302
|
+
Compile Result: [UzonCalc Full Example](https://calc.uzoncloud.com/example.en.html)
|
uzoncalc-1.0.1/README.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# UzonCalc
|
|
2
|
+
|
|
3
|
+
[中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
UzonCalc is a tool for writing engineering calculation documents using Python. With it, you can write calculation reports as smoothly as writing Python, and benefit from the full Python ecosystem and AI assistance.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
1. Write using Python code — no extra syntax to learn
|
|
10
|
+
2. Benefit from the Python ecosystem and AI support
|
|
11
|
+
3. Focus on calculations, not layout
|
|
12
|
+
4. Output beautiful HTML directly; convertible to PDF and Docx
|
|
13
|
+
|
|
14
|
+
## Start
|
|
15
|
+
|
|
16
|
+
**Installation**
|
|
17
|
+
|
|
18
|
+
``` bash
|
|
19
|
+
pip install uzoncalc
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Copy Template**
|
|
23
|
+
|
|
24
|
+
``` Python
|
|
25
|
+
# example.py
|
|
26
|
+
from uzoncalc import *
|
|
27
|
+
|
|
28
|
+
@uzon_calc()
|
|
29
|
+
def sheet():
|
|
30
|
+
doc_title("uzoncalc example")
|
|
31
|
+
|
|
32
|
+
"Hello, UzonCalc!"
|
|
33
|
+
|
|
34
|
+
save()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
sheet()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Execution**
|
|
42
|
+
|
|
43
|
+
``` python
|
|
44
|
+
python example.py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
|
|
49
|
+
``` python
|
|
50
|
+
from numpy import sqrt
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
import sys
|
|
53
|
+
|
|
54
|
+
# Ensure project root is on sys.path so `import core` works when running
|
|
55
|
+
# this script from the `core` folder.
|
|
56
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
from core.setup import uzon_calc
|
|
60
|
+
from core.utils import *
|
|
61
|
+
from core.utils_extra.excel import get_excel_table
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@uzon_calc()
|
|
65
|
+
def sheet():
|
|
66
|
+
doc_title("UzonCalc Full Example")
|
|
67
|
+
page_size("A4")
|
|
68
|
+
|
|
69
|
+
H1("UzonCalc Full Example")
|
|
70
|
+
|
|
71
|
+
"This is a full example demonstrating various features of UzonCalc."
|
|
72
|
+
|
|
73
|
+
toc()
|
|
74
|
+
|
|
75
|
+
# description:
|
|
76
|
+
# this is a full example of using UzonCalc.
|
|
77
|
+
|
|
78
|
+
H2("Auto Table of Contents")
|
|
79
|
+
"You can automatically generate a table of contents for your document."
|
|
80
|
+
|
|
81
|
+
H2("Basic Constants")
|
|
82
|
+
# number
|
|
83
|
+
H3("Numbers")
|
|
84
|
+
intNumber = 100
|
|
85
|
+
floatNumber = 3.1415
|
|
86
|
+
scientificNumber = 1.2e3
|
|
87
|
+
complexNumber = 2 + 3j
|
|
88
|
+
|
|
89
|
+
H3("Strings")
|
|
90
|
+
helloString = "Hello,"
|
|
91
|
+
uzonCalcString = "UzonCalc!"
|
|
92
|
+
greeting = helloString + uzonCalcString
|
|
93
|
+
|
|
94
|
+
H3("String Output")
|
|
95
|
+
# you can output strings directly
|
|
96
|
+
"This is a string output inline."
|
|
97
|
+
|
|
98
|
+
"""
|
|
99
|
+
This is a string output block.
|
|
100
|
+
It can span multiple lines.
|
|
101
|
+
It will be rendered as paragraph.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
H3("String Formatting")
|
|
105
|
+
name = "Uzon"
|
|
106
|
+
f"Hello, {name}! Welcome to UzonCalc."
|
|
107
|
+
pi = 3.1415926535
|
|
108
|
+
f"Value of pi up to 3 decimal places: {pi:.3f}"
|
|
109
|
+
|
|
110
|
+
H3("String Formatting With Equations")
|
|
111
|
+
enable_fstring_equation()
|
|
112
|
+
f"Hello, {name}! Welcome to UzonCalc."
|
|
113
|
+
f"The value of pi is approximately {pi:.3f}, which is useful in calculations."
|
|
114
|
+
disable_fstring_equation()
|
|
115
|
+
|
|
116
|
+
H2("Units and Calculations")
|
|
117
|
+
length = 5 * unit.meter
|
|
118
|
+
time = 2 * unit.second
|
|
119
|
+
speed = length / time
|
|
120
|
+
|
|
121
|
+
H3("Complex Calculation")
|
|
122
|
+
|
|
123
|
+
acceleration = speed / time
|
|
124
|
+
force = 10 * unit.kilogram * acceleration
|
|
125
|
+
stress = force / (length**2)
|
|
126
|
+
|
|
127
|
+
H3("Unit Conversion")
|
|
128
|
+
"Original speed in m/s:"
|
|
129
|
+
speed
|
|
130
|
+
hide()
|
|
131
|
+
speedKmh = speed.to(unit.kilometer / unit.hour)
|
|
132
|
+
show()
|
|
133
|
+
f"Speed in km/h: {speedKmh}"
|
|
134
|
+
|
|
135
|
+
# use matplotlib to plot a sine wave
|
|
136
|
+
H2("Plotting Example")
|
|
137
|
+
"You can use Matplotlib to create plots within UzonCalc."
|
|
138
|
+
hide()
|
|
139
|
+
import numpy as np
|
|
140
|
+
import matplotlib.pyplot as plt
|
|
141
|
+
|
|
142
|
+
x = np.linspace(0, 2 * np.pi, 100)
|
|
143
|
+
y = np.sin(x)
|
|
144
|
+
plt.plot(x, y)
|
|
145
|
+
plt.title("Sine Wave")
|
|
146
|
+
plt.xlabel("x (radians)")
|
|
147
|
+
plt.ylabel("sin(x)")
|
|
148
|
+
plt.legend(["sin(x)"])
|
|
149
|
+
plt.grid(True)
|
|
150
|
+
show()
|
|
151
|
+
Plot(plt)
|
|
152
|
+
|
|
153
|
+
# sub
|
|
154
|
+
H2("Variable subscription")
|
|
155
|
+
|
|
156
|
+
H3("Default Subscript Rule")
|
|
157
|
+
|
|
158
|
+
"if you want to make a word to be subscript, you can use _ after it. For example, H_2 will be rendered as H₂."
|
|
159
|
+
a_x = 10 * unit.meter / unit.second**2
|
|
160
|
+
speed_2 = a_x * 2 * unit.second
|
|
161
|
+
|
|
162
|
+
H3("complex Subscript")
|
|
163
|
+
|
|
164
|
+
"You can also use other language characters as subscripts, like gamma_混凝土."
|
|
165
|
+
"You can use alias"
|
|
166
|
+
|
|
167
|
+
H3("Array Subscript")
|
|
168
|
+
"You can use array subscript like A[i]."
|
|
169
|
+
|
|
170
|
+
# 希腊字母
|
|
171
|
+
H2("Greek Letters")
|
|
172
|
+
"You can use Greek letters like 'alpha' (α), 'beta' (β), 'gamma' (γ), 'delta' (δ), etc. in your calculations."
|
|
173
|
+
"When you write 'alpha', it will be rendered as α."
|
|
174
|
+
"Capitalized Greek letters like 'Beta' will be rendered as Β."
|
|
175
|
+
|
|
176
|
+
rho_water = 1000 * unit.kilogram / unit.meter**3
|
|
177
|
+
g = 9.81 * unit.meter / unit.second**2
|
|
178
|
+
h = 10 * unit.meter
|
|
179
|
+
pressure = rho_water * g * h
|
|
180
|
+
"Pressure calculated using ρgh:"
|
|
181
|
+
pressure
|
|
182
|
+
|
|
183
|
+
H2("Functions Converter")
|
|
184
|
+
|
|
185
|
+
"Some functions can automatically convert to math style."
|
|
186
|
+
|
|
187
|
+
H3("Square Root")
|
|
188
|
+
"You can use sqrt(x) to represent the square root of x."
|
|
189
|
+
|
|
190
|
+
edge1 = 3 * unit.meter
|
|
191
|
+
edge2 = 4 * unit.meter
|
|
192
|
+
diagonal = sqrt(edge1**2 + edge2**2)
|
|
193
|
+
|
|
194
|
+
H3("Absolute Value")
|
|
195
|
+
"You can use abs(x) to represent the absolute value of x."
|
|
196
|
+
value = -15 * unit.newton
|
|
197
|
+
absValue = abs(value)
|
|
198
|
+
|
|
199
|
+
H2("Tables")
|
|
200
|
+
|
|
201
|
+
"You can create tables to organize data."
|
|
202
|
+
|
|
203
|
+
Table(
|
|
204
|
+
[
|
|
205
|
+
[
|
|
206
|
+
th("Component", rowspan=3),
|
|
207
|
+
th("Material", rowspan=3),
|
|
208
|
+
th("Elastic Modulus (MPa)", colspan=2),
|
|
209
|
+
th("Design Strength (MPa)", colspan=2),
|
|
210
|
+
th("Standard Strength (MPa)", colspan=2),
|
|
211
|
+
],
|
|
212
|
+
[
|
|
213
|
+
"Ec/Es",
|
|
214
|
+
"Compressive",
|
|
215
|
+
"Tensile",
|
|
216
|
+
"Compressive",
|
|
217
|
+
"Tensile",
|
|
218
|
+
],
|
|
219
|
+
],
|
|
220
|
+
[
|
|
221
|
+
["Cap Beam", "C60", 3.6e4, 26.5, 1.96, 38.5, 2.85],
|
|
222
|
+
["Cap Beam 2", "C60", 3.6e4, 26.5, 1.96, 38.5, 2.85],
|
|
223
|
+
],
|
|
224
|
+
title="Sample Table",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
H2("Call Excel Calculation")
|
|
228
|
+
|
|
229
|
+
"You can update values for Excel calculation and get results table back."
|
|
230
|
+
"This is very useful for re-using of existing Excel calculation."
|
|
231
|
+
|
|
232
|
+
P(
|
|
233
|
+
get_excel_table(
|
|
234
|
+
excel_path="examples/calculation.xlsx",
|
|
235
|
+
values={
|
|
236
|
+
"A3": 6,
|
|
237
|
+
"B3": 10,
|
|
238
|
+
"C3": 2,
|
|
239
|
+
},
|
|
240
|
+
range="A1:D3",
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
"Excel table will be cached for faster rendering next time if cache=True and the input values are not changed."
|
|
245
|
+
|
|
246
|
+
H2("Saving Document")
|
|
247
|
+
|
|
248
|
+
H3("Save as HTML")
|
|
249
|
+
|
|
250
|
+
"You can save the document as an HTML file using the save() function."
|
|
251
|
+
|
|
252
|
+
H3("Export To Word Document")
|
|
253
|
+
|
|
254
|
+
"You can export the html document to a word document by pandoc command."
|
|
255
|
+
|
|
256
|
+
from core.utils.doc import save
|
|
257
|
+
|
|
258
|
+
save("../output/example.en.html")
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
if __name__ == "__main__":
|
|
262
|
+
import time
|
|
263
|
+
|
|
264
|
+
t0 = time.perf_counter()
|
|
265
|
+
sheet() # type: ignore
|
|
266
|
+
t1 = time.perf_counter()
|
|
267
|
+
print(f"Execution time: {t1 - t0} seconds")
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Preview:
|
|
272
|
+
|
|
273
|
+

|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
## Demo
|
|
277
|
+
|
|
278
|
+
Source: [example.en.py](https://github.com/uyoufu/UzonCalc/blob/master/examples/example.en.py)
|
|
279
|
+
|
|
280
|
+
Compile Result: [UzonCalc Full Example](https://calc.uzoncloud.com/example.en.html)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
import os
|
|
3
|
+
from .context_options import ContextOptions
|
|
4
|
+
from .db.json_db import JsonDB
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CalcContext:
|
|
8
|
+
def __init__(self, *, name: str | None = None, file_path: str | None = None):
|
|
9
|
+
self.name = name or "calc_ctx" + hex(id(self))
|
|
10
|
+
self.file_path = file_path
|
|
11
|
+
|
|
12
|
+
self.options = ContextOptions()
|
|
13
|
+
|
|
14
|
+
# 记录结果
|
|
15
|
+
self.__contents = []
|
|
16
|
+
|
|
17
|
+
# 记录行内内容的临时存储
|
|
18
|
+
self.__inline_values: list[str] | None = None
|
|
19
|
+
self.__inline_separator: str = " "
|
|
20
|
+
|
|
21
|
+
# sqlite
|
|
22
|
+
self.json_db: None | JsonDB = None
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def contents(self):
|
|
26
|
+
return self.__contents
|
|
27
|
+
|
|
28
|
+
# region content recording
|
|
29
|
+
def append_content(self, content: str):
|
|
30
|
+
if self.options.skip_content:
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
# 对 content 进行后处理
|
|
34
|
+
for handler in self.options.post_handlers:
|
|
35
|
+
content = handler.handle(content, ctx=self)
|
|
36
|
+
|
|
37
|
+
# 若有 row_values,则添加到 row_values 中
|
|
38
|
+
# 在其它地方将其转换成一行内容
|
|
39
|
+
if self.__inline_values is not None:
|
|
40
|
+
self.__inline_values.append(content)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
self.__contents.append(content)
|
|
44
|
+
|
|
45
|
+
def start_inline(self, separator: str = " "):
|
|
46
|
+
self.__inline_separator = separator
|
|
47
|
+
if self.__inline_values is not None:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
self.__inline_values = []
|
|
51
|
+
|
|
52
|
+
def end_inline(self):
|
|
53
|
+
if self.__inline_values:
|
|
54
|
+
combined = self.__inline_separator.join(self.__inline_values)
|
|
55
|
+
# 将整行内容包装在 <p> 标签中
|
|
56
|
+
self.__contents.append(f"<p>{combined}</p>")
|
|
57
|
+
self.__inline_values = None
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def is_inline_mode(self) -> bool:
|
|
61
|
+
"""检查是否处于 inline 模式"""
|
|
62
|
+
return self.__inline_values is not None
|
|
63
|
+
|
|
64
|
+
# endregion
|
|
65
|
+
|
|
66
|
+
# region result generation
|
|
67
|
+
def html_content(self) -> str:
|
|
68
|
+
return "\n".join(self.__contents)
|
|
69
|
+
|
|
70
|
+
# endregion
|
|
71
|
+
|
|
72
|
+
def get_location_dir(self) -> str:
|
|
73
|
+
"""
|
|
74
|
+
获取当前上下文文件所在目录
|
|
75
|
+
若 file_path 未设置,则返回当前工作目录
|
|
76
|
+
"""
|
|
77
|
+
if self.file_path:
|
|
78
|
+
return os.path.dirname(os.path.abspath(self.file_path))
|
|
79
|
+
return os.getcwd()
|
|
80
|
+
|
|
81
|
+
def get_json_db(self) -> JsonDB:
|
|
82
|
+
"""
|
|
83
|
+
获取 SQLite 游标
|
|
84
|
+
若尚未创建数据库连接,则创建一个内存数据库连接
|
|
85
|
+
"""
|
|
86
|
+
if self.json_db is not None:
|
|
87
|
+
return self.json_db
|
|
88
|
+
|
|
89
|
+
dir = self.get_location_dir()
|
|
90
|
+
|
|
91
|
+
# 开始连接
|
|
92
|
+
self.json_db = JsonDB(os.path.join(dir, f"data/db.json"))
|
|
93
|
+
return self.json_db
|
|
94
|
+
|
|
95
|
+
def exit(self):
|
|
96
|
+
"""退出上下文,关闭数据库连接等"""
|
|
97
|
+
if self.json_db is not None:
|
|
98
|
+
self.json_db.save()
|