From 5c728aeb81f94c1fd86828512c2f8fc3d2e31fc9 Mon Sep 17 00:00:00 2001 From: Elias Lousseief Date: Sun, 10 Mar 2024 12:46:01 +0100 Subject: [PATCH 1/2] Fix bug with wrong method flag returned on failure of calculation of D and improved calculation of actual D when combinations (-c) are used. --- .gitignore | 3 --- .python-version | 1 + BirthdayProblem.py | 32 +++++++++++++++++++++++++++----- DEVELOPERS_NOTES.md | 15 +++++++++++++++ DataTest.py | 43 +++++++++++++++++++++++++++---------------- LibraryTest.py | 25 +++++++++++++++---------- OutputTest.py | 38 ++++++++++++++++++++++---------------- README.md | 5 +++++ 8 files changed, 112 insertions(+), 50 deletions(-) create mode 100644 .python-version diff --git a/.gitignore b/.gitignore index 0b93ff8..6a5b926 100644 --- a/.gitignore +++ b/.gitignore @@ -81,9 +81,6 @@ target/ profile_default/ ipython_config.py -# pyenv -.python-version - # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..8d7f852 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10.4 diff --git a/BirthdayProblem.py b/BirthdayProblem.py index 370bfa9..9a9630d 100644 --- a/BirthdayProblem.py +++ b/BirthdayProblem.py @@ -171,6 +171,13 @@ def facultyNTakeMLogE(n, nLogE, m): nTakeMFacLogE = _DecimalContext.ctx.subtract(nFacLogE, nSubMFacLogE) return nTakeMFacLogE + @staticmethod + def facultyNaive(n): + nFac = _DecimalFns.ONE + for i in range(int(n),0, -1): + nFac = _DecimalContext.ctx.multiply(nFac, Decimal(i)) + return nFac + # faculty method wrapper for both natural and base-2 logarithms @staticmethod def facultyLog(n, nLog, isLog2): @@ -824,6 +831,12 @@ class _BirthdayProblemInputHandler: ######################################################################################################################################################################################################## ######################################################################################################################################################################################################## + # threshold for resulting log2 d size input under which we use the exact naive method for calculating inputs with + # both -c and -b flags (for too large inputs we will get overflow when calculating d which is needed for the naive + # method but d is not really needed to solve the problem in log 2 space so then we downgrade to Sterling's + # approximation when processing the inputs instead). The used threshold implies naive calculation of 32768! + LOG2_THRESHOLD_FOR_NAIVE_CALCULATION_OF_D_FOR_COMBINATIONS_AND_BINARY = Decimal('15') # corresponds to 32768 + @staticmethod def illegalInputString(varName = None): return "Illegal input" if varName is None else "Illegal input for '" + varName + "'" @@ -892,11 +905,20 @@ def setup(dOrDLog, nOrNLog, p, isBinary, isCombinations): if isCombinations: # d is the size of a set of items, calculate the number of permutations that is possible with it if isBinary: - dLog = _DecimalFns.facultyLog(_DecimalContext.ctx.power(_DecimalFns.TWO, dOrDLog), dOrDLog, True) - d = _DecimalContext.ctx.power(_DecimalFns.TWO, dLog) + if _DecimalFns.isGreaterThan(dOrDLog, _BirthdayProblemInputHandler.LOG2_THRESHOLD_FOR_NAIVE_CALCULATION_OF_D_FOR_COMBINATIONS_AND_BINARY): + # use approximation + dLog = _DecimalFns.facultyLog(_DecimalContext.ctx.power(_DecimalFns.TWO, dOrDLog), dOrDLog, True) + d = _DecimalContext.ctx.power(_DecimalFns.TWO, dLog) + else: + # use exact calculation + d = _DecimalContext.ctx.power(_DecimalFns.TWO, dOrDLog) + d = _DecimalFns.facultyNaive(d) + dLog = _DecimalContext.ctx.divide(_DecimalContext.ctx.ln(d), _DecimalFns.LOG_E_2) else: - dLog = _DecimalFns.facultyLog(d, _DecimalContext.ctx.ln(dOrDLog), False) - d = _DecimalContext.ctx.exp(dLog) + # here we always need to display d in the output so if we can't calculate it, the request will fail, + # therefore we can just calculate it in a naive way without log space + d = _DecimalFns.facultyNaive(dOrDLog) + dLog = _DecimalContext.ctx.ln(d) else: # d is already the size of the set of combinations if isBinary: @@ -1107,7 +1129,7 @@ def solveJson(d, dLog, n, nLog, p, pPercent, isBinary, isStirling, isTaylor, isE (n, methodUsed) = _BirthdayProblemSolverChecked.birthdayProblemInv(d, dLog, p, method, isBinary) lastMethodUsed = methodUsed except BaseException as e: - methodKey = _BirthdayProblemTextFormatter.methodToText(_BirthdayProblemSolver.CalcPrecision.TAYLOR_APPROX).lower() + methodKey = _BirthdayProblemTextFormatter.methodToText(method).lower() errorMessage = str(e).lower() if isinstance(e, KeyboardInterrupt): res['results'][methodKey] = { 'error': 'interrupted' } diff --git a/DEVELOPERS_NOTES.md b/DEVELOPERS_NOTES.md index 4d9b838..9d29eb5 100644 --- a/DEVELOPERS_NOTES.md +++ b/DEVELOPERS_NOTES.md @@ -1,4 +1,6 @@ +## Good to know about `Decimal` and calculations + * `Decimal`'s are immutable but in some places, an input is wrapped in `Decimal(x)`. This is likely because this input can sometimes be a regular number OR has been so historically and the creation of a `Decimal` has been left. * Adjustments of `Decimal`'s via `adjustPrecisions` is an attempt to allow a certain number of decimals to the right of @@ -6,3 +8,16 @@ different times after some processing has been done. If this results in a too big number, then the precision needed is too big and we can't carry out the calculations. This limit is set at 1000 digits (out of which 100 at most are to the right of the comma). Larger numbers than this will result in the calculations failing. +* It takes longer to calculate a loop where a log operation occurs in every iteration rather than a multiplication, + therefore calculating stuff in log space can be more time-consuming but has the advantage of allowing larger numbers + without overflowing. + +## How to release + +* Create a new branch with the name `X.X.X-feature` +* Commit and push to git +* Merge in git +* Pull master locally +* Add tag with `git tag X.X.X` +* Push tags with `git push tags` +* Add new release for tag in Github diff --git a/DataTest.py b/DataTest.py index 480590e..1593784 100644 --- a/DataTest.py +++ b/DataTest.py @@ -79,10 +79,10 @@ '52 -p 0.1 -c -t', True, { - 'd': '≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67)', + 'd': '80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67)', 'p': '10%', 'results': { - 'taylor': {'result': '4119363813276486714957808853108064 (≈4*10^33)'} + 'taylor': {'result': '4122665867622533660736208120290868 (≈4*10^33)'} } } ], @@ -90,10 +90,10 @@ '52 -p 0.5 -c -t', True, { - 'd': '≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67)', + 'd': '80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67)', 'p': '50%', 'results': { - 'taylor': {'result': '10565837726592754214318243269428637 (≈10^34)'} + 'taylor': {'result': '10574307231100289363611308602026252 (≈10^34)'} } } ], @@ -101,7 +101,7 @@ '52 -n 10000000000000000000 -c -s -t', True, { - 'd': '≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67)', + 'd': '80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67)', 'n': '10000000000000000000 (=10^19)', 'results': { 'stirling': {'result': '≈0% (≈6*10^-31)'}, @@ -113,11 +113,11 @@ '52 -n 10000000000000000000000000000000000 -c -s -t', True, { - 'd': '≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67)', + 'd': '80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67)', 'n': '10000000000000000000000000000000000 (=10^34)', 'results': { - 'stirling': {'result': '≈46.2536366051%'}, - 'taylor': {'result': '≈46.2536366051%'} + 'stirling': {'result': '≈46.2001746672%'}, + 'taylor': {'result': '≈46.2001746672%'} } } ], @@ -125,12 +125,12 @@ '4 -n 18 -b -c -a', True, { - 'd': '≈2^44.2426274105', + 'd': '≈2^44.2501404699', 'n': '2^18', 'results': { - 'exact': {'result': '≈0.1649423866% (≈2*10^-3)'}, - 'stirling': {'result': '≈0.1649422224% (≈2*10^-3)'}, - 'taylor': {'result': '≈0.1649428504% (≈2*10^-3)'} + 'exact': {'result': '≈0.1640861961% (≈2*10^-3)'}, + 'stirling': {'result': '≈0.1640861961% (≈2*10^-3)'}, + 'taylor': {'result': '≈0.1640868208% (≈2*10^-3)'} } } ], @@ -138,12 +138,12 @@ '16 -n 262144 -c -a', True, { - 'd': '≈20814114415223 (≈2*10^13)', + 'd': '20922789888000 (≈2*10^13)', 'n': '262144 (≈3*10^5)', 'results': { - 'exact': {'result': '≈0.1649423866% (≈2*10^-3)'}, - 'stirling': {'result': '≈0.1649422224% (≈2*10^-3)'}, - 'taylor': {'result': '≈0.1649428504% (≈2*10^-3)'} + 'exact': {'result': '≈0.1640861961% (≈2*10^-3)'}, + 'stirling': {'result': '≈0.1640861961% (≈2*10^-3)'}, + 'taylor': {'result': '≈0.1640868208% (≈2*10^-3)'} } } ], @@ -184,6 +184,17 @@ } } ], + [ + '1280 -p 0.5 -b -c -e', + True, + { + 'd': '≈2^26614275474014559821953787196100807012412948367028783328633986189111799719299525295290069853854877867120534538070982737886888824825850066183609939356930416666755910887266773840385877776851876084664629106697034459995685244418266399190317043076208186461319737435225525519543453247219560088300601118286958869004726993677805799134087110255288245085785541666888810491274634074724367056992419344.3330052449', + 'p': '50%', + 'results': { + 'exact': {'error': 'd exceeds maximum size and is needed for method'} + } + } + ], [ '12800 -n 6400 -b -c -s -t', False, diff --git a/LibraryTest.py b/LibraryTest.py index ee923bc..c29c23d 100644 --- a/LibraryTest.py +++ b/LibraryTest.py @@ -244,12 +244,12 @@ def testFn(args): [ { "dOrDLog": "52", "p": "0.1", "method": BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("4119363813276486714957808853108064"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) + (Decimal("4122665867622533660736208120290868"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], [ { "dOrDLog": "52", "p": "0.5", "method": BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("10565837726592754214318243269428637"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) + (Decimal("10574307231100289363611308602026252"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], [ { "dOrDLog": "52", "nOrNLog": "10000000000000000000", "method": BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX, "isCombinations": True, "isBinary": False }, @@ -264,42 +264,42 @@ def testFn(args): [ { "dOrDLog": "52", "nOrNLog": "10000000000000000000000000000000000", "method": BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("0.462536366051"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) + (Decimal("0.462001746672"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) ], [ { "dOrDLog": "52", "nOrNLog": "10000000000000000000000000000000000", "method": BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("0.462536366051"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) + (Decimal("0.462001746672"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], [ { "dOrDLog": "4", "nOrNLog": "18", "method": BirthdayProblem.Solver.CalcPrecision.EXACT, "isCombinations": True, "isBinary": True }, True, - (Decimal("0.001649423866"), BirthdayProblem.Solver.CalcPrecision.EXACT) + (Decimal("0.001640861961"), BirthdayProblem.Solver.CalcPrecision.EXACT) ], [ { "dOrDLog": "4", "nOrNLog": "18", "method": BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX, "isCombinations": True, "isBinary": True }, True, - (Decimal("0.001649422224"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) + (Decimal("0.001640861961"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) ], [ { "dOrDLog": "4", "nOrNLog": "18", "method": BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX, "isCombinations": True, "isBinary": True }, True, - (Decimal("0.001649428504"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) + (Decimal("0.001640868208"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], [ { "dOrDLog": "16", "nOrNLog": "262144", "method": BirthdayProblem.Solver.CalcPrecision.EXACT, "isCombinations": True, "isBinary": False }, True, - (Decimal("0.001649423866"), BirthdayProblem.Solver.CalcPrecision.EXACT) + (Decimal("0.001640861961"), BirthdayProblem.Solver.CalcPrecision.EXACT) ], [ { "dOrDLog": "16", "nOrNLog": "262144", "method": BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("0.001649422224"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) + (Decimal("0.001640861961"), BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX) ], [ { "dOrDLog": "16", "nOrNLog": "262144", "method": BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX, "isCombinations": True, "isBinary": False }, True, - (Decimal("0.001649428504"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) + (Decimal("0.001640868208"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], [ { "dOrDLog": "20922789888000", "nOrNLog": "262144", "method": BirthdayProblem.Solver.CalcPrecision.EXACT, "isCombinations": False, "isBinary": False }, @@ -336,6 +336,11 @@ def testFn(args): True, (Decimal("0"), BirthdayProblem.Solver.CalcPrecision.TAYLOR_APPROX) ], + [ + { "dOrDLog": "1280", "p": "0.5", "method": BirthdayProblem.Solver.CalcPrecision.EXACT, "isCombinations": True, "isBinary": True }, + False, + "d exceeds maximum size and is needed for method" + ], [ { "dOrDLog": "12800", "nOrNLog": "6400", "method": BirthdayProblem.Solver.CalcPrecision.STIRLING_APPROX, "isCombinations": True, "isBinary": True }, False, diff --git a/OutputTest.py b/OutputTest.py index c23df9b..4eb331c 100644 --- a/OutputTest.py +++ b/OutputTest.py @@ -148,44 +148,44 @@ ], ['52 -p 0.1 -c -t', True, [ - 'The number of samples, sampled uniformly at random from a set of ≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67) items, needed to have at least a 10% chance of a non-unique sample is:', - ' 4119363813276486714957808853108064 (≈4*10^33) (Taylor series approximation used in main calculation)' + 'The number of samples, sampled uniformly at random from a set of 80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67) items, needed to have at least a 10% chance of a non-unique sample is:', + ' 4122665867622533660736208120290868 (≈4*10^33) (Taylor series approximation used in main calculation)' ] ], ['52 -p 0.5 -c -t', True, [ - 'The number of samples, sampled uniformly at random from a set of ≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67) items, needed to have at least a 50% chance of a non-unique sample is:', - ' 10565837726592754214318243269428637 (≈10^34) (Taylor series approximation used in main calculation)' + 'The number of samples, sampled uniformly at random from a set of 80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67) items, needed to have at least a 50% chance of a non-unique sample is:', + ' 10574307231100289363611308602026252 (≈10^34) (Taylor series approximation used in main calculation)' ] ], ['52 -n 10000000000000000000 -c -s -t', True, [ - 'The probability of finding at least one non-unique sample among 10000000000000000000 (=10^19) samples, sampled uniformly at random from a set of ≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67) items, is:', + 'The probability of finding at least one non-unique sample among 10000000000000000000 (=10^19) samples, sampled uniformly at random from a set of 80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67) items, is:', " ≈0% (≈6*10^-31) (Stirling's approximation used in factorial calculation)", ' ≈0% (≈6*10^-31) (Taylor series approximation used in main calculation (removes need for factorial calculation))' ] ], ['52 -n 10000000000000000000000000000000000 -c -s -t', True, [ - 'The probability of finding at least one non-unique sample among 10000000000000000000000000000000000 (=10^34) samples, sampled uniformly at random from a set of ≈80529020383886612857810199580012764961409004334781435987268084328737 (≈8*10^67) items, is:', - " ≈46.2536366051% (Stirling's approximation used in factorial calculation)", - ' ≈46.2536366051% (Taylor series approximation used in main calculation (removes need for factorial calculation))' + 'The probability of finding at least one non-unique sample among 10000000000000000000000000000000000 (=10^34) samples, sampled uniformly at random from a set of 80658175170943878571660636856403766975289505440883277824000000000000 (≈8*10^67) items, is:', + " ≈46.2001746672% (Stirling's approximation used in factorial calculation)", + ' ≈46.2001746672% (Taylor series approximation used in main calculation (removes need for factorial calculation))' ] ], ['4 -n 18 -b -c -a', True, [ - 'The probability of finding at least one non-unique sample among 2^18 samples, sampled uniformly at random from a set of ≈2^44.2426274105 items, is:', - ' ≈0.1649423866% (≈2*10^-3) (Exact method)', - " ≈0.1649422224% (≈2*10^-3) (Stirling's approximation used in factorial calculation)", - ' ≈0.1649428504% (≈2*10^-3) (Taylor series approximation used in main calculation (removes need for factorial calculation))' + 'The probability of finding at least one non-unique sample among 2^18 samples, sampled uniformly at random from a set of ≈2^44.2501404699 items, is:', + ' ≈0.1640861961% (≈2*10^-3) (Exact method)', + " ≈0.1640861961% (≈2*10^-3) (Stirling's approximation used in factorial calculation)", + ' ≈0.1640868208% (≈2*10^-3) (Taylor series approximation used in main calculation (removes need for factorial calculation))' ] ], ['16 -n 262144 -c -a', True, [ - 'The probability of finding at least one non-unique sample among 262144 (≈3*10^5) samples, sampled uniformly at random from a set of ≈20814114415223 (≈2*10^13) items, is:', - ' ≈0.1649423866% (≈2*10^-3) (Exact method)', - " ≈0.1649422224% (≈2*10^-3) (Stirling's approximation used in factorial calculation)", - ' ≈0.1649428504% (≈2*10^-3) (Taylor series approximation used in main calculation (removes need for factorial calculation))' + 'The probability of finding at least one non-unique sample among 262144 (≈3*10^5) samples, sampled uniformly at random from a set of 20922789888000 (≈2*10^13) items, is:', + ' ≈0.1640861961% (≈2*10^-3) (Exact method)', + " ≈0.1640861961% (≈2*10^-3) (Stirling's approximation used in factorial calculation)", + ' ≈0.1640868208% (≈2*10^-3) (Taylor series approximation used in main calculation (removes need for factorial calculation))' ] ], ['20922789888000 -n 262144 -a', True, @@ -210,6 +210,12 @@ ' 0% (Taylor series approximation used in main calculation (removes need for factorial calculation))' ] ], + ['1280 -p 0.5 -b -c -e', True, + [ + 'The number of samples, sampled uniformly at random from a set of ≈2^26614275474014559821953787196100807012412948367028783328633986189111799719299525295290069853854877867120534538070982737886888824825850066183609939356930416666755910887266773840385877776851876084664629106697034459995685244418266399190317043076208186461319737435225525519543453247219560088300601118286958869004726993677805799134087110255288245085785541666888810491274634074724367056992419344.3330052449 items, needed to have at least a 50% chance of a non-unique sample is:', + " N/A (Calculation failed: d exceeds maximum size and is needed for method (Exact method))" + ] + ], ['12800 -n 6400 -b -c -s -t', False, "dLog exceeds maximum size and is needed to initialize calculations"] ] diff --git a/README.md b/README.md index 5860fcf..7e1c823 100644 --- a/README.md +++ b/README.md @@ -161,3 +161,8 @@ Elias Lousseief (2020) * Documentation, text and smaller fixes forgotten in v. 1.4. * Added tests where the project is used as a library (previous tests only used the project's command line API). +* *v. 1.4.2* + * Corrected wrong method flag returned when solving for `N` with overflow in `D`. + * Added exact (naive) calculation of `D` parameter when `-c` flag is used. Earlier this relied on the Sterling + approximation. It still relies on Sterling approximation when `-b` and `-c` are used in combination with an input + `D` larger than 15. From af7068004413db5050087b53a07408f1468d0750 Mon Sep 17 00:00:00 2001 From: Elias Lousseief Date: Sun, 10 Mar 2024 13:01:25 +0100 Subject: [PATCH 2/2] Rename test files so harmonize with Kotlin version and improve understanding --- DEVELOPERS_NOTES.md | 2 +- DataTest.py => JsonTest.py | 0 RunTests.py | 8 ++++---- OutputTest.py => TextTest.py | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename DataTest.py => JsonTest.py (100%) rename OutputTest.py => TextTest.py (100%) diff --git a/DEVELOPERS_NOTES.md b/DEVELOPERS_NOTES.md index 9d29eb5..b0ca083 100644 --- a/DEVELOPERS_NOTES.md +++ b/DEVELOPERS_NOTES.md @@ -19,5 +19,5 @@ * Merge in git * Pull master locally * Add tag with `git tag X.X.X` -* Push tags with `git push tags` +* Push the new tag with `git push origin XXX` * Add new release for tag in Github diff --git a/DataTest.py b/JsonTest.py similarity index 100% rename from DataTest.py rename to JsonTest.py diff --git a/RunTests.py b/RunTests.py index aabb5e1..2f78595 100644 --- a/RunTests.py +++ b/RunTests.py @@ -1,5 +1,5 @@ -import OutputTest -import DataTest +import TextTest +import JsonTest import LibraryTest from BirthdayProblem import SolverException import subprocess @@ -65,8 +65,8 @@ def runTest(testData, resFn, assemblerFn, dividerFn): print("Running all tests...") print() tests = [ - ["OutputTest", OutputTest.testData, OutputTest.testFn, OutputTest.assemblerFn, OutputTest.dividerFn], - ["DataTest", DataTest.testData, DataTest.testFn, DataTest.assemblerFn, DataTest.dividerFn], + ["TextTest", TextTest.testData, TextTest.testFn, TextTest.assemblerFn, TextTest.dividerFn], + ["JsonTest", JsonTest.testData, JsonTest.testFn, JsonTest.assemblerFn, JsonTest.dividerFn], ["LibraryTest", LibraryTest.testData, LibraryTest.testFn, LibraryTest.assemblerFn, LibraryTest.dividerFn] ] for (testName, testData, testFn, assemblerFn, dividerFn) in tests: diff --git a/OutputTest.py b/TextTest.py similarity index 100% rename from OutputTest.py rename to TextTest.py