PKZMHYiH 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 PKZMHR 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 PKZMH\? ? 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 {HBeepseudorandom/__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.1' from pseudorandom._enforce import Enforce from pseudorandom._constraint import MaxRep, MinDist from pseudorandom._exceptions import EnforceFailed, InvalidConstraint PK{H^- 3python_pseudorandom-0.2.1.dist-info/DESCRIPTION.rstUNKNOWN PK{H!ZZ1python_pseudorandom-0.2.1.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.1"}PK{Hw 1python_pseudorandom-0.2.1.dist-info/top_level.txtpseudorandom PK{Hndnn)python_pseudorandom-0.2.1.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{H{G,python_pseudorandom-0.2.1.dist-info/METADATAMetadata-Version: 2.0 Name: python-pseudorandom Version: 0.2.1 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{HqY*python_pseudorandom-0.2.1.dist-info/RECORDpseudorandom/__init__.py,sha256=qidlk29CK69aL_Q9lydFUbnRsCy-8AB_4HG4WKo813o,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.1.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 python_pseudorandom-0.2.1.dist-info/METADATA,sha256=cygOrUNKW6jdMZQuThbBlneBrG4j3CDGI17ELhp3gz0,683 python_pseudorandom-0.2.1.dist-info/RECORD,, python_pseudorandom-0.2.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 python_pseudorandom-0.2.1.dist-info/metadata.json,sha256=anvapkYjJGF4rP_GzZC7eKNw8eXTpp60WaOJPnMljXI,858 python_pseudorandom-0.2.1.dist-info/top_level.txt,sha256=uO2YX0v5jC_eRsgHGBchNTjwcIllRfDlntjNs9WTSj0,13 PKZMHYiH H pseudorandom/_constraint.pyPKZMHR  pseudorandom/_exceptions.pyPKZMH\? ?  pseudorandom/_enforce.pyPK {HBee(pseudorandom/__init__.pyPK{H^- 3python_pseudorandom-0.2.1.dist-info/DESCRIPTION.rstPK{H!ZZ1python_pseudorandom-0.2.1.dist-info/metadata.jsonPK{Hw 1!python_pseudorandom-0.2.1.dist-info/top_level.txtPK{Hndnn)#"python_pseudorandom-0.2.1.dist-info/WHEELPK{H{G,"python_pseudorandom-0.2.1.dist-info/METADATAPK{HqY*%python_pseudorandom-0.2.1.dist-info/RECORDPK F)