PK ZMHYiH
H
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
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
else:
self.cols = [name for name, col in self.dm.columns if col in cols]
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 ZMH\? ? 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:
import copy
# _dm = copy.deepcopy(self.dm)
_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 PHLde 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.0'
from pseudorandom._enforce import Enforce
from pseudorandom._constraint import MaxRep, MinDist
from pseudorandom._exceptions import EnforceFailed, InvalidConstraint
PK exH^-
3 python_pseudorandom-0.2.0.dist-info/DESCRIPTION.rstUNKNOWN
PK exHr?_ _ 1 python_pseudorandom-0.2.0.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 Math\u00f4t", "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.0"}PK exHw
1 python_pseudorandom-0.2.0.dist-info/top_level.txtpseudorandom
PK exHndn n ) python_pseudorandom-0.2.0.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 exHLj , python_pseudorandom-0.2.0.dist-info/METADATAMetadata-Version: 2.0
Name: python-pseudorandom
Version: 0.2.0
Summary: A Python library for generating pseudorandom condition/ stimulus lists for psychological experiments
Home-page: https://github.com/smathot/python-random
Author: Sebastiaan Mathôt
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 exH * python_pseudorandom-0.2.0.dist-info/RECORDpseudorandom/__init__.py,sha256=wXl_BpsQT-m9QUMuB39_qUbYj5JzU6B7BD9pTiKZBLk,869
pseudorandom/_constraint.py,sha256=yAPpWRmmpcVDunGXgfIXmjMKO9l5sGXUPSXrA8USYBM,2632
pseudorandom/_enforce.py,sha256=x8gJYcKUvuv4tynYwDb8NmzUEgwenGI506vaWa0r52I,3135
pseudorandom/_exceptions.py,sha256=z08lo9e4LOFPKR4W_40kVImOQFSVcNLa7yeF-bGx5zk,761
python_pseudorandom-0.2.0.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10
python_pseudorandom-0.2.0.dist-info/METADATA,sha256=x6ih2RseOjYkNQdB943pnrXKcsIKjdQv14AQV-eGJSk,684
python_pseudorandom-0.2.0.dist-info/RECORD,,
python_pseudorandom-0.2.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110
python_pseudorandom-0.2.0.dist-info/metadata.json,sha256=64DG88aAA_Uah2LvSNzt9pE6RMjMQaV8Xaoe_BPd51w,863
python_pseudorandom-0.2.0.dist-info/top_level.txt,sha256=uO2YX0v5jC_eRsgHGBchNTjwcIllRfDlntjNs9WTSj0,13
PK ZMHYiH
H
pseudorandom/_constraint.pyPK ZMHR
pseudorandom/_exceptions.pyPK ZMH\? ?
pseudorandom/_enforce.pyPK PHLde e ( pseudorandom/__init__.pyPK exH^-
3 python_pseudorandom-0.2.0.dist-info/DESCRIPTION.rstPK exHr?_ _ 1 python_pseudorandom-0.2.0.dist-info/metadata.jsonPK exHw
1 ! python_pseudorandom-0.2.0.dist-info/top_level.txtPK exHndn n ) (" python_pseudorandom-0.2.0.dist-info/WHEELPK exHLj , " python_pseudorandom-0.2.0.dist-info/METADATAPK exH * % python_pseudorandom-0.2.0.dist-info/RECORDPK
F )