Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.90 KB | None | 0 0
  1. import requests
  2. import time
  3. from datetime import datetime
  4. import plotly
  5. import plotly.plotly as py
  6. import plotly.graph_objs as go
  7. import config
  8. import numpy as np
  9. import igraph
  10. from igraph import plot, Graph
  11. from collections import Counter
  12.  
  13. plotly.tools.set_credentials_file(username=config.plotlyUsername, api_key=config.plotlyApiKey)
  14.  
  15.  
  16. def get(url, params={}, timeout=5, max_retries=5, backoff_factor=0.3):
  17. """ Выполнить GET-запрос
  18. :param url: адрес, на который необходимо выполнить запрос
  19. :param params: параметры запроса
  20. :param timeout: максимальное время ожидания ответа от сервера
  21. :param max_retries: максимальное число повторных запросов
  22. :param backoff_factor: коэффициент экспоненциального нарастания задержки
  23. """
  24. for attempt in range(max_retries):
  25. try:
  26. response = requests.get(url, params=params, timeout=timeout)
  27. return response
  28. except requests.exceptions.RequestException:
  29. if attempt == max_retries - 1:
  30. raise
  31. backoff_value = backoff_factor * (2 ** attempt)
  32. time.sleep(backoff_value)
  33.  
  34.  
  35. def get_friends(user_id, fields=''):
  36. """ Вернуть данных о друзьях пользователя
  37. :param user_id: идентификатор пользователя, список друзей которого нужно получить
  38. :param fields: список полей, которые нужно получить для каждого пользователя
  39. """
  40. assert isinstance(user_id, int), "user_id must be positive integer"
  41. assert isinstance(fields, str), "fields must be string"
  42. assert user_id > 0, "user_id must be positive integer"
  43. query_params = {
  44. 'domain': config.domain,
  45. 'access_token': config.vkApiKey2,
  46. 'user_id': user_id,
  47. 'fields': fields,
  48. 'v': config.v
  49. }
  50. url = "{}/friends.get".format(config.domain)
  51. response = get(url, params=query_params)
  52. return response.json()
  53.  
  54.  
  55. def age_predict(user_id):
  56. """ Наивный прогноз возраста по возрасту друзей
  57. Возраст считается как медиана среди возраста всех друзей пользователя
  58. :param user_id: идентификатор пользователя
  59. """
  60. assert isinstance(user_id, int), "user_id must be positive integer"
  61. assert user_id > 0, "user_id must be positive integer"
  62. getFriendsValue = get_friends(user_id, 'bdate')
  63. birthdays = [date.get('bdate') for date in getFriendsValue.get('response').get('items')]
  64. age = [2017 - int(birthdays[date][-4:]) for date in range(len(birthdays))
  65. if (birthdays[date]) and (len(birthdays[date]) >= 8)]
  66. return sum(age) // len(age)
  67.  
  68.  
  69. def messages_get_history(user_id, offset=0, count=20):
  70. """ Получить историю переписки с указанным пользователем
  71. :param user_id: идентификатор пользователя, с которым нужно получить историю переписки
  72. :param offset: смещение в истории переписки
  73. :param count: число сообщений, которое нужно получить
  74. """
  75. assert isinstance(user_id, int), "user_id must be positive integer"
  76. assert user_id > 0, "user_id must be positive integer"
  77. assert isinstance(offset, int), "offset must be positive integer"
  78. assert offset >= 0, "user_id must be positive integer"
  79. assert count >= 0, "user_id must be positive integer"
  80. max_count = 200
  81. messages = []
  82. query_params = {
  83. 'domain': config.domain,
  84. 'access_token': config.vkApiKey,
  85. 'user_id': user_id,
  86. 'offset': offset,
  87. 'count': min(count, max_count),
  88. 'v': config.v
  89. }
  90. while count > 0:
  91. url = "{}/messages.getHistory".format(config.domain)
  92. response = get(url, params=query_params)
  93. count -= min(count, max_count)
  94. query_params['offset'] += 200
  95. query_params['count'] = min(count, max_count)
  96. messages += response.json()['response']['items']
  97. time.sleep(0.333333334)
  98.  
  99. return messages
  100.  
  101.  
  102. def count_dates_from_messages(messages):
  103. """ Получить список дат и их частот
  104. :param messages: список сообщений
  105. """
  106. date = [datetime.fromtimestamp(messages[i]['date']).strftime("%Y-%m-%d")
  107. for i in range(len(messages))]
  108. frequency = Counter(date)
  109. x = [date for date in frequency]
  110. y = [frequency[date] for date in frequency]
  111. return x, y
  112.  
  113.  
  114. def plotly_messages_freq(freq_list):
  115. """ Построение графика с помощью Plot.ly
  116. :param freq_list: список дат и их частот
  117. """
  118. data = [go.Scatter(x=freq_list[0], y=freq_list[1])]
  119. py.plot(data)
  120.  
  121.  
  122. def get_network(user_id, as_edgelist=True):
  123. users_ids = get_friends(user_id)['response']['items']
  124. edges = []
  125. matrix = np.zeros((len(users_ids), len(users_ids)))
  126. for i in range(len(users_ids)):
  127. time.sleep(0.33333334)
  128. response = get_friends(users_ids[i])
  129. if response.get('error'):
  130. continue
  131. friends = response['response']['items']
  132. for j in range(i + 1, len(users_ids)):
  133. if users_ids[j] in friends:
  134. if as_edgelist:
  135. edges.append((i, j))
  136. else:
  137. matrix[i][j] = 1
  138. if as_edgelist:
  139. return edges
  140. else:
  141. return matrix
  142.  
  143.  
  144. def plot_graph(user_id):
  145. surnames = get_friends(user_id, 'last_name')
  146. vertices = [surnames['response']['items'][i]['last_name'] for i in range(len(surnames['response']['items']))]
  147. edges = get_network(user_id)
  148. g = Graph(vertex_attrs={"shape": "circle",
  149. "label": vertices,
  150. "size": 10},
  151. edges=edges, directed=False)
  152.  
  153. N = len(vertices)
  154. visual_style = {
  155. "vertex_size": 20,
  156. "bbox": (2000, 2000),
  157. "margin": 100,
  158. "vertex_label_dist": 1.6,
  159. "edge_color": "gray",
  160. "autocurve": True,
  161. "layout": g.layout_fruchterman_reingold(
  162. maxiter=100000,
  163. area=N ** 2,
  164. repulserad=N ** 2)
  165. }
  166.  
  167. clusters = g.community_multilevel()
  168. pal = igraph.drawing.colors.ClusterColoringPalette(len(clusters))
  169. g.vs['color'] = pal.get_many(clusters.membership)
  170.  
  171. plot(g, **visual_style)
  172.  
  173.  
  174. print(age_predict(432815097))
  175. plot_graph(432815097)
  176. plotly_messages_freq(count_dates_from_messages(messages_get_history(432815097, offset=0, count=200)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement