timeit

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

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

Решение на Социална мрежа от Емил Илиев

Обратно към всички решения

Към профила на Емил Илиев

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 8 успешни тест(а)
  • 0 неуспешни тест(а)

Код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        return uuid in self.__followers


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        del self.users[user_uuid]

    def follow(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        if follower == followee:
            raise UserFollowError
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user)}

    def friends(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user) and
                self.is_following(user, user_uuid)}

    def max_distance(self, user_uuid):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        self.check_existing_user(from_user_uuid)
        self.check_existing_user(to_user_uuid)
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        self.check_existing_user(user_uuid)
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Лог от изпълнението

........
----------------------------------------------------------------------
Ran 8 tests in 0.065s

OK

История (6 версии и 0 коментара)

Емил обнови решението на 18.04.2016 10:27 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.__posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.__posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        if uuid in self.__followers:
            return True
        return False


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        del self.users[user_uuid]

    def follow(self, follower, followee):
        if follower == followee:
            raise UserFollowError
        elif follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        if follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        if follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer)}

    def friends(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer) and
                self.is_following(customer, user_uuid)}

    def max_distance(self, user_uuid):
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Емил обнови решението на 18.04.2016 10:38 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        if uuid in self.__followers:
            return True
        return False


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        del self.users[user_uuid]

    def follow(self, follower, followee):
        if follower == followee:
            raise UserFollowError
        self.check_existing_users(follower,followee)
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_users(follower,followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_users(follower,followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer)}

    def friends(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer) and
                self.is_following(customer, user_uuid)}

    def max_distance(self, user_uuid):
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_users(self,follower, followee=None):
        if follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Емил обнови решението на 18.04.2016 10:39 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        if uuid in self.__followers:
            return True
        return False


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        del self.users[user_uuid]

    def follow(self, follower, followee):
        if follower == followee:
            raise UserFollowError
        self.check_existing_users(follower, followee)
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_users(follower, followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_users(follower, followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer)}

    def friends(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer) and
                self.is_following(customer, user_uuid)}

    def max_distance(self, user_uuid):
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_users(self, follower, followee=None):
        if follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Емил обнови решението на 18.04.2016 10:42 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        if uuid in self.__followers:
            return True
        return False


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        del self.users[user_uuid]

    def follow(self, follower, followee):
        if follower == followee:
            raise UserFollowError
        self.check_existing_users(follower, followee)
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_users(follower, followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_users(follower, followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer)}

    def friends(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError
        return {customer for customer in self.users
                if self.is_following(user_uuid, customer) and
                self.is_following(customer, user_uuid)}

    def max_distance(self, user_uuid):
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_users(self, follower, followee):
        if follower not in self.users or followee not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Емил обнови решението на 18.04.2016 14:07 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        return uuid in self.__followers


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        del self.users[user_uuid]

    def follow(self, follower, followee):
        if follower == followee:
            raise UserFollowError
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user)}

    def friends(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user) and
                self.is_following(user, user_uuid)}

    def max_distance(self, user_uuid):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        self.check_existing_user(from_user_uuid)
        self.check_existing_user(to_user_uuid)
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_user(self, follower):
        if follower not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass

Емил обнови решението на 18.04.2016 14:11 (преди над 1 година)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import uuid
import math
import datetime
from collections import deque


class User():

    def __init__(self, name):
        self.full_name = name
        self.uuid = uuid.uuid4()
        self.posts = deque(maxlen=50)
        self.__followers = set()

    def add_post(self, post_content):
        new_post = Post(self.uuid, post_content)
        self.posts.append(new_post)

    def get_post(self):
        return (post for post in self.posts)

    def add_follower(self, uuid):
        self.__followers.add(uuid)

    def remove_follower(self, uuid):
        self.__followers.discard(uuid)

    def get_followers(self):
        return self.__followers

    def search_follower(self, uuid):
        return uuid in self.__followers


class Post():

    def __init__(self, author, content):
        self.author = author
        self.published_at = datetime.datetime.now()
        self.content = content


class SocialGraph():

    def __init__(self):
        self.users = {}

    def add_user(self, user):
        if user.uuid in self.users:
            raise UserAlreadyExistsError
        self.users[user.uuid] = user

    def get_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid]

    def delete_user(self, user_uuid):
        self.check_existing_user(user_uuid)
        del self.users[user_uuid]

    def follow(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        if follower == followee:
            raise UserFollowError
        self.users[followee].add_follower(follower)

    def unfollow(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        self.users[followee].remove_follower(follower)

    def is_following(self, follower, followee):
        self.check_existing_user(follower)
        self.check_existing_user(followee)
        return self.users[followee].search_follower(follower)

    def followers(self, user_uuid):
        self.check_existing_user(user_uuid)
        return self.users[user_uuid].get_followers()

    def following(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user)}

    def friends(self, user_uuid):
        self.check_existing_user(user_uuid)
        return {user for user in self.users
                if self.is_following(user_uuid, user) and
                self.is_following(user, user_uuid)}

    def max_distance(self, user_uuid):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = ['#', user_uuid]
        distance = 0
        while queue:
            node = queue.pop(0)
            if node not in visited and node != '#':
                visited.add(node)
                queue.extend(self.following(node) - visited)
            elif node is '#' and len(queue) > 0:
                queue.append('#')
                distance += 1

        return distance - 1

    def min_distance(self, from_user_uuid, to_user_uuid):
        self.check_existing_user(from_user_uuid)
        self.check_existing_user(to_user_uuid)
        queue = []
        queue.append([from_user_uuid])
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node == to_user_uuid:
                return len(path) - 1
            for adjacent in self.following(node):
                new_path = list(path)
                new_path.append(adjacent)
                queue.append(new_path)
        raise UsersNotConnectedError

    def nth_layer_followings(self, user_uuid, n):
        self.check_existing_user(user_uuid)
        visited = set()
        queue = [user_uuid]
        nth_level_followings = []
        for level in range(n):
            level_nodes = len(queue)
            for index in range(level_nodes):
                node = queue.pop(0)
                if node not in visited and level < n - 1:
                    visited.add(node)
                    queue.extend(self.following(node) - visited)
                elif node not in visited and level == n - 1:
                    nth_level_followings.extend(self.following(node) - visited)
        return nth_level_followings

    def generate_feed(self, user_uuid, offset=0, limit=10):
        self.check_existing_user(user_uuid)
        feed = [post for user in self.following(user_uuid)
                for post in self.get_user(user).get_post()]
        feed.sort(key=lambda p: p.published_at, reverse=True)
        return feed[offset: offset + limit: 1]

    def check_existing_user(self, user_uuid):
        if user_uuid not in self.users:
            raise UserDoesNotExistError


class UserDoesNotExistError(Exception):
    pass


class UserAlreadyExistsError(Exception):
    pass


class UsersNotConnectedError(Exception):
    pass


class UserFollowError(Exception):
    pass