Skip to content
Open
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
4 changes: 2 additions & 2 deletions .github/workflows/cs102.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8.6
- name: Set up Python 3.10.7
uses: actions/setup-python@v2
with:
python-version: '3.8.6'
python-version: '3.10.7'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
14 changes: 14 additions & 0 deletions .idea/Chzh.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 12 additions & 11 deletions homework05/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
responses==0.12.1
requests==2.24.0
httpretty==1.0.2
tqdm==4.52.0
networkx==2.5
pandas==1.1.4
matplotlib==3.3.3
python-louvain==0.14
gensim==3.8.3
textacy==0.10.1
pyLDAvis==2.1.2
responses
requests
httpretty
tqdm
networkx
pandas
matplotlib
python-louvain
gensim
textacy
pyLDAvis
types-requests
19 changes: 16 additions & 3 deletions homework05/research/age.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,23 @@
def age_predict(user_id: int) -> tp.Optional[float]:
"""
Наивный прогноз возраста пользователя по возрасту его друзей.

Возраст считается как медиана среди возраста всех друзей пользователя

:param user_id: Идентификатор пользователя.
:return: Медианный возраст пользователя.
"""
pass
friends = get_friends(user_id, fields=["bdate"]).items
ages = []
for friend in friends:
if "bdate" in friend:
bdate = friend["bdate"].split(".")
if len(bdate) == 3:
age = dt.datetime.now().year - int(bdate[2])
if dt.datetime.now().month < int(bdate[1]) and dt.datetime.now().day < int(
bdate[0]
):
age -= 1
ages.append(age)

if len(ages) == 0:
return None
return statistics.median(ages)
14 changes: 9 additions & 5 deletions homework05/research/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
import matplotlib.pyplot as plt
import networkx as nx
import pandas as pd

from vkapi.friends import get_friends, get_mutual
from vkapi.friends import get_friends, get_mutual_with_class


def ego_network(
user_id: tp.Optional[int] = None, friends: tp.Optional[tp.List[int]] = None
friends: tp.List[int],
user_id: tp.Optional[int] = None,
) -> tp.List[tp.Tuple[int, int]]:
"""
Построить эгоцентричный граф друзей.

:param user_id: Идентификатор пользователя, для которого строится граф друзей.
:param friends: Идентификаторы друзей, между которыми устанавливаются связи.
"""
pass
net = []
mutual = get_mutual_with_class(source_uid=friends[0], target_uids=friends)
for friend in mutual:
for uid in friend["common_friends"]:
net.append((friend["id"], uid))
return net


def plot_ego_network(net: tp.List[tp.Tuple[int, int]]) -> None:
Expand Down
1 change: 0 additions & 1 deletion homework05/research/topic_modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from gensim.corpora import Dictionary
from textacy import preprocessing
from tqdm import tqdm

from vkapi.wall import get_wall_execute


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_api/test_friends.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import unittest

import responses

from vkapi.friends import FriendsResponse, get_friends, get_mutual


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_api/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import httpretty
import responses
from requests.exceptions import ConnectionError, HTTPError, ReadTimeout, RetryError

from vkapi.session import Session


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_api/test_wall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import pandas as pd
import responses

from vkapi.wall import get_wall_execute


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_research/test_age.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import unittest

import responses

from research.age import age_predict


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_research/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import unittest

import responses

from research.network import ego_network


Expand Down
2 changes: 1 addition & 1 deletion homework05/vkapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

VK_CONFIG = {
"domain": "https://api.vk.com/method",
"access_token": "",
"access_token": "vk1.a.jEhY_ByNYk_8nfSc4c3IOQM155w7sKxDJfCulh0P23TdsbWTHzBhNWIauYLefFi8TeKrKKt0f2eQNEfpG-YT7mrxH-BcOpjPz1rXowjzhHe1WJ70b1uN_SCPyhZ9-PihsVKzBOvcfJUjPvjHyBdwYNCyCzUIIYjikZ6wyoeHLkrqa6I0bYrsALHQwxPp05ag",
"version": "5.126",
}
79 changes: 74 additions & 5 deletions homework05/vkapi/friends.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@dataclasses.dataclass(frozen=True)
class FriendsResponse:
count: int
items: tp.Union[tp.List[int], tp.List[tp.Dict[str, tp.Any]]]
items: tp.List[tp.Dict[str, tp.Any]]


def get_friends(
Expand All @@ -21,14 +21,23 @@ def get_friends(
"""
Получить список идентификаторов друзей пользователя или расширенную информацию
о друзьях пользователя (при использовании параметра fields).

:param user_id: Идентификатор пользователя, список друзей для которого нужно получить.
:param count: Количество друзей, которое нужно вернуть.
:param offset: Смещение, необходимое для выборки определенного подмножества друзей.
:param fields: Список полей, которые нужно получить для каждого пользователя.
:return: Список идентификаторов друзей пользователя или список пользователей.
"""
pass
friends = session.get(
"friends.get",
user_id=user_id,
count=count,
offset=offset,
fields=fields,
v=config.VK_CONFIG["version"],
access_token=config.VK_CONFIG["access_token"],
).json()["response"]

return FriendsResponse(friends["count"], friends["items"])


class MutualFriends(tp.TypedDict):
Expand All @@ -40,15 +49,58 @@ class MutualFriends(tp.TypedDict):
def get_mutual(
source_uid: tp.Optional[int] = None,
target_uid: tp.Optional[int] = None,
target_uids: tp.Optional[tp.List[int]] = None,
target_uids: tp.Optional[tp.List[tp.Optional[int]]] = None,
order: str = "",
count: tp.Optional[int] = None,
offset: int = 0,
progress=None,
) -> tp.Union[tp.List[int], tp.List[MutualFriends]]:
"""
Получить список идентификаторов общих друзей между парой пользователей.
:param source_uid: Идентификатор пользователя, чьи друзья пересекаются с друзьями пользователя с идентификатором target_uid.
:param target_uid: Идентификатор пользователя, с которым необходимо искать общих друзей.
:param target_uids: Cписок идентификаторов пользователей, с которыми необходимо искать общих друзей.
:param order: Порядок, в котором нужно вернуть список общих друзей.
:param count: Количество общих друзей, которое нужно вернуть.
:param offset: Смещение, необходимое для выборки определенного подмножества общих друзей.
:param progress: Callback для отображения прогресса.
"""
if target_uids is None:
target_uids = [target_uid]

result = []

for i in range(0, len(target_uids), 100):
result += session.get(
"friends.getMutual",
source_uid=source_uid,
target_uids=target_uids,
order=order,
count=count,
offset=offset + i,
v=config.VK_CONFIG["version"],
access_token=config.VK_CONFIG["access_token"],
).json()["response"]

if i % 200 == 0:
time.sleep(1)

if target_uid is not None:
return result[0]["common_friends"]

return result


def get_mutual_with_class(
target_uids: tp.List[int],
source_uid: tp.Optional[int] = None,
order: str = "",
count: tp.Optional[int] = None,
offset: int = 0,
progress=None,
) -> tp.List[MutualFriends]:
"""
Получить список идентификаторов общих друзей между парой пользователей.
:param source_uid: Идентификатор пользователя, чьи друзья пересекаются с друзьями пользователя с идентификатором target_uid.
:param target_uid: Идентификатор пользователя, с которым необходимо искать общих друзей.
:param target_uids: Cписок идентификаторов пользователей, с которыми необходимо искать общих друзей.
Expand All @@ -57,4 +109,21 @@ def get_mutual(
:param offset: Смещение, необходимое для выборки определенного подмножества общих друзей.
:param progress: Callback для отображения прогресса.
"""
pass
result = []

for i in range(0, len(target_uids), 100):
result += session.get(
"friends.getMutual",
source_uid=source_uid,
target_uids=target_uids,
order=order,
count=count,
offset=offset + i,
v=config.VK_CONFIG["version"],
access_token=config.VK_CONFIG["access_token"],
).json()["response"]

if i % 200 == 0:
time.sleep(1)

return result
Loading