physeq 0.1.0__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.
- physeq-0.1.0/CHANGELOG.md +6 -0
- physeq-0.1.0/LICENSE.txt +67 -0
- physeq-0.1.0/PKG-INFO +241 -0
- physeq-0.1.0/README.md +217 -0
- physeq-0.1.0/physeq/__init__.py +15 -0
- physeq-0.1.0/physeq/cas/__init__.py +1 -0
- physeq-0.1.0/physeq/cas/equation.py +225 -0
- physeq-0.1.0/physeq/cas/exprorder.py +1774 -0
- physeq-0.1.0/physeq/cas/printing.py +404 -0
- physeq-0.1.0/physeq/cas/problem.py +279 -0
- physeq-0.1.0/physeq/cas/symbol.py +933 -0
- physeq-0.1.0/physeq/cas/wrapped.py +111 -0
- physeq-0.1.0/physeq/configuration.py +96 -0
- physeq-0.1.0/physeq/fmtversion.py +206 -0
- physeq-0.1.0/physeq/force.py +42 -0
- physeq-0.1.0/physeq/symbols/__init__.py +1 -0
- physeq-0.1.0/physeq/symbols/constants.py +24 -0
- physeq-0.1.0/physeq/symbols/force.py +85 -0
- physeq-0.1.0/physeq/symbols/kinematics.py +32 -0
- physeq-0.1.0/physeq/symbols/mass.py +23 -0
- physeq-0.1.0/physeq/symbols/space.py +36 -0
- physeq-0.1.0/physeq/symbols/time.py +17 -0
- physeq-0.1.0/physeq/symbols/work_energy.py +42 -0
- physeq-0.1.0/physeq/version.py +4 -0
- physeq-0.1.0/physeq/work_energy.py +37 -0
- physeq-0.1.0/physeq.egg-info/PKG-INFO +241 -0
- physeq-0.1.0/physeq.egg-info/SOURCES.txt +30 -0
- physeq-0.1.0/physeq.egg-info/dependency_links.txt +1 -0
- physeq-0.1.0/physeq.egg-info/requires.txt +2 -0
- physeq-0.1.0/physeq.egg-info/top_level.txt +1 -0
- physeq-0.1.0/pyproject.toml +45 -0
- physeq-0.1.0/setup.cfg +4 -0
physeq-0.1.0/LICENSE.txt
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026, Geoffrey M. Poore
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
------------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Some methods of the `LatexPrinter` class are adapted from SymPy
|
|
36
|
+
(https://github.com/sympy/sympy). See the implementation for details and
|
|
37
|
+
references to the SymPy source. SymPy license:
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Copyright (c) 2006-2023 SymPy Development Team
|
|
41
|
+
|
|
42
|
+
All rights reserved.
|
|
43
|
+
|
|
44
|
+
Redistribution and use in source and binary forms, with or without
|
|
45
|
+
modification, are permitted provided that the following conditions are met:
|
|
46
|
+
|
|
47
|
+
a. Redistributions of source code must retain the above copyright notice,
|
|
48
|
+
this list of conditions and the following disclaimer.
|
|
49
|
+
b. Redistributions in binary form must reproduce the above copyright
|
|
50
|
+
notice, this list of conditions and the following disclaimer in the
|
|
51
|
+
documentation and/or other materials provided with the distribution.
|
|
52
|
+
c. Neither the name of SymPy nor the names of its contributors
|
|
53
|
+
may be used to endorse or promote products derived from this software
|
|
54
|
+
without specific prior written permission.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
58
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
59
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
60
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
|
61
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
62
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
63
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
64
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
65
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
66
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
67
|
+
DAMAGE.
|
physeq-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: physeq
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Library for generating physics problems with realistic values and step-by-step solutions
|
|
5
|
+
Author-email: "Geoffrey M. Poore" <gpoore@gmail.com>
|
|
6
|
+
Project-URL: homepage, https://github.com/gpoore/physeq
|
|
7
|
+
Project-URL: repository, https://github.com/gpoore/physeq
|
|
8
|
+
Project-URL: changelog, https://github.com/gpoore/physeq/blob/main/CHANGELOG.md
|
|
9
|
+
Keywords: physics,education,SymPy
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Education
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE.txt
|
|
21
|
+
Requires-Dist: astropy
|
|
22
|
+
Requires-Dist: sympy
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# PhysEq – Generate physics problems with realistic values and step-by-step solutions
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
PhysEq simplifies the process of creating realistic physics problems with
|
|
29
|
+
step-by-step solutions at the high school and introductory college levels.
|
|
30
|
+
You specify the setup and the relevant equations, and PhysEq solves for
|
|
31
|
+
unknowns and creates solutions. There is built-in support for randomizing
|
|
32
|
+
values, with safeguards against unphysical values.
|
|
33
|
+
|
|
34
|
+
Currently, there is not built-in support for calculus.
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
* Symbols, equations, and algebra for solutions are based on
|
|
39
|
+
[SymPy](https://www.sympy.org/).
|
|
40
|
+
|
|
41
|
+
* Equations and algebra track expression order. When you define equations,
|
|
42
|
+
you are also defining your preferred order for symbols, terms, and
|
|
43
|
+
factors. For example, if you define an equation as $F=ma$, then it will
|
|
44
|
+
appear as $F=ma$ in solutions. The appearance of equations is not based
|
|
45
|
+
on the ordering used internally within the computer algebra system
|
|
46
|
+
(similar to alphabetical order), so $F=ma$ is **not** transformed into
|
|
47
|
+
$F=am$ in solutions. This makes solutions much easier to read.
|
|
48
|
+
|
|
49
|
+
* Physical values are represented with `Quantity` from
|
|
50
|
+
[Astropy](https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html).
|
|
51
|
+
`Quantity` combines a numerical value with a unit and has built-in
|
|
52
|
+
support for unit conversions. PhysEq checks inputs to ensure that they
|
|
53
|
+
have appropriate units. Inputs are automatically converted into standard
|
|
54
|
+
SI units before numerical calculations.
|
|
55
|
+
|
|
56
|
+
* When numerical values are substituted into symbolic equations, values are
|
|
57
|
+
checked against mathematical assumptions and any additional value
|
|
58
|
+
constraints that have been defined. For example, masses and vector
|
|
59
|
+
magnitudes cannot be negative, so attempting to replace them with negative
|
|
60
|
+
numbers results in an error. Similarly, functions for generating
|
|
61
|
+
randomized quantities raise an error for unphysical values.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
Examples are under `examples/` in the project repository. Here is example
|
|
67
|
+
output for a friction problem:
|
|
68
|
+
|
|
69
|
+
A mass $m$ is initially traveling at speed $v_{0}$ across a
|
|
70
|
+
flat surface with coefficient of kinetic friction $\mu_{k}$. It comes to
|
|
71
|
+
rest after traveling a distance $d$.
|
|
72
|
+
|
|
73
|
+
**Known**
|
|
74
|
+
|
|
75
|
+
* $g = 9.80 \\, \mathrm{\tfrac{m}{s^{2}}}\quad v = 0 \\, \mathrm{\tfrac{m}{s}}\quad m = 22.0 \\, \mathrm{kg}\quad \mu_{k} = 0.154\quad v_{0} = 8.10 \\, \mathrm{\tfrac{m}{s}}$
|
|
76
|
+
|
|
77
|
+
**Unknown**
|
|
78
|
+
|
|
79
|
+
* $d$
|
|
80
|
+
|
|
81
|
+
**Solutions**
|
|
82
|
+
|
|
83
|
+
* $\displaystyle W_{\text{nc}} = \Delta \text{KE} + \Delta \text{PE}$
|
|
84
|
+
|
|
85
|
+
$\displaystyle W_{\text{nc}} = \Delta \text{KE}$
|
|
86
|
+
|
|
87
|
+
$\displaystyle - F_{k} d = \text{KE} - \text{KE}_{0}$
|
|
88
|
+
|
|
89
|
+
$\displaystyle - \mu_{k} F_{N} d = \frac{1}{2} m v^{2} - \frac{1}{2} m v_{0}^{2}$
|
|
90
|
+
|
|
91
|
+
$\displaystyle - \mu_{k} m g d = \frac{1}{2} m v^{2} - \frac{1}{2} m v_{0}^{2}$
|
|
92
|
+
|
|
93
|
+
$\displaystyle d = \frac{- \frac{1}{2} m v^{2} + \frac{1}{2} m v_{0}^{2}}{\mu_{k} m g}$
|
|
94
|
+
|
|
95
|
+
$\displaystyle d = \frac{- v^{2} + v_{0}^{2}}{2 \mu_{k} g}$
|
|
96
|
+
|
|
97
|
+
$d = \frac{- \left(0\right)^{2} + \left(8.10\right)^{2}}{2 \left(0.154\right) \left(9.80\right)}$
|
|
98
|
+
|
|
99
|
+
$\displaystyle d = 21.7 \\, \mathrm{m}$
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Creating problems
|
|
104
|
+
|
|
105
|
+
The examples under `examples/` in the project repository may be a good place
|
|
106
|
+
to start in creating problems.
|
|
107
|
+
|
|
108
|
+
Problems are created with the `Problem` class:
|
|
109
|
+
```
|
|
110
|
+
problem = Problem(
|
|
111
|
+
setup: dict[<symbols>, <numbers or quantities>],
|
|
112
|
+
knowns: list[<symbols>],
|
|
113
|
+
unknowns: list[<symbols>],
|
|
114
|
+
equations: list[<equation>],
|
|
115
|
+
definitions: list[<equation>] | None = None,
|
|
116
|
+
simplify: bool = False,
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
`setup` provides a mapping of symbols to numerical values that allows a
|
|
120
|
+
complete problem to be generated. It may include symbols that will ultimately
|
|
121
|
+
be used as unknowns. The goal at this stage is to generate a complete set of
|
|
122
|
+
values, regardless of which ones will ultimately treated as unknowns. In many
|
|
123
|
+
cases, it is simpler to create a physically realistic problem by starting with
|
|
124
|
+
quantities such as velocity and mass, even if one or more of these are
|
|
125
|
+
ultimately treated as unknowns.
|
|
126
|
+
|
|
127
|
+
`setup` values may be numbers, in which case they are interpreted as values in
|
|
128
|
+
the standard SI units for the corresponding symbols. Alternatively, values may
|
|
129
|
+
be provided as Astropy `Quantity`, in which case they are automatically
|
|
130
|
+
converted into standard SI units before use.
|
|
131
|
+
|
|
132
|
+
`knowns` are the symbols whose values will be given in the problem.
|
|
133
|
+
`unknowns` are the symbols that must be solved for.
|
|
134
|
+
|
|
135
|
+
`equations` are the primary equations to be used in solving. This list would
|
|
136
|
+
typically include fundamental equations such as $\sum F_x=ma_x$ or
|
|
137
|
+
$W_{\text{nc}} = \Delta \text{KE} + \Delta \text{PE}$, plus important
|
|
138
|
+
problem-specific relationships. These equations are shown in detail in
|
|
139
|
+
step-by-step solutions.
|
|
140
|
+
|
|
141
|
+
Currently, there is only support for problems that can be solved as a sequence
|
|
142
|
+
of solving equations with one unknown. For example, an equation might have
|
|
143
|
+
two unknowns, but it is possible to solve for one of these using a separate
|
|
144
|
+
equation with only one unknown, so ultimately the problem only involves
|
|
145
|
+
solving equations with one unknown. Limited support for problems involving
|
|
146
|
+
systems of equations with multiple unknowns may be added in the future.
|
|
147
|
+
|
|
148
|
+
`definitions` are substituted into `equations` as needed, but typically would
|
|
149
|
+
not appear independently in step-by-step solutions. They may be simple
|
|
150
|
+
equations that define terms in `equations` (such as $F_G=mg$) or equations
|
|
151
|
+
that provide information about initial or final conditions (such as $v_0=0$).
|
|
152
|
+
These equations are limited to the form `<symbol>=<expression>`, where
|
|
153
|
+
`<symbol>` appears in `equations`.
|
|
154
|
+
|
|
155
|
+
By default, step-by-step solutions use minimal simplifications, so that they
|
|
156
|
+
will be easier to follow and maintain a form closer to the starting equations.
|
|
157
|
+
This can be changed by setting `simplify=True`.
|
|
158
|
+
|
|
159
|
+
When a problem is created with `problem = Problem(...)`, there are three
|
|
160
|
+
relevant attributes for converting `problem` into a form that can be used in
|
|
161
|
+
teaching.
|
|
162
|
+
|
|
163
|
+
* `problem.knowns: dict[<symbol>, <quantity>]`: This maps known symbols to
|
|
164
|
+
the quantities that are given. Quantities are instances of
|
|
165
|
+
[Astropy `Quantity`](https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html),
|
|
166
|
+
so they have both a numerical value and a unit.
|
|
167
|
+
|
|
168
|
+
* `problem.unknowns: dict[<symbol>, <quantity>]`: This maps unknown symbols
|
|
169
|
+
to the quantities that should be found.
|
|
170
|
+
|
|
171
|
+
* `problem.equations: dict[<equation>, list[<equation>]]`: This maps
|
|
172
|
+
equations to step-by-step solutions. Solutions are represented as lists
|
|
173
|
+
of equations.
|
|
174
|
+
|
|
175
|
+
There is also a method `problem.simple_solutions()` that creates simple
|
|
176
|
+
solutions in Markdown format.
|
|
177
|
+
|
|
178
|
+
`physeq.cas.printing` provides a `latex()` function for converting symbols,
|
|
179
|
+
equations, and quantities into strings in LaTeX format, compatible with LaTeX
|
|
180
|
+
documents and HTML libraries like MathJax and KaTeX.
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
### Customizing symbols and equations
|
|
184
|
+
|
|
185
|
+
PhysEq includes an expanding library of pre-defined physics symbols
|
|
186
|
+
(`physeq.symbols.<physics_category>`) and equations
|
|
187
|
+
(`physeq.<physics_category>`).
|
|
188
|
+
|
|
189
|
+
Some physical quantities do not have completely standardized representations
|
|
190
|
+
in introductory physics materials. For example, kinetic energy commonly
|
|
191
|
+
appears as either $\text{KE}$ or $E_k$. By default, PhysEq uses $\text{KE}$,
|
|
192
|
+
but this can be changed for all built-in kinetic energy symbols by setting
|
|
193
|
+
`physeq.config.kinetic_energy = 'E_k'` (or using another definition). It is
|
|
194
|
+
also possible to customize `config.potential_energy` (default $\text{PE}$),
|
|
195
|
+
`config.coulombs_constant` (default $k$), and `config.spring_constant`
|
|
196
|
+
(default $k$).
|
|
197
|
+
|
|
198
|
+
Most symbols support subscripting. For example, for a problem involving
|
|
199
|
+
multiple masses, additional mass symbols can be defined from the predefined
|
|
200
|
+
mass symbol `m` via `m_1 = m.subscript(1)`, `m_2 = m.subscript(2)`, and so
|
|
201
|
+
forth. This is typically simpler than creating new symbols from scratch.
|
|
202
|
+
|
|
203
|
+
Additional custom symbols should be created using `physeq.cas.wrapped.Symbol`.
|
|
204
|
+
Additional equations should be created using `physeq.cas.wrapped.Eq`. When
|
|
205
|
+
possible, SymPy representations of numbers (for example,
|
|
206
|
+
`Rational`) and functions (for example, `sqrt` and `cos`) should not be used
|
|
207
|
+
directly; the wrappers in `physeq.cas.wrapped` should be used instead. These
|
|
208
|
+
`Symbol` and `Eq` classes along with the wrappers track expression order, so
|
|
209
|
+
that solutions will be easier to follow. Without expression order tracking,
|
|
210
|
+
equations would appear with symbols sorted in something like alphabetical
|
|
211
|
+
order (for example, $F=ma$ would appear as $F=am$).
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### Creating randomized values
|
|
215
|
+
|
|
216
|
+
Symbols include built-in support for randomization. (This does not apply to
|
|
217
|
+
symbols representing physical constants.) For example,
|
|
218
|
+
`m.randint_quantity(1, 10)` might return the Astropy `Quantity` 2 kg.
|
|
219
|
+
|
|
220
|
+
There are four methods for generating randomized quantities. All of these
|
|
221
|
+
build on Python's
|
|
222
|
+
[`random` module](https://docs.python.org/3/library/random.html). These
|
|
223
|
+
methods select a random number, and then create a `Quantity` by combining that
|
|
224
|
+
number with the symbol's standard SI unit.
|
|
225
|
+
|
|
226
|
+
* `randrange_quantity(start, stop[, step])`: Create a `Quantity` using a
|
|
227
|
+
random integer from `range(start, stop, step)`.
|
|
228
|
+
|
|
229
|
+
* `randint_quantity(first, last)`: Create a `Quantity` using a random
|
|
230
|
+
integer `N` selected so that `first <= N <= last`.
|
|
231
|
+
|
|
232
|
+
* `choice_quantity(seq)`: Randomly select a number from the sequence
|
|
233
|
+
`seq`, and create a `Quantity` from it.
|
|
234
|
+
|
|
235
|
+
* `uniform_quantity(a, b)`: Randomly select a floating-point number
|
|
236
|
+
between `a` and `b` (inclusive of both), and create a `Quantity` from it.
|
|
237
|
+
|
|
238
|
+
When quantities are randomly generated using these methods, the resulting
|
|
239
|
+
numerical values are checked against mathematical assumptions and any
|
|
240
|
+
additional value constraints that have been defined. An error is raised for
|
|
241
|
+
unphysical values.
|
physeq-0.1.0/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# PhysEq – Generate physics problems with realistic values and step-by-step solutions
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
PhysEq simplifies the process of creating realistic physics problems with
|
|
5
|
+
step-by-step solutions at the high school and introductory college levels.
|
|
6
|
+
You specify the setup and the relevant equations, and PhysEq solves for
|
|
7
|
+
unknowns and creates solutions. There is built-in support for randomizing
|
|
8
|
+
values, with safeguards against unphysical values.
|
|
9
|
+
|
|
10
|
+
Currently, there is not built-in support for calculus.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
* Symbols, equations, and algebra for solutions are based on
|
|
15
|
+
[SymPy](https://www.sympy.org/).
|
|
16
|
+
|
|
17
|
+
* Equations and algebra track expression order. When you define equations,
|
|
18
|
+
you are also defining your preferred order for symbols, terms, and
|
|
19
|
+
factors. For example, if you define an equation as $F=ma$, then it will
|
|
20
|
+
appear as $F=ma$ in solutions. The appearance of equations is not based
|
|
21
|
+
on the ordering used internally within the computer algebra system
|
|
22
|
+
(similar to alphabetical order), so $F=ma$ is **not** transformed into
|
|
23
|
+
$F=am$ in solutions. This makes solutions much easier to read.
|
|
24
|
+
|
|
25
|
+
* Physical values are represented with `Quantity` from
|
|
26
|
+
[Astropy](https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html).
|
|
27
|
+
`Quantity` combines a numerical value with a unit and has built-in
|
|
28
|
+
support for unit conversions. PhysEq checks inputs to ensure that they
|
|
29
|
+
have appropriate units. Inputs are automatically converted into standard
|
|
30
|
+
SI units before numerical calculations.
|
|
31
|
+
|
|
32
|
+
* When numerical values are substituted into symbolic equations, values are
|
|
33
|
+
checked against mathematical assumptions and any additional value
|
|
34
|
+
constraints that have been defined. For example, masses and vector
|
|
35
|
+
magnitudes cannot be negative, so attempting to replace them with negative
|
|
36
|
+
numbers results in an error. Similarly, functions for generating
|
|
37
|
+
randomized quantities raise an error for unphysical values.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
Examples are under `examples/` in the project repository. Here is example
|
|
43
|
+
output for a friction problem:
|
|
44
|
+
|
|
45
|
+
A mass $m$ is initially traveling at speed $v_{0}$ across a
|
|
46
|
+
flat surface with coefficient of kinetic friction $\mu_{k}$. It comes to
|
|
47
|
+
rest after traveling a distance $d$.
|
|
48
|
+
|
|
49
|
+
**Known**
|
|
50
|
+
|
|
51
|
+
* $g = 9.80 \\, \mathrm{\tfrac{m}{s^{2}}}\quad v = 0 \\, \mathrm{\tfrac{m}{s}}\quad m = 22.0 \\, \mathrm{kg}\quad \mu_{k} = 0.154\quad v_{0} = 8.10 \\, \mathrm{\tfrac{m}{s}}$
|
|
52
|
+
|
|
53
|
+
**Unknown**
|
|
54
|
+
|
|
55
|
+
* $d$
|
|
56
|
+
|
|
57
|
+
**Solutions**
|
|
58
|
+
|
|
59
|
+
* $\displaystyle W_{\text{nc}} = \Delta \text{KE} + \Delta \text{PE}$
|
|
60
|
+
|
|
61
|
+
$\displaystyle W_{\text{nc}} = \Delta \text{KE}$
|
|
62
|
+
|
|
63
|
+
$\displaystyle - F_{k} d = \text{KE} - \text{KE}_{0}$
|
|
64
|
+
|
|
65
|
+
$\displaystyle - \mu_{k} F_{N} d = \frac{1}{2} m v^{2} - \frac{1}{2} m v_{0}^{2}$
|
|
66
|
+
|
|
67
|
+
$\displaystyle - \mu_{k} m g d = \frac{1}{2} m v^{2} - \frac{1}{2} m v_{0}^{2}$
|
|
68
|
+
|
|
69
|
+
$\displaystyle d = \frac{- \frac{1}{2} m v^{2} + \frac{1}{2} m v_{0}^{2}}{\mu_{k} m g}$
|
|
70
|
+
|
|
71
|
+
$\displaystyle d = \frac{- v^{2} + v_{0}^{2}}{2 \mu_{k} g}$
|
|
72
|
+
|
|
73
|
+
$d = \frac{- \left(0\right)^{2} + \left(8.10\right)^{2}}{2 \left(0.154\right) \left(9.80\right)}$
|
|
74
|
+
|
|
75
|
+
$\displaystyle d = 21.7 \\, \mathrm{m}$
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Creating problems
|
|
80
|
+
|
|
81
|
+
The examples under `examples/` in the project repository may be a good place
|
|
82
|
+
to start in creating problems.
|
|
83
|
+
|
|
84
|
+
Problems are created with the `Problem` class:
|
|
85
|
+
```
|
|
86
|
+
problem = Problem(
|
|
87
|
+
setup: dict[<symbols>, <numbers or quantities>],
|
|
88
|
+
knowns: list[<symbols>],
|
|
89
|
+
unknowns: list[<symbols>],
|
|
90
|
+
equations: list[<equation>],
|
|
91
|
+
definitions: list[<equation>] | None = None,
|
|
92
|
+
simplify: bool = False,
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
`setup` provides a mapping of symbols to numerical values that allows a
|
|
96
|
+
complete problem to be generated. It may include symbols that will ultimately
|
|
97
|
+
be used as unknowns. The goal at this stage is to generate a complete set of
|
|
98
|
+
values, regardless of which ones will ultimately treated as unknowns. In many
|
|
99
|
+
cases, it is simpler to create a physically realistic problem by starting with
|
|
100
|
+
quantities such as velocity and mass, even if one or more of these are
|
|
101
|
+
ultimately treated as unknowns.
|
|
102
|
+
|
|
103
|
+
`setup` values may be numbers, in which case they are interpreted as values in
|
|
104
|
+
the standard SI units for the corresponding symbols. Alternatively, values may
|
|
105
|
+
be provided as Astropy `Quantity`, in which case they are automatically
|
|
106
|
+
converted into standard SI units before use.
|
|
107
|
+
|
|
108
|
+
`knowns` are the symbols whose values will be given in the problem.
|
|
109
|
+
`unknowns` are the symbols that must be solved for.
|
|
110
|
+
|
|
111
|
+
`equations` are the primary equations to be used in solving. This list would
|
|
112
|
+
typically include fundamental equations such as $\sum F_x=ma_x$ or
|
|
113
|
+
$W_{\text{nc}} = \Delta \text{KE} + \Delta \text{PE}$, plus important
|
|
114
|
+
problem-specific relationships. These equations are shown in detail in
|
|
115
|
+
step-by-step solutions.
|
|
116
|
+
|
|
117
|
+
Currently, there is only support for problems that can be solved as a sequence
|
|
118
|
+
of solving equations with one unknown. For example, an equation might have
|
|
119
|
+
two unknowns, but it is possible to solve for one of these using a separate
|
|
120
|
+
equation with only one unknown, so ultimately the problem only involves
|
|
121
|
+
solving equations with one unknown. Limited support for problems involving
|
|
122
|
+
systems of equations with multiple unknowns may be added in the future.
|
|
123
|
+
|
|
124
|
+
`definitions` are substituted into `equations` as needed, but typically would
|
|
125
|
+
not appear independently in step-by-step solutions. They may be simple
|
|
126
|
+
equations that define terms in `equations` (such as $F_G=mg$) or equations
|
|
127
|
+
that provide information about initial or final conditions (such as $v_0=0$).
|
|
128
|
+
These equations are limited to the form `<symbol>=<expression>`, where
|
|
129
|
+
`<symbol>` appears in `equations`.
|
|
130
|
+
|
|
131
|
+
By default, step-by-step solutions use minimal simplifications, so that they
|
|
132
|
+
will be easier to follow and maintain a form closer to the starting equations.
|
|
133
|
+
This can be changed by setting `simplify=True`.
|
|
134
|
+
|
|
135
|
+
When a problem is created with `problem = Problem(...)`, there are three
|
|
136
|
+
relevant attributes for converting `problem` into a form that can be used in
|
|
137
|
+
teaching.
|
|
138
|
+
|
|
139
|
+
* `problem.knowns: dict[<symbol>, <quantity>]`: This maps known symbols to
|
|
140
|
+
the quantities that are given. Quantities are instances of
|
|
141
|
+
[Astropy `Quantity`](https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html),
|
|
142
|
+
so they have both a numerical value and a unit.
|
|
143
|
+
|
|
144
|
+
* `problem.unknowns: dict[<symbol>, <quantity>]`: This maps unknown symbols
|
|
145
|
+
to the quantities that should be found.
|
|
146
|
+
|
|
147
|
+
* `problem.equations: dict[<equation>, list[<equation>]]`: This maps
|
|
148
|
+
equations to step-by-step solutions. Solutions are represented as lists
|
|
149
|
+
of equations.
|
|
150
|
+
|
|
151
|
+
There is also a method `problem.simple_solutions()` that creates simple
|
|
152
|
+
solutions in Markdown format.
|
|
153
|
+
|
|
154
|
+
`physeq.cas.printing` provides a `latex()` function for converting symbols,
|
|
155
|
+
equations, and quantities into strings in LaTeX format, compatible with LaTeX
|
|
156
|
+
documents and HTML libraries like MathJax and KaTeX.
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
### Customizing symbols and equations
|
|
160
|
+
|
|
161
|
+
PhysEq includes an expanding library of pre-defined physics symbols
|
|
162
|
+
(`physeq.symbols.<physics_category>`) and equations
|
|
163
|
+
(`physeq.<physics_category>`).
|
|
164
|
+
|
|
165
|
+
Some physical quantities do not have completely standardized representations
|
|
166
|
+
in introductory physics materials. For example, kinetic energy commonly
|
|
167
|
+
appears as either $\text{KE}$ or $E_k$. By default, PhysEq uses $\text{KE}$,
|
|
168
|
+
but this can be changed for all built-in kinetic energy symbols by setting
|
|
169
|
+
`physeq.config.kinetic_energy = 'E_k'` (or using another definition). It is
|
|
170
|
+
also possible to customize `config.potential_energy` (default $\text{PE}$),
|
|
171
|
+
`config.coulombs_constant` (default $k$), and `config.spring_constant`
|
|
172
|
+
(default $k$).
|
|
173
|
+
|
|
174
|
+
Most symbols support subscripting. For example, for a problem involving
|
|
175
|
+
multiple masses, additional mass symbols can be defined from the predefined
|
|
176
|
+
mass symbol `m` via `m_1 = m.subscript(1)`, `m_2 = m.subscript(2)`, and so
|
|
177
|
+
forth. This is typically simpler than creating new symbols from scratch.
|
|
178
|
+
|
|
179
|
+
Additional custom symbols should be created using `physeq.cas.wrapped.Symbol`.
|
|
180
|
+
Additional equations should be created using `physeq.cas.wrapped.Eq`. When
|
|
181
|
+
possible, SymPy representations of numbers (for example,
|
|
182
|
+
`Rational`) and functions (for example, `sqrt` and `cos`) should not be used
|
|
183
|
+
directly; the wrappers in `physeq.cas.wrapped` should be used instead. These
|
|
184
|
+
`Symbol` and `Eq` classes along with the wrappers track expression order, so
|
|
185
|
+
that solutions will be easier to follow. Without expression order tracking,
|
|
186
|
+
equations would appear with symbols sorted in something like alphabetical
|
|
187
|
+
order (for example, $F=ma$ would appear as $F=am$).
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
### Creating randomized values
|
|
191
|
+
|
|
192
|
+
Symbols include built-in support for randomization. (This does not apply to
|
|
193
|
+
symbols representing physical constants.) For example,
|
|
194
|
+
`m.randint_quantity(1, 10)` might return the Astropy `Quantity` 2 kg.
|
|
195
|
+
|
|
196
|
+
There are four methods for generating randomized quantities. All of these
|
|
197
|
+
build on Python's
|
|
198
|
+
[`random` module](https://docs.python.org/3/library/random.html). These
|
|
199
|
+
methods select a random number, and then create a `Quantity` by combining that
|
|
200
|
+
number with the symbol's standard SI unit.
|
|
201
|
+
|
|
202
|
+
* `randrange_quantity(start, stop[, step])`: Create a `Quantity` using a
|
|
203
|
+
random integer from `range(start, stop, step)`.
|
|
204
|
+
|
|
205
|
+
* `randint_quantity(first, last)`: Create a `Quantity` using a random
|
|
206
|
+
integer `N` selected so that `first <= N <= last`.
|
|
207
|
+
|
|
208
|
+
* `choice_quantity(seq)`: Randomly select a number from the sequence
|
|
209
|
+
`seq`, and create a `Quantity` from it.
|
|
210
|
+
|
|
211
|
+
* `uniform_quantity(a, b)`: Randomly select a floating-point number
|
|
212
|
+
between `a` and `b` (inclusive of both), and create a `Quantity` from it.
|
|
213
|
+
|
|
214
|
+
When quantities are randomly generated using these methods, the resulting
|
|
215
|
+
numerical values are checked against mathematical assumptions and any
|
|
216
|
+
additional value constraints that have been defined. An error is raised for
|
|
217
|
+
unphysical values.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025, Geoffrey M. Poore
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the BSD 3-Clause License:
|
|
7
|
+
# http://opensource.org/licenses/BSD-3-Clause
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from .version import __version__, __version_info__
|
|
12
|
+
|
|
13
|
+
from .configuration import Config
|
|
14
|
+
config = Config()
|
|
15
|
+
del Config
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|