jrpycpp 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.
- jrpycpp-0.1.0/PKG-INFO +16 -0
- jrpycpp-0.1.0/jrpycpp/__init__.py +3 -0
- jrpycpp-0.1.0/jrpycpp/__version__.py +1 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter2/demo/01-class.cpp +24 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter2/demo/02-const.cpp +25 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter2/exercise/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter2/solution/stats.cpp +44 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/bindings.cpp +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/pi.cpp +10 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/pi.h +3 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/01-free-function/test_pi.py +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/bindings.cpp +17 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/demo/02-class/test_livstats.py +18 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/exercise/bindings.cpp +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/exercise/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/exercise/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/exercise/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/exercise/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/bindings.cpp +22 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter3/solution/test_livstats.py +18 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/arrays.cpp +13 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/arrays.h +7 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/bindings.cpp +73 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/demo/test_arrays.py +38 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/exercise/arrays.cpp +13 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/exercise/arrays.h +7 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/exercise/bindings.cpp +36 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/exercise/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/exercise/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/arrays.cpp +13 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/arrays.h +7 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/bindings.cpp +49 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/setup.py +12 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter4/solution/test_arrays.py +19 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/01-cmake/CMakeLists.txt +22 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/01-cmake/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/01-cmake/src/main.cpp +9 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/01-cmake/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/01-cmake/tests/test_stats.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/CMakeLists.txt +28 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/python/bindings.cpp +17 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/tests/test_livstats.py +10 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/demo/02-python/tests/test_stats.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/exercise/CMakeLists.txt +17 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/exercise/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/exercise/src/main.cpp +9 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/exercise/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/exercise/tests/test_stats.cpp +16 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/solution/CMakeLists.txt +22 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/solution/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/solution/src/main.cpp +9 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/solution/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter5/solution/tests/test_stats.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/demo/01-map.cpp +19 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/demo/02-lambda.cpp +22 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/demo/03-move.cpp +14 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/demo/04-unique.cpp +19 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/exercise/copies.cpp +34 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/exercise/integrate.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/exercise/words.cpp +21 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/solution/copies.cpp +37 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/solution/integrate.cpp +25 -0
- jrpycpp-0.1.0/jrpycpp/examples/cpp_scripts/chapter6/solution/words.cpp +21 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/CMakeLists.txt +22 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/README.md +68 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/src/main.cpp +9 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/cpp-project/tests/test_stats.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/CMakeLists.txt +28 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/README.md +72 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/include/stats.h +15 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/pyproject.toml +11 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/python/bindings.cpp +17 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/src/stats.cpp +26 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/tests/test_livstats.py +10 -0
- jrpycpp-0.1.0/jrpycpp/examples/templates/python-cpp-project/tests/test_stats.cpp +20 -0
- jrpycpp-0.1.0/jrpycpp/examples.py +43 -0
- jrpycpp-0.1.0/pyproject.toml +23 -0
jrpycpp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: jrpycpp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Jumping Rivers: C++ and Python
|
|
5
|
+
Author: Jumping Rivers
|
|
6
|
+
Author-email: info@jumpingrivers.com
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: numpy (>=2.0,<3.0)
|
|
13
|
+
Requires-Dist: pybind11 (>=3.0,<4.0)
|
|
14
|
+
Requires-Dist: pytest (>=8.0,<9.0)
|
|
15
|
+
Requires-Dist: scikit-build-core (>=0.11,<0.12)
|
|
16
|
+
Requires-Dist: setuptools (>=64)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <vector>
|
|
3
|
+
|
|
4
|
+
class Stats {
|
|
5
|
+
public:
|
|
6
|
+
Stats(const std::vector<double>& values) : values_(values) {}
|
|
7
|
+
|
|
8
|
+
double mean() {
|
|
9
|
+
double total = 0.0;
|
|
10
|
+
for (double v : values_) {
|
|
11
|
+
total += v;
|
|
12
|
+
}
|
|
13
|
+
return total / values_.size();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private:
|
|
17
|
+
std::vector<double> values_;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
int main() {
|
|
21
|
+
Stats s({2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0});
|
|
22
|
+
std::cout << "mean " << s.mean() << "\n";
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <vector>
|
|
3
|
+
|
|
4
|
+
class Stats {
|
|
5
|
+
public:
|
|
6
|
+
Stats(const std::vector<double>& values) : values_(values) {}
|
|
7
|
+
double mean() const {
|
|
8
|
+
double total = 0.0;
|
|
9
|
+
for (double v : values_) {
|
|
10
|
+
total += v;
|
|
11
|
+
}
|
|
12
|
+
return total / values_.size();
|
|
13
|
+
}
|
|
14
|
+
private:
|
|
15
|
+
std::vector<double> values_;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
void report(const Stats& s) {
|
|
19
|
+
std::cout << "mean " << s.mean() << "\n";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
int main() {
|
|
23
|
+
report(Stats({2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0}));
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include <cmath>
|
|
2
|
+
#include <iostream>
|
|
3
|
+
#include <vector>
|
|
4
|
+
|
|
5
|
+
double mean(const std::vector<double>& values) {
|
|
6
|
+
double total = 0.0;
|
|
7
|
+
for (double v : values) {
|
|
8
|
+
total += v;
|
|
9
|
+
}
|
|
10
|
+
return total / values.size();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
double stddev(const std::vector<double>& values) {
|
|
14
|
+
double m = mean(values);
|
|
15
|
+
double total = 0.0;
|
|
16
|
+
for (double v : values) {
|
|
17
|
+
total += (v - m) * (v - m);
|
|
18
|
+
}
|
|
19
|
+
return std::sqrt(total / values.size());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
int main() {
|
|
23
|
+
std::vector<double> values = {2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0};
|
|
24
|
+
std::cout << "mean " << mean(values) << ", standard deviation " << stddev(values) << "\n";
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#include <cmath>
|
|
2
|
+
#include <iostream>
|
|
3
|
+
#include <vector>
|
|
4
|
+
|
|
5
|
+
class Stats {
|
|
6
|
+
public:
|
|
7
|
+
Stats(const std::vector<double>& values) : values_(values) {}
|
|
8
|
+
|
|
9
|
+
double mean() const {
|
|
10
|
+
double total = 0.0;
|
|
11
|
+
for (double v : values_) {
|
|
12
|
+
total += v;
|
|
13
|
+
}
|
|
14
|
+
return total / values_.size();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
double stddev() const {
|
|
18
|
+
double m = mean();
|
|
19
|
+
double total = 0.0;
|
|
20
|
+
for (double v : values_) {
|
|
21
|
+
total += (v - m) * (v - m);
|
|
22
|
+
}
|
|
23
|
+
return std::sqrt(total / values_.size());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int count() const {
|
|
27
|
+
return static_cast<int>(values_.size());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private:
|
|
31
|
+
std::vector<double> values_;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
void report(const Stats& s) {
|
|
35
|
+
std::cout << "mean " << s.mean() << "\n";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
int main() {
|
|
39
|
+
Stats s({2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0});
|
|
40
|
+
std::cout << "mean " << s.mean() << ", standard deviation " << s.stddev() << "\n";
|
|
41
|
+
std::cout << "count " << s.count() << "\n";
|
|
42
|
+
report(s);
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
|
|
3
|
+
#include "pi.h"
|
|
4
|
+
|
|
5
|
+
namespace py = pybind11;
|
|
6
|
+
|
|
7
|
+
PYBIND11_MODULE(pidemo, m) {
|
|
8
|
+
m.doc() = "Yesterday's pi loop, callable from Python";
|
|
9
|
+
m.def("estimate_pi", &estimate_pi, py::arg("n"),
|
|
10
|
+
"Estimate pi with n rectangles");
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
3
|
+
|
|
4
|
+
ext_modules = [
|
|
5
|
+
Pybind11Extension(
|
|
6
|
+
"pidemo",
|
|
7
|
+
["bindings.cpp", "pi.cpp"],
|
|
8
|
+
cxx_std=17,
|
|
9
|
+
),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
setup(ext_modules=ext_modules, cmdclass={"build_ext": build_ext})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
#include <pybind11/stl.h>
|
|
3
|
+
|
|
4
|
+
#include "stats.h"
|
|
5
|
+
|
|
6
|
+
namespace py = pybind11;
|
|
7
|
+
|
|
8
|
+
PYBIND11_MODULE(livstats, m) {
|
|
9
|
+
m.doc() = "Yesterday's stats program, callable from Python";
|
|
10
|
+
|
|
11
|
+
py::class_<Stats>(m, "Stats")
|
|
12
|
+
.def(py::init<const std::vector<double>&>(), py::arg("values"),
|
|
13
|
+
"Build from a sequence of numbers")
|
|
14
|
+
.def("mean", &Stats::mean, "Arithmetic mean")
|
|
15
|
+
.def("stddev", &Stats::stddev, "Standard deviation, dividing by n")
|
|
16
|
+
.def("count", &Stats::count, "How many values");
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
3
|
+
|
|
4
|
+
ext_modules = [
|
|
5
|
+
Pybind11Extension(
|
|
6
|
+
"livstats",
|
|
7
|
+
["bindings.cpp", "stats.cpp"],
|
|
8
|
+
cxx_std=17,
|
|
9
|
+
),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
setup(ext_modules=ext_modules, cmdclass={"build_ext": build_ext})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include "stats.h"
|
|
2
|
+
|
|
3
|
+
#include <cmath>
|
|
4
|
+
|
|
5
|
+
Stats::Stats(const std::vector<double>& values) : values_(values) {}
|
|
6
|
+
|
|
7
|
+
double Stats::mean() const {
|
|
8
|
+
double total = 0.0;
|
|
9
|
+
for (double v : values_) {
|
|
10
|
+
total += v;
|
|
11
|
+
}
|
|
12
|
+
return total / values_.size();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
double Stats::stddev() const {
|
|
16
|
+
double m = mean();
|
|
17
|
+
double total = 0.0;
|
|
18
|
+
for (double v : values_) {
|
|
19
|
+
total += (v - m) * (v - m);
|
|
20
|
+
}
|
|
21
|
+
return std::sqrt(total / values_.size());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
int Stats::count() const {
|
|
25
|
+
return static_cast<int>(values_.size());
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
import livstats
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_the_chapter_one_promise():
|
|
7
|
+
s = livstats.Stats([2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0])
|
|
8
|
+
assert s.mean() == pytest.approx(5.0)
|
|
9
|
+
assert s.stddev() == pytest.approx(2.0)
|
|
10
|
+
assert s.count() == 8
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_a_list_of_ints_is_accepted():
|
|
14
|
+
assert livstats.Stats([1, 2, 3]).mean() == pytest.approx(2.0)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_the_constructor_takes_a_named_argument():
|
|
18
|
+
assert livstats.Stats(values=[1.0, 3.0]).mean() == pytest.approx(2.0)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
#include <pybind11/stl.h>
|
|
3
|
+
|
|
4
|
+
#include "stats.h"
|
|
5
|
+
|
|
6
|
+
namespace py = pybind11;
|
|
7
|
+
|
|
8
|
+
PYBIND11_MODULE(livstats, m) {
|
|
9
|
+
py::class_<Stats>(m, "Stats")
|
|
10
|
+
.def(py::init<const std::vector<double>&>(), py::arg("values"))
|
|
11
|
+
.def("mean", &Stats::mean);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
3
|
+
|
|
4
|
+
ext_modules = [
|
|
5
|
+
Pybind11Extension(
|
|
6
|
+
"livstats",
|
|
7
|
+
["bindings.cpp", "stats.cpp"],
|
|
8
|
+
cxx_std=17,
|
|
9
|
+
),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
setup(ext_modules=ext_modules, cmdclass={"build_ext": build_ext})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include "stats.h"
|
|
2
|
+
|
|
3
|
+
#include <cmath>
|
|
4
|
+
|
|
5
|
+
Stats::Stats(const std::vector<double>& values) : values_(values) {}
|
|
6
|
+
|
|
7
|
+
double Stats::mean() const {
|
|
8
|
+
double total = 0.0;
|
|
9
|
+
for (double v : values_) {
|
|
10
|
+
total += v;
|
|
11
|
+
}
|
|
12
|
+
return total / values_.size();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
double Stats::stddev() const {
|
|
16
|
+
double m = mean();
|
|
17
|
+
double total = 0.0;
|
|
18
|
+
for (double v : values_) {
|
|
19
|
+
total += (v - m) * (v - m);
|
|
20
|
+
}
|
|
21
|
+
return std::sqrt(total / values_.size());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
int Stats::count() const {
|
|
25
|
+
return static_cast<int>(values_.size());
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
#include <pybind11/stl.h>
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#include "stats.h"
|
|
7
|
+
|
|
8
|
+
namespace py = pybind11;
|
|
9
|
+
|
|
10
|
+
PYBIND11_MODULE(livstats, m) {
|
|
11
|
+
m.doc() = "Yesterday's stats program, callable from Python";
|
|
12
|
+
|
|
13
|
+
py::class_<Stats>(m, "Stats")
|
|
14
|
+
.def(py::init<const std::vector<double>&>(), py::arg("values"),
|
|
15
|
+
"Build from a sequence of numbers")
|
|
16
|
+
.def("mean", &Stats::mean, "Arithmetic mean")
|
|
17
|
+
.def("stddev", &Stats::stddev, "Standard deviation, dividing by n")
|
|
18
|
+
.def("count", &Stats::count, "How many values")
|
|
19
|
+
.def("__repr__", [](const Stats& s) {
|
|
20
|
+
return "Stats(count=" + std::to_string(s.count()) + ")";
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
3
|
+
|
|
4
|
+
ext_modules = [
|
|
5
|
+
Pybind11Extension(
|
|
6
|
+
"livstats",
|
|
7
|
+
["bindings.cpp", "stats.cpp"],
|
|
8
|
+
cxx_std=17,
|
|
9
|
+
),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
setup(ext_modules=ext_modules, cmdclass={"build_ext": build_ext})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include "stats.h"
|
|
2
|
+
|
|
3
|
+
#include <cmath>
|
|
4
|
+
|
|
5
|
+
Stats::Stats(const std::vector<double>& values) : values_(values) {}
|
|
6
|
+
|
|
7
|
+
double Stats::mean() const {
|
|
8
|
+
double total = 0.0;
|
|
9
|
+
for (double v : values_) {
|
|
10
|
+
total += v;
|
|
11
|
+
}
|
|
12
|
+
return total / values_.size();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
double Stats::stddev() const {
|
|
16
|
+
double m = mean();
|
|
17
|
+
double total = 0.0;
|
|
18
|
+
for (double v : values_) {
|
|
19
|
+
total += (v - m) * (v - m);
|
|
20
|
+
}
|
|
21
|
+
return std::sqrt(total / values_.size());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
int Stats::count() const {
|
|
25
|
+
return static_cast<int>(values_.size());
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
import livstats
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_all_three_are_bound():
|
|
7
|
+
s = livstats.Stats([2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0])
|
|
8
|
+
assert s.mean() == pytest.approx(5.0)
|
|
9
|
+
assert s.stddev() == pytest.approx(2.0)
|
|
10
|
+
assert s.count() == 8
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_repr_says_what_it_holds():
|
|
14
|
+
assert repr(livstats.Stats([1.0, 2.0, 3.0])) == "Stats(count=3)"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_the_docstrings_arrived():
|
|
18
|
+
assert "Arithmetic mean" in livstats.Stats.mean.__doc__
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#include "arrays.h"
|
|
2
|
+
|
|
3
|
+
double total(const double* data, std::size_t n) {
|
|
4
|
+
double sum = 0.0;
|
|
5
|
+
for (std::size_t i = 0; i < n; ++i) {
|
|
6
|
+
sum += data[i];
|
|
7
|
+
}
|
|
8
|
+
return sum;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
double total_vector(const std::vector<double>& v) {
|
|
12
|
+
return total(v.data(), v.size());
|
|
13
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
#include <pybind11/numpy.h>
|
|
3
|
+
#include <pybind11/stl.h>
|
|
4
|
+
|
|
5
|
+
#include <vector>
|
|
6
|
+
|
|
7
|
+
#include "arrays.h"
|
|
8
|
+
|
|
9
|
+
namespace py = pybind11;
|
|
10
|
+
|
|
11
|
+
double total_array(py::array_t<double> values) {
|
|
12
|
+
auto v = values.unchecked<1>();
|
|
13
|
+
double sum = 0.0;
|
|
14
|
+
for (py::ssize_t i = 0; i < v.shape(0); ++i) {
|
|
15
|
+
sum += v(i);
|
|
16
|
+
}
|
|
17
|
+
return sum;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void scale_inplace(py::array_t<double> values, double factor) {
|
|
21
|
+
auto v = values.mutable_unchecked<1>();
|
|
22
|
+
for (py::ssize_t i = 0; i < v.shape(0); ++i) {
|
|
23
|
+
v(i) *= factor;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
py::array_t<double> squares(py::ssize_t n) {
|
|
28
|
+
py::array_t<double> out(n);
|
|
29
|
+
auto o = out.mutable_unchecked<1>();
|
|
30
|
+
for (py::ssize_t i = 0; i < n; ++i) {
|
|
31
|
+
o(i) = static_cast<double>(i) * static_cast<double>(i);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class Grid {
|
|
37
|
+
public:
|
|
38
|
+
Grid(py::ssize_t n) : values_(static_cast<std::size_t>(n), 1.0) {}
|
|
39
|
+
|
|
40
|
+
py::ssize_t size() const { return static_cast<py::ssize_t>(values_.size()); }
|
|
41
|
+
double* data() { return values_.data(); }
|
|
42
|
+
void grow() { values_.push_back(1.0); }
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
std::vector<double> values_;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
PYBIND11_MODULE(livarrays, m) {
|
|
49
|
+
m.doc() = "NumPy arrays crossing into C++";
|
|
50
|
+
|
|
51
|
+
m.def("total_array", &total_array, py::arg("values"),
|
|
52
|
+
"Sum an array of doubles without copying it");
|
|
53
|
+
|
|
54
|
+
m.def("total_list", &total_vector, py::arg("values"),
|
|
55
|
+
"Sum a sequence, copying it into a vector first");
|
|
56
|
+
|
|
57
|
+
m.def("scale_inplace", &scale_inplace,
|
|
58
|
+
py::arg("values").noconvert(), py::arg("factor"),
|
|
59
|
+
"Multiply an array of doubles in place");
|
|
60
|
+
|
|
61
|
+
m.def("squares", &squares, py::arg("n"),
|
|
62
|
+
"Return the first n squares as a new array");
|
|
63
|
+
|
|
64
|
+
py::class_<Grid>(m, "Grid")
|
|
65
|
+
.def(py::init<py::ssize_t>(), py::arg("n"))
|
|
66
|
+
.def("grow", &Grid::grow, "Append one element")
|
|
67
|
+
.def("view", [](py::object self) {
|
|
68
|
+
Grid& g = self.cast<Grid&>();
|
|
69
|
+
return py::array_t<double>({g.size()},
|
|
70
|
+
{static_cast<py::ssize_t>(sizeof(double))},
|
|
71
|
+
g.data(), self);
|
|
72
|
+
}, "A NumPy view onto this Grid's own memory");
|
|
73
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
3
|
+
|
|
4
|
+
ext_modules = [
|
|
5
|
+
Pybind11Extension(
|
|
6
|
+
"livarrays",
|
|
7
|
+
["bindings.cpp", "arrays.cpp"],
|
|
8
|
+
cxx_std=17,
|
|
9
|
+
),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
setup(ext_modules=ext_modules, cmdclass={"build_ext": build_ext})
|