Skip to content

Commit 3314ff8

Browse files
committed
Add pure Python implementation
1 parent 8dac0f6 commit 3314ff8

File tree

6 files changed

+59
-12
lines changed

6 files changed

+59
-12
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
average.c
2+
average_pure.c
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
VERSION = cpython-34m
1+
VERSION = cpython-311-x86_64-linux-gnu
22
AVERAGE_LIB = average.$(VERSION).so
3+
AVERAGE_PURE_LIB = average_pure.$(VERSION).so
34

4-
all: $(AVERAGE_LIB)
5+
all: $(AVERAGE_LIB) $(AVERAGE_PURE_LIB)
56

67
$(AVERAGE_LIB): average.pyx
78
python setup.py build_ext --inplace
89

10+
$(AVERAGE_PURE_LIB): average_pure.py
11+
python setup.py build_ext --inplace
12+
913
clean:
1014
python setup.py clean
11-
rm -f average.c $(AVERAGE_LIB)
15+
$(RM) average.c average_pure.c $(AVERAGE_LIB) $(AVERAGE_PURE_LIB)
16+
$(RM) -r build

source-code/cython/Exceptions/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
Error handling in Cython code.
33

44
## What is it?
5-
1. `average.pyx`: code to be compiled using Cython, implements two
5+
1. `average.pyx`: Cython code to be compiled using Cython, implements two
66
functions to compute the average of an array slice, one with, the
77
other without error handling.
8+
1. `average_pure.py`: pure Python code to be compiled using Cython,
9+
implements two functions to compute the average of an array slice,
10+
one with, the other without error handling.
811
1. `setup.py`: Python build script.
912
1. `Makefile`: make file to build the extension.
1013
1. `compute_average.py`: script to load the compiled module and call the
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cython
2+
3+
4+
def average(data, m=0, n=None):
5+
if n is None:
6+
n = len(data)
7+
return _average(memoryview(data), m, n)
8+
9+
def average_no_except(data, m=0, n=None):
10+
if n is None:
11+
n = len(data)
12+
return _average_no_except(memoryview(data), m, n)
13+
14+
@cython.cfunc
15+
@cython.exceptval(-1.0, check=True)
16+
def _average(data, m: cython.int=0, n: cython.int=-1) -> cython.double:
17+
i: cython.int
18+
mean: cython.double = 0.0
19+
for i in range(m, n):
20+
mean += data[i]
21+
return mean/(n - m + 1)
22+
23+
@cython.cfunc
24+
def _average_no_except(data, m: cython.int=0, n: cython.int=-1) -> cython.double:
25+
i: cython.int
26+
mean: cython.double = 0.0
27+
for i in range(m, n):
28+
mean += data[i]
29+
return mean/(n - m + 1)

source-code/cython/Exceptions/compute_average.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22

33
from argparse import ArgumentParser
44
import array
5-
import average
65

7-
8-
size = 10
6+
DEFAULT_SIZE = 10
97

108
arg_parser = ArgumentParser(description='test Cython errors')
119
arg_parser.add_argument('--m', type=int, default=0, help='lower bound')
12-
arg_parser.add_argument('--n', type=int, default=size, help='upper bound')
10+
arg_parser.add_argument('--n', type=int, default=DEFAULT_SIZE,
11+
help='upper bound')
12+
arg_parser.add_argument('--size', type=int, default=DEFAULT_SIZE,
13+
help='array size')
14+
arg_parser.add_argument('--implementation', choices=['pure', 'cython'],
15+
default='cython', help='implementation to use')
1316
options = arg_parser.parse_args()
14-
data = array.array('d', list(range(size)))
17+
if options.implementation == 'cython':
18+
from average import average, average_no_except
19+
elif options.implementation == 'pure':
20+
from average_pure import average, average_no_except
21+
data = array.array('d', list(range(options.size)))
1522
print('with except:')
1623
try:
17-
print(average.average(data, options.m, options.n))
24+
print(average(data, options.m, options.n))
1825
except Exception as e:
1926
print('caught exception {0}: {1}'.format(str(e.__class__), str(e)))
2027
print('without except:')
2128
try:
22-
print(average.average_no_except(data, options.m, options.n))
29+
print(average_no_except(data, options.m, options.n))
2330
print('no exception caught')
2431
except Exception as e:
2532
print('caught exception {0}: {1}'.format(e.__class__, str(e)))

source-code/cython/Exceptions/setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
from Cython.Build import cythonize
55

66
setup(
7-
ext_modules=cythonize('average.pyx')
7+
ext_modules=cythonize(['average.pyx', 'average_pure.py'],
8+
language_level='3str')
89
)

0 commit comments

Comments
 (0)