-
-
Save julen/5905d6c311038cf4c0bd257431f88965 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Leire | |
Ander | |
Jon | |
Ane | |
Maite | |
Josu | |
Ane | |
Nerea | |
Ane A. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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()]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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