timeit

Програмиране с Python

Курс във Факултета по Математика и Информатика към СУ

Социална мрежа

Предадени решения

Краен срок:
18.04.2016 17:00
Точки:
10

Срокът за предаване на решения е отминал

Нашата социална мрежа ще дава възможност на потребителите в нея да се следят, да бъдат следени и да изпращат съобщения. Колко сложно може да бъде?

Потребител

Всеки потребител представяме като инстанция на класа User с атрибути:

  • full_name: подаден като аргумент по време на инициализация
  • uuid: генериран по време на инциализация с uuid.uuid4

add_post(self, post_content)

Създава нова публикация на потребителя. Максималният размер на публикации, които даден потребител може да пази е 50. При добавяне на 51-вото, трябва да "изчезне" първото. Този метод се предполага да отбележи дата и час на публикуване.

Повече за това какво представлява една публикация след малко.

get_post(self)

Генератор, който yield-ва публикациите на дадено потребител, започвайки от най-старото.

Важно: Този метод НЕ изтрива върната публикациа.

Публикация

Съобщението е инстанция на типа Post с атрибути:

  • author - uuid на изпращача
  • published_at - дата и час на публикуване (Hint: datatime.datetime.now)
  • content - самото съдържание на публикацията

SocialGraph

Това е същината на нашата мрежа. Тя пази информацията за това кои потребители се следят и кои могат да си пишат. Мислете си за нея като за ориентиран граф.

add_user(self, user)

Добавя създаден потребител към социалния граф.

get_user(self, user_uuid)

Връща потребител с подадено user_uuid от социалния граф.

delete_user(self, user_uuid)

Премахва потребител по подадено uuid.

follow(self, follower, followee)

Подадените аргументи са uuid-та на потребители. Потребителят с uuid=follower се отбелязва, че вече следва потребителя с uuid=followee. Ако това вече е така, този метод не трябва да върне грешка.

unfollow(self, follower, followee)

Подадените аргументи са uuid-та на потребители. Потребителят с uuid=follower се отбелязва, че вече не следва потребителя с uuid=followee. Ако това вече е така, този метод не трябва да върне грешка.

is_following(self, follower, followee)

Връща истина, ако потребителят follower следва потребителя followee.

followers(self, user_uuid)

Връща множеството от всички uuid-та на потребители, следящи потребителя с user_uuid.

following(self, user_uuid)

Връща множеството от всички uuid-та на потребители, следени от потребителя с user_uuid.

friends(self, user_uuid)

Приятели, в рамките на нашата социална мрежа, наричаме двама потребителя, които се следят взаимно. Този метод връща множеството от всички uuid-та на потребители, които са приятели с потребителя с user_uuid.

max_distance(self, user_uuid)

Намира разстоянието до най-отдалечения потребител от потребителя с user_uuid в неговата свързана компонента. Под "разстояние" разбираме броя на ребра в намерен път и очакваме методът да върне това число.

min_distance(self, from_user_uuid, to_user_uuid)

Връща възможно най-малкото разстояние между два потребителя в социалния граф.

nth_layer_followings(self, user_uuid, n)

Връща всички потребители следени от потребителя с подаденото user_uuid на разстояние n.

Пример:

>>> graph.follow(maria.uuid, ivan.uuid)
>>> graph.follow(ivan.uuid, pesho.uuid)
>>> list(graph.nth_layer_followings(maria.uuid, 2))
<<< [pesho.uuid]

generate_feed(self, user_uuid, offset=0, limit=10)

Връща итеруемо с най-скоро добавените limit на брой (по подразбиране 10) публикации от всички потребители, които потребителят с user_uuid следва, започвайки от публикация номер offset.

Напълно в реда на нещата е да се поискат повече от наличните, тогава просто се очаква да се върнат всички налични.

Пример:

Имаме 40 публикации за feed-а на даден потребител. Ще ги представяме като числа от 1 до 40 (включително):

>>> graph.generate_feed(user_uuid, 0, 10)
<<< [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> graph.generate_feed(user_uuid, 10, 10)
<<< [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

>>> graph.generate_feed(user_uuid, 20, 10)
<<< [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

>>> graph.generate_feed(user_uuid, 30, 10)
<<< [31, 32, 33, 34, 35, 36, 37, 38, 39, 40]

>>> graph.generate_feed(user_uuid, 0, 0)
<<< []

Грешки

UserDoesNotExistError

Ако се опитаме да достъпим потребител с uuid, което не е добавено в социалния ни граф, се очаква да се предизвика UserDoesNotExistError. Това ще рече, че всеки метод, който очаква потребителско uuid като аргумент, трябва да предизвика това изключение.

UserAlreadyExistsError

Предизвиква се това изключение, ако опитаме да добавим потребител с uuid към нашия граф, при положение, че вече съществува потребител с такова.

Пример:

>>> graph.add_user(john)
>>> graph.add_user(john)
---------------------------------------------------------------------------
UserAlreadyExistsError                    Traceback (most recent call last)
[...]

UsersNotConnectedError

Предизвиква се това изключение, ако SocialGraph.min_distance не открие възможен път между два потребителя.