<jupyter_start><jupyter_text>Анализ данных на Python Семинар 6. Множества и словари. Задачи.<jupyter_code>mySet = set()
myDict = dict()
myList = [1, 1, 1, 2, 3]
set(myList)
s = 'ab' # неизменяемый тип
s[1] = 'c'
myTuple = (1, 2, 3)
myTuple[1] = 3
15
d = {1: 'abc', (2, 3): 1, 'key': [1, 2, 3]}
d[1]
d[(2, 3)]
d['key']
d.values()
d.keys()
d.items()
d = {1: {'a': 1, 'b':2}}
d[1]
d[1]['b']
def test_problem(func, test_data):
    for inputs, true_answer in test_data:
        answer = func(inputs)
        assert answer == true_answer, f'Expected {true_answer}, got {answer}. Input: {inputs}'
    print("OK!")
    
def test_problem_13(func, test_data):
    for inputs, true_answer in test_data:
        answer = func(*inputs)
        assert answer == true_answer, f'Expected {true_answer}, got {answer}. Input: {inputs}'
    print("OK!")<jupyter_output><empty_output><jupyter_text>Задачка 1: магазинВам предостоит обработать базу данных о продажах некоторого интернет-магазина. База данных представляет собой набор кортежей, в каждом кортеже три элемента: (Покупатель, товар, количество), где Покупатель — имя покупателя (строка без пробелов), товар — название товара (строка без пробелов), количество — количество приобретенных единиц товара.Создайте словарь, ключами которого являются имена покупателей, а значениями — словари, ключами которых являются названия товаров, а значениями — количество единиц этого товара, которые купил этот покупатель.Напишите функцию aggregate, принимающую некоторое количество набор кортежей из базы данных и возвращающую сводную информацию в виде словаря.<jupyter_code>input_ = [("Petrov","pens",5), ("Petrov","pens",6), ("Ivanov","marker",3), ("Ivanov","paper",7), 
      ("Petrov","envelope",20), ("Ivanov","envelope",5)]
from collections import defaultdict

dd = defaultdict(dict)
dd["Petrov"]['pens']= 5
dd
d1 = {}
d1['Petrov']['pens'] = 5
d1
dd = defaultdict(dict)

for name, item, num in input_:
    if item in dd[name]:
        dd[name][item] += num
    else:
        dd[name][item] = num
dd
d = {}

for tup in input_:
    if tup[0] in d:
        if tup[1] in d[tup[0]]:
            d[tup[0]][tup[1]] += tup[2]
        else:
            d[tup[0]][tup[1]] = tup[2]
    else:
        d[tup[0]] = {}
        d[tup[0]][tup[1]] = tup[2]
d
'Ivanov' in d
'Petrov' in d
'Sidorov' in d
def aggregate(names):
    d = {}

    for tup in names:
        if tup[0] in d:
            if tup[1] in d[tup[0]]:
                d[tup[0]][tup[1]] += tup[2]
            else:
                d[tup[0]][tup[1]] = tup[2]
        else:
            d[tup[0]] = {}
            d[tup[0]][tup[1]] = tup[2]
    return d
AGG_TESTS_DATA = [
    ([("Petrov","pens",5), ("Ivanov","marker",3), ("Ivanov","paper",7), 
      ("Petrov","envelope",20), ("Ivanov","envelope",5)], 
     {'Petrov': {'pens': 5, 'envelope': 20}, 
      'Ivanov': {'marker': 3, 'paper': 7, 'envelope': 5}}),
    
    ([("Ivanov","aaa",1), ("Petrov","aaa",2), ("Sidorov","aaa",3), ("Ivanov","aaa",6), 
      ("Petrov","aaa",7), ("Sidorov","aaa",8), ("Ivanov","bbb",3), ("Petrov","bbb",7), 
      ("Sidorov","aaa",345), ("Ivanov","ccc",45), ("Petrov","ddd",34), 
      ("Ziborov","eee",234), ("Ivanov","aaa",45)],
    {'Ivanov': {'aaa': 52, 'bbb': 3, 'ccc': 45},
     'Petrov': {'aaa': 9, 'bbb': 7, 'ddd': 34},
     'Sidorov': {'aaa': 356},
     'Ziborov': {'eee': 234}})
]
test_problem(aggregate, AGG_TESTS_DATA)<jupyter_output>OK!<jupyter_text>Задачка 2: одинаковые строкиНапишите функцию, которая приенимает на вход две строки и возвращает True, если перестановкой символов можно получить вторую строку из первой.```s1 = 'aab's2 = 'ab```<jupyter_code>s1, s2 = ('foo', 'oof')
s3, s4 = ('aab', 'ab')
s1
s2
# решение 1
set(s1) == set(s2)
# решение 2
sorted(list(s1)) == sorted(list(s2))
sorted(list(s3)) == sorted(list(s4))
sorted(list(s2))
# решение 3
from collections import Counter
Counter(s1) == Counter(s2)
Counter(s1)
Counter(s2)
# решение 4
s1
def myCounter(string):
    d = {}
    for letter in string:
        if letter in d:
            d[letter] += 1
        else:
            d[letter] = 1
    return d
myCounter(s1)
myCounter(s2)
myCounter(s1) == myCounter(s2)
def is_isomorphic(a, b):
    if Counter(a) == Counter(b):
        return True
    else:
        return False
TEST_DATA = [
    (('foo', 'bar'), False),
    (('foo', 'oof'), True),
    (('a', 'a'), True),
    (('aaa', 'aaab'), False),
    (('140', '041'), True),
]

test_problem_13(is_isomorphic, TEST_DATA)<jupyter_output>OK!<jupyter_text>Задачка 3. ПарковкаНапишите функцию, которая принимает на вход словарь, где ключом является индекс парковочного места, а значением True/False (занято/свободно). Вторым аргументом функция должна принимать индекс места, которое хочется занять.Функция должна возращать True, если место можно занять и модифицировать словарь, занимая место. Функция возвращает False, если место уже занято.<jupyter_code>def parking_lot(data, index):
    if data[index] == False: # место свободно
        data[index] = True # заняли место
        return True
    else: # место занято
        return False
# PEP8
def parking_lot(data, index):
    if not data[index]: # место свободно
        data[index] = True # заняли место
        return True
    else: # место занято
        return False
if True:
    print('x')
if False:
    print('x')
not False
parking = {0: False, 1: False, 2: False, 3: False}

TEST_DATA = [
    ((parking, 0), True),
    ((parking, 0), False),
    ((parking, 1), True),
    ((parking, 3), True),
]

test_problem_13(parking_lot, TEST_DATA)<jupyter_output>OK!<jupyter_text>Задачка 4. Последовательность ДНК.Последовательность ДНК содержит четыре вида символов: 'A', 'C', 'G', и 'T'.Напишите функцию, которая будет возращать все подпоследовательности длины 10, которые встретились чаще одного раза.<jupyter_code>s = 'AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT'
len(s) - 10 + 1
d = {} # ключи – подпоследовательности длины 10, значения – сколько раз она встретилась
for i in range(len(s) - 10 + 1):
    if s[i:i+10] in d:
        d[s[i:i+10]] += 1
    else:
        d[s[i:i+10]] = 1
# решение через цикл
answer = []
for k, v in d.items():
    if v > 1:
        answer.append(k)
# решение через dictionary comprehension
{k:v for k, v in d.items() if v > 1}
{k:v for k, v in d.items() if v > 1}.keys()
answer
[int(x) for x in input().split() if int(x) % 2 == 0]
d.items()
d
def repeated_dna(s):
    d = {} # ключи – подпоследовательности длины 10, значения – сколько раз она встретилась
    for i in range(len(s) - 10 + 1):
        if s[i:i+10] in d:
            d[s[i:i+10]] += 1
        else:
            d[s[i:i+10]] = 1
            
    filtered_dict = {k:v for k, v in d.items() if v > 1}
    return list(filtered_dict.keys())
TEST_DATA = [
    ('AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT', ['AAAAACCCCC','CCCCCAAAAA']),
    ('AAAAAAAAAAAAA', ['AAAAAAAAAA']),
]

test_problem(repeated_dna, TEST_DATA)<jupyter_output>OK!
{'fraction_non_alphanumeric': 0.17034242600116076, 'fraction_numerical': 0.029889727219965176, 'mean_word_length': 3.638627187079408, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '490135', 'license': 'MIT', 'n_tokens_mistral': 2935, 'n_tokens_neox': 3018, 'n_words': 710, 'path': 'sem06_dict/2011_sem06_set_dict.ipynb', 'repo_name': 'hse-econ-data-science/dap_2021_spring', 'size': '6892'}