Основната ви цел е да напишете функция със следните име и аргументи: module_game(m1, m2).
Входни данни: m1 и m2 са модули.
Резултат: n-торка с 2 елемента, с броя на точките събрали първия и втория модул при играта, която е описана по-долу в условието.
Предварително известни факти:
{} {'baba': 5} {'a': 42, 'b': -69, 'x': 4360000634}[] [()] [(1023, 4095, 8191), (), (), (0, 17), (3,)]Правила на играта:
За атрибути по-надолу ще смятаме само тези реални атрибути на модулите, които не започват с _ (долна черта, подчертавка)
Всеки модул получава 1 точка за всяка функция в него, чието име започва с последните 3 символа на друга функция в същия модул. Ето пример за част от модул, която ни гарантира две точки по този параграф:
s = "baba"
def destroy(x, y):
print "Destroyed."
return 0
def roy_keen(x, y):
print "Babyboy."
return 0
def roy_boss(x, y):
print "Holy-shmolly, that is tea!"
return 0
Всеки модул получава 1 точка, за всеки списък в него, за който средното-аритметично на сумите от квадратите на n-орките в него е по-голямо от средно-аритметичното на всички цели числа в другия модул. Ако някоя n-торка е празна, нейната сума може да се смята за 0. Ако един списък е празен, неговото аритметично също може да се смята за 0.
Пример: имаме списъка [(1, 2), (), (8, -2), (-1, 5, -1)]. Сумите на квадратите на n-торките са съответно: 5, 0, 68, 27. Средното им аритметично е точно 25.
По 1 точка получава модул, за всяка функция в него, която удовлетворява следните условия:
Пример за такава функция: def f(x, y): return x*y
3 точки носи на модул всеки речник, за който:
Пример за такъв речник: {'Chapman': 11, 'Charlie': 99, 'GILLIAM': 102, 'Idle': 666, 'Jones': 883, 'Palin': 55, 'Cleese': 1101}
def module_game(m1, m2):
return (assess(m1, m2), assess(m2, m1))
def assess(mod, mod_other):
return sum((
end3_funcs(mod),
avg_lists(mod, mod_other),
commutatives(mod),
3*monty_python_dicts(mod),
))
def valid_attributes(mod):s
return (attr for attr in dir(mod) if not attr.startswith('_'))
sum приема последователност и му даваме n-торка: sum((valid_attributes няма нужда да връща списък, може да ползваме generator expressiondef end3_funcs(mod):
func_names = [attr for attr in valid_attributes(mod) if callable(getattr(mod, attr))]
count = 0
for func in func_names:
if len(func) < 3: continue
start = func[:3]
if any((otherfunc.endswith(start) for otherfunc in func_names if func != otherfunc)):
count += 1
return count
func_names е списък (или „за влагането на генератори“)?any?g = (x*x for x in xrange(4))
for a in g:
for b in g:
print (a, b)
(0, 1)
(0, 4)
(0, 9)
g.next() във външния цикъл, a, става 0g.next() във вътрешния циъкл, b, става 1g.next() във вътрешния циъкл, b, става 4g.next() във вътрешния циъкл, b, става 9g = [x for x in xrange(4)]g = (x*x for x in xrange(4))
g_inner = (x*x for x in xrange(4))for a in (x*x for x in xrange(4)):
for b in (x*x for x in xrange(4)):
print (a, b)def gen_sq(n):
for x in xrange(n):
yield x*xdef gen_sq2(n):
return (x*x for x in xrange(n))def avg_lists(mod, other):
other_ints = [getattr(other, attr) for attr in valid_attributes(other)
if isinstance(getattr(other, attr), (int, long))]
other_sum, other_len = sum(other_ints), len(other_ints)
mod_lists = (getattr(mod, attr) for attr in valid_attributes(mod)
if isinstance(getattr(mod, attr), list))
count = 0
square = lambda x: x*x
for l in mod_lists:
jingled_items = [sum(imap(square, tup)) for tup in l]
jingled_sum, jingled_len = sum(jingled_items), len(jingled_items)
# don't use floats
# we know that always both the sum and the len are non-negative
# except that other_sum could be negative
if jingled_sum > 0 and 0 == other_len:
count += 1
elif jingled_len == 0 and other_sum < 0:
count += 1
elif jingled_sum*other_len > jingled_len*other_sum:
count += 1
return count
def commutatives(mod):
# този път ф-ии--не имена
funcs = [getattr(mod, attr) for attr in valid_attributes(mod)
if callable(getattr(mod, attr))]
count = 0
for func in funcs:
if func(0,0) == 0 and\
all((func(i, j) == func(j, i)
for i in xrange(0, 99) for j in xrange(i+1, 100))):
count += 1
return count
def commutatives(mod):
# този път ф-ии--не имена
funcs = [getattr(mod, attr) for attr in valid_attributes(mod)
if callable(getattr(mod, attr))]
count = 0
for func in funcs:
point_commutative = ( func(i, j) == func(j, i)
for i in xrange(0, 99) for j in xrange(i+1, 100))
if func(0,0) == 0 and\
all(point_commutative):
count += 1
return count
any(iterable) — връща истина, ако поне един от елементите на iterable е истина.all(iterable) — връща истина, ако всички елементи на iterable са истина.>>>people = ('God', 'Monty', 'Pinkie', 'Mityo')
>>>wannaplay = lambda name: 'x' in name
>>>friends = lambda x,y: x[0] == y[0] and x != y
>>>capitalised = lambda x: x[0].isupper()
>>>print any(map(wannaplay, people))
False # Nobody wants to play
>>>print any([friends(name, 'Mityo') for name in people])
True # Monty
>>>print all(imap(capitalised, people))
True
>>>print all((friends(name, 'Mityo') for name in people))
False
def monty_python_dicts(mod):
WANTED = set(['chapman', 'cleese', 'gilliam', 'idle', 'jones', 'palin'])
dicts = [getattr(mod, attr) for attr in valid_attributes(mod) if isinstance(getattr(mod, attr), dict)]
count = 0
def make_strange_cmp(dict_):
def strange_cmp(x, y):
x, y = dict_[x], dict_[y]
sx, sy = str(sx).lstrip('-'), str(sx).lstrip('-')
if (len(sx) != len(sy)):
return cmp(len(sx), len(sy))
return cmp(math.tan(math.radians(x)), math.tan(math.radians(y)))
for d in dicts:
ordered = sorted(d, cmp=make_strange_cmp(d), reverse=True)
if set(imap(string.lower, ordered[:6])) == WANTED:
count += 1
return count
def monty_python_dicts(mod):
WANTED = set(['chapman', 'cleese', 'gilliam', 'idle', 'jones', 'palin'])
dicts = [getattr(mod, attr) for attr in valid_attributes(mod)
if isinstance(getattr(mod, attr), dict)]
count = 0
# DSU, DSU
def make_decorate(dict_):
def decorate(key):
value = dict_[key]
svalue = str(value).lstrip('-')
return (len(svalue), math.tan(math.radians(value)))
return decorate
for d in dicts:
ordered = sorted(d, key=make_decorate(d), reverse=True)
if set(imap(string.lower, ordered[:6])) == WANTED:
count += 1
return count
names = ['Monty Python', 'Bilbo Baggins', 'Mityo Python']
# 2 пъти split
# цялото се вика n*log(n) пъти
def names_cmp(n1, n2):
first1, last1 = n1.split()
first2, last2 = n2.split()
if last1 != last2:
return cmp(last1, last2)
else:
return cmp(first1, first2)
names.sort(names_cmp)
# (('Python', 'Monty'), 'Monty Python')
decorated = zip([tuple(reversed(name.split())) for name in names], names)
decorated.sort()
undecorated = [value for (decor, value) in decorated]
print undecorated
['Bilbo Baggins', 'Mityo Python', 'Monty Python']
zip взима няколко списъка и връща списък от n-орки с поредните елементи на списъцитеready = sorted(names, key = lambda name: tuple(reversed(name.split())))
или:
def decorate(name):
first, last = name.split()
return last, first
ready = sorted(names, key = decorate)
key параметъра на sort и sortedkey очаква функция с един аргумент и сортира по нейната стойност, а не по стойността на елементите на поредицатаkey