Skip to content

Commit

Permalink
Impl constants module (#63)
Browse files Browse the repository at this point in the history
* prepare `pyconstant` variable and export it from SciPy

* collect constant-like objects and store them in d["constant"]

* implement `constants` module

* mv docstring

* fix

* write comment because the implenentation of `constants` module is more complicated than other submodules of SciPy.jl

* add type checking test

* write more tests

* fix docstring

* add comment

* Revert "add comment"

This reverts commit 939e506.

* Revert "collect constant-like objects and store them in d["constant"]"

This reverts commit 1a7b6c9.

* rewrite constants.jl

* add test
  • Loading branch information
terasakisatoshi authored Oct 29, 2022
1 parent 3caf6d2 commit 4610d78
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 27 deletions.
31 changes: 4 additions & 27 deletions src/SciPy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export print_configulations
export cluster, constants, fft, integrate, interpolate, io, linalg, ndimage, odr
export optimize, signal, sparse, spatial, stats, special
# raw PyObject modules
export pystats, pyoptimize, pyinterpolate, pyspatial
export pyconstants, pystats, pyoptimize, pyinterpolate, pyspatial


const scipy = PyNULL()
Expand Down Expand Up @@ -73,31 +73,8 @@ julia> SciPy.cluster.vq.kmeans(whitened, [whitened[1,:] whitened[3,:]] )
"""
const cluster = PyNULL()

"""
scipy.constants module
- [Constants (scipy.constants) Reference Guide](https://docs.scipy.org/doc/scipy/reference/constants.html)
# Examples
You can access each constants:
```julia-repl
julia> SciPy.constants.golden
1.618033988749895
julia> SciPy.constants.physical_constants["electron mass"]
(9.10938356e-31, "kg", 1.1e-38)
julia> SciPy.constants.convert_temperature([-40, 40.0], "Celsius", "Kelvin")
2-element Array{Float64,1}:
233.14999999999998
313.15
```
"""
const constants = PyNULL()
const pyconstants = PyNULL()
include("constants.jl")

"""
scipy.fft module
Expand Down Expand Up @@ -326,7 +303,6 @@ Module initialization function
function __init__()
copy!(scipy, pyimport_conda("scipy", "scipy"))
copy!(cluster, pyimport_conda("scipy.cluster", "scipy"))
copy!(constants, pyimport_conda("scipy.constants", "scipy"))
copy!(fft, pyimport_conda("scipy.fft", "scipy"))
copy!(integrate, pyimport_conda("scipy.integrate", "scipy"))
copy!(io, pyimport_conda("scipy.io", "scipy"))
Expand All @@ -341,6 +317,7 @@ function __init__()
copy!(pystats, pyimport_conda("scipy.stats", "scipy"))
copy!(pyoptimize, pyimport_conda("scipy.optimize", "scipy"))
copy!(pyinterpolate, pyimport_conda("scipy.interpolate", "scipy"))
copy!(pyconstants, pyimport_conda("scipy.constants", "scipy"))
end

"""
Expand Down
73 changes: 73 additions & 0 deletions src/constants.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
scipy.constants module
- [Constants (scipy.constants) Reference Guide](https://docs.scipy.org/doc/scipy/reference/constants.html)
# Examples
You can access each constants:
```julia-repl
julia> SciPy.constants.golden
1.618033988749895
julia> SciPy.constants.physical_constants["electron mass"]
(9.10938356e-31, "kg", 1.1e-38)
julia> SciPy.constants.convert_temperature([-40, 40.0], "Celsius", "Kelvin")
2-element Vector{Float64}:
233.14999999999998
313.15
```
"""
module constants

using PyCall

pyimport_conda("scipy", "scipy")
@pyinclude(joinpath(pkgdir(@__MODULE__), "src", "scipy_api_list.py"))
apis = py"generate_scipy_apis"("constants")

all_properties = [apis["function"]; apis["class"]]

import ..pyconstants

import ..LazyHelp

const _ignore_funcs = ["constants"]

for f in [apis["function"]; apis["class"]]
f in _ignore_funcs && continue

sf = Symbol(f)
@eval @doc LazyHelp(pyconstants, $f) $sf(args...; kws...) =
pycall(pyconstants.$f, PyAny, args...; kws...)
end

function __init__()
copy!(pyconstants, pyimport_conda("scipy.constants", "scipy"))

#=
The following metaprogramming will generate expressions like:
const zero_Celsius = 273.15
const golden = 1.618033988749895
const centi = 0.01
=#
for f in pyconstants.__all__ |> unique |> sort
f in _ignore_funcs && continue # just in case
a = pybuiltin("getattr")(pyconstants, f)
if a isa PyObject
# The variable `a` should be python function, class or module
continue
else
# The variable `a` is converted in a Julia's native type. We assume this is a constant value.
sf = Symbol(f)
@eval @doc LazyHelp(pyconstants, $f) const $sf = $a
end
end
end

end # module
11 changes: 11 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,18 @@ using Test
end

@testset "constants" begin
@test constants.zero_Celsius == 273.15
@test constants.golden == 1.618033988749895
@test constants.centi == 0.01

@test typeof(pyconstants.zero_Celsius) == typeof(constants.zero_Celsius)
@test typeof(pyconstants.golden) == typeof(constants.golden)
@test typeof(pyconstants.centi) == typeof(constants.centi)

@test constants.convert_temperature([-40, 40.0], "Celsius", "Kelvin") [233.14999999999998, 313.15]

@test typeof(pyconstants.physical_constants) == typeof(constants.physical_constants)
@test constants.physical_constants["electron mass"] == (9.1093837015e-31, "kg", 2.8e-40)
end

@testset "fft" begin
Expand Down

0 comments on commit 4610d78

Please sign in to comment.