PK ~|HC
pseudorandom/_constraint.py#-*- coding:utf-8 -*-
"""
This file is part of pseudorandom.
pseudorandom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pseudorandom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pseudorandom. If not, see .
"""
from datamatrix.py3compat import *
from pseudorandom._exceptions import InvalidConstraint
from datamatrix._datamatrix._basecolumn import BaseColumn
class Constraint(object):
def __init__(self, enforce, **kwargs):
self.enforce = enforce
self.init(**kwargs)
def setcols(self, cols):
if cols is None:
self.cols = self.dm.column_names
elif isinstance(cols, BaseColumn):
self.cols = [cols.name]
else:
self.cols = [col.name for col in cols]
if not self.cols:
raise InvalidConstraint(u'No (valid) columns specified')
def ok(self, row):
raise NotImplementedError
@staticmethod
def count(l):
return len(set(l))
@property
def dm(self):
return self.enforce.dm
class MaxRep(Constraint):
"""
desc:
Limits the number of times that a value can occur in direct succession.
A maxrep of 1 means that values cannot be repeated.
example: |
ef = Enforce(df)
ef.add_constraint(MaxRep, cols=['word'], maxrep=2)
"""
def init(self, cols=None, maxrep=1):
if maxrep < 1:
raise InvalidConstraint(u'maxrep should be >= 1')
self.maxrep = maxrep
self.setcols(cols)
def ok(self, row):
if row < self.maxrep:
return True
for colname in self.cols:
col = self.dm[colname]
# We only check for preceding repetitions. I.e. in the string:
# AABABBB
# The number of repetitions would be:
# 1211123
if row < self.maxrep:
continue
l = col[row-self.maxrep:row+1]
if self.count(l) == 1:
return False
return True
class MinDist(Constraint):
"""
desc:
Sets a minimum distance between value repetitions. A minimum distance of
2 avoids direct repetitions.
example: |
ef = Enforce(dm)
ef.add_constraint(MinDist, cols=['word'], mindist=2)
"""
def init(self, cols=None, mindist=2):
if mindist < 2:
raise InvalidConstraint(u'mindist should be >= 2')
self.mindist = mindist
self.setcols(cols)
def ok(self, row):
for colname in self.cols:
col = self.dm[colname]
context = list(col[row-self.mindist+1:row]) \
+ list(col[row+1:row+self.mindist])
target = col[row]
if target in context:
return False
return True
PK ZMHR pseudorandom/_exceptions.py#-*- coding:utf-8 -*-
"""
This file is part of pseudorandom.
pseudorandom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pseudorandom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pseudorandom. If not, see .
"""
class InvalidConstraint(Exception):
pass
class EnforceFailed(Exception):
pass
PK
~|H#
pseudorandom/_enforce.py#-*- coding:utf-8 -*-
"""
This file is part of pseudorandom.
pseudorandom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pseudorandom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pseudorandom. If not, see .
"""
from datamatrix.py3compat import *
import time
import random
from pseudorandom._exceptions import EnforceFailed
from datamatrix import operations
class Enforce(object):
"""
desc:
A class that enforces a set of constraints by modifying (if necessary)
the DataMatrix.
"""
def __init__(self, dm):
"""
desc:
Constructor.
arguments:
dm:
desc: The data.
type: DataMatrix
"""
self.dm = dm[:]
self.constraints = []
self.report = None
def add_constraint(self, constraint, **kwargs):
"""
desc:
Adds a constraint to enforce.
arguments:
constraint:
desc: A constraint class. Note, the class itself should be
passed, not an instance of the class.
type: type
keyword-dict:
kwargs: The keyword arguments that are passed to the constraint
constructor.
"""
self.constraints.append(constraint(self, **kwargs))
def _enforce(self, reverse=False):
redo = False
_range = range(len(self.dm))
if reverse:
_range = reversed(_range)
for row in _range:
if not self.ok(row):
redo = True
if reverse:
heaprange = list(range(row+1, len(self.dm)))
else:
heaprange = list(range(row))
random.shuffle(heaprange)
for heaprow in heaprange:
_dm = self.dm[:]
for name, col in self.dm.columns:
col[row, heaprow] = col[heaprow, row]
if self.ok(row):
break
self.dm = _dm
return redo
def enforce(self, maxreshuffle=100, maxpass=100):
"""
desc:
Enforces constraints.
keywords:
maxpass:
desc: The maximum number of times that the enforce algorithm
may be restarted.
type: int
returns:
desc: A `DataMatrix` that respects the constraints.
type: DataMatrix
"""
t0 = time.time()
reverse = False
for i in range(maxreshuffle):
self.dm = operations.shuffle(self.dm)
for j in range(maxpass):
if not self._enforce(reverse=reverse):
break
reverse = not reverse
else:
# If the maximum passes were exhausted, restart the loop
continue
# If the maximum passes were not exhausted, we are done
break
else:
raise EnforceFailed(
u'Failed to enforce constraints (maxreshuffle = %d)' \
% maxreshuffle)
t1 = time.time()
self.report = {
u'time' : t1-t0,
u'reshuffle' : i+1,
}
return self.dm
def ok(self, row):
return all([constraint.ok(row) for constraint in self.constraints])
PK W|H.^e e pseudorandom/__init__.py#-*- coding:utf-8 -*-
"""
This file is part of pseudorandom.
pseudorandom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pseudorandom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pseudorandom. If not, see .
"""
__version__ = u'0.2.2'
from pseudorandom._enforce import Enforce
from pseudorandom._constraint import MaxRep, MinDist
from pseudorandom._exceptions import EnforceFailed, InvalidConstraint
PK u|H^-
3 python_pseudorandom-0.2.2.dist-info/DESCRIPTION.rstUNKNOWN
PK u|Hk[#Z Z 1 python_pseudorandom-0.2.2.dist-info/metadata.json{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Topic :: Scientific/Engineering", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3"], "extensions": {"python.details": {"contacts": [{"email": "s.mathot@cogsci.nl", "name": "Sebastiaan Mathot", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/smathot/python-random"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "license": "GNU GPL Version 3", "metadata_version": "2.0", "name": "python-pseudorandom", "run_requires": [{"requires": ["python-datamatrix"]}], "summary": "A Python library for generating pseudorandom condition/ stimulus lists for psychological experiments", "version": "0.2.2"}PK u|Hw
1 python_pseudorandom-0.2.2.dist-info/top_level.txtpseudorandom
PK u|Hndn n ) python_pseudorandom-0.2.2.dist-info/WHEELWheel-Version: 1.0
Generator: bdist_wheel (0.26.0)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any
PK u|H{ , python_pseudorandom-0.2.2.dist-info/METADATAMetadata-Version: 2.0
Name: python-pseudorandom
Version: 0.2.2
Summary: A Python library for generating pseudorandom condition/ stimulus lists for psychological experiments
Home-page: https://github.com/smathot/python-random
Author: Sebastiaan Mathot
Author-email: s.mathot@cogsci.nl
License: GNU GPL Version 3
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Requires-Dist: python-datamatrix
UNKNOWN
PK u|H^:x * python_pseudorandom-0.2.2.dist-info/RECORDpseudorandom/__init__.py,sha256=Fq6ZSSnEvwv3REoqc6_Ut84-g492wheKyyANQucl6uY,869
pseudorandom/_constraint.py,sha256=O_0VSUvS175SSQv8TXN79Ed129P5ywdTv3X6BxC4tMI,2806
pseudorandom/_enforce.py,sha256=sMzR3VnSEchMZkZHFCeoIlDVS0ccUKryS0QWGTvgjuw,3082
pseudorandom/_exceptions.py,sha256=z08lo9e4LOFPKR4W_40kVImOQFSVcNLa7yeF-bGx5zk,761
python_pseudorandom-0.2.2.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10
python_pseudorandom-0.2.2.dist-info/METADATA,sha256=6SwxRlWiX48ClsJ4ijkH1zVYUlVZbTxzFItwvdXx0aU,683
python_pseudorandom-0.2.2.dist-info/RECORD,,
python_pseudorandom-0.2.2.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110
python_pseudorandom-0.2.2.dist-info/metadata.json,sha256=BCZdTKrf7Ns5TpzdxI9WG_idRElfq0RueyxQtMgp5EA,858
python_pseudorandom-0.2.2.dist-info/top_level.txt,sha256=uO2YX0v5jC_eRsgHGBchNTjwcIllRfDlntjNs9WTSj0,13
PK ~|HC
pseudorandom/_constraint.pyPK ZMHR / pseudorandom/_exceptions.pyPK
~|H#
a pseudorandom/_enforce.pyPK W|H.^e e pseudorandom/__init__.pyPK u|H^-
3 < python_pseudorandom-0.2.2.dist-info/DESCRIPTION.rstPK u|Hk[#Z Z 1 python_pseudorandom-0.2.2.dist-info/metadata.jsonPK u|Hw
1 @" python_pseudorandom-0.2.2.dist-info/top_level.txtPK u|Hndn n ) " python_pseudorandom-0.2.2.dist-info/WHEELPK u|H{ , Q# python_pseudorandom-0.2.2.dist-info/METADATAPK u|H^:x * F&