αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αžαžΎβ€‹αž’αŸ’αž“αž€β€‹αž˜αžΆαž“β€‹αž€αž·αž…αŸ’αž…αž€αžΆαžšβ€‹αžŠαŸ‚αž›β€‹αž’αŸ’αžœαžΎβ€‹αž˜αŸ’αžαž„β€‹αž‘αŸ€αžβ€‹αž–αžΈβ€‹αž˜αž½αž™β€‹αžαŸ’αž„αŸƒβ€‹αž‘αŸ…β€‹αž˜αž½αž™β€‹αžŸαž”αŸ’αžαžΆαž αŸβ€‹αž¬β€‹αž‘αŸ? αž§αž‘αžΆαž αžšαžŽαŸαž€αžΆαžšαžŸαžšαžŸαŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαŸ” αž’αŸ’αž“αž€αžŸαŸ’αž“αžΎαžŸαž»αŸ†αž‘αž·αž“αŸ’αž“αž“αŸαž™ αžœαž·αž—αžΆαž‚αžœαžΆ αžŸαŸ’αžšαž˜αŸƒαž˜αžΎαž›αžœαžΆ (αž’αŸ’αžœαžΎαž€αŸ’αžšαžΆαž αŸ’αžœ αž‚αŸ†αž“αžΌαžŸαžαžΆαž„) αž αžΎαž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž•αŸ’αž‰αžΎαžœαžΆαž‘αŸ…αž…αŸ…αž αŸ’αžœαžΆαž™αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž…αž»αŸ‡αž™αŸ‰αžΆαž„αžŽαžΆαž”αžΎαž’αŸ’αžœαžΈαŸ—αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·?

αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αŸαžšαŸ€αž“αž“αŸαŸ‡ αž™αžΎαž„αž“αžΉαž„αž”αž„αŸ’αž€αžΎαž bot αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ Telegram αžŠαŸ‚αž›αž“αžΉαž„αž‡αž½αž™αž’αŸ’αžœαžΎαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αŸ” αž αžΎαž™αž’αŸ’αžœαžΈαžŠαŸ‚αž›αž–αž·αžŸαŸαžŸαž”αŸ†αž•αž»αžαž“αŸ„αŸ‡αž‚αžΊαžαžΆαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‘αžΆαŸ†αž„αž˜αžΌαž›αž“αžΉαž„αž˜αžΆαž“αž€αžΌαžŠαžαŸ’αžšαžΉαž˜αžαŸ‚ 50 αž”αž“αŸ’αž‘αžΆαžαŸ‹αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡! αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž€αŸ†αž–αž»αž„αž”αž„αŸ’αž€αžΎαž bot αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ Telegram αž‡αžΆαž›αžΎαž€αžŠαŸ†αž”αžΌαž„αž“αŸ„αŸ‡ αž’αŸ’αž“αž€αž€αŸαž‚αž½αžšαžαŸ‚αž’αžΆαž“αžœαžΆαžŠαŸ‚αžšαŸ” αž”αŸ’αžšαž€αžΆαžŸ.

Skillbox αžŽαŸ‚αž“αžΆαŸ†αŸ– αžœαž‚αŸ’αž‚αžŸαž·αž€αŸ’αžŸαžΆαž‡αžΆαž€αŸ‹αžŸαŸ’αžαŸ‚αž„ αž’αŸ’αž“αž€αž’αž—αž·αžœαžŒαŸ’αžαž“αŸ Python αž–αžΈαžŠαŸ†αž”αžΌαž„.

αž™αžΎαž„αžšαŸ†αž›αžΉαž€αŸ– αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αž’αžΆαž“αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸƒ "Habr" - αž€αžΆαžšαž”αž‰αŸ’αž…αž»αŸ‡αžαž˜αŸ’αž›αŸƒ 10 rubles αž“αŸ…αž–αŸαž›αž…αž»αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡αž€αŸ’αž“αž»αž„αžœαž‚αŸ’αž‚αžŸαž·αž€αŸ’αžŸαžΆ Skillbox αžŽαžΆαž˜αž½αž™αžŠαŸ„αž™αž”αŸ’αžšαžΎαž›αŸαžαž€αžΌαžŠαž•αŸ’αžŸαž–αŸ’αžœαž•αŸ’αžŸαžΆαž™ "Habr" αŸ”

αžαŸ„αŸ‡β€‹αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜

αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„αž”αžŽαŸ’αžŽαžΆαž›αŸαž™

αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎ google-cloud-bigquery αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αž–αžΈ Google BigQuery αŸ” matplotlib, αžŸαŸ’αž–αžΉαž€αžŸαŸ’αžšαž–αž“αŸ‹ ΠΈ αžαŸ’αž›αžΆαžƒαŸ’αž˜αž»αŸ†αž•αŸαž“αžŠαžΆ αž“αžΉαž„αž‡αž½αž™αž’αŸ’αž“αž€αž±αŸ’αž™αž˜αžΎαž›αžƒαžΎαž‰αž‘αž·αž“αŸ’αž“αž“αŸαž™αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ” python-telegram-bot αž“αžΉαž„αž”αž‰αŸ’αž‡αžΌαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž…αž”αŸ‹αž‘αŸ… Telegram αŸ”

pip3 αžŠαŸ†αž‘αžΎαž„ google-cloud-bigquery matplotlib numpy pandas python-telegram-bot

αž€αŸ†αž–αž»αž„αž—αŸ’αž‡αžΆαž”αŸ‹ Google BigQuery API

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž™αžΎαž„αž…αž„αŸ‹αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžŸαŸαžœαžΆαž€αž˜αŸ’αž˜ αž™αžΎαž„αžαŸ’αžšαžΌαžœαž—αŸ’αž‡αžΆαž”αŸ‹ Google BigQuery APIαŸ” αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŠαžΌαž…αž“αŸαŸ‡αž™αžΎαž„αž‘αŸ… Google Developers Console αž αžΎαž™αž”αž„αŸ’αž€αžΎαžαž‚αž˜αŸ’αžšαŸ„αž„αžαŸ’αž˜αžΈ (αž¬αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž‚αž˜αŸ’αžšαŸ„αž„αžŠαŸ‚αž›αž˜αžΆαž“αžŸαŸ’αžšαžΆαž”αŸ‹)αŸ”

αž“αŸ…αž€αŸ’αž“αž»αž„αž•αŸ’αž‘αžΆαŸ†αž„αž”αž‰αŸ’αž‡αžΆ αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αž”αžΎαž€ APIS αž“αž·αž„ SERVICES αž αžΎαž™αžšαž€αž˜αžΎαž› BigQuery APIαŸ”

αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αž’αž“αž»αž‰αŸ’αž‰αžΆαž αžŠαžΎαž˜αŸ’αž”αžΈαž—αŸ’αž‡αžΆαž”αŸ‹ API αŸ”

αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αž”αž„αŸ’αž€αžΎαžαžŸαŸ„αž‚αžŽαž“αžΈ

αžαŸ„αŸ‡αž‘αŸ…αž˜αŸ’αžαž„αž‘αŸ€αž Google Developers Consoleαž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž•αŸ’αž‘αžΆαŸ†αž„αž–αŸαžαŸŒαž˜αžΆαž“αžŸαž˜αŸ’αž„αžΆαžαŸ‹ αž”αž„αŸ’αž€αžΎαžαž–αŸαžαŸŒαž˜αžΆαž“αžŸαž˜αŸ’αž„αžΆαžαŸ‹ αž“αž·αž„αžŸαŸ„αž‚αžŽαž“αžΈαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αŸ”

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€ - αž‚αžŽαž“αžΈαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αžαŸ’αž˜αžΈ αž αžΎαž™αž”αž‰αŸ’αž…αžΌαž›αžˆαŸ’αž˜αŸ„αŸ‡αž€αŸ’αž“αž»αž„αž”αŸ’αžšαž’αž”αŸ‹αžˆαŸ’αž˜αŸ„αŸ‡αž‚αžŽαž“αžΈαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αŸ”

αž–αžΈαž”αž‰αŸ’αž‡αžΈαž‘αž˜αŸ’αž›αžΆαž€αŸ‹αž…αž»αŸ‡ αžαž½αž“αžΆαž‘αžΈ αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αž‚αž˜αŸ’αžšαŸ„αž„ > αž˜αŸ’αž…αžΆαžŸαŸ‹ αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž”αž„αŸ’αž€αžΎαžαŸ”

αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αž―αž€αžŸαžΆαžšαžŠαŸ‚αž›αž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‘αžΆαž‰αž™αž€αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αŸαž αŸ…αžαžΆ creds.json αŸ”

αž€αŸ†αžŽαžαŸ‹ GOOGLE_APPLICATION_CREDENTIALS αžŠαŸ„αž™αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž•αŸ’αž›αžΌαžœαž‘αŸ…αž€αžΆαž“αŸ‹ creds.json αž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸ’αžαžΆαž“αžΈαž™αŸ”

αž“αžΆαŸ†αž…αŸαž‰ GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_CREDS.JSON]'

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αžœαžΈαŸ—αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž›αŸ’αž’ αžŠαž›αŸ‹αž–αŸαž›αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž αžΎαž™αŸ”

αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈ

αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž”αž„αŸ’αžšαŸ€αž“ αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎαž‘αž·αž“αŸ’αž“αž“αŸαž™αž–αžΈ bigquery-public-data.stackoverflow αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžšαž”αžŸαŸ‹αž™αžΎαž„ αž™αžΎαž„αž“αžΉαž„αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αŸ„αŸ‡αž–αž»αž˜αŸ’αž–αž”αŸ’αžšαž…αžΆαŸ†αžαŸ’αž„αŸƒαŸ”

αž’αŸ’αžœαžΈαž‚αŸ’αžšαž”αŸ‹αž™αŸ‰αžΆαž„αž‚αžΊαžŸαžΆαž˜αž‰αŸ’αž‰αžŽαžΆαžŸαŸ‹αŸ”

αžŸαž½αžšαžαžΆαžšαžΆαž„ -> αž˜αžΎαž›αžƒαžΎαž‰αž‘αž·αž“αŸ’αž“αž“αŸαž™ -> αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž€αžΆαžšαž˜αžΎαž›αžƒαžΎαž‰ -> αž•αŸ’αž‰αžΎαžšαžΌαž”αž—αžΆαž–

αžαŸ„αŸ‡αž”αž„αŸ’αž€αžΎαžαž˜αž»αžαž„αžΆαžšαž˜αž½αž™αžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ†αžŽαžαŸ‹αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž“αžΈαž˜αž½αž™αŸ—αŸ”

αžŸαŸ†αžŽαž½αžšαž‘αŸ…αž€αžΆαž“αŸ‹ BigQuery

αžŠαŸ†αž”αžΌαž„αž™αžΎαž„αž“αžΆαŸ†αž…αžΌαž›αž”αžŽαŸ’αžŽαžΆαž›αŸαž™αŸ”

αž–αžΈ google.cloud αž“αžΆαŸ†αž…αžΌαž› bigquery

αž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαž˜αž»αžαž„αžΆαžšαž˜αž½αž™αž αŸ…αžαžΆ query_to_bigquery αžŠαŸ‚αž›αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž‚αžΊ query αŸ”

def query_to_bigquery(query):
    client = bigquery.Client()
    query_job = client.query(query)
    result = query_job.result()
    dataframe = result.to_dataframe()
    return dataframe

αž˜αž»αžαž„αžΆαžšαž“αŸαŸ‡αž“αžΉαž„αžαŸ’αžšαž‘αž”αŸ‹αžŸαŸ†αžŽαžΎαž‡αžΆαžŸαŸŠαž»αž˜αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ”

αž€αžΆαžšαž˜αžΎαž›αžƒαžΎαž‰αž‘αž·αž“αŸ’αž“αž“αŸαž™

αžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αž‰αŸ’αž αžΆαž“αŸαŸ‡ αžŸαžΌαž˜αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ matplotlib αŸ”

αž“αžΆαŸ†αž…αžΌαž› matplotlib.pyplot αž‡αžΆ plt

αž™αžΎαž„αžαŸ’αžšαžΌαžœαž€αžΆαžšαž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž…αŸ†αž“αž½αž“αž”αŸ’αžšαžΆαŸ† αžŠαŸ‚αž› x αž‡αžΆαž‘αž·αž“αŸ’αž“αž“αŸαž™αž’αŸαž€αŸ’αžŸ x x_label αž‚αžΊαž‡αžΆαž…αŸ†αžŽαž„αž‡αžΎαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸαž€αŸ’αžŸ y αž‚αžΊαž‡αžΆαž‘αž·αž“αŸ’αž“αž“αŸαž™αž’αŸαž€αŸ’αžŸ y y_label αž‚αžΊαž‡αžΆαž…αŸ†αžŽαž„αž‡αžΎαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸαž€αŸ’αžŸ αž αžΎαž™αž…αŸ†αžŽαž„αž‡αžΎαž„αž‚αžΊαž‡αžΆαž…αŸ†αžŽαž„αž‡αžΎαž„αž“αŸƒαž€αžΆαžšαž˜αžΎαž›αžƒαžΎαž‰αž‘αžΆαŸ†αž„αž˜αžΌαž›αŸ”

def visualize_bar_chart(x, x_label, y, y_label, title):
    plt.title(title)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    index = np.arange(len(x))
    plt.xticks(index, x, fontsize=5, rotation=30)
    plt.bar(index, y)
    return plt

αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αžšαžΌαž”αž—αžΆαž–

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž…αžΌαžšαž™αžΎαž„αž”αŸ’αžšαžΎαž˜αž»αžαž„αžΆαžšαž–αžΈαžšαžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαžαž€αžΆαžšαž˜αžΎαž›αžƒαžΎαž‰ αž“αž·αž„αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αžœαžΆαŸ”

αž™αžΎαž„β€‹αž“αžΉαž„β€‹αž•αŸ’αž‰αžΎβ€‹αž…αŸ†αž“αž½αž“β€‹αž”αŸ’αžšαž€αžΆαžŸβ€‹αž…αŸαž‰β€‹αž•αŸ’αžŸαžΆαž™β€‹αž‡αžΆβ€‹αžšαŸ€αž„β€‹αžšαžΆαž›αŸ‹β€‹αžαŸ’αž„αŸƒαŸ” αžŠαŸ†αž”αžΌαž„αž™αžΎαž„αžŸαžšαžŸαŸαžšαžŸαŸ†αžŽαžΎαŸ”

query = """
        SELECT DATE(creation_date) date, COUNT(*) total_posts
        FROM `bigquery-public-data.stackoverflow.post_history`
        GROUP BY 1
        HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
        ORDER BY 1
        """

αžŸαŸ†αžŽαž½αžšαž‡αž½αž™αž”αŸ’αžšαž˜αžΌαž›αž‘αž·αž“αŸ’αž“αž“αŸαž™αžšαž™αŸˆαž–αŸαž›αž–αžΈαžšαžŸαž”αŸ’αžαžΆαž αŸαžŠαŸ„αž™αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž–αžΈαžαŸ’αž„αŸƒαž‘αžΈ 2 αžαŸ‚αž’αŸ’αž“αžΌ αž†αŸ’αž“αžΆαŸ† 2018αŸ”

αž™αžΎαž„αž”αŸ’αžšαžΎαž€αžΆαž›αž”αžšαž·αž…αŸ’αž†αŸαž‘αž“αŸαŸ‡ αž–αžΈαž–αŸ’αžšαŸ„αŸ‡ 2018-12-02 αž‚αžΊαž‡αžΆαž‘αž·αž“αŸ’αž“αž“αŸαž™αž…αž»αž„αž€αŸ’αžšαŸ„αž™αž”αŸ†αž•αž»αžαžŠαŸ‚αž›αž”αžΆαž“αž€αžαŸ‹αžαŸ’αžšαžΆαž“αŸ…αž€αŸ’αž“αž»αž„ bigquery-public-data.stackoverflow.post_history αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎ CURRENT_DATE() αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αžαŸ’αž˜αžΈαž”αŸ†αž•αž»αžαŸ”

αž αŸ…αž˜αž»αžαž„αžΆαžš query_to_bigquery αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ”

dataframe = query_to_bigquery(αžŸαŸ†αžŽαž½αžš)

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž™αžΎαž„αž”αŸ’αžšαžΎαž‡αž½αžšαžˆαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™αž€αžΆαž›αž”αžšαž·αž…αŸ’αž†αŸαž‘αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸαž€αŸ’αžŸ x αž“αž·αž„αž‡αž½αžšαžˆαžš total_posts αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸαž€αŸ’αžŸ y αŸ”

x = dataframe['date'].tolist()
y = dataframe['total_posts'].tolist()

αž™αžΎαž„αž˜αžΎαž›αžƒαžΎαž‰αžœαžΆαžŠαŸ„αž™αž”αŸ’αžšαžΎαž˜αž»αžαž„αžΆαžš visualize_bar_chart αž αžΎαž™αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αžœαžΆαž‡αžΆαžšαžΌαž”αž—αžΆαž–αŸ”

plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='αž”αŸ’αžšαž€αžΆαžŸαž”αŸ’αžšαž…αžΆαŸ†αžαŸ’αž„αŸƒ')
plt.savefig('viz.png')

αž™αžΎαž„αžšαž»αŸ†αž€αžΌαžŠαž“αŸαŸ‡αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αž»αžαž„αžΆαžšαž˜αž½αž™αž αŸ…αžαžΆ get_and_save_imageαŸ”

def get_and_save_image():
    query = """
            SELECT DATE(creation_date) date, COUNT(*) total_posts
            FROM `bigquery-public-data.stackoverflow.post_history`
            GROUP BY 1
            HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
            ORDER BY 1
            """
    dataframe = query_to_bigquery(query)  
    x = dataframe['date'].tolist()
    y = dataframe['total_posts'].tolist()
    plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='Daily Posts')
    plt.savefig('viz.png')

αž•αŸ’αž‰αžΎαžšαžΌαž”αž—αžΆαž–

αžŠαžΎαž˜αŸ’αž”αžΈαž•αŸ’αž‰αžΎαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαž‘αŸ…αž€αžΆαž“αŸ‹αž’αŸ’αž“αž€αž‘αž‘αž½αž› αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαžŠαžΉαž„αž–αžΈαž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžš chat_idαŸ”

αž™αžΎαž„β€‹αž”αŸ’αžšαžΎ userinfobot αž αžΎαž™αžœαžΆαž™ /start αŸ” bot αž†αŸ’αž›αžΎαž™αžαž”αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž–αŸαžαŸŒαž˜αžΆαž“αž…αžΆαŸ†αž”αžΆαž…αŸ‹ chat_id αž˜αžΆαž“αž“αŸ…αž€αŸ’αž“αž»αž„αžœαžΆαž›αž›αŸαžαžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž…αžΌαžšαž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαž˜αž»αžαž„αžΆαžš send_imageαŸ” αžœαžΆαž“αžΉαž„αž”αŸ’αžšαžΎαž˜αž»αžαž„αžΆαžš get_and_save_image αžŠαžΎαž˜αŸ’αž”αžΈαž‘αžΆαž‰αž™αž€ αž“αž·αž„αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αžšαžΌαž”αž—αžΆαž–αŸ” αž αžΎαž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž™αžΎαž„αž•αŸ’αž‰αžΎαž’αŸ’αžœαžΈαž‚αŸ’αžšαž”αŸ‹αž™αŸ‰αžΆαž„αž‘αŸ…αž‘αŸ†αž“αžΆαž€αŸ‹αž‘αŸ†αž“αž„αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœαŸ”

def send_image(bot, update):
    get_and_save_image()
    chat_id = 'CHAT_ID_RECEIVER'
    bot.send_photo(chat_id=chat_id, photo=open('viz.png','rb'))

αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž…αž˜αŸ’αž”αž„

αž‡αžΆαž…αž»αž„αž€αŸ’αžšαŸ„αž™ αž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαž˜αž»αžαž„αžΆαžšαž˜αž½αž™αž‘αŸ€αž αžŸαŸ†αžαžΆαž“αŸ‹ αžŠαžΎαž˜αŸ’αž”αžΈαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαŸ” αž€αž»αŸ†αž—αŸ’αž›αŸαž…αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžš YOUR_TOKEN αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αžΌαžαŸ”

αž…αž„αž…αžΆαŸ†αŸ– αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž“αŸαŸ‡αž“αžΉαž„αž•αŸ’αž‰αžΎαžšαžΌαž”αž—αžΆαž–αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž“αŸ…αž–αŸαž›αž’αŸ’αž“αž€αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αŸ” αž‡αžΆαž§αž‘αžΆαž αžšαžŽαŸ αž™αžΎαž„αž“αžΉαž„αž•αŸ’αž‰αžΎαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαž“αŸ…αž˜αŸ‰αŸ„αž„αž”αŸ’αžšαžΆαŸ†αž”αž½αž“αž–αŸ’αžšαžΉαž€αž‡αžΆαžšαŸ€αž„αžšαžΆαž›αŸ‹αžαŸ’αž„αŸƒαŸ”

def main():
    updater = Updater('YOUR_TOKEN')
    updater.job_queue.run_daily(send_image, time=datetime.datetime.strptime('9:00AM', '%I:%M%p').time(), days=(0,1,2,3,4,5,6))
    updater.start_polling()
    updater.idle()
 
if __name__ == '__main__':
    main()

αž‡αžΆαž›αž‘αŸ’αž’αž•αž› αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžšαž”αžŸαŸ‹αž™αžΎαž„αž“αžΉαž„αž˜αžΎαž›αž‘αŸ…αžŠαžΌαž…αž“αŸαŸ‡αŸ–

from google.cloud import bigquery
from telegram.ext import Updater
 
import matplotlib.pyplot as plt
import numpy as np
import datetime
 
def query_to_bigquery(query):
    client = bigquery.Client()
    query_job = client.query(query)
    result = query_job.result()
    dataframe = result.to_dataframe()
    return dataframe
 
def visualize_bar_chart(x, x_label, y, y_label, title):
    plt.title(title)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    index = np.arange(len(x))
    plt.xticks(index, x, fontsize=5, rotation=30)
    plt.bar(index, y)
    return plt
 
def get_and_save_image():
    query = """
            SELECT DATE(creation_date) date, COUNT(*) total_posts
            FROM `bigquery-public-data.stackoverflow.post_history`
            GROUP BY 1
            HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
            ORDER BY 1
            """
    dataframe = query_to_bigquery(query)  
    x = dataframe['date'].tolist()
    y = dataframe['total_posts'].tolist()
    plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='Daily Posts')
    plt.savefig('viz.png')
 
def send_image(bot, update):
    get_and_save_image()
    chat_id = 'CHAT_ID_RECEIVER'
    bot.send_photo(chat_id=chat_id, photo=open('viz.png', 'rb'))
 
def main():
    updater = Updater('YOUR_TOKEN')
    updater.job_queue.run_daily(send_image, time=datetime.datetime.strptime('9:00AM', '%I:%M%p').time(), days=(0,1,2,3,4,5,6))
    updater.start_polling()
    updater.idle()
 
if __name__ == '__main__':
main()

αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž―αž€αžŸαžΆαžšαž αžΎαž™αž αŸ…αžœαžΆαžαžΆ main.py αŸ”

αž™αžΎαž„αž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ„αž™αž”αž‰αŸ’αž…αžΌαž›αž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆαž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸ’αžαžΆαž“αžΈαž™αŸ–

python3 main.py

αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αžšαž½αž…αžšαžΆαž›αŸ‹αž αžΎαž™αŸ” αž₯αž‘αžΌαžœαž“αŸαŸ‡αž™αžΎαž„αž˜αžΆαž“αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαžŠαŸ‚αž›αž˜αžΆαž“ 50 αž”αž“αŸ’αž‘αžΆαžαŸ‹αž“αŸƒαž€αžΌαžŠαžŠαŸ‚αž›αž”αž„αŸ’αž€αžΎαžαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž’αž“αŸ’αžαžšαžΆαž‚αž˜αž“αŸαžšαž”αžŸαŸ‹αž™αžΎαž„αŸ”

αžαŸ„αŸ‡αž–αž·αž“αž·αžαŸ’αž™αž˜αžΎαž› bot αž–αžΈαž‘αžΈαž“αŸαŸ‡αžŠαŸ„αž™αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ / αž•αŸ’αž‰αžΎαŸ”

αžšαž”αŸ€αž”αž•αŸ’αž‘αŸαžšαžšαž”αžΆαž™αž€αžΆαžšαžŽαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž‘αŸ…αž˜αž“αž»αžŸαŸ’αžŸαž™αž“αŸ’αžαŸ” αž€αžΆαžšαžŸαžšαžŸαŸαžš bot αž“αŸ…αž€αŸ’αž“αž»αž„ Python αž“αž·αž„ Google BigQuery

αž’αŸ’αž“αž€αž’αžΆαž…αž‘αž‘αž½αž›αž”αžΆαž“αž›αŸαžαž€αžΌαžŠαžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž…αž”αŸ‹αž“αŸ… GitHub αžšαž”αžŸαŸ‹αžαŸ’αž‰αž»αŸ†.

Skillbox αžŽαŸ‚αž“αžΆαŸ†αŸ–

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹