Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3 (with tests) #161

Merged
merged 6 commits into from
May 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Container-based builds used if "sudo: false" --> fast boot (1-6s)
# https://docs.travis-ci.com/user/ci-environment/
sudo: false
dist: trusty

language: python
python:
- "2.7"
- "3.4"
- "3.5"

env:
matrix:
- DJANGO="1.8"
- DJANGO="1.9"
- DJANGO="1.10"
- DJANGO="1.11"

matrix:
include:
# The Django 1.8 series is the last to support Python 3.2 and 3.3.
- python: "3.3"
env: DJANGO="1.8"
# Django 1.11 is the first release to support Python 3.6.
- python: "3.6"
env: DJANGO="1.11"

services:
- redis-server

install:
- pip install tox

script:
- tox -vvvv -e $( echo $TRAVIS_PYTHON_VERSION | sed -e 's/^2\./py2/' -e 's/^3\./py3/' )-django${DJANGO}
3 changes: 3 additions & 0 deletions experiments/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class LazyAutoCreate(object):
A lazy version of the setting is used so that tests can change the setting and still work
"""
def __nonzero__(self):
return self.__bool__()

def __bool__(self):
return getattr(settings, 'EXPERIMENTS_AUTO_CREATE', True)


Expand Down
6 changes: 3 additions & 3 deletions experiments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ def ensure_alternative_exists(self, alternative, weight=None):

@property
def default_alternative(self):
for alternative, alternative_conf in self.alternatives.iteritems():
for alternative, alternative_conf in self.alternatives.items():
if alternative_conf.get('default'):
return alternative
return conf.CONTROL_GROUP

def set_default_alternative(self, alternative):
for alternative_name, alternative_conf in self.alternatives.iteritems():
for alternative_name, alternative_conf in self.alternatives.items():
if alternative_name == alternative:
alternative_conf['default'] = True
elif 'default' in alternative_conf:
Expand All @@ -81,7 +81,7 @@ def random_alternative(self):
if all('weight' in alt for alt in self.alternatives.values()):
return weighted_choice([(name, details['weight']) for name, details in self.alternatives.items()])
else:
return random.choice(self.alternatives.keys())
return random.choice(list(self.alternatives))

def __unicode__(self):
return self.name
Expand Down
14 changes: 7 additions & 7 deletions experiments/significance.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def mann_whitney(a_distribution, b_distribution, use_continuity=True):
"""Returns (u, p_value)"""
MINIMUM_VALUES = 20

all_values = sorted(set(a_distribution.keys() + b_distribution.keys()))
all_values = sorted(set(a_distribution) | set(b_distribution))

count_so_far = 0
a_rank_sum = 0
Expand Down Expand Up @@ -61,24 +61,24 @@ def mann_whitney(a_distribution, b_distribution, use_continuity=True):
def chi_square_p_value(matrix):
"""
Accepts a matrix (an array of arrays, where each child array represents a row)

Example from http://math.hws.edu/javamath/ryan/ChiSquare.html:

Suppose you conducted a drug trial on a group of animals and you
hypothesized that the animals receiving the drug would survive better than
those that did not receive the drug. You conduct the study and collect the
following data:

Ho: The survival of the animals is independent of drug treatment.

Ha: The survival of the animals is associated with drug treatment.

In that case, your matrix should be:
[
[ Survivors in Test, Dead in Test ],
[ Survivors in Control, Dead in Control ]
]

Code adapted from http://codecomments.wordpress.com/2008/02/13/computing-chi-squared-p-value-from-contingency-table-in-python/
"""
try:
Expand Down
2 changes: 1 addition & 1 deletion experiments/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_set_alternative(self):
'experiment': experiment.name,
'alternative': alternative,
})
self.assertDictEqual(json.loads(response.content), {
self.assertDictEqual(json.loads(response.content.decode('utf-8')), {
'success': True,
'alternative': alternative,
})
Expand Down
4 changes: 2 additions & 2 deletions experiments/tests/test_significance.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def test_is_none(self):
def test_stress(self):
# Generate a large matrix
matrix = []
for col in xrange(0, 100):
for col in range(0, 100):
matrix.append([])
for row in xrange(0, 100):
for row in range(0, 100):
matrix[col].append(random.randint(0, 10))

self.assertIsNotNone(chi_square_p_value(matrix))
Expand Down
2 changes: 1 addition & 1 deletion experiments/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ def _is_verified_human(self):
def _get_all_enrollments(self):
enrollments = self.session.get('experiments_enrollments', None)
if enrollments:
for experiment_name, data in enrollments.items():
for experiment_name, data in list(enrollments.items()):
alternative, _, enrollment_date, last_seen = _session_enrollment_latest_version(data)
experiment = experiment_manager.get_experiment(experiment_name)
if experiment:
Expand Down
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
include_package_data=True,
license='MIT',
install_requires=[
'django>=1.7.0',
'django>=1.8',
'django-modeldict-yplan>=1.5.0',
'jsonfield>=1.0.3',
'redis>=2.4.9',
Expand All @@ -36,11 +36,14 @@
'License :: OSI Approved :: MIT License',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries',
'Programming Language :: Python :: 2 :: Only',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Framework :: Django',
'Framework :: Django :: 1.7',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10',
Expand Down
53 changes: 42 additions & 11 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,16 +1,47 @@
# Tox (http://tox.testrun.org/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.


[tox]
# Python 3 isn't supported yet
# require tox>=2.7 or refuse to run the tests.
minversion=2.7

# return success even if some of the specified environments are missing
skip_missing_interpreters=True

# The Django 1.8 series is the last to support Python 3.2 and 3.3.
# Django 1.11 is the first release to support Python 3.6.
# Due to the end of upstream support for Python 3.2 in February 2016, we won’t
# test Django 1.8.x on Python 3.2 after the end of 2016.
envlist =
py27-django{18,19,110,111}
# py32-django{18}
# py33-django{18}
# py{34,35}-django{19,110,111}
# py{36}-django{111}
py27-django{1.8,1.9,1.10,1.11}
py33-django{1.8}
py34-django{1.8,1.9,1.10,1.11}
py35-django{1.8,1.9,1.10,1.11}
py36-django{1.11}
pypy-django{1.8,1.9,1.10,1.11}

[testenv]
commands = python setup.py test
recreate=True
usedevelop=False
passenv=
BUILD_NUMBER
BUILD_URL
XDG_CACHE_HOME

# continue running commands even if previous commands have failed (ie: always produce coverage report)
ignore_errors = True

commands =
coverage erase
coverage run --branch --source={toxinidir}/experiments setup.py test
coverage report

deps =
django18: Django>=1.8,<1.9
django19: Django>=1.9,<1.10
django110: Django>=1.10,<1.11
django111: Django>=1.11,<2.0
coverage
django1.8: Django>=1.8,<1.9
django1.9: Django>=1.9,<1.10
django1.10: Django>=1.10,<1.11
django1.11: Django>=1.11,<2.0