Skip to content
Closed
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
13 changes: 13 additions & 0 deletions homeworks/homework_02/check_encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# returns file encoding as a string


def check_e(filename):
for enc in ('utf-8', 'utf-16', 'cp1251'):
try:
with open(filename, encoding=enc) as f:
data = f.read(10)
return enc
except (UnicodeDecodeError, UnicodeError):
pass

raise SystemExit
23 changes: 23 additions & 0 deletions homeworks/homework_02/check_format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# returns file format as a string

import json
import csv


def check_f(filename, enc):
try:
with open(filename, encoding=enc) as f:
data = json.load(f)
return 'json'

except json.decoder.JSONDecodeError:
pass

with open(filename, encoding=enc) as f:
data = csv.reader(f, delimiter='\t')
length = -1
for row in data:
if (len(row) != length and length != -1):
raise SystemExit
length = len(row)
return 'tsv'
45 changes: 45 additions & 0 deletions homeworks/homework_02/construct_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# returns list of strings


def draw_table(table):

# find max column lengths
column_lengths = dict.fromkeys([i for i in range(len(table[0]))], -1)
for row in table:
for i in range(len(row)):
if (column_lengths.get(i) and len(row[i]) > column_lengths[i]):
column_lengths[i] = len(row[i])

# form columns
for row in table:
if (table.index(row) != 0):
for i in range(len(row)):
if (i == len(row) - 1): # last column
row[i] = '| ' + ' '*(column_lengths[i] - len(row[i]))\
+ row[i] + ' |'
else: # other columns
row[i] = '| ' + row[i] + ' '*(column_lengths[i] -
len(row[i])) + ' '

else:
for i in range(len(row)):

s = (column_lengths[i] - len(row[i]))//2

if (i == len(row) - 1): # last column first row
if ((column_lengths[i] - len(row[i])) % 2 == 0):
row[i] = '| ' + ' '*s + row[i] + ' '*s + ' |'
else:
row[i] = '| ' + ' '*s + row[i] + ' '*(s+1) + ' |'
else: # other columns first row
if ((column_lengths[i] - len(row[i])) % 2 == 0):
row[i] = '| ' + ' '*s + row[i] + ' '*s + ' '
else:
row[i] = '| ' + ' '*s + row[i] + ' '*(s+1) + ' '

added_symbols = (len(table[0]) - 1) * 5 + 6
table_length = sum(column_lengths.values()) + added_symbols

table.append('-'*table_length)
table.insert(0, '-'*table_length)
return table
22 changes: 21 additions & 1 deletion homeworks/homework_02/fastmerger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# coding: utf-8


from .heap import MaxHeap
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.5б



Expand All @@ -12,4 +13,23 @@ def merge_first_k(list_of_lists, k):
принимает на вход список отсортированных непоубыванию списков и число
на выходе выдает один список длинной k, отсортированных по убыванию
'''
raise NotImplementedError

_list = []
max_list = []

for i in range(len(list_of_lists)):
if (len(list_of_lists[i]) > 0):
_list.append((list_of_lists[i].pop(), i))

max_heap = MaxHeap(_list)

while (k > 0):
if (len(max_heap._heap) == 0):
break
max_list.append(max_heap.extract_maximum())
element, list_index = max_list[-1]
if (len(list_of_lists[list_index]) > 0):
max_heap.add((list_of_lists[list_index].pop(), list_index))
k -= 1

return [element[0] for element in max_list]
44 changes: 39 additions & 5 deletions homeworks/homework_02/heap.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,56 @@
class Heap():

def __init__(self, array):
pass
self._heap = array[:]
self.build_heap()

def add(self, elem_with_priority):
pass
self._heap.append(elem_with_priority)
self.sift_up()

def build_heap(self):
pass
for i in range(len(self._heap)//2, -1, -1):
self.sift_down(i)

def sift_up(self):
i = len(self._heap) - 1
while True:
if (i > 0 and comparator_d(self._heap[i], self._heap[(i-1)//2])):

self._heap[i], self._heap[(i-1)//2] = self._heap[(i-1)//2],\
self._heap[i]
i = (i-1)//2
else:
break

def sift_down(self, element_index):
i = element_index
largest = element_index
if (2*i+1 <= len(self._heap)-1 and comparator_d(self._heap[2*i+1],
self._heap[i])):
largest = 2*i + 1
if (2*i+2 <= len(self._heap)-1 and comparator_d(self._heap[2*i+2],
self._heap[largest])):
largest = 2*i + 2
if (largest != element_index):
self._heap[i], self._heap[largest] = self._heap[largest],\
self._heap[i]
self.sift_down(largest)


class MaxHeap(Heap):

def __init__(self, array):
raise NotImplementedError
super().__init__(array)

def extract_maximum(self):
pass
max_element = None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1,5б

if (len(self._heap) != 0):
max_element = self._heap.pop(0)
if (len(self._heap) != 0):
self._heap.insert(0, self._heap.pop())
self.sift_down(0)
return max_element


def comparator_d(x, y):
Expand Down
31 changes: 28 additions & 3 deletions homeworks/homework_02/table.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
import sys
import check_encoding as ce
import check_format as cf
import withdraw_data as wd
import construct_table as ct

# Ваши импорты

if __name__ == '__main__':
filename = sys.argv[1]
try:
filename = sys.argv[1]
except IndexError:
print('Файл не валиден')
raise SystemExit

# Ваш код
try:
with open(filename, 'rb') as f:
pass
except FileNotFoundError:
print('Файл не валиден')
raise SystemExit

try:

enc = ce.check_e(filename)
frmt = cf.check_f(filename, enc)
data = wd.receive_data(filename, enc, frmt)
table = ct.draw_table(data)

for row in table:
print(''.join(row))

except SystemExit:
print("Формат не валиден")
47 changes: 41 additions & 6 deletions homeworks/homework_02/vkposter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
class VKPoster:

def __init__(self):
raise NotImplementedError
self._posted_posts = {}
self._read_posts = {}
self._followed_for = {}

def user_posted_post(self, user_id: int, post_id: int):
'''
Expand All @@ -19,7 +21,10 @@ def user_posted_post(self, user_id: int, post_id: int):
:param post_id: id поста. Число.
:return: ничего
'''
pass
if (self._posted_posts.get(user_id)):
self._posted_posts[user_id].append(post_id)
else:
self._posted_posts[user_id] = [post_id]

def user_read_post(self, user_id: int, post_id: int):
'''
Expand All @@ -29,7 +34,11 @@ def user_read_post(self, user_id: int, post_id: int):
:param post_id: id поста. Число.
:return: ничего
'''
pass
if (self._read_posts.get(user_id) and post_id
not in self._read_posts.get(user_id)):
self._read_posts[user_id].append(post_id)
elif (not self._read_posts.get(user_id)):
self._read_posts[user_id] = [post_id]

def user_follow_for(self, follower_user_id: int, followee_user_id: int):
'''
Expand All @@ -39,7 +48,10 @@ def user_follow_for(self, follower_user_id: int, followee_user_id: int):
:param followee_user_id: id пользователя. Число.
:return: ничего
'''
pass
if (self._followed_for.get(follower_user_id)):
self._followed_for[follower_user_id].append(followee_user_id)
else:
self._followed_for[follower_user_id] = [followee_user_id]

def get_recent_posts(self, user_id: int, k: int)-> list:
'''
Expand All @@ -50,7 +62,13 @@ def get_recent_posts(self, user_id: int, k: int)-> list:
:return: Список из post_id размером К из свежих постов в
ленте пользователя. list
'''
pass
recent_posts = []

for followee in self._followed_for[user_id]:
if (self._posted_posts.get(followee)):
recent_posts.append(sorted(self._posted_posts[followee]))

return FastSortedListMerger.merge_first_k(recent_posts, k)

def get_most_popular_posts(self, k: int) -> list:
'''
Expand All @@ -60,4 +78,21 @@ def get_most_popular_posts(self, k: int) -> list:
необходимо вывести. Число.
:return: Список из post_id размером К из популярных постов. list
'''
pass
popularity = {}
for user_id in self._read_posts:
for post_id in self._read_posts[user_id]:
if (post_id in popularity):
popularity[post_id] += 1
else:
popularity[post_id] = 1

pop_and_recent = [(value, key) for (key, value) in popularity.items()]

pop_heap = MaxHeap(pop_and_recent)
popular_posts = []
for i in range(k):
if (len(pop_heap._heap) != 0):
popular_posts.append(pop_heap.extract_maximum())
else:
break
return [post[1] for post in popular_posts]
51 changes: 51 additions & 0 deletions homeworks/homework_02/withdraw_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# returns list of lists that should be interpreted as rows of a table

import json
import csv
import copy


def test_data(table):
s = ''
length = -1
for row in table:
if (len(row) != length and length != -1):
raise SystemExit
length = len(row)
l = copy.deepcopy(row)
s += ''.join(l)
if len(s) == 0:
raise SystemExit


def receive_data(filename, enc, frmt):
table = []
if (frmt == 'json'):
with open(filename, encoding=enc) as f:
data = json.load(f)
table_header = []
table_content = []

for column_name in data[0]: # get table header from first dict
table_header.append(column_name)

for content in data: # every row has same header
if list(content.keys()) != table_header:
raise SystemExit

table.append(table_header)
for content in data:
table_content = [value for value in content.values()]
table.append(table_content)
for i in range(len(table)):
for j in range(len(table[i])):
table[i][j] = str(table[i][j])

elif (frmt == 'tsv'):
with open(filename, encoding=enc) as f:
data = csv.reader(f, delimiter='\t')
for row in data:
table.append(row)
test_data(table)

return table