ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื”ื™ื™ ื”ื‘ืจ.

ืžืืžืจ ื–ื” ื”ื•ื ื”ืžืฉืš ื”ื’ื™ื•ื ื™ ืฉืœ ื”ื“ื™ืจื•ื’ ืžืืžืจื™ Habr ื”ื˜ื•ื‘ื™ื ื‘ื™ื•ืชืจ ืœืฉื ืช 2018. ื•ืœืžืจื•ืช ืฉื”ืฉื ื” ืขื“ื™ื™ืŸ ืœื ื”ืกืชื™ื™ืžื”, ื›ื™ื“ื•ืข, ื‘ืงื™ืฅ ื—ืœื• ืฉื™ื ื•ื™ื™ื ื‘ื›ืœืœื™ื, ื‘ื”ืชืื, ื”ืคืš ืžืขื ื™ื™ืŸ ืœืจืื•ืช ืื ื–ื” ื”ืฉืคื™ืข ืขืœ ืžืฉื”ื•.

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื‘ื ื•ืกืฃ ืœืกื˜ื˜ื™ืกื˜ื™ืงื” ื‘ืคื•ืขืœ, ื™ื™ื ืชืŸ ื“ื™ืจื•ื’ ืžืขื•ื“ื›ืŸ ืฉืœ ืžืืžืจื™ื, ื•ื›ืŸ ืงื•ื“ ืžืงื•ืจ ื›ืœืฉื”ื• ืœืžื™ ืฉืžืชืขื ื™ื™ืŸ ื›ื™ืฆื“ ื–ื” ืขื•ื‘ื“.

ืœืžื™ ืฉืžืชืขื ื™ื™ืŸ ื‘ืžื” ืฉืงืจื”, ื”ื”ืžืฉืš ื‘ืงื˜ืข. ืžื™ ืฉืžืขื•ื ื™ื™ืŸ ื‘ื ื™ืชื•ื— ืžืคื•ืจื˜ ื™ื•ืชืจ ืฉืœ ื—ืœืงื™ื ื‘ืืชืจ ื™ื›ื•ืœ ื’ื ืœื”ืกืชื›ืœ ื”ื—ืœืง ื”ื‘ื.

ื ืชื•ื ื™ื ื’ื•ืœืžื™ื™ื

ื“ื™ืจื•ื’ ื–ื” ืื™ื ื• ืจืฉืžื™, ื•ืื™ืŸ ืœื™ ืžื™ื“ืข ืคื ื™ืžื™. ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช ื‘ืงืœื•ืช ืขืœ ื™ื“ื™ ื”ืชื‘ื•ื ื ื•ืช ื‘ืฉื•ืจืช ื”ื›ืชื•ื‘ืช ืฉืœ ื”ื“ืคื“ืคืŸ ืฉืœืš, ืœื›ืœ ื”ืžืืžืจื™ื ืขืœ Habrรฉ ื™ืฉ ืžืกืคื•ืจ ืจืฆื™ืฃ. ืื– ื–ื” ืขื ื™ื™ืŸ ืฉืœ ื˜ื›ื ื™ืงื”, ืื ื—ื ื• ืคืฉื•ื˜ ืงื•ืจืื™ื ืืช ื›ืœ ื”ืžืืžืจื™ื ื‘ืจืฆืฃ ื‘ืžื—ื–ื•ืจ (ื‘ืฉืจืฉื•ืจ ืื—ื“ ื•ืขื ื”ืคืกืงื•ืช, ื›ื“ื™ ืœื ืœื˜ืขื•ืŸ ืืช ื”ืฉืจืช). ื”ืขืจื›ื™ื ืขืฆืžื ื”ื•ืฉื’ื• ืขืœ ื™ื“ื™ ืžื ืชื— ืคืฉื•ื˜ ื‘ืคื™ื™ืชื•ืŸ (ืžืงื•ืจื•ืช ื–ืžื™ื ื™ื ื›ืืŸ) ื•ื ืฉืžืจ ื‘ืงื•ื‘ืฅ csv ืžืฉื”ื• ื›ื–ื”:

2019-08-11T22:36Z,https://habr.com/ru/post/463197/,"Blazor + MVVM = Silverlight ะฝะฐะฝะพัะธั‚ ะพั‚ะฒะตั‚ะฝั‹ะน ัƒะดะฐั€, ะฟะพั‚ะพะผัƒ ั‡ั‚ะพ ะดั€ะตะฒะฝะตะต ะทะปะพ ะฝะตะฟะพะฑะตะดะธะผะพ",votes:11,votesplus:17,votesmin:6,bookmarks:40,views:5300,comments:73
2019-08-11T05:26Z,https://habr.com/ru/news/t/463199/,"ะ’ NASA ะธัะฟั‹ั‚ะฐะปะธ ัะธัั‚ะตะผัƒ ะฐะฒั‚ะพะฝะพะผะฝะพะณะพ ัƒะฟั€ะฐะฒะปะตะฝะธั ะพะดะฝะพะณะพ ะผะธะบั€ะพัะฟัƒั‚ะฝะธะบะฐ ะดั€ัƒะณะธะผ",votes:15,votesplus:15,votesmin:0,bookmarks:2,views:1700,comments:7

ืขื™ื‘ื•ื“

ืœื ื™ืชื•ื— ื ืฉืชืžืฉ ื‘- Python, Pandas ื•-Matplotlib. ืžื™ ืฉืœื ืžืชืขื ื™ื™ืŸ ื‘ืกื˜ื˜ื™ืกื˜ื™ืงื” ื™ื›ื•ืœ ืœื“ืœื’ ืขืœ ื”ื—ืœืง ื”ื–ื” ื•ืœืขื‘ื•ืจ ื™ืฉืจ ืœื›ืชื‘ื•ืช.

ืจืืฉื™ืช ืขืœื™ืš ืœื˜ืขื•ืŸ ืืช ืžืขืจืš ื”ื ืชื•ื ื™ื ืœื–ื™ื›ืจื•ืŸ ื•ืœื‘ื—ื•ืจ ื ืชื•ื ื™ื ืขื‘ื•ืจ ื”ืฉื ื” ื”ืจืฆื•ื™ื”.

import pandas as pd
import datetime
import matplotlib.dates as mdates
from matplotlib.ticker import FormatStrFormatter
from pandas.plotting import register_matplotlib_converters


df = pd.read_csv("habr.csv", sep=',', encoding='utf-8', error_bad_lines=True, quotechar='"', comment='#')
dates = pd.to_datetime(df['datetime'], format='%Y-%m-%dT%H:%MZ')
df['datetime'] = dates
year = 2019
df = df[(df['datetime'] >= pd.Timestamp(datetime.date(year, 1, 1))) & (df['datetime'] < pd.Timestamp(datetime.date(year+1, 1, 1)))]

print(df.shape)

ืžืกืชื‘ืจ ืฉื”ืฉื ื” (ืื ื›ื™ ืขื“ื™ื™ืŸ ืœื ื”ืกืชื™ื™ืžื”) ื‘ื–ืžืŸ ื›ืชื™ื‘ืช ืฉื•ืจื•ืช ืืœื• ื”ืชืคืจืกืžื• 12715 ืžืืžืจื™ื. ืœืฉื ื”ืฉื•ื•ืื”, ืœื›ืœ 2018 - 15904. ื‘ื›ืœืœ ื”ืจื‘ื” - ืžื“ื•ื‘ืจ ืขืœ 43 ื›ืชื‘ื•ืช ื‘ื™ื•ื (ื•ื–ื” ืจืง ืขื ื“ื™ืจื•ื’ ื—ื™ื•ื‘ื™; ื›ืžื” ืกื”"ื› ืžื•ืจื™ื“ื™ื ื›ืชื‘ื•ืช ืฉืขื‘ืจื• ืฉืœื™ืœื™ื•ืช ืื• ื ืžื—ืงื•, ืืคืฉืจ ืจืง ืœื ื—ืฉ ืื• ืื•ืžื“ืŸ ื’ืก ืžื”ืคืขืจื™ื ื‘ื™ืŸ ื”ืžื–ื”ื™ื).

ื‘ื•ืื• ื ื‘ื—ืจ ืืช ื”ืฉื“ื•ืช ื”ื“ืจื•ืฉื™ื ืžืชื•ืš ืžืขืจืš ื”ื ืชื•ื ื™ื. ื›ืžื“ื“ื™ื ื ืฉืชืžืฉ ื‘ืžืกืคืจ ื”ืฆืคื™ื•ืช, ื”ื”ืขืจื•ืช, ืขืจื›ื™ ื”ื“ื™ืจื•ื’ ื•ืžืกืคืจ ื”ืกื™ืžื ื™ื•ืช.

def to_float(s):
    # "bookmarks:22" => 22.0
    num = ''.join(i for i in s if i.isdigit())
    return float(num)

def to_int(s):
    # "bookmarks:22" => 22
    num = ''.join(i for i in s if i.isdigit())
    return int(num)

def to_date(dt):
    return dt.date() 

date = dates.map(to_date, na_action=None)
views = df["views"].map(to_int, na_action=None)
bookmarks = df["bookmarks"].map(to_int, na_action=None)
votes = df["votes"].map(to_float, na_action=None)
votes_up = df["up"].map(to_float, na_action=None)
votes_down = df["down"].map(to_float, na_action=None)
comments = df["comments"].map(to_int, na_action=None)

df['date'] = date
df['views'] = views
df['votes'] = votes
df['bookmarks'] = bookmarks
df['up'] = votes_up
df['down'] = votes_down

ื›ืขืช ื”ื ืชื•ื ื™ื ื ื•ืกืคื• ืœืžืขืจืš ื”ื ืชื•ื ื™ื ื•ื ื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ื”ื. ื‘ื•ืื• ื ืงื‘ืฅ ืืช ื”ื ืชื•ื ื™ื ืœืคื™ ื™ื•ื ื•ื ื™ืงื— ืืช ื”ืขืจื›ื™ื ื”ืžืžื•ืฆืขื™ื.

g = df.groupby(['date'])
days_count = g.size().reset_index(name='counts')
year_days = days_count['date'].values
grouped = g.median().reset_index()
grouped['counts'] = days_count['counts']
counts_per_day = grouped['counts'].values
counts_per_day_avg = grouped['counts'].rolling(window=20).mean()
view_per_day = grouped['views'].values
view_per_day_avg = grouped['views'].rolling(window=20).mean()
votes_per_day = grouped['votes'].values
votes_per_day_avg = grouped['votes'].rolling(window=20).mean()
bookmarks_per_day = grouped['bookmarks'].values
bookmarks_per_day_avg = grouped['bookmarks'].rolling(window=20).mean()

ืขื›ืฉื™ื• ื”ื—ืœืง ื”ืžืขื ื™ื™ืŸ ื”ื•ื ืฉืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื”ืกืชื›ืœ ืขืœ ื”ื’ืจืคื™ื.

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ืžืกืคืจ ื”ืคืจืกื•ืžื™ื ืขืœ Habrรฉ ื‘ืฉื ืช 2019.

import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = (16, 8)
fig, ax = plt.subplots()

plt.bar(year_days, counts_per_day, label='Articles/day')
plt.plot(year_days, counts_per_day_avg, 'g-', label='Articles avg/day')
plt.xticks(rotation=45)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d-%m-%Y"))  
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
plt.legend(loc='best')
plt.tight_layout()
plt.show()

ื”ืชื•ืฆืื” ืžืขื ื™ื™ื ืช. ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช, ื”ื‘ืจ ื”ื™ื” "ื ืงื ื™ืง" ืงื˜ืŸ ืœืื•ืจืš ื›ืœ ื”ืฉื ื”. ืื ื™ ืœื ื™ื•ื“ืข ืืช ื”ืกื™ื‘ื”.

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ืœืฉื ื”ืฉื•ื•ืื”, 2018 ื ืจืื™ืช ืงืฆืช ื™ื•ืชืจ ื—ืœืงื”:

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื‘ืื•ืคืŸ ื›ืœืœื™, ืœื ืจืื™ืชื™ ื™ืจื™ื“ื” ื“ืจืกื˜ื™ืช ื‘ืžืกืคืจ ื”ืžืืžืจื™ื ืฉืคื•ืจืกืžื• ื‘-2019 ื‘ื’ืจืฃ. ื™ืชืจื” ืžื›ืš, ืœื”ื™ืคืš, ื ืจืื” ืฉื”ื•ื ืืฃ ื’ื“ืœ ืžืขื˜ ืžืื– ื”ืงื™ืฅ.

ืื‘ืœ ืฉื ื™ ื”ื’ืจืคื™ื ื”ื‘ืื™ื ืžื“ื›ืื™ื ืื•ืชื™ ืงืฆืช ื™ื•ืชืจ.

ืžืกืคืจ ืฆืคื™ื•ืช ืžืžื•ืฆืข ืœืžืืžืจ:

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื“ื™ืจื•ื’ ืžืžื•ืฆืข ืœืžืืžืจ:

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช, ืžืกืคืจ ื”ืฆืคื™ื•ืช ื”ืžืžื•ืฆืข ื™ื•ืจื“ ืžืขื˜ ื‘ืžื”ืœืš ื”ืฉื ื”. ื ื™ืชืŸ ืœื”ืกื‘ื™ืจ ื–ืืช ื‘ื›ืš ืฉืžืืžืจื™ื ื—ื“ืฉื™ื ืขื“ื™ื™ืŸ ืœื ื”ื•ืกืคื• ืœืื™ื ื“ืงืก ืขืœ ื™ื“ื™ ืžื ื•ืขื™ ื”ื—ื™ืคื•ืฉ, ื•ื”ื ืœื ืžื•ืฆืื™ื ืœืขืชื™ื ืงืจื•ื‘ื•ืช ื›ืœ ื›ืš. ืื‘ืœ ื”ื™ืจื™ื“ื” ื‘ื“ื™ืจื•ื’ ื”ืžืžื•ืฆืข ืœืžืืžืจ ื™ื•ืชืจ ืœื ืžื•ื‘ื ืช. ื”ืชื—ื•ืฉื” ื”ื™ื ืฉืคืฉื•ื˜ ืื™ืŸ ืœืงื•ืจืื™ื ื–ืžืŸ ืœืขื™ื™ืŸ ื‘ื›ืœ ื›ืš ื”ืจื‘ื” ืžืืžืจื™ื ืื• ืฉืœื ืฉืžื™ื ืœื‘ ืœื“ื™ืจื•ื’ื™ื. ืžื ืงื•ื“ืช ื”ืžื‘ื˜ ืฉืœ ืชื•ื›ื ื™ืช ื”ืชื’ืžื•ืœ ืœืกื•ืคืจ, ืžื’ืžื” ื–ื• ื”ื™ื ืžืื•ื“ ืœื ื ืขื™ืžื”.

ืื’ื‘, ื–ื” ืœื ืงืจื” ื‘-2018, ื•ืœื•ื— ื”ื–ืžื ื™ื ืฉื•ื•ื” ืคื—ื•ืช ืื• ื™ื•ืชืจ.

ืกื˜ื˜ื™ืกื˜ื™ืงื”: ืื™ืš ื—ื‘ืจ ื—ื™ ื‘ืœื™ ื–ืžื ื™ ื—ื ื•ืŸ

ื‘ืื•ืคืŸ ื›ืœืœื™, ืœื‘ืขืœื™ ืžืฉืื‘ื™ื ื™ืฉ ืขืœ ืžื” ืœื—ืฉื•ื‘.

ืื‘ืœ ื‘ื•ืื• ืœื ื ื“ื‘ืจ ืขืœ ื“ื‘ืจื™ื ืขืฆื•ื‘ื™ื. ื‘ืื•ืคืŸ ื›ืœืœื™ ื ื™ืชืŸ ืœื•ืžืจ ืฉื”ื‘ืจ "ืฉืจื“" ืืช ืฉื™ื ื•ื™ื™ ื”ืงื™ืฅ ื‘ื”ืฆืœื—ื” ืจื‘ื”, ื•ืžืกืคืจ ื”ื›ืชื‘ื•ืช ื‘ืืชืจ ืœื ื™ืจื“.

ื“ืจื•ื’

ืขื›ืฉื™ื•, ืœืžืขืฉื”, ื”ื“ื™ืจื•ื’. ื›ืœ ื”ื›ื‘ื•ื“ ืœืžื™ ืฉื ื›ื ืก ืœื–ื”. ื”ืจืฉื• ืœื™ ืœื”ื–ื›ื™ืจ ืœื›ื ืฉื•ื‘ ืฉื”ื“ื™ืจื•ื’ ืื™ื ื• ืจืฉืžื™, ืื•ืœื™ ืคืกืคืกืชื™ ืžืฉื”ื•, ื•ืื ื‘ื”ื—ืœื˜ ืฆืจื™ืš ืœื”ื™ื•ืช ื›ืืŸ ืื™ื–ื” ืžืืžืจ, ืื‘ืœ ื”ื•ื ืœื, ื›ืชื•ื‘, ืื ื™ ืื•ืกื™ืฃ ืื•ืชื• ื™ื“ื ื™ืช. ื‘ืชื•ืจ ื“ื™ืจื•ื’, ืื ื™ ืžืฉืชืžืฉ ื‘ืžื“ื“ื™ื ืžื—ื•ืฉื‘ื™ื, ืฉืœื“ืขืชื™ ื™ืฆืื• ืžืขื ื™ื™ื ื™ื ืœืžื“ื™.

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ืžืกืคืจ ืฆืคื™ื•ืช

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ื™ื—ืก ื“ื™ืจื•ื’ ืœืฆืคื™ื•ืช

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ื™ื—ืก ื”ืขืจื•ืช ืœืฆืคื™ื•ืช

ื”ื›ืชื‘ื•ืช ื”ืฉื ื•ื™ื•ืช ื‘ื™ื•ืชืจ ื‘ืžื—ืœื•ืงืช

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ื“ื™ืจื•ื’

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ืžืกืคืจ ื”ืกื™ืžื ื™ื•ืช

ืœืžืขืœื” ืœืคื™ ื”ื™ื—ืก ื‘ื™ืŸ ืกื™ืžื ื™ื•ืช ืœืฆืคื™ื•ืช

ืžืืžืจื™ื ืžื•ื‘ื™ืœื™ื ืœืคื™ ืžืกืคืจ ืชื’ื•ื‘ื•ืช

ื•ืœื‘ืกื•ืฃ, ื”ืื—ืจื•ืŸ Antitop ืœืคื™ ืžืกืคืจ ื“ื™ืกืœื™ื™ืงื™ื

ืื•ืฃ. ื™ืฉ ืœื™ ืขื•ื“ ื›ืžื” ื‘ื—ื™ืจื•ืช ืžืขื ื™ื™ื ื•ืช, ืื‘ืœ ืœื ืืฉืขืžื ืืช ื”ืงื•ืจืื™ื.

ืžืกืงื ื”

ื‘ืขืช ื‘ื ื™ื™ืช ื”ื“ื™ืจื•ื’, ืฉืžืชื™ ืœื‘ ืœืฉืชื™ ื ืงื•ื“ื•ืช ืฉื ืจืื• ืžืขื ื™ื™ื ื•ืช.

ืจืืฉื™ืช, 60% ืžื”ืจืืฉ ื”ื ืžืืžืจื™ื ืžื–'ืื ืจ "ื’ื™ืงtimes". ืื ื‘ืฉื ื” ื”ื‘ืื” ื™ื”ื™ื• ืคื—ื•ืช ืžื”ื, ื•ืื™ืš ื™ืจืื” ื”ื‘ืจ ื‘ืœื™ ื›ืชื‘ื•ืช ืขืœ ื‘ื™ืจื”, ื—ืœืœ, ืจืคื•ืื” ื•ื›ื•', ืื ื™ ืœื ื™ื•ื“ืข. ื‘ื”ื—ืœื˜, ื”ืงื•ืจืื™ื ื™ืคืกื™ื“ื• ืžืฉื”ื•. ื‘ื•ื ื ืจืื”.

ืฉื ื™ืช, ื”ืกื™ืžื ื™ื•ืช ื”ืžื•ื‘ื™ืœื•ืช ื”ืชื‘ืจืจื• ื›ืื™ื›ื•ืช ื’ื‘ื•ื”ื” ื‘ืื•ืคืŸ ื‘ืœืชื™ ืฆืคื•ื™. ื–ื” ืžื•ื‘ืŸ ืžื‘ื—ื™ื ื” ืคืกื™ื›ื•ืœื•ื’ื™ืช; ื”ืงื•ืจืื™ื ืื•ืœื™ ืœื ื™ืฉื™ืžื• ืœื‘ ืœื“ื™ืจื•ื’, ืื‘ืœ ืื ื”ืžืืžืจ ื™ืฉ ืฆื•ืจืš, ืื– ื”ื•ื ื™ืชื•ื•ืกืฃ ืœืกื™ืžื ื™ื•ืช ืฉืœืš. ื•ื›ืืŸ ื‘ื“ื™ื•ืง ื”ืจื™ื›ื•ื– ื”ื’ื“ื•ืœ ื‘ื™ื•ืชืจ ืฉืœ ืžืืžืจื™ื ืฉื™ืžื•ืฉื™ื™ื ื•ืจืฆื™ื ื™ื™ื. ืื ื™ ื—ื•ืฉื‘ ืฉื‘ืขืœื™ ื”ืืชืจ ืฆืจื™ื›ื™ื ืื™ื›ืฉื”ื• ืœื—ืฉื•ื‘ ืขืœ ื”ืงืฉืจ ื‘ื™ืŸ ืžืกืคืจ ื”ืกื™ืžื ื™ื•ืช ืœืชื•ื›ื ื™ืช ื”ืชื’ืžื•ืœื™ื ืื ื”ื ืจื•ืฆื™ื ืœื”ื’ื“ื™ืœ ืืช ื”ืงื˜ื’ื•ืจื™ื” ื”ืกืคืฆื™ืคื™ืช ื”ื–ื• ืฉืœ ืžืืžืจื™ื ื›ืืŸ ื‘-Habrรฉ.

ืžืฉื”ื• ื›ื–ื”. ืื ื™ ืžืงื•ื•ื” ืฉื–ื” ื”ื™ื” ืื™ื ืคื•ืจืžื˜ื™ื‘ื™.

ืจืฉื™ืžืช ื”ืžืืžืจื™ื ื”ืชื‘ืจืจื” ื›ืืจื•ื›ื”, ื•ื‘ื›ืŸ, ื–ื” ื›ื ืจืื” ืœื˜ื•ื‘ื”. ืงืจื™ืื” ืžื”ื ื” ืœื›ื•ืœื.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”