version bump 1.0.2: cleanup
- cont: more direct reverse iteration - README cleanup - python linting and tests
This commit is contained in:
parent
2f54d2f5c1
commit
9a9ed4d1fa
8
Makefile
8
Makefile
@ -65,10 +65,16 @@ dist-deps:
|
||||
## Python
|
||||
|
||||
.PHONY: pylint
|
||||
pylint: frac.py
|
||||
pylint: frac.py $(wildcard test_*.py)
|
||||
pep8 $^
|
||||
|
||||
.PHONY: pypi
|
||||
pypi: frac.py
|
||||
python setup.py sdist upload
|
||||
|
||||
.PHONY: pytest pypytest
|
||||
pytest: pylint
|
||||
py.test -v --durations=5
|
||||
|
||||
pypytest: pylint
|
||||
pypy $$(which py.test) -v --durations=5
|
||||
|
56
README.md
56
README.md
@ -9,6 +9,8 @@ described by Aberth in "A method for exact computation with rational numbers".
|
||||
|
||||
## Installation
|
||||
|
||||
### JS
|
||||
|
||||
With [npm](https://www.npmjs.org/package/frac):
|
||||
|
||||
$ npm install frac
|
||||
@ -21,9 +23,15 @@ The script will manipulate `module.exports` if available (e.g. in a CommonJS
|
||||
`require` context). This is not always desirable. To prevent the behavior,
|
||||
define `DO_NOT_EXPORT_FRAC`
|
||||
|
||||
### Python
|
||||
|
||||
From [PyPI](https://pypi.python.org/pypi/frac):
|
||||
|
||||
$ pip install frac
|
||||
|
||||
## Usage
|
||||
|
||||
The exported `frac` function takes three arguments:
|
||||
In all cases, the relevant function takes 3 arguments:
|
||||
|
||||
- `x` the number we wish to approximate
|
||||
- `D` the maximum denominator
|
||||
@ -33,18 +41,48 @@ The return value is an array of the form `[quot, num, den]` where `quot==0`
|
||||
for improper fractions. `quot <= x` for mixed fractions, which may lead to some
|
||||
unexpected results when rendering negative numbers.
|
||||
|
||||
### JS
|
||||
|
||||
The exported `frac` function implements the Mediant method.
|
||||
|
||||
`frac.cont` implements the Aberth algorithm
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
```js
|
||||
> // var frac = require('frac'); // uncomment this line if in node
|
||||
> frac(Math.PI,100); // [ 0, 22, 7 ]
|
||||
> frac(Math.PI,100,true); // [ 3, 1, 7 ]
|
||||
> frac(-Math.PI,100); // [ 0, -22, 7 ]
|
||||
> frac(-Math.PI,100,true); // [ -4, 6, 7 ] // the approximation is (-4) + (6/7)
|
||||
> frac(1.3, 9); // [ 0, 9, 7 ] // 1.3 ~ 9/7
|
||||
> frac(1.3, 9, true); // [ 1, 2, 7 ] // 1.3 ~ 1 + 2/7
|
||||
> frac(-1.3, 9); // [ 0, -9, 7 ] // -1.3 ~ -9/7
|
||||
> frac(-1.3, 9, true); // [ -2, 5, 7 ] // -1.3 ~ -2 + 5/7
|
||||
|
||||
> frac.cont(1.3, 9); // [ 0, 4, 3 ] // 1.3 ~ 4/3
|
||||
> frac.cont(1.3, 9, true); // [ 1, 1, 3 ] // 1.3 ~ 1 + 1/3
|
||||
> frac.cont(-1.3, 9); // [ 0, -4, 3 ] // -1.3 ~ -4/3
|
||||
> frac.cont(-1.3, 9, true); // [ -2, 2, 3 ] // -1.3 ~ -2 + 2/3
|
||||
```
|
||||
|
||||
`frac.cont` implements the Aberth algorithm (input and output specifications
|
||||
match the original `frac` function)
|
||||
|
||||
### Python
|
||||
|
||||
`frac.med` implements Mediant method.
|
||||
|
||||
`frac.cont` implements Aberth algorithm
|
||||
|
||||
For example:
|
||||
|
||||
```py
|
||||
>>> import frac
|
||||
>>> frac.med(1.3, 9) # [ 0, 9, 7 ]
|
||||
>>> frac.med(1.3, 9, True) # [ 1, 2, 7 ]
|
||||
>>> frac.med(-1.3, 9) # [ 0, -9, 7 ]
|
||||
>>> frac.med(-1.3, 9, True) # [ -2, 5, 7 ]
|
||||
|
||||
>>> frac.cont(1.3, 9) # [ 0, 4, 3 ]
|
||||
>>> frac.cont(1.3, 9, True) # [ 1, 1, 3 ]
|
||||
>>> frac.cont(-1.3, 9) # [ 0, -4, 3 ]
|
||||
>>> frac.cont(-1.3, 9, True) # [ -2, 2, 3 ]
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
@ -68,4 +106,4 @@ granted by the Apache 2.0 license are reserved by the Original Author.
|
||||
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/frac/master.svg)](https://coveralls.io/r/SheetJS/frac?branch=master)
|
||||
|
||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/731e31b3a26382ccd5d213b9e74ea552 "githalytics.com")](http://githalytics.com/SheetJS/frac)
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/frac?pixel)](https://github.com/SheetJS/frac)
|
||||
|
3
dist/frac.js
vendored
3
dist/frac.js
vendored
@ -33,8 +33,7 @@ frac.cont = function cont(x, D, mixed) {
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
}
|
||||
if(Q > D) { Q = Q_1; P = P_1; }
|
||||
if(Q > D) { Q = Q_2; P = P_2; }
|
||||
if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
|
||||
if(!mixed) return [0, sgn * P, Q];
|
||||
var q = Math.floor(sgn * P/Q);
|
||||
return [q, sgn*P - q*Q, Q];
|
||||
|
2
dist/frac.min.js
vendored
2
dist/frac.min.js
vendored
@ -1,2 +1,2 @@
|
||||
/* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */
|
||||
var frac=function(x,D,mixed){var n1=Math.floor(x),d1=1;var n2=n1+1,d2=1;if(x!==n1)while(d1<=D&&d2<=D){var m=(n1+n2)/(d1+d2);if(x===m){if(d1+d2<=D){d1+=d2;n1+=n2;d2=D+1}else if(d1>d2)d2=D+1;else d1=D+1;break}else if(x<m){n2=n1+n2;d2=d1+d2}else{n1=n1+n2;d1=d1+d2}}if(d1>D){d1=d2;n1=n2}if(!mixed)return[0,n1,d1];var q=Math.floor(n1/d1);return[q,n1-q*d1,d1]};frac.cont=function cont(x,D,mixed){var sgn=x<0?-1:1;var B=x*sgn;var P_2=0,P_1=1,P=0;var Q_2=1,Q_1=0,Q=0;var A=Math.floor(B);while(Q_1<D){A=Math.floor(B);P=A*P_1+P_2;Q=A*Q_1+Q_2;if(B-A<5e-10)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){Q=Q_1;P=P_1}if(Q>D){Q=Q_2;P=P_2}if(!mixed)return[0,sgn*P,Q];var q=Math.floor(sgn*P/Q);return[q,sgn*P-q*Q,Q]};if(typeof module!=="undefined"&&typeof DO_NOT_EXPORT_FRAC==="undefined")module.exports=frac;
|
||||
var frac=function(x,D,mixed){var n1=Math.floor(x),d1=1;var n2=n1+1,d2=1;if(x!==n1)while(d1<=D&&d2<=D){var m=(n1+n2)/(d1+d2);if(x===m){if(d1+d2<=D){d1+=d2;n1+=n2;d2=D+1}else if(d1>d2)d2=D+1;else d1=D+1;break}else if(x<m){n2=n1+n2;d2=d1+d2}else{n1=n1+n2;d1=d1+d2}}if(d1>D){d1=d2;n1=n2}if(!mixed)return[0,n1,d1];var q=Math.floor(n1/d1);return[q,n1-q*d1,d1]};frac.cont=function cont(x,D,mixed){var sgn=x<0?-1:1;var B=x*sgn;var P_2=0,P_1=1,P=0;var Q_2=1,Q_1=0,Q=0;var A=Math.floor(B);while(Q_1<D){A=Math.floor(B);P=A*P_1+P_2;Q=A*Q_1+Q_2;if(B-A<5e-10)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){if(Q_1>D){Q=Q_2;P=P_2}else{Q=Q_1;P=P_1}}if(!mixed)return[0,sgn*P,Q];var q=Math.floor(sgn*P/Q);return[q,sgn*P-q*Q,Q]};if(typeof module!=="undefined"&&typeof DO_NOT_EXPORT_FRAC==="undefined")module.exports=frac;
|
||||
|
2
dist/frac.min.map
vendored
2
dist/frac.min.map
vendored
@ -1 +1 @@
|
||||
{"version":3,"file":"dist/frac.min.js","sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":";AACA,GAAIA,MAAO,SAASC,EAAGC,EAAGC,OACxB,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,MAAc,KAC3BP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAEkB,EAAID,GAAKF,GAAID,IACzB,GAAGI,EAAIlB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,IACzB,IAAIZ,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAE1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB"}
|
||||
{"version":3,"file":"dist/frac.min.js","sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":";AACA,GAAIA,MAAO,SAASC,EAAGC,EAAGC,OACxB,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,MAAc,KAC3BP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAE,GAAGiB,IAAMjB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,QAAY,CAAEK,EAAID,GAAKF,GAAID,KAClE,IAAIb,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAE1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB"}
|
@ -33,8 +33,7 @@ frac.cont = function cont(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Arra
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
}
|
||||
if(Q > D) { Q = Q_1; P = P_1; }
|
||||
if(Q > D) { Q = Q_2; P = P_2; }
|
||||
if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
|
||||
if(!mixed) return [0, sgn * P, Q];
|
||||
var q = Math.floor(sgn * P/Q);
|
||||
return [q, sgn*P - q*Q, Q];
|
||||
|
3
frac.js
3
frac.js
@ -33,8 +33,7 @@ frac.cont = function cont(x, D, mixed) {
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
}
|
||||
if(Q > D) { Q = Q_1; P = P_1; }
|
||||
if(Q > D) { Q = Q_2; P = P_2; }
|
||||
if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
|
||||
if(!mixed) return [0, sgn * P, Q];
|
||||
var q = Math.floor(sgn * P/Q);
|
||||
return [q, sgn*P - q*Q, Q];
|
||||
|
10
frac.md
10
frac.md
@ -147,11 +147,10 @@ At the end of each iteration, advance `k` by one step:
|
||||
}
|
||||
```
|
||||
|
||||
In case we end up overstepping, walk back an iteration or two:
|
||||
In case we end up overstepping, walk back to the last valid iteration:
|
||||
|
||||
```
|
||||
if(Q > D) { Q = Q_1; P = P_1; }
|
||||
if(Q > D) { Q = Q_2; P = P_2; }
|
||||
if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
|
||||
```
|
||||
|
||||
The final result is `r = (sgn x)p_k / q_k`:
|
||||
@ -185,7 +184,7 @@ var xltestfiles=[
|
||||
];
|
||||
|
||||
function xlline(o,j,m,w) {
|
||||
it(j, function(done) {
|
||||
it(j, function() {
|
||||
var d, q, qq;
|
||||
for(var i = j*w; i < m-3 && i < (j+1)*w; ++i) {
|
||||
d = o[i].split("\t");
|
||||
@ -202,7 +201,6 @@ function xlline(o,j,m,w) {
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
assert.equal(qq, d[3], d[3] + " 3");
|
||||
}
|
||||
done();
|
||||
});
|
||||
}
|
||||
function parsexl(f,w) {
|
||||
@ -241,7 +239,7 @@ xltestfiles.forEach(function(x) {
|
||||
```json>package.json
|
||||
{
|
||||
"name": "frac",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"author": "SheetJS",
|
||||
"description": "Rational approximation with bounded denominator",
|
||||
"keywords": [ "math", "fraction", "rational", "approximation" ],
|
||||
|
25
frac.py
25
frac.py
@ -16,18 +16,16 @@ All functions take 3 arguments:
|
||||
The return value is a list of 3 elements: [quotient, numerator, denominator]
|
||||
"""
|
||||
|
||||
import math as Math
|
||||
|
||||
|
||||
def med(x, D, mixed=False):
|
||||
"""Generate fraction representation using Mediant method"""
|
||||
n1, d1 = int(Math.floor(x)), 1
|
||||
n1, d1 = int(x), 1
|
||||
n2, d2 = n1+1, 1
|
||||
m = 0.
|
||||
if x != n1:
|
||||
while d1 <= D and d2 <= D:
|
||||
m = float(n1 + n2) / (d1 + d2)
|
||||
if(x == m):
|
||||
if x == m:
|
||||
if d1 + d2 <= D:
|
||||
n1, d1 = n1 + n2, d1 + d2
|
||||
d2 = D + 1
|
||||
@ -50,23 +48,24 @@ def med(x, D, mixed=False):
|
||||
|
||||
def cont(x, D, mixed=False):
|
||||
"""Generate fraction representation using Aberth method"""
|
||||
sgn = -1 if x < 0 else 1
|
||||
B = abs(x)
|
||||
P_2, P_1, P = 0, 1, 0
|
||||
Q_2, Q_1, Q = 1, 0, 0
|
||||
I = int
|
||||
P_2, P_1, P, Q_2, Q_1, Q = 0, 1, 0, 1, 0, 0
|
||||
while Q_1 < D:
|
||||
A = int(Math.floor(B))
|
||||
A = I(B)
|
||||
P = A * P_1 + P_2
|
||||
Q = A * Q_1 + Q_2
|
||||
if ((B - A) < 0.0000000005):
|
||||
if (B - A) < 0.0000000005:
|
||||
break
|
||||
B = 1. / (B-A)
|
||||
P_2, P_1 = P_1, P
|
||||
Q_2, Q_1 = Q_1, Q
|
||||
if(Q > D):
|
||||
P, Q = P_1, Q_1
|
||||
if(Q > D):
|
||||
P, Q = P_2, Q_2
|
||||
if Q > D:
|
||||
if Q_1 <= D:
|
||||
P, Q = P_1, Q_1
|
||||
else:
|
||||
P, Q = P_2, Q_2
|
||||
sgn = -1 if x < 0 else 1
|
||||
if not mixed:
|
||||
return [0, sgn * P, Q]
|
||||
q = divmod(sgn * P, Q)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "frac",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"author": "SheetJS",
|
||||
"description": "Rational approximation with bounded denominator",
|
||||
"keywords": [ "math", "fraction", "rational", "approximation" ],
|
||||
|
7
setup.py
7
setup.py
@ -1,7 +1,7 @@
|
||||
from distutils.core import setup
|
||||
setup(
|
||||
name='frac',
|
||||
version='0.0.1',
|
||||
version='1.0.2',
|
||||
author='SheetJS',
|
||||
author_email='dev@sheetjs.com',
|
||||
url='http://oss.sheetjs.com/frac',
|
||||
@ -20,9 +20,10 @@ This module can generate fraction representations using:
|
||||
license = "Apache-2.0",
|
||||
keywords = ['frac', 'fraction', 'rational', 'approximation'],
|
||||
classifiers = [
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Development Status :: 5 - Production/Stable'
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Topic :: Office/Business',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Scientific/Engineering :: Mathematics',
|
||||
'Topic :: Utilities',
|
||||
]
|
||||
)
|
||||
|
3
test.js
3
test.js
@ -10,7 +10,7 @@ var xltestfiles=[
|
||||
];
|
||||
|
||||
function xlline(o,j,m,w) {
|
||||
it(j, function(done) {
|
||||
it(j, function() {
|
||||
var d, q, qq;
|
||||
for(var i = j*w; i < m-3 && i < (j+1)*w; ++i) {
|
||||
d = o[i].split("\t");
|
||||
@ -27,7 +27,6 @@ function xlline(o,j,m,w) {
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
assert.equal(qq, d[3], d[3] + " 3");
|
||||
}
|
||||
done();
|
||||
});
|
||||
}
|
||||
function parsexl(f,w) {
|
||||
|
105
test_all.py
Normal file
105
test_all.py
Normal file
@ -0,0 +1,105 @@
|
||||
import frac
|
||||
import pytest
|
||||
|
||||
xltestfiles = [
|
||||
['xl.00001.tsv', 10000],
|
||||
['xl.0001.tsv', 10000],
|
||||
['xl.001.tsv', 10000],
|
||||
['xl.01.tsv', 10000],
|
||||
['oddities.tsv', 25]
|
||||
]
|
||||
|
||||
mediant_tests = [
|
||||
[0.1, 9, False, 0, 1, 9],
|
||||
[0.2, 9, False, 0, 1, 5],
|
||||
[0.3, 9, False, 0, 2, 7],
|
||||
[0.4, 9, False, 0, 2, 5],
|
||||
[0.5, 9, False, 0, 1, 2],
|
||||
[0.6, 9, False, 0, 3, 5],
|
||||
[0.7, 9, False, 0, 5, 7],
|
||||
[0.8, 9, False, 0, 4, 5],
|
||||
[0.9, 9, False, 0, 8, 9],
|
||||
[1.0, 9, False, 0, 1, 1],
|
||||
[1.0, 9, True, 1, 0, 1],
|
||||
[1.7, 9, True, 1, 5, 7],
|
||||
[1.7, 9, False, 0, 12, 7]
|
||||
]
|
||||
|
||||
|
||||
def test_mediant_tenths():
|
||||
for t in mediant_tests:
|
||||
assert frac.med(t[0], t[1], t[2]) == [t[3], t[4], t[5]]
|
||||
|
||||
|
||||
def make9(q):
|
||||
S = str
|
||||
if q[0] or q[1]:
|
||||
qq = (S(q[0]) if q[0] else "")
|
||||
qq += " "
|
||||
qq += ("/".join([S(q[1]), S(q[2])]) if q[1] else " ")
|
||||
return qq
|
||||
else:
|
||||
return "0 "
|
||||
|
||||
|
||||
def make99(q):
|
||||
S = str
|
||||
if q[0] or q[1]:
|
||||
qq = (S(q[0]) if q[0] else "")
|
||||
qq += " "
|
||||
if q[1]:
|
||||
if q[1] < 10:
|
||||
qq += " "
|
||||
qq += ("/".join([S(q[1]), S(q[2])]))
|
||||
if q[2] < 10:
|
||||
qq += " "
|
||||
else:
|
||||
qq += " "
|
||||
return qq
|
||||
else:
|
||||
return "0 "
|
||||
|
||||
|
||||
def make999(q):
|
||||
S = str
|
||||
if q[0] or q[1]:
|
||||
qq = (S(q[0]) if q[0] else "")
|
||||
qq += " "
|
||||
if q[1]:
|
||||
if q[1] < 10:
|
||||
qq += " "
|
||||
elif q[1] < 100:
|
||||
qq += " "
|
||||
qq += "/".join([S(q[1]), S(q[2])])
|
||||
if q[2] < 10:
|
||||
qq += " "
|
||||
elif q[2] < 100:
|
||||
qq += " "
|
||||
else:
|
||||
qq += " "
|
||||
return qq
|
||||
else:
|
||||
return "0 "
|
||||
|
||||
|
||||
def xlline(o, j, m, w):
|
||||
for i in xrange(j*w, min(m-3, (j+1) * w)):
|
||||
d = o[i].split("\t")
|
||||
dd = float(d[0])
|
||||
assert make9(frac.cont(dd, 9, True)) == d[1]
|
||||
assert make99(frac.cont(dd, 99, True)) == d[2]
|
||||
assert make999(frac.cont(dd, 999, True)) == d[3]
|
||||
|
||||
|
||||
def parsexl(f, w):
|
||||
oo = open(f)
|
||||
d = oo.readlines()
|
||||
o = filter(lambda x: len(x) > 0, map(lambda x: x.strip("\n"), d))
|
||||
m = len(o)-3
|
||||
for j in xrange(int(m/w)):
|
||||
xlline(o, j, m, w)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filename,step", xltestfiles)
|
||||
def test_file(filename, step):
|
||||
parsexl('./test_files/' + filename, step)
|
Loading…
Reference in New Issue
Block a user