เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เชนเซ‡ เชนเชฌเชฐ.

ะ’ เช…เช—เชพเช‰เชจเซ‹ เชญเชพเช— เชนเซ‡เชฌเซเชฐเชจเชพ เชŸเซเชฐเชพเชซเชฟเช•เชจเซเช‚ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เชฎเซเช–เซเชฏ เชชเชฐเชฟเชฎเชพเชฃเซ‹ - เชฒเซ‡เช–เซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ, เชคเซ‡เชฎเชจเชพ เชฎเช‚เชคเชตเซเชฏเซ‹ เช…เชจเซ‡ เชฐเซ‡เชŸเชฟเช‚เช—เซเชธ เช…เชจเซเชธเชพเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเชคเซเช‚. เชœเซ‹ เช•เซ‡, เชธเชพเช‡เชŸ เชตเชฟเชญเชพเช—เซ‹เชจเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏเชคเชพเชจเซ‹ เชฎเซเชฆเซเชฆเซ‹ เชคเชชเชพเชธเซเชฏเชพ เชตเชฟเชจเชพ เชฐเชนเซเชฏเซ‹. เช†เชจเซ‡ เชตเชงเซ เชตเชฟเช—เชคเชตเชพเชฐ เชœเซ‹เชตเชพเชจเซเช‚ เช…เชจเซ‡ เชธเซŒเชฅเซ€ เชตเชงเซ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เช…เชจเซ‡ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชชเซเชฐเชฟเชฏ เชนเชฌ เชถเซ‹เชงเชตเชพเชจเซเช‚ เชฐเชธเชชเซเชฐเชฆ เชฌเชจเซเชฏเซเช‚. เช›เซ‡เชฒเซเชฒเซ‡, เชนเซเช‚ เชจเชตเชพ เชฐเซ‡เชจเซเช•เชฟเช‚เช—เชจเชพ เช†เชงเชพเชฐเซ‡ เชถเซเชฐเซ‡เชทเซเช  เชฒเซ‡เช–เซ‹เชจเซ€ เชจเชตเซ€ เชชเชธเช‚เชฆเช—เซ€ เชธเชพเชฅเซ‡ เชธเชฎเชพเชชเซเชค เชฅเชคเชพ geektimes เช…เชธเชฐเชจเซ‡ เชตเชงเซ เชตเชฟเช—เชคเชตเชพเชฐ เชœเซ‹เชˆเชถ.

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เชœเซ‡เช“ เชถเซเช‚ เชฅเชฏเซเช‚ เชคเซ‡เชฎเชพเช‚ เชฐเชธ เชงเชฐเชพเชตเชคเชพ เชฒเซ‹เช•เซ‹ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ เชฐเชพเช–เชตเชพเชจเซเช‚ เช•เชŸ เชนเซ‡เช เชณ เช›เซ‡.

เชนเซเช‚ เชคเชฎเชจเซ‡ เชซเชฐเซ€ เชเช•เชตเชพเชฐ เชฏเชพเชฆ เช…เชชเชพเชตเซ€ เชฆเช‰เช‚ เช•เซ‡ เช†เช‚เช•เชกเชพ เช…เชจเซ‡ เชฐเซ‡เชŸเชฟเช‚เช— เชธเชคเซเชคเชพเชตเชพเชฐ เชจเชฅเซ€, เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช•เซ‹เชˆ เช†เช‚เชคเชฐเชฟเช• เชฎเชพเชนเชฟเชคเซ€ เชจเชฅเซ€. เช เชตเชพเชคเชจเซ€ เชชเชฃ เช–เชพเชคเชฐเซ€ เชจเชฅเซ€ เช•เซ‡ เชฎเชพเชฐเชพเชฅเซ€ เช•เซเชฏเชพเช‚เช• เชญเซ‚เชฒ เชคเซ‹ เชจเชฅเซ€ เชฅเชˆ เช—เชˆ เช•เซ‡ เช•เช‚เชˆเช• เชšเซ‚เช•เซ€ เช—เชˆ. เชชเชฐเช‚เชคเซ เชนเชœเซ€ เชชเชฃ, เชฎเชจเซ‡ เชฒเชพเช—เซ‡ เช›เซ‡ เช•เซ‡ เชคเซ‡ เชฐเชธเชชเซเชฐเชฆ เชฌเชจเซเชฏเซเช‚. เช…เชฎเซ‡ เชชเชนเซ‡เชฒเชพ เช•เซ‹เชกเชฅเซ€ เชถเชฐเซ‚เช†เชค เช•เชฐเซ€เชถเซเช‚; เชœเซ‡เชฎเชจเซ‡ เช†เชฎเชพเช‚ เชฐเชธ เชจเชฅเซ€ เชคเซ‡เช“ เชชเซเชฐเชฅเชฎ เชตเชฟเชญเชพเช—เซ‹เชจเซ‡ เช›เซ‹เชกเซ€ เชถเช•เซ‡ เช›เซ‡.

เชฎเชพเชนเชฟเชคเซ€ เชธเช‚เช—เซเชฐเชน

เชชเชพเชฐเซเชธเชฐเชจเชพ เชชเซเชฐเชฅเชฎ เชธเช‚เชธเซเช•เชฐเชฃเชฎเชพเช‚, เชซเช•เซเชค เชœเซ‹เชตเชพเชฏเชพเชจเซ€ เชธเช‚เช–เซเชฏเชพ, เชŸเชฟเชชเซเชชเชฃเซ€เช“ เช…เชจเซ‡ เชฒเซ‡เช– เชฐเซ‡เชŸเชฟเช‚เช—เซเชธ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เชนเชคเชพ. เช† เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชธเชพเชฐเซเช‚ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเซ‡ เชคเชฎเชจเซ‡ เชตเชงเซ เชœเชŸเชฟเชฒ เชชเซเชฐเชถเซเชจเซ‹ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชคเซเช‚ เชจเชฅเซ€. เชธเชพเช‡เชŸเชจเชพ เชตเชฟเชทเชฏเซ‹เชจเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เช•เชฐเชตเชพเชจเซ‹ เช† เชธเชฎเชฏ เช›เซ‡; เช† เชคเชฎเชจเซ‡ เช–เซ‚เชฌ เชœ เชฐเชธเชชเซเชฐเชฆ เชธเช‚เชถเซ‹เชงเชจ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชœเซเช“ เช•เซ‡ เช•เซ‡เชŸเชฒเชพเช‚เช• เชตเชฐเซเชทเซ‹เชฎเชพเช‚ "C++" เชตเชฟเชญเชพเช—เชจเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏเชคเชพ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชพเชˆ เช›เซ‡.

เชฒเซ‡เช– เชตเชฟเชถเซเชฒเซ‡เชทเช•เชฎเชพเช‚ เชธเซเชงเชพเชฐเซ‹ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เช›เซ‡, เชนเชตเซ‡ เชคเซ‡ เชนเชฌ เชชเชฐเชค เช•เชฐเซ‡ เช›เซ‡ เช•เซ‡ เชœเซ‡เชจเชพเชฅเซ€ เชฒเซ‡เช– เชธเช‚เชฌเช‚เชงเชฟเชค เช›เซ‡, เชคเซ‡เชฎเชœ เชฒเซ‡เช–เช•เชจเซเช‚ เช‰เชชเชจเชพเชฎ เช…เชจเซ‡ เชคเซ‡เชจเซเช‚ เชฐเซ‡เชŸเชฟเช‚เช— (เช˜เชฃเซ€ เชฌเชงเซ€ เชฐเชธเชชเซเชฐเชฆ เชตเชธเซเชคเซเช“ เช…เชนเซ€เช‚ เชชเชฃ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเซ‡ เชชเช›เซ€เชฅเซ€ เช†เชตเชถเซ‡). เชกเซ‡เชŸเชพ csv เชซเชพเช‡เชฒเชฎเชพเช‚ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชœเซ‡ เช†เชจเชพ เชœเซ‡เชตเซ‹ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

2018-12-18T12:43Z,https://habr.com/ru/post/433550/,"ะœะตััะตะฝะดะถะตั€ Slack โ€” ะฟั€ะธั‡ะธะฝั‹ ะฒั‹ะฑะพั€ะฐ, ะบะพััะบะธ ะฟั€ะธ ะฒะฝะตะดั€ะตะฝะธะธ ะธ ะพัะพะฑะตะฝะฝะพัั‚ะธ ัะตั€ะฒะธัะฐ, ะพะฑะปะตะณั‡ะฐัŽั‰ะธะต ะถะธะทะฝัŒ",votes:7,votesplus:8,votesmin:1,bookmarks:32,
views:8300,comments:10,user:ReDisque,karma:5,subscribers:2,hubs:productpm+soft
...

เช…เชฎเชจเซ‡ เชธเชพเช‡เชŸเชจเชพ เชฎเซเช–เซเชฏ เชตเชฟเชทเชฏเซ‹เชจเซเช‚ เชนเชฌเชจเซ€ เชธเซ‚เชšเชฟ เชชเซเชฐเชพเชชเซเชค เชฅเชถเซ‡.

def get_as_str(link: str) -> Str:
    try:
        r = requests.get(link)
        return Str(r.text)
    except Exception as e:
        return Str("")

def get_hubs():
    hubs = []
    for p in range(1, 12):
        page_html = get_as_str("https://habr.com/ru/hubs/page%d/" % p)
        # page_html = get_as_str("https://habr.com/ru/hubs/geektimes/page%d/" % p)  # Geektimes
        # page_html = get_as_str("https://habr.com/ru/hubs/develop/page%d/" % p)  # Develop
        # page_html = get_as_str("https://habr.com/ru/hubs/admin/page%d" % p)  # Admin
        for hub in page_html.split("media-obj media-obj_hub"):
            info = Str(hub).find_between('"https://habr.com/ru/hub', 'list-snippet__tags') 
            if "*</span>" in info:
                hub_name = info.find_between('/', '/"')
                if len(hub_name) > 0 and len(hub_name) < 32:
                    hubs.append(hub_name)
    print(hubs)

find_between เชซเช‚เช•เซเชถเชจ เช…เชจเซ‡ Str เช•เซเชฒเชพเชธ เชฌเซ‡ เชŸเซ…เช—เซเชธ เชตเชšเซเชšเซ‡ เชธเซเชŸเซเชฐเชฟเช‚เช— เชชเชธเช‚เชฆ เช•เชฐเซ‡ เช›เซ‡, เชฎเซ‡เช‚ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเชฏเซ‹ เช›เซ‡ เช…เช—เชพเช‰. เชฅเซ€เชฎเซ‡เชŸเชฟเช• เชนเชฌเชจเซ‡ "*" เชธเชพเชฅเซ‡ เชšเชฟเชนเซเชจเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชœเซ‡เชฅเซ€ เชคเซ‡เช“ เชธเชฐเชณเชคเชพเชฅเซ€ เชชเซเชฐเช•เชพเชถเชฟเชค เชฅเชˆ เชถเช•เซ‡, เช…เชจเซ‡ เชคเชฎเซ‡ เช…เชจเซเชฏ เช•เซ‡เชŸเซ‡เช—เชฐเซ€เชจเชพ เชตเชฟเชญเชพเช—เซ‹ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเชŸเซ‡ เช…เชจเซเชฐเซ‚เชช เชฐเซ‡เช–เชพเช“เชจเซ‡ เช…เชจเช•เซ‹เชฎเซ‡เชจเซเชŸ เชชเชฃ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

get_hubs เชซเช‚เช•เซเชถเชจเชจเซเช‚ เช†เช‰เชŸเชชเซเชŸ เชเช•เชฆเชฎ เชชเซเชฐเชญเชพเชตเชถเชพเชณเซ€ เชฏเชพเชฆเซ€ เช›เซ‡, เชœเซ‡เชจเซ‡ เช†เชชเชฃเซ‡ เชถเชฌเซเชฆเช•เซ‹เชถ เชคเชฐเซ€เช•เซ‡ เชธเชพเชšเชตเซ€เช เช›เซ€เช. เชนเซเช‚ เช–เชพเชธ เช•เชฐเซ€เชจเซ‡ เชธเซ‚เชšเชฟเชจเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชฐเซ€เชคเซ‡ เชฐเชœเซ‚ เช•เชฐเซ€ เชฐเชนเซเชฏเซ‹ เช›เซเช‚ เชœเซ‡เชฅเซ€ เช•เชฐเซ€เชจเซ‡ เชคเชฎเซ‡ เชคเซ‡เชจเชพ เชตเซ‹เชฒเซเชฏเซเชฎเชจเซ‹ เช…เช‚เชฆเชพเชœ เชฒเช—เชพเชตเซ€ เชถเช•เซ‹.

hubs_profile = {'infosecurity', 'programming', 'webdev', 'python', 'sys_admin', 'it-infrastructure', 'devops', 'javascript', 'open_source', 'network_technologies', 'gamedev', 'cpp', 'machine_learning', 'pm', 'hr_management', 'linux', 'analysis_design', 'ui', 'net', 'hi', 'maths', 'mobile_dev', 'productpm', 'win_dev', 'it_testing', 'dev_management', 'algorithms', 'go', 'php', 'csharp', 'nix', 'data_visualization', 'web_testing', 's_admin', 'crazydev', 'data_mining', 'bigdata', 'c', 'java', 'usability', 'instant_messaging', 'gtd', 'system_programming', 'ios_dev', 'oop', 'nginx', 'kubernetes', 'sql', '3d_graphics', 'css', 'geo', 'image_processing', 'controllers', 'game_design', 'html5', 'community_management', 'electronics', 'android_dev', 'crypto', 'netdev', 'cisconetworks', 'db_admins', 'funcprog', 'wireless', 'dwh', 'linux_dev', 'assembler', 'reactjs', 'sales', 'microservices', 'search_technologies', 'compilers', 'virtualization', 'client_side_optimization', 'distributed_systems', 'api', 'media_management', 'complete_code', 'typescript', 'postgresql', 'rust', 'agile', 'refactoring', 'parallel_programming', 'mssql', 'game_promotion', 'robo_dev', 'reverse-engineering', 'web_analytics', 'unity', 'symfony', 'build_automation', 'swift', 'raspberrypi', 'web_design', 'kotlin', 'debug', 'pay_system', 'apps_design', 'git', 'shells', 'laravel', 'mobile_testing', 'openstreetmap', 'lua', 'vs', 'yii', 'sport_programming', 'service_desk', 'itstandarts', 'nodejs', 'data_warehouse', 'ctf', 'erp', 'video', 'mobileanalytics', 'ipv6', 'virus', 'crm', 'backup', 'mesh_networking', 'cad_cam', 'patents', 'cloud_computing', 'growthhacking', 'iot_dev', 'server_side_optimization', 'latex', 'natural_language_processing', 'scala', 'unreal_engine', 'mongodb', 'delphi',  'industrial_control_system', 'r', 'fpga', 'oracle', 'arduino', 'magento', 'ruby', 'nosql', 'flutter', 'xml', 'apache', 'sveltejs', 'devmail', 'ecommerce_development', 'opendata', 'Hadoop', 'yandex_api', 'game_monetization', 'ror', 'graph_design', 'scada', 'mobile_monetization', 'sqlite', 'accessibility', 'saas', 'helpdesk', 'matlab', 'julia', 'aws', 'data_recovery', 'erlang', 'angular', 'osx_dev', 'dns', 'dart', 'vector_graphics', 'asp', 'domains', 'cvs', 'asterisk', 'iis', 'it_monetization', 'localization', 'objectivec', 'IPFS', 'jquery', 'lisp', 'arvrdev', 'powershell', 'd', 'conversion', 'animation', 'webgl', 'wordpress', 'elm', 'qt_software', 'google_api', 'groovy_grails', 'Sailfish_dev', 'Atlassian', 'desktop_environment', 'game_testing', 'mysql', 'ecm', 'cms', 'Xamarin', 'haskell', 'prototyping', 'sw', 'django', 'gradle', 'billing', 'tdd', 'openshift', 'canvas', 'map_api', 'vuejs', 'data_compression', 'tizen_dev', 'iptv', 'mono', 'labview', 'perl', 'AJAX', 'ms_access', 'gpgpu', 'infolust', 'microformats', 'facebook_api', 'vba', 'twitter_api', 'twisted', 'phalcon', 'joomla', 'action_script', 'flex', 'gtk', 'meteorjs', 'iconoskaz', 'cobol', 'cocoa', 'fortran', 'uml', 'codeigniter', 'prolog', 'mercurial', 'drupal', 'wp_dev', 'smallbasic', 'webassembly', 'cubrid', 'fido', 'bada_dev', 'cgi', 'extjs', 'zend_framework', 'typography', 'UEFI', 'geo_systems', 'vim', 'creative_commons', 'modx', 'derbyjs', 'xcode', 'greasemonkey', 'i2p', 'flash_platform', 'coffeescript', 'fsharp', 'clojure', 'puppet', 'forth', 'processing_lang', 'firebird', 'javame_dev', 'cakephp', 'google_cloud_vision_api', 'kohanaphp', 'elixirphoenix', 'eclipse', 'xslt', 'smalltalk', 'googlecloud', 'gae', 'mootools', 'emacs', 'flask', 'gwt', 'web_monetization', 'circuit-design', 'office365dev', 'haxe', 'doctrine', 'typo3', 'regex', 'solidity', 'brainfuck', 'sphinx', 'san', 'vk_api', 'ecommerce'}

เชธเชฐเช–เชพเชฎเชฃเซ€ เชฎเชพเชŸเซ‡, geektimes เชตเชฟเชญเชพเช—เซ‹ เชตเชงเซ เชธเชพเชงเชพเชฐเชฃ เชฒเชพเช—เซ‡ เช›เซ‡:

hubs_gt = {'popular_science', 'history', 'soft', 'lifehacks', 'health', 'finance', 'artificial_intelligence', 'itcompanies', 'DIY', 'energy', 'transport', 'gadgets', 'social_networks', 'space', 'futurenow', 'it_bigraphy', 'antikvariat', 'games', 'hardware', 'learning_languages', 'urban', 'brain', 'internet_of_things', 'easyelectronics', 'cellular', 'physics', 'cryptocurrency', 'interviews', 'biotech', 'network_hardware', 'autogadgets', 'lasers', 'sound', 'home_automation', 'smartphones', 'statistics', 'robot', 'cpu', 'video_tech', 'Ecology', 'presentation', 'desktops', 'wearable_electronics', 'quantum', 'notebooks', 'cyberpunk', 'Peripheral', 'demoscene', 'copyright', 'astronomy', 'arvr', 'medgadgets', '3d-printers', 'Chemistry', 'storages', 'sci-fi', 'logic_games', 'office', 'tablets', 'displays', 'video_conferencing', 'videocards', 'photo', 'multicopters', 'supercomputers', 'telemedicine', 'cybersport', 'nano', 'crowdsourcing', 'infographics'}

เชฌเชพเช•เซ€เชจเชพ เชนเชฌ เช เชœ เชฐเซ€เชคเซ‡ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เชนเชคเชพ. เชนเชตเซ‡ เชซเช‚เช•เซเชถเชจ เชฒเช–เชตเซเช‚ เชธเชฐเชณ เช›เซ‡ เชœเซ‡ เชชเชฐเชฟเชฃเชพเชฎ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ เชถเซเช‚ เชฒเซ‡เช– geektimes เช…เชฅเชตเชพ เชชเซเชฐเซ‹เชซเชพเช‡เชฒ เชนเชฌเชจเซ‹ เช›เซ‡.

def is_geektimes(hubs: List) -> bool:
    return len(set(hubs) & hubs_gt) > 0

def is_geektimes_only(hubs: List) -> bool:
    return is_geektimes(hubs) is True and is_profile(hubs) is False

def is_profile(hubs: List) -> bool:
    return len(set(hubs) & hubs_profile) > 0

เช…เชจเซเชฏ เชตเชฟเชญเชพเช—เซ‹ ("เชตเชฟเช•เชพเชธ", "เชตเชนเซ€เชตเชŸ", เชตเช—เซ‡เชฐเซ‡) เชฎเชพเชŸเซ‡ เชธเชฎเชพเชจ เช•เชพเชฐเซเชฏเซ‹ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เชนเชคเชพ.

เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ

เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เชถเชฐเซ‚ เช•เชฐเชตเชพเชจเซ‹ เชธเชฎเชฏ เช›เซ‡. เช…เชฎเซ‡ เชกเซ‡เชŸเชพเชธเซ‡เชŸ เชฒเซ‹เชก เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชนเชฌ เชกเซ‡เชŸเชพ เชชเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เช•เชฐเซ€เช เช›เซ€เช.

def to_list(s: str) -> List[str]:
    # "user:popular_science+astronomy" => [popular_science, astronomy]
    return s.split(':')[1].split('+')

def to_date(dt: datetime) -> datetime.date:
    return dt.date()

df = pd.read_csv("habr_2019.csv", sep=',', encoding='utf-8', error_bad_lines=True, quotechar='"', comment='#')
dates = pd.to_datetime(df['datetime'], format='%Y-%m-%dT%H:%MZ')
dates += datetime.timedelta(hours=3)
df['date'] = dates.map(to_date, na_action=None)
hubs = df["hubs"].map(to_list, na_action=None)
df['hubs'] = hubs
df['is_profile'] = hubs.map(is_profile, na_action=None)
df['is_geektimes'] = hubs.map(is_geektimes, na_action=None)
df['is_geektimes_only'] = hubs.map(is_geektimes_only, na_action=None)
df['is_admin'] = hubs.map(is_admin, na_action=None)
df['is_develop'] = hubs.map(is_develop, na_action=None)

เชนเชตเซ‡ เช†เชชเชฃเซ‡ เชกเซ‡เชŸเชพเชจเซ‡ เชฆเชฟเชตเชธ เชชเซเชฐเชฎเชพเชฃเซ‡ เชœเซ‚เชฅเชฌเชฆเซเชง เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช เช…เชจเซ‡ เชตเชฟเชตเชฟเชง เชนเชฌ เชฎเชพเชŸเซ‡ เชชเซเชฐเช•เชพเชถเชจเซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เชฆเชฐเซเชถเชพเชตเซ€ เชถเช•เซ€เช เช›เซ€เช.

g = df.groupby(['date'])
days_count = g.size().reset_index(name='counts')
year_days = days_count['date'].values
grouped = g.sum().reset_index()
profile_per_day_avg = grouped['is_profile'].rolling(window=20, min_periods=1).mean()
geektimes_per_day_avg = grouped['is_geektimes'].rolling(window=20, min_periods=1).mean()
geektimesonly_per_day_avg = grouped['is_geektimes_only'].rolling(window=20, min_periods=1).mean()
admin_per_day_avg = grouped['is_admin'].rolling(window=20, min_periods=1).mean()
develop_per_day_avg = grouped['is_develop'].rolling(window=20, min_periods=1).mean()

เช…เชฎเซ‡ Matplotlib เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชชเซเชฐเช•เชพเชถเชฟเชค เชฒเซ‡เช–เซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเซ€เช เช›เซ€เช:

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เชฎเซ‡เช‚ เชšเชพเชฐเซเชŸเชฎเชพเช‚ โ€œเช—เซ€เช•เชŸเชพเช‡เชฎเซเชธโ€ เช…เชจเซ‡ โ€œเชซเช•เซเชค geektimesโ€ เชฒเซ‡เช–เซ‹เชจเซ‡ เชตเชฟเชญเชพเชœเชฟเชค เช•เชฐเซเชฏเชพ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชฒเซ‡เช– เชเช• เชœ เชธเชฎเชฏเซ‡ เชฌเช‚เชจเซ‡ เชตเชฟเชญเชพเช—เซ‹เชจเซ‹ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡ (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, โ€œDIYโ€ + โ€œเชฎเชพเชˆเช•เซเชฐเซ‹เช•เชจเซเชŸเซเชฐเซ‹เชฒเชฐเซเชธโ€ + โ€œC++โ€). เชฎเซ‡เช‚ เชธเชพเช‡เชŸ เชชเชฐ เชชเซเชฐเซ‹เชซเชพเช‡เชฒ เชฒเซ‡เช–เซ‹เชจเซ‡ เชนเชพเช‡เชฒเชพเช‡เชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชนเซ‹เชฆเซเชฆเซ‹ "เชชเซเชฐเซ‹เชซเชพเช‡เชฒ" เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเชฏเซ‹ เช›เซ‡, เชœเซ‹ เช•เซ‡ เช•เชฆเชพเชš เช† เชฎเชพเชŸเซ‡เชจเซ‹ เช…เช‚เช—เซเชฐเซ‡เชœเซ€ เชถเชฌเซเชฆ เชชเซเชฐเซ‹เชซเชพเช‡เชฒ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชธเชพเชšเซ‹ เชจเชฅเซ€.

เช…เช—เชพเช‰เชจเชพ เชญเชพเช—เชฎเชพเช‚ เช…เชฎเซ‡ เช† เช‰เชจเชพเชณเชพเชฎเชพเช‚ เชถเชฐเซ‚ เชฅเชคเชพ geektimes เชฎเชพเชŸเซ‡เชจเชพ เชฒเซ‡เช–เซ‹ เชฎเชพเชŸเซ‡ เชšเซ‚เช•เชตเชฃเซ€เชจเชพ เชจเชฟเชฏเชฎเซ‹เชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐ เชธเชพเชฅเซ‡ เชธเช‚เช•เชณเชพเชฏเซ‡เชฒ "geektimes เช…เชธเชฐ" เชตเชฟเชถเซ‡ เชชเซ‚เช›เซเชฏเซเช‚ เชนเชคเซเช‚. เชšเชพเชฒเซ‹ geektimes เชฒเซ‡เช–เซ‹เชจเซ‡ เช…เชฒเช—เชฅเซ€ เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเซ€เช:

df_gt = df[(df['is_geektimes_only'] == True)]
group_gt = df_gt.groupby(['date'])
days_count_gt = group_gt.size().reset_index(name='counts')
grouped = group_gt.sum().reset_index()
year_days_gt = days_count_gt['date'].values
view_gt_per_day_avg = grouped['views'].rolling(window=20, min_periods=1).mean()

เชชเชฐเชฟเชฃเชพเชฎ เชฐเชธเชชเซเชฐเชฆ เช›เซ‡. geektimes เชฒเซ‡เช–เซ‹เชจเชพ เช•เซเชฒ เชœเซ‹เชตเชพเชฏเชพเชจเซ‹ เช…เช‚เชฆเชพเชœเชฟเชค เช—เซเชฃเซ‹เชคเซเชคเชฐ เช•เซเชฏเชพเช‚เช• 1:5 เชจเซ€ เช†เชธเชชเชพเชธ เช›เซ‡. เชชเชฐเช‚เชคเซ เชœเซเชฏเชพเชฐเซ‡ เชœเซ‹เชตเชพเชฏเชพเชจเซ€ เช•เซเชฒ เชธเช‚เช–เซเชฏเชพเชฎเชพเช‚ เชจเซ‹เช‚เชงเชชเชพเชคเซเชฐ เชฐเซ€เชคเซ‡ เชตเชงเช˜เชŸ เชฅเชˆ, เชคเซเชฏเชพเชฐเซ‡ "เชฎเชจเซ‹เชฐเช‚เชœเชจ" เชฒเซ‡เช–เซ‹ เชœเซ‹เชตเชพเชจเซเช‚ เชชเซเชฐเชฎเชพเชฃ เชฒเช—เชญเช— เชธเชฎเชพเชจ เชธเซเชคเชฐเซ‡ เชฐเชนเซเชฏเซเช‚.

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เชคเชฎเซ‡ เช เชชเชฃ เชจเซ‹เช‚เชงเซ€ เชถเช•เซ‹ เช›เซ‹ เช•เซ‡ เชจเชฟเชฏเชฎเซ‹ เชฌเชฆเชฒเซเชฏเชพ เชชเช›เซ€ เชชเชฃ โ€œเช—เซ€เช•เชŸเชพเช‡เชฎเซเชธโ€ เชตเชฟเชญเชพเช—เชฎเชพเช‚ เชฒเซ‡เช–เซ‹เชจเซ€ เช•เซเชฒ เชฆเซƒเชถเซเชฏเซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เช˜เชŸเซ€ เช›เซ‡, เชชเชฐเช‚เชคเซ โ€œเช†เช‚เช– เชฆเซเชตเชพเชฐเชพโ€, เช•เซเชฒ เชฎเซ‚เชฒเซเชฏเซ‹เชจเชพ 5% เช•เชฐเชคเชพ เชตเชงเซ เชจเชนเซ€เช‚.

เชฒเซ‡เช– เชฆเซ€เช  เชœเซ‹เชตเชพเชฏเชพเชจเซ€ เชธเชฐเซ‡เชฐเชพเชถ เชธเช‚เช–เซเชฏเชพ เชœเซ‹เชตเชพเชจเซเช‚ เชฐเชธเชชเซเชฐเชฆ เช›เซ‡:

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

"เชฎเชจเซ‹เชฐเช‚เชœเชจ" เชฒเซ‡เช–เซ‹ เชฎเชพเชŸเซ‡ เชคเซ‡ เชธเชฐเซ‡เชฐเชพเชถเชฅเซ€ เชฒเช—เชญเช— 40% เชตเชงเชพเชฐเซ‡ เช›เซ‡. เช† เช•เชฆเชพเชš เช†เชถเซเชšเชฐเซเชฏเชœเชจเช• เชจเชฅเซ€. เชเชชเซเชฐเชฟเชฒเชจเซ€ เชถเชฐเซ‚เช†เชคเชฎเชพเช‚ เชจเชฟเชทเซเชซเชณเชคเชพ เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เช…เชธเซเชชเชทเซเชŸ เช›เซ‡, เช•เชฆเชพเชš เชคเซ‡ เชœ เชฅเชฏเซเช‚ เช›เซ‡, เช…เชฅเชตเชพ เชคเซ‡ เช…เชฎเซเช• เชชเซเชฐเช•เชพเชฐเชจเซ€ เชชเชพเชฐเซเชธเชฟเช‚เช— เชญเซ‚เชฒ เช›เซ‡, เช…เชฅเชตเชพ เช•เชฆเชพเชš เช—เซ€เช•เชŸเชพเช‡เชฎเซเชธเชจเชพ เชฒเซ‡เช–เช•เซ‹เชฎเชพเช‚เชจเชพ เชเช• เชตเซ‡เช•เซ‡เชถเชจ เชชเชฐ เช—เชฏเชพ เชนเชคเชพ;).

เชฎเชพเชฐเซเช— เชฆเซเชตเชพเชฐเชพ, เช—เซเชฐเชพเชซ เชฒเซ‡เช–เซ‹เชจเชพ เชฆเซƒเชถเซเชฏเซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพเชฎเชพเช‚ เชฌเซ‡ เชตเชงเซ เชจเซ‹เช‚เชงเชชเชพเชคเซเชฐ เชถเชฟเช–เชฐเซ‹ เชฌเชคเชพเชตเซ‡ เช›เซ‡ - เชจเชตเซเช‚ เชตเชฐเซเชท เช…เชจเซ‡ เชฎเซ‡เชจเซ€ เชฐเชœเชพเช“.

เชนเชฌเซเชธ

เชšเชพเชฒเซ‹ เชนเชฌเชจเชพ เชตเชšเชจเชฌเชฆเซเชง เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เชคเชฐเชซ เช†เช—เชณ เชตเชงเซ€เช. เชšเชพเชฒเซ‹ เชœเซ‹เชตเชพเชฏเชพเชจเซ€ เชธเช‚เช–เซเชฏเชพ เชฆเซเชตเชพเชฐเชพ เชŸเซ‹เชšเชจเชพ 20 เชนเชฌเชจเซ‡ เชธเซ‚เชšเชฟเชฌเชฆเซเชง เช•เชฐเซ€เช:

hubs_info = []
for hub_name in hubs_all:
    mask = df['hubs'].apply(lambda x: hub_name in x)
    df_hub = df[mask]

    count, views = df_hub.shape[0], df_hub['views'].sum()
    hubs_info.append((hub_name, count, views))

# Draw hubs
hubs_top = sorted(hubs_info, key=lambda v: v[2], reverse=True)[:20]
top_views = list(map(lambda x: x[2], hubs_top))
top_names = list(map(lambda x: x[0], hubs_top))

plt.rcParams["figure.figsize"] = (8, 6)
plt.bar(range(0, len(top_views)), top_views)
plt.xticks(range(0, len(top_names)), top_names, rotation=90)
plt.ticklabel_format(style='plain', axis='y')
plt.tight_layout()
plt.show()

เชชเชฐเชฟเชฃเชพเชฎ:

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เช†เชถเซเชšเชฐเซเชฏเชœเชจเช• เชฐเซ€เชคเซ‡, เชฆเซƒเชทเซเชŸเชฟเช•เซ‹เชฃเชจเซ€ เชฆเซเชฐเชทเซเชŸเชฟเช เชธเซŒเชฅเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชนเชฌ "เชฎเชพเชนเชฟเชคเซ€ เชธเซเชฐเช•เซเชทเชพ" เชนเชคเซเช‚; เชŸเซ‹เชšเชจเชพ 5 เชจเซ‡เชคเชพเช“เชฎเชพเช‚ "เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—" เช…เชจเซ‡ "เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชตเชฟเชœเซเชžเชพเชจ" เชชเชฃ เชถเชพเชฎเซ‡เชฒ เช›เซ‡.

เชเชจเซเชŸเชฟเชŸเซ‹เชช เชœเซ€เชŸเซ€เช•เซ‡ เช…เชจเซ‡ เช•เซ‹เช•เซ‹ เชชเชฐ เช•เชฌเชœเซ‹ เช•เชฐเซ‡ เช›เซ‡.

เชนเซ‡เชฌเซเชฐเชพเชธเซเชŸเซ‡เชŸเชฟเชธเซเชŸเชฟเช•เซเชธ: เชธเชพเช‡เชŸเชจเชพ เชธเซŒเชฅเซ€ เชตเชงเซ เช…เชจเซ‡ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒเชพ เชตเชฟเชญเชพเช—เซ‹เชจเซเช‚ เช…เชจเซเชตเซ‡เชทเชฃ เช•เชฐเชตเซเช‚

เชนเซเช‚ เชคเชฎเชจเซ‡ เชเช• เชฐเชนเชธเซเชฏ เช•เชนเซ€เชถ, เชŸเซ‹เชšเชจเชพ เชนเชฌ เชชเชฃ เชœเซ‹เชˆ เชถเช•เชพเชฏ เช›เซ‡ เช…เชนเซ€เช‚, เชœเซ‹ เช•เซ‡ เชœเซ‹เชตเชพเชฏเชพเชจเซ€ เชธเช‚เช–เซเชฏเชพ เชคเซเชฏเชพเช‚ เชฆเชฐเซเชถเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชจเชฅเซ€.

เชฐเซ‡เชŸเชฟเช‚เช—

เช…เชจเซ‡ เช…เช‚เชคเซ‡, เชตเชšเชจ เช†เชชเซ‡เชฒ เชฐเซ‡เชŸเชฟเช‚เช—. เชนเชฌ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เชกเซ‡เชŸเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡, เช…เชฎเซ‡ เช† เชตเชฐเซเชท 2019 เชฎเชพเชŸเซ‡ เชธเซŒเชฅเซ€ เชตเชงเซ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชนเชฌ เชฎเชพเชŸเซ‡เชจเชพ เชธเซŒเชฅเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชฒเซ‡เช–เซ‹ เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช.

เชฎเชพเชนเชฟเชคเซ€ เชธเซเชฐเช•เซเชทเชพ

เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชตเชฟเชœเซเชžเชพเชจ

เช•เชพเชฐเช•เชฟเชฐเซเชฆเซ€

เช†เช‡เชŸเซ€เชฎเชพเช‚ เช•เชพเชฏเชฆเซ‹

เชตเซ‡เชฌ เชตเชฟเช•เชพเชธ

เชœเซ€เชŸเซ€เช•เซ‡

เช…เชจเซ‡ เช…เช‚เชคเซ‡, เชœเซ‡เชฅเซ€ เช•เซ‹เชˆ เชจเชพเชฐเชพเชœ เชจ เชฅเชพเชฏ, เชนเซเช‚ เชธเซŒเชฅเซ€ เช“เช›เชพ เชฎเซเชฒเชพเช•เชพเชค เชฒเซ‡เชตเชพเชฏเซ‡เชฒ เชนเชฌ "gtk" เชจเซเช‚ เชฐเซ‡เชŸเชฟเช‚เช— เช†เชชเซ€เชถ. เชเช• เชตเชฐเซเชทเชฎเชพเช‚ เชคเซ‡ เชชเซเชฐเช•เชพเชถเชฟเชค เชฅเชฏเซเช‚ เชเช• เชฒเซ‡เช–, เชœเซ‡ "เช†เชชเชฎเซ‡เชณเซ‡" เชชเชฃ เชฐเซ‡เชŸเชฟเช‚เช—เชจเซ€ เชชเซเชฐเชฅเชฎ เชฒเชพเช‡เชจ เชงเชฐเชพเชตเซ‡ เช›เซ‡.

เชจเชฟเชทเซเช•เชฐเซเชท

เช•เซ‹เชˆ เชจเชฟเชทเซเช•เชฐเซเชท เชนเชถเซ‡ เชจเชนเซ€เช‚. เชฆเชฐเซ‡เช•เชจเซ‡ เชตเชพเช‚เชšเซ€เชจเซ‡ เช†เชจเช‚เชฆ เชฅเชฏเซ‹.

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹