Skip to content

Instantly share code, notes, and snippets.

@julen
Last active November 30, 2016 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julen/5905d6c311038cf4c0bd257431f88965 to your computer and use it in GitHub Desktop.
Save julen/5905d6c311038cf4c0bd257431f88965 to your computer and use it in GitHub Desktop.
Leire
Ander
Jon
Ane
Maite
Josu
Ane
Nerea
Ane A.
# -*- coding: utf-8 -*-
import random
class NoFriendsLeft(Exception):
pass
def choose_friend(name, friends):
"""Makes a choice out of `friends`, leaving `name` aside.
:param name: string
:param friends: set
:return: string
"""
available = friends - set([name])
if len(available) == 0:
raise NoFriendsLeft
return random.choice(list(available))
def get_friend_pairs(names):
"""Returns a list of friend pairs (tuples), randomly chosen out of the pool
of `names`.
:param names: list of friends :)
:return: list of tuples which reflect the random friend pairings.
"""
# Filter out non-strings and repeated names
friends = set([name for name in names if isinstance(name, basestring)])
if not friends:
return None
if len(friends) < 2:
return None
pairs = []
choices = friends
for name in list(friends):
try:
choice = choose_friend(name, choices)
except NoFriendsLeft:
return get_friend_pairs(names) # Retry
choices.remove(choice)
pairs.append((name, choice))
return pairs
# -*- coding: utf-8 -*-
class Table(object):
underline = '='
def __init__(self, columns, rows, *args, **kwargs):
self.columns = columns
self.rows = rows
self.column_width = 15
def get_column(self, value, is_last=False):
if is_last:
return value
return ''.join([value, (self.column_width - len(value)) * ' '])
def get_header(self):
header = []
for i, column in enumerate(self.columns):
is_last_column = i == len(self.columns) - 1;
header.append(self.get_column(column, is_last=is_last_column))
header.append('\n')
header.append((self.column_width * i + len(column)) * self.underline)
return ''.join(header)
def get_body(self):
rows = []
for row in self.rows:
rows.append('\n')
rows.append(''.join([self.get_column(column) for column in row]))
return ''.join(rows)
def render(self):
return ''.join([self.get_header(), self.get_body()])
# -*- coding: utf-8 -*-
import pytest
from secret_santa import NoFriendsLeft, choose_friend, get_friend_pairs
@pytest.mark.parametrize('name, friends', (
('foo', set(['foo'])),
('foo', set()),
))
def test_choose_friend_unavailable(name, friends):
"""Tests choice cannot be done for self or from empty choices."""
with pytest.raises(NoFriendsLeft):
choose_friend(name, friends)
def test_choose_friend():
"""Tests friend's choice is not for self."""
choice = choose_friend('foo', set(['foo', 'bar', 'baz', 'blah']))
assert choice != 'foo'
choice = choose_friend('foo', set(['foo', 'bar']))
assert choice == 'bar'
@pytest.mark.parametrize('names', (
[],
[None],
[1, 2, 3, 4],
['foo'],
))
def test_get_friend_pairs_invalid_input(names):
assert get_friend_pairs(names) is None
def test_get_friend_pairs_repeated_friends():
"""Tests repeated friends are ignored."""
friends = ['foo', 'bar', 'foo', 'bar', 'baz', 'blah']
pairs = get_friend_pairs(friends)
assert len(pairs) == 4
def test_get_friend_pairs_no_repeated_names():
"""Tests no repeated names are in the output, i.e. input names and output
names match.
"""
friends = ['foo', 'bar', 'baz', 'blah']
pairs = get_friend_pairs(friends)
pairs_dict = dict(pairs)
assert sorted(pairs_dict.keys()) == sorted(pairs_dict.values())
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from secret_santa import get_friend_pairs
from table import Table
FILENAME = 'kuadrilla.txt'
MSG_FILE_ERROR = '[E!] Ezin da "%s" fitxategia ireki'
MSG_FRIENDS_ERROR = '[E!] Lagun nahikorik ez!'
TITLE_FROM = 'Nork'
TITLE_TO = 'Nori'
if __name__ == '__main__':
filename = sys.argv[1] if len(sys.argv) == 2 else FILENAME
try:
names_list = [name.rstrip() for name in open(filename)]
except IOError:
print(MSG_FILE_ERROR % filename)
sys.exit(-1)
name_pairs = get_friend_pairs(names_list)
if name_pairs is None:
print(MSG_FRIENDS_ERROR)
sys.exit(-1)
table = Table(columns=(TITLE_FROM, TITLE_TO), rows=name_pairs)
print(table.render())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment