Сон та здоров'я

Статистика по місяцях. Статистика днів народження. Смертність у Росії за місяцями

Народжуваність кожної країни має значення. Якщо державі цей показник низький рівень, то створюється загроза територіальної цілісності країни. Висока народжуваність та низька покращують, гарантують збереження нації. Статистика народжуваності дає змогу відстежувати необхідні показники.

Народжуваність також показник рівня країни. У бідних державах, де люди отримують маленьку, зазвичай високий рівень, дітей світ з'являється мало. У розвинених країнах, де хороші умови для проживання, населення не боїться народжувати по кілька дітей.

Динаміка чисельності населення РФ

У таблиці представлена ​​статистика народжуваності у Росії за роками. Нею можна будувати висновки про тому, як змінювався природний приріст населення:


Рік Кількість народжених дітей Загальна чисельність населення
1927 4 688 000 94 596 000
1939 4 329 000 108 785 000
1950 2 859 000 102 833 000
1960 2 782 353 119 906 000
1970 1 903 713 130 252 000
1980 2 202 779 138 483 00
1990 1 988 858 148 273 746
2000 1 266 800 146 303 611
2010 1 788 948 142 865 433
2015 1 940 579 146 544 710
2016 1 888 729 146 804 372

Щоб з'ясувати, якої статі дітей з'являється на світ більше, існує статистика народжуваності хлопчиків та дівчаток. Розглянемо показники по місту Новополоцьку. У 2014 році з'явилося на світ близько п'ятисот дітей жіночої статі та майже шістсот чоловічої. 2015 рік ознаменувався народженням 595 хлопчиків та 537 дівчаток. За іншими населеними пунктами йде приблизно так само.

Статистика народжуваності дівчаток і хлопчиків говорить про те, що немовлят чоловічої статі з'являється на світ більше.

  1. Чеченська Республіка.
  2. Інгушетія.
  3. Ямало-Ненецький автономний округ.

Найгірші показники має:

  1. Тюменська обл.
  2. Львівська обл.
  3. Львівська обл.

Загальна кількість продовжує зменшуватися, незважаючи на те, що смертність не перевищила статистику народжуваності в Росії в 2016 році. При цьому в державі вийшло більш високий рівень. Статистика народжуваності за 10 років показує, що Росія посідала 63 місце у світі (дані за 2016 рік) за природним приростом населення. У таблиці відображено основні причини, через які вмирали росіяни (період із січня по серпень 2016 року):

Кількість осіб (у тисячах)
716,7
198,2
13,5
5,7
16,3
7,2
інфекцій21,8

Статистика народжуваності за 2016 рік показує, що щільність населення РФ становить 8,6 людина на 1 км². Це один із найнижчих показників у світі. Величезні території просто порожні. Села та маленькі міста за останні 20 років вимерли, а деякі місцевості ніколи не були заселені.

Ситуація у світі на початок 2017 року

Майже на 50 млн. осіб зросла народжуваність у світі за статистикою на першу чверть 2017 року. Щодня у світі народжується кілька сотень тисяч малюків. Етой факт можна перевірити за лічильником людства в режимі.

Народжуваність та смертність за 2017 рік у Росії

Росія завжди була найбільшою територіальною державою у світі. Проте чисельність населення тут невблаганно скорочується. Країна переживає демографічну кризу. Згідно зі статистикою народжуваності в Росії на початок 2017 року, дітей народилося менше порівняно з попереднім роком.

Приріст населення в Білорусі та Україні

Статистика народжуваності за роками в Україні:

Рік Кількість народжених дітей Загальна чисельність населення
2000 немає даних48 663 600
2005 426 100 47 100 462
2010 497 700 45 782 592
2015 411 800 42 759 300

Нижче представлена ​​діаграма зстатистикою народжуваності в Україні а також смертність за роками (за останні 25 років). Він наочно показує, які роки чисельність населення зростала, а які – знижувалася.

Статистика народжуваності в Білорусі за роками:

Рік Кількість народжених дітей Загальна чисельність населення
2000 93 691 9 988 000
2005 90 508 9 664 000
2010 108 050 9 491 000
2015 119 509 9 481 000

Статистика народжуваності хлопчиків у Республіці Білорусь наводиться у цифрах на графіку нижче. Немовлят чоловічої статі народжується трохи більше ніж жіночої статі. Але останнім часом кількість народжених хлопчиків трохи зменшилася. Що стосується чисельності чоловічого та жіночого населення, то, судячи з таблиці чоловіків у Білорусі більше, ніж жінок.


За останні роки в Росії та Україні чисельність населення знизилася, а в Білорусі зросла, статистика народжуваності та смертності в Росії підтверджує цей факт.

Ось, тримай підфарбований варіант: посилання(https://transfiles.ru/m757t)
В ексельці це робиться через умовне форматування/колірні шкали (у цьому випадку кожен рядок підфарбований незалежно від інших)
+ додав знизу середнє за весь період та середні за десятиліттями.

Протягом 50-60 років рекордна народжуваність відзначалася у січні, а найнижча – у грудні, що дивно, враховуючи що сусідні місяці. можу припустити 2 причини:
а - при народженні в грудні час зачаття припадало на велику посаду, а при народженні в січні - на проміжок часу між паскою та інтенсивними травневими польовими роботами.
б – дітей, народжених у грудні люди навмисно записували (реєстрували) у січень. Про таку тенденцію мені бабуся розповідала (до речі, тіткою мою вона саме так зареєструвала на січень, хоча за фактом та народжена в грудні). Але в 70-х ця тенденція зменшилася (або облік став вестися суворіше завдяки розвитку пологової допомоги).

Загалом протягом усієї другої половини 20-го століття переважала по дітонародження весна. А якщо точніше, то в середині 20-го століття переважали зимово-весняні народження (зачаття відповідно навесні та на початку літа), а далі йшло невпевнене зміщення дітороджень на весняно-літній період (тобто зачаття зміщувалися на кінець літа – початок осені – сезон) відпусток) - що явно говорить про збільшення частки городян, розвиток міської культури та деградацію сільського суспільства. Причому в умовах кризових 90-х стався відкіт цієї тенденції на 20 років тому - що може відображати деградацію економіки та широкого розвитку такого культурного явища як дачі/городи/підсобне господарство (якими обзавелося багато городян у 90-х). Відпустки використовувалися тепер не для відпочинку (і зачаття), а для продовольства для власного харчування.

З настанням 21 століття пік дітонароджень різко змістився більш пізній період, причому зміщення відбулося дуже різке і сильне (майже півроку). З середини 00-х переважають по дітородінню стають літньо-осінні. Тобто зачаття змістилися на осінньо-зимові місяці (з жовтня до січня). Якщо це не одвірок статистики, то виходить цікава картина. Найбільш плідними по зачаттю стали темні-холодні місяці, в які люди намагаються сидіти вдома і як ми бачимо буквально не вилазити з ліжка.

Чому я назвав картину Цікавою. Справа в тому, що в міру розвитку освітлення (вуличного і домашнього) і зміщення періоду неспання на більш пізній термін (люди лягають спати і прокидаються все пізніше) - зачаття дітей поступово зміщується на темнішу пору року. Іншими словами, коли електрики не було (або його намагалися берегти), дітей зачинали в травні-липні, а коли в квартирах (і на вулицях) освітлення включено цілодобово безперервно (Москоу невер сліп) - дітей зачинають у жовтні-грудні. Грубо кажучи - робити дітей цікавіше при світлі (а в темряві можна й промахнутися).

На основі даних Міністерства охорони здоров'я РФ Федеральна служба державної статистики (Росстат) збирає статистику про смертність у Росії. Статистика загальнодоступна, з її допомогою всі бажаючі можуть дізнатися, які причини смертності у Росії, як змінюються демографічні показники у Росії загалом і її окремих територіях за роками.

Докладніше ознайомитися з аналізом статистики смертності в Росії ви можете у запропонованій нижче статті.

Причини смертності у Росії

Основні причини смертності в Росії у 2016 р.

Загалом у 2016 році померло 1 891 015 росіян.

    Найчастіше до смерті приводили: хвороби системи кровообігу – 904 055 смертельних випадків, зокрема ішемічна хвороба серця забрала 481 780 життя.

    Злоякісні утворення є другою основною причиною смертності в Росії - від цієї групи хвороб померло 295729 осіб.

    Третя основна причина смертності – звані «зовнішні причини смерті». Ця категорія включає нещасні випадки, вбивства, самогубства, завдання травм, що призвели до смерті і т.д. Загалом із зазначених причин померло 167 543 особи.

    Частими причинами смерті ставали ДТП (15854), випадкові отруєння алкоголем (14021) та самогубства (23119).

    Отруєння алкоголем також є суттєвою причиною смертності в Росії – від спиртного та хвороб, спричинених надмірним вживанням алкоголю, померло 56 283 осіб.

Загалом у зазначений період померло 1107443 росіян.

Порівняльна статистика за 2016 та 2017 рік

Порівняння статистики за 2016 та 2017 рік дає можливість встановити, як змінюються причини смертності в Росії. Оскільки на сьогоднішній день відсутні повні статистичні дані щодо 2017 року, порівняємо дані за перше півріччя 2016 та 2017 року.

Загалом можна побачити, що кількість померлих у період із січня до липня у порівнянні з минулим роком скоротилася на 23 668 смертей. Незважаючи на те, що кількість систем кровообігу, що померли від хвороб, знизилася на 17 821 людини, ця причина смертності залишається ключовою і значущою - 513 432 смертей за зазначений період. Суттєво знизилася кількість людей, які стали жертвою зовнішніх причин смерті – травми та отруєння стали причиною 80 516 смертей у першій половині 2016 р. проти 90 214 у першому півріччі 2017-го. Важливо враховувати, що це числа є попередніми, і загальна річна статистика може бути менш оптимістичною.

Смертність у Росії за роками

Хоча відносне покращення ситуації у 2017 році виглядає оптимістично, слід також враховувати, що це є наслідком тривалого процесу. У період між 1995 та 2005 роком щорічна смертність коливалася між 2,2 та 2,36 млн осіб. Починаючи з 2006 року, спостерігається зниження щорічної кількості померлих. Так, у 2005 році померло 2 303 935 осіб, тоді як у 2006 цифра знизилася до 2 166 703, а вже 2011 року вперше за довгий час стала нижчою за 2 млн осіб. У 2013 та 2014 pp. приріст населення вперше став вищим за смертність, хоча число померлих піднялося з 1 871 809 до 1 912 347 осіб. Після скачка 2014-го року, статистика смертності в Росії продовжувала знижуватися, що демонструють числа за 2015 та 2016 рр., а також попередні дані по 2017 р. На жаль, зниження смертності в Росії обумовлюється багатьма причинами, у тому числі й високою смертністю серед літнього населення країни у попередні роки. Саме люди пенсійного віку є найбільшою демографічною групою серед померлих у Росії.

Смертність у Росії за місяцями

Аналіз статистики щодо місячної смертності в Росії за проміжок у десять років з 2006 по 2015 дає можливість встановити, в які місяці відбувається найбільша кількість смертей. З усіх місяців найвища смертність у січні – у середньому 9,15% смертей. При цьому важливо враховувати неточності у статистиці – чимало смертей, що трапилися у грудні, «переносяться» з грудня на січень. Досить багато громадян також помирають у березні та травні – 8,81% та 8,53% від середньої річної смертності. Найбільш «безпечними» є вересень та листопад – 7,85% та 7,89% від загальної кількості смертей за рік припадає на ці місяці.

Кілька днів тому в блозі The Daily Viz був опублікований запис, який привернув увагу широкому загалу як приклад простої та ефективної візуалізації даних.

Візуалізація була картою популярності днів народження, реалізованою як теплокарта (heatmap) у вигляді календаря. По вертикалі розташовувалися числа, по горизонталі - місяці, і, дивлячись у цю нехитру таблицю, ми могли за насиченістю відтінку судити про те, наскільки популярний той чи інший день у році з точки зору народження дітей.

Через деякий час автор візуалізації опублікував у тому ж блозі другий пост, вибачившись за те, що ввів спільноту в оману, не прокоментувавши належним чином вихідні дані, використані в роботі над зображенням. Проблема була в тому, що вихідний сет даних не містив інформації про реальну кількість людей, що народилися того чи іншого дня. Інформація була дана в іншому вигляді - на якому місці (rank) знаходиться той чи інший день у рейтингу популярності днів народження.

Тобто різниця між першою та другою позицією в рейтингу могла бути колосальною (скажімо, вдвічі), але відрізнялися б вони все одно лише на один тон. Іншими словами, візуалізація не відображала реальних даних через те, що сет містив лише похідні дані.

Небагато подумавши над цією проблемою, я вирішив описати власний приклад створення такої візуалізації від початку до кінця - тобто від збору даних до, власне, зображення зображення. Цей приклад хороший тим, що він, з одного боку, відносно простий, а з іншого – є цілісним завершеним проектом із певним цікавим результатом.

Для всіх операцій я використовував середовище Processing, яке традиційно використовується для подібних завдань (на проблемі вибору інструменту докладно не варто зупинятися).

Отже, процес роботи над проектом має стійку структуру і складається із трьох етапів:
збір даних > сортування даних > візуалізація даних

Наслідуватимемо цю структуру.

1. Збір даних

Дані будемо вилучати із профілів користувачів соціальної мережі vk.com. На щастя для нас, деякі методи її API є відкритими і не вимагають авторизації програми, що значно спрощує завдання.

Досвідченим шляхом я встановив, що даних 100 000 профілів буде достатньо для того, щоб нівелювати випадкові неоднорідності у розподілі днів народження у календарі та виявити основні тенденції. Тим не менш, для економії часу та демонстрації зберемо 10 000 записів. Пізніше ми зможемо підставити в програму будь-яку необхідну кількість профілів.

Писати програму ми будемо всередині основної функції setup(). Функція draw()нам не знадобиться, оскільки програма генерує статичне зображення та не містить анімації. Докладніше зі структурою програми на Processing можна ознайомитись на сайті проекту. Там є опис всіх вбудованих функцій і прекрасний довідник з синтаксису.

Крім того, ми не писатимемо програму, яка виконує завдання від і до: збирає дані, обробляє їх та створює візуалізацію. Розділимо «слона» на кілька модулів, щоб було простіше працювати і витрачати менше часу на налагодження та усунення помилок. Т. е. спочатку напишемо програму, яка збирає дані, зберемо з її допомогою дані. Потім напишемо окремо програму, яка на основі збережених зібраних даних генерує необхідне зображення.

Отже, пишемо болванку-заготівлю для програми.

Void setup() ( //наша основна функція exit(); //виходимо з програми )

Тепер розберемося, як працює VK API. Ми звертаємося до сервера за спеціальним URL, що містить параметри нашого запиту:

http://api.vk.com/method/users.get.xml/uids=(тут список id цікавлять нас користувачів через кому)&fields=(тут список назв цікавлять нас полів профілю користувача)

Якщо ми напишемо ім'я методу без .xml, то отримаємо відповідь від сервера у вигляді рядка у форматі JSON. Це один із варіантів, але в даному прикладі ми будемо використовувати XML. Припустимо, ми хочемо отримати інформацію з облікового запису Павла Дурова, засновника vkontakte. Наш Адреса:

http://api.vk.com/method/users.get.xml?uids=1&fields=bdate

Id його профілю - 1, цікаве для нас поле - день народження - називається bdate.

Спробуємо отримати інформацію про цей профіль. Використовуємо вбудовану функцію loadStrings(), яка в якості параметра приймає рядок з адресою файлу, що цікавить нас, а повертає вміст файлу у вигляді масиву рядків.

Void setup() ( String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=1&fields=bdate"); //завантажуємо інформацію println(user); //виводимо вміст масиву (відповідь сервера) у консоль exit(); //виходимо з програми )

Після запуску програми в консолі з'явиться наша відповідь від сервера:

"" "" " " " 1" " Павло" " Дуров" " 10.10.1984" " " ""

Числа в квадратних дужках означають номер запису (index) у масиві і немає відношення до вмісту масиву. Також кожен рядок поміщений у лапки. Власне, те, що знаходиться між лапками, є наш вміст. Нас цікавить поле

(Рядок ). Воно містить інформацію, що нас цікавить - дату народження користувача №1 у зрозумілому форматі: 10 число 10 місяця (жовтня) 1984 року.

Ми домовилися зібрати 10 тисяч дат народження. Що ми робимо? Перебираємо id користувачів від 1 до потрібного числа. Проблема полягає в тому, що не всі id мають профілі, що діють, і не всі користувачі відкривають свою дату народження. Таким чином, нам потрібно два лічильники: перший лічильник буде відраховувати id користувачів по порядку, а другий вважатиме, скільки дат ми справді зібрали, щоб вчасно зупинитися. За досвідом, щоб набрати 10 000 дат, потрібно перебрати близько 15 000 облікових записів.

Пишемо цикл:

Void setup() ( int count = 0; // лічильник успішних звернень до сервера for (int i = 1; count<= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счетчик на место id for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) ( //якщо рядок містить поле println(i + "\t" + count + "\t" + user[j]); //виводимо дані в консоль count++; //збільшуємо лічильник успіху на 1)))) exit(); //виходимо з програми)

Зауважте, що значення лічильника i, коли ми підставляємо його в рядок, обгорнуто функцією str(). Вона потрібна для переведення типу даних із числа в рядок. Строго кажучи, програма зрозуміє, що ми від неї хочемо і без цієї операції, але краще відразу взяти за звичку контролювати такі речі, як переклад даних з одного типу в інший (у деяких ситуаціях автоматичний переклад не працює).

При переборі рядків відповіді ми використовуємо метод indexOf(), який повертає розташування зазначеної в параметрі рядка в рядку, до якого застосовується метод. Якщо в нашому рядку рядка-параметра немає, метод повертає значення -1, ніж ми і користуємося для перевірки того, чи поточний рядок потрібний нам.

Коли ми виводимо дані, що цікавлять нас, в консоль, додамо додаткову інформацію: стан лічильників, щоб стежити за прогресом. Значення змінних у дужках функції виводу println()розділені рядком "\t"що означає символ табуляції.

Якщо зараз запустити програму, ми побачимо, що значення лічильників швидко розходяться. У моєму випадку після перебору 55 id була зібрана лише 31 дата.

Отже, здається, все працює нормально, залишилося лише змусити програму записувати дані у файл у міру надходження. Для цього створимо об'єкт класу PrintWriter. Він оголошується як нормальна змінна, і йому зазвичай відразу присвоюється значення функції createWriter(шлях до файлу):

PrintWriter p = createWriter("data/bdates.txt");

У цьому випадку ми називаємо об'єкт "p", прив'язуючи до нього файл за адресою "папка-програми/data/bdates.txt", що дозволить нам записувати в цей файл те, що нам потрібно. Як ми це робимо? До нашого об'єкту можна застосувати метод println(), який працює так само, як однойменна функція, але виводить дані не в консоль, а у вказаний файл. Виглядає це так:

P.println(дані);

Після того, як ми попрацювали з нашим файлом, потрібно правильно завершити роботу з ним, інакше інформація в нього не запишеться. Робиться це за допомогою такого запису:

P.flush(); p.close();

Ці дві функції завжди використовуються для коректного завершення роботи з файлом разом. Наша програма:

<= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счётчик на место id for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) ( //якщо рядок містить поле p.println(user[j]), що нас цікавить; //записуємо результат у файл println(count); //виводимо лічильник у консоль для спостереження за прогресом count++; / /збільшуємо лічильник успіху на 1 ) ) ) p.flush();p.close(); //завершуємо роботу з файлом exit(); //виходимо з програми )

При зборі даних ми відмовилися від виведення значення рядка та лічильника id у консоль: виведення занадто великої кількості даних у консоль іноді може гальмувати роботу програми, тому краще обмежитися лише необхідним – лічильником зібраних дат.

Здавалося б, що ще потрібне? Можна запускати програму! І так і ні. При опитуванні віддаленого сервера завжди потрібно мати на увазі, що інколи сервер не відповідає. Уявімо, що ми надіслали запит до сервера, чекаємо на відповідь і не отримуємо його. Через деякий час програма вирішить, що сервер «ляжить» і просто продовжуватиме виконуватися далі. Що буде? Адже ми не отримали даних про користувача, наш масив порожній. Якщо програма звернеться до нього, програма видасть у консоль повідомлення про помилку і зупиниться. Цього може й не статися, але може й статися, і тоді доведеться знову запускати програму, чекати і молитися, щоб сервер відповів на всі 15 000 наших запитів.

Щоб не покладатися на сліпу долю, було винайдено обрабоку помилок. Помилки обробляються за допомогою такого запису:

Try ( // тут код, який може викликати збій ) catch (тут тип помилки) ( // тут код, який виконується у випадку, якщо помилка сталася )

Програма з обробкою помилок:

Void setup() ( PrintWriter p = createWriter("data/bdates.txt"); //об'єкт для виведення даних у файл int count = 0; //лічильник успішних звернень до сервера for (int i = 1; count)<= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счётчик на место id try { for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) ( //якщо рядок містить поле p.println(user[j]), що нас цікавить; //записуємо результат у файл println(count); //виводимо лічильник у консоль для спостереження за прогресом count++; / /збільшуємо лічильник успіху на 1)))) catch (Exception e) ()) p.flush();p.close(); //завершуємо роботу з файлом exit(); //виходимо з програми)

Тепер, якщо виникає помилка при зверненні до масиву (якщо масив порожній), виконається код… ніякого коду не виконається, програма виведе повідомлення про помилку, але не зупиниться. Ми просто ігноруємо помилку і йдемо далі - всього доведеться запитати інформацію ще одного користувача. Тип помилки вказано ExceptionЦе означає, що ми «ловимо» будь-які помилки, які виникнуть. Запис eпісля типу помилки потрібно, тому що програмі потрібна якась змінна, в яку можна записати інформацію про помилку. Ми можемо звертатися до цієї змінної при обробці помилок, проте це не потрібно.

2. Сортування даних

Через якийсь час (зазвичай не більше півгодини) після запуску програми вона завершиться і ми побачимо в консолі заповітне число 10 000. Це означає, що дані зібрані і можна сортувати. Відкриємо файл у текстовому редакторі та подивимося на результат наших праць:

Що не так? Ага, ми забули, що записували у файл дані разом із XML-тегами. Не біда! У будь-якому текстовому редакторі є функція автозаміни, за допомогою якої можна почистити файл від зайвої інформації. Строго кажучи, ми могли б програмно «відловити» зайве вже на етапі збору даних, але в принципі, для простоти та економії часу не соромно скористатися будь-яким доступним інструментом.

Почистивши файл, зберігаємо його та закриваємо. Тепер програмі просто його читатиме.

3. Візуалізація даних

А тепер візьмемося малюванням. Спочатку нам потрібно відкрити файл і порахувати, скільки користувачів народилося в кожен окремий день. Для відкриття файлу використовуємо стару знайому функцію loadStrings(). Для того, щоб зберігати кількість користувачів, що народилися в певний день, використовуємо натуральний чисел:

Int table = new int

Ми вказали розмір масиву 12 на 31. На рік у нас 12 місяців і максимум 31 день. За ідеєю, 31 лютого не повинно народитись жодної людини, тому нас не повинно хвилювати, що масив для деяких місяців занадто довгий.

Як працюватиме наша програма? Ми повинні взяти дату, визначити, який у ній міститься день і місяць, і збільшити відповідний осередок масиву на одиницю.

Для того, щоб розбити рядок на числа дня, місяця та року, ми будемо використовувати метод split(). Він повертає масив рядків, а приймає як аргумент рядок-розділювач: інструкція

String s="00010010".split("1");
надасть масиву sзначення
"000" "00" "0"

Що це означає для нашої практики? Ми беремо рядок масиву і ділимо його за допомогою символу точки як роздільник. Є одна технічна проблема: символ точки зарезервований як позначення будь-якого символу. Тому замість "." як аргумент ми передаємо "\\." - Такий запис означає потрібний нам символ точки. Виходить так:

< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты } exit(); //выходим из программы }

Тепер у осередку dateміститься рядок з номером дня на місяці, а в date- Номер місяця. Ми повинні збільшити відповідний осередок масиву tableна одиницю:

Table++;

Вказуючи адресу комірки відповідну даті, ми переводимо рядок у число за допомогою функції int(), а також забираємо одиницю. Навіщо забирати одиницю? Потім відлік осередків масиву починається з нуля. Ми вказали довжину 12, це означає, що осередки масиву мають нумерацію від 0 до 11. На відміну від місяців, що нумеруються від 1 до 12. Про цю невідповідність необхідно пам'ятати.

Правильно? Правильно, та не зовсім. Якщо зараз запустити програму, то вона видасть помилку. Справа в тому, що наш сет даних не є ідеальним. З якоїсь невідомої причини у деяких користувачів у полі дати народження стоять якісь непотрібні числа на зразок 666.666 або 32.13.888888888. Іноді можна навіть зустріти користувача, який народився, наприклад, мінус п'ятого грудня. Щоб їх відсортувати, потрібно відкинути значення місяців більше 12 і днів більше 31, а також всі значення менше або рівні нулю:

If ((int(date))<= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все в порядку table++; //збільшуємо комірку таблиці на 1)

Програма повністю:

Void setup() ( String file = loadStrings("data/bdates.txt"); // завантажуємо файл з даними int table = new int; for (int i = 0; i< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все в порядку table++; //збільшуємо комірку таблиці на 1)) exit(); //виходимо з програми)

Тепер, коли дані нарешті зібрані і зберігаються в пам'яті програми, можна приступити до творчості - малювання. Спочатку визначимося з кольором, яким ми малюватимемо: я взяв фірмовий синій колір VK: RGB 54, 99, 142. Оголосимо змінну-колір, щоб не писати щоразу три заповітні числа:

Color c = color(54, 99, 142);

Також нам потрібно (за традицією, на самому початку програми) вирішити, якою шириною та висотою буде наше зображення. Для цього напишемо функцію:

Size (ширина, висота);

Яка у нас буде ширина та висота? Припустимо, кожен осередок теплокартки буде шириною 40 пікселів плюс один піксель для відступу між осередками. Місяці відкладаємо по ширині. Не забуваймо про відступ від край (10 пікселів). Виходить 20+41*12. Якщо не хочеться рахувати в умі або відкривати програму-калькулятор, можна просто написати цей вислів як аргумент функції println(20+41*12);і отримати відповідь – 512. Це ширина зображення. З урахуванням висоти осередку в 20 пікселів і такого ж відступу від краю, отримуємо:

Size (512, 671);

Тепер тимчасово приберемо команду exit();в кінці програми, щоб ми не виходили з програми після завершення, і запустимо виконання коду:

< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все гаразд table++; //збільшуємо комірку таблиці на 1 ) ) color c = color(54, 99, 142); // Колір)

Після вказівки розміру кадру я додав команду встановити білий фон: якщо ми вказуємо колір одним числом, він розпізнається як відтінки сірого від 0 (чорний) до 255 (білий). При запуску програми має відкритися вікно з білим тлом потрібного нам розміру.

Почнемо малювати. Як ми малюємо? Пробігаємось по масиву table- по кожному рядку (місяць) та у кожному рядку (день цього місяця) по осередках. Малюємо у потрібному місці та потрібним кольором прямокутник 40 на 20. Як обчислюється позиція X? 10 (відступ) + 41 (ширина + зазор між) * i (лічильник місяців). Позиція Y? 10 (відступ) + 21 (висота + зазор між) * j (лічильник днів). Прямокутник малюється функцією rect(x, y, ширина, висота); -

Rect(10+41*i, 10+21*j, 40, 20);

Програма:

Void setup() ( size(512, 671); //встановлюємо розмір background(255); //колір фону - білий String file = loadStrings("data/bdates.txt"); //завантажуємо файл з даними int table = new int;for (int i = 0; i< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все гаразд table++; //збільшуємо комірку таблиці на 1 ) ) color c = color(54, 99, 142); //Колір for (int i = 0; i< table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } }

Якщо запустити цей код, ми отримаємо поле, дивним чином розкреслене прямокутниками з обведенням. Спочатку приберемо обведення, додавши перед малюванням команду noStroke();. Тепер встановимо наш колір як заливку: fill(c);

Прекрасно. Тепер площа замощена красивими синіми плиточками із білими проміжками. Далі нам потрібно якось закодувати значення таблиці в колір заливки. Зробимо це за допомогою прозорості. Прозорість кольору набуває значення від 0 до 255. Запис fill(c, 10);дасть ледь помітний синюватий відтінок, а запис fill(c, 240);дасть майже повністю насичений синій колір. Отже, діапазон прозоростей – 0..255. Діапазон значень у нашому масиві набагато більший (або менше). Припустимо, ми знаємо максимальне значення у масиві. Мінімальним, ясна річ, буде нуль. Нам потрібно якось вписати значення з масиву в діапазон 0.255, як би зменшивши (збільшивши) масштаб. Для цього існує функція map (значення, початок вихідного діапазону, кінець вихідного діапазону, початок нового діапазону, кінець нового діапазону):

Map (table [i] [j], 0, 1000, 0, 255);

Тут ми зробили припущення, що максимальне значення масиву – 1000. Тоді за значення table[i][j] 1000 функція поверне 255, а при значенні 0 - поверне нуль.

Як же розрахувати мінімальне та максимальне значення двомірного масиву? Для одновимірного масиву існують функції відповідно min()і max(). Використовуємо їх. Пробіжимося циклом по «місяцях» і порівняємо мінімальне та максимальне значення кожного «місяця» (який сприймається середовищем як одновимірний масив) зі змінними, що зберігають поточне мінімальне або максимальне значення в масиві. І не забудемо ще одну важливу річ: іноді в сеті даних траплялися некоректні дати, тобто. хтось міг вказати дату народження 31 листопада чи 30 лютого. Щоб цей факт нам не заважав, встановимо значення неіснуючих дат на нуль.

Table = 0; //30 лютого table = 0; //31 лютого table = 0; //31 квітня table = 0; //31 червня table = 0; //31 вересня table = 0; //31 листопада int mi = table; //Мінімальне значення int ma = table; //максимальне значення for(int i = 0; i< table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) >0)) ( //якщо мінімальне значення цього рядка менше поточного мінімуму і більше за нуль mi = min(table[i]); //зробити це значення мінімумом ) if (max(table[i]) > ma) ( //якщо максимальне значення цього рядка більше за поточний максимум ma = max(table[i]);//зробити це значення максимумом ) ) println(mi + " " + ma); //виводимо значення

У мене значення вийшло 14 і 47. В принципі, це не важливо, тому що ми можемо використовувати значення змінних. Тепер треба при кожному зверненні до осередку таблиці, тобто. перед малюванням кожного прямокутника, встановити свою заливку:

Void setup() ( size(512, 671); //встановлюємо розмір background(255); //колір фону - білий String file = loadStrings("data/bdates.txt"); //завантажуємо файл з даними int table = new int;for (int i = 0; i< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) > < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) >0)) ( //якщо мінімальне значення цього рядка менше поточного мінімуму і більше за нуль mi = min(table[i]); //зробити це значення мінімумом ) if (max(table[i]) >< table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням fill(c, map(table[i][j], 0, ma, 0, 255)); //считаем заливку rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } }

Що ми бачимо після запуску програми? Плиточки стали різного кольору, залежно від кількості тих, хто народився того чи іншого дня. Також ми бачимо, що 29 лютого має досить чіткий колір. Очевидно, що кількість тих, хто народився в цей день мінімально, а це означає, що ми втрачаємо більшу частину діапазону кольорів, доступного для відображення (значення починаються з 14, а у нас мінімум стоїть на 0 - це значить, ми не використовуємо значення прозорості навскідку приблизно від 0 до 85. Непорядок Поставимо мінімальним значенням функції map()не нуль, а 12, щоб плиточка 29 лютого була ледь помітна. Через те, що наш мінімум тепер становить 12, а не нуль, прозорість тих плиточок, які мають значення 0, буде негативною. А оскільки при негативних значеннях прозорість відкочується циклічно (-5 - це все одно, що 250!), вийде, що неіснуючі дні будуть не білими, а темними. Додамо умову, за якої «нульові» дні взагалі не малюються:

Void setup() ( size(512, 671); //встановлюємо розмір background(255); //колір фону - білий String file = loadStrings("data/bdates.txt"); //завантажуємо файл з даними int table = new int;for (int i = 0; i< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все в порядку table++; //збільшуємо комірку таблиці на 1) ) table = 0; //30 лютого table = 0; //31 лютого table = 0; //31 квітня table = 0; //31 червня table = 0; //31 вересня table = 0; //31 листопада int mi = table; //Мінімальне значення int ma = table; //максимальне значення for(int i = 0; i< table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) >0)) ( //якщо мінімальне значення цього рядка менше поточного мінімуму і більше за нуль mi = min(table[i]); //зробити це значення мінімумом ) if (max(table[i]) > ma) ( //якщо максимальне значення цього рядка більше за поточний максимум ma = max(table[i]);//зробити це значення максимумом ) ) color c = color(54, 99, 142); noStroke(); for (int i = 0; i< table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням if (table[i][j] >0) ( fill(c, map(table[i][j], 12, ma, 0, 255)); //вважаємо заливку rect(10+41*i, 10+21*j, 40, 20); //малюємо прямокутник у потрібній позиції)))))

Але що ми бачимо? Серед навколишніх днів особливо виділяється 1 січня. Така сама тенденція зберігається на набагато більших числах користувачів. Коли я збирав дані по 300 000 акаунтів, 1 січня так само сяяло глибоким синім, а інші кольори були блідими. Очевидно, таке явище пов'язане з діями користувачів, які, не бажаючи публікувати свій реальний день народження, обирають перше число у списку. Відокремити справді народжених у Новий рік від жалюгідних симулянтів неможливо. Щоб вирівняти сет, просто видалимо звідти дані, присоивши осередку tableзначення нуль. Щоб зберегти картинку, використовуємо команду saveFrame("frame.jpg");наприкінці програми. У нас з'явиться відповідний файл у папці із програмою.

Код програми повністю:

Void setup() ( size(512, 671); //встановлюємо розмір background(255); //колір фону - білий String file = loadStrings("data/bdates.txt"); //завантажуємо файл з даними int table = new int;for (int i = 0; i< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) >0) && (int(date)<= 31) && (int(date) >0)) ( //якщо з числом все в порядку table++; //збільшуємо комірку таблиці на 1) ) table = 0; //1 січня table = 0; //30 лютого table = 0; //31 лютого table = 0; //31 квітня table = 0; //31 червня table = 0; //31 вересня table = 0; //31 листопада int mi = table; //Мінімальне значення int ma = table; //максимальне значення for(int i = 0; i< table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) >0)) ( //якщо мінімальне значення цього рядка менше поточного мінімуму і більше за нуль mi = min(table[i]); //зробити це значення мінімумом ) if (max(table[i]) > ma) ( //якщо максимальне значення цього рядка більше за поточний максимум ma = max(table[i]);//зробити це значення максимумом ) ) color c = color(54, 99, 142); noStroke(); for (int i = 0; i< table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням if (table[i][j] >0) ( fill(c, map(table[i][j], 12, ma, 0, 255)); //вважаємо заливку rect(10+41*i, 10+21*j, 40, 20); //малюємо прямокутник у потрібній позиції)))) saveFrame("frame.jpg"); //зберігаємось)

Готово! З картинки, що вийшла, поки що не особливо зрозумілі, як зараз кажуть, тренди, тому що ми зібрали занадто мало даних. Ось картинка для 300 000 акаунтів (ні, я не чекав для збору даних 100 років, а використовував асинхронні запити до сервера - можливо, я коли-небудь напишу про реалізацію їх у Processing), на якій ясно видно тенденцію (хоча і не дуже яскрава):

А аналіз отриманої візуалізації лягає на ваші плечі! ;]