Представитель Шуры Люберецкого в ЖЖ (brat_luber) wrote,
Представитель Шуры Люберецкого в ЖЖ
brat_luber

А вот вам красивый график

Взял и от нечего делать разобрал файлик с выгрузкой данных по электронному голосованию:

http://observer2020.mos.ru/observer/downloads/ballots_decrypted_2020-07-01T19:47:00.csv

Получился такой вот забавный график (кликабельно):

e-voting

Интересно было бы сопоставить явно видимые на графике “скачки” с разными событиями прошедшей недели – например, резкий прирост голосов “за” в Москве в 17:00 25 июня, или синхронные скачки “против” в Москве и Нижнем в 16:00 26 июня и в 14:00 29 июня.

Наговняканный за полчаса код прилагается:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct voteblock {
	int time; // time in seconds since day start
	int res[2][2];
};

voteblock votes[2300000]; // max. block number is about 2.27M

int gettime(char *token){
	token[2] = '\0';
	token[5] = '\0';

	int hours = atoi(token);
	int minutes = atoi(token + 3);
	int seconds = atoi(token + 6);

	return hours * 60 * 60 + minutes * 60 + seconds;
}

void process_vote(char *buf){
	char *token;
	int district, res;

	token = strtok(buf, "\";"); // номер голоса
	int n = atoi(token);

	token = strtok(NULL, "\";"); // избир. округ
	if (strcmp(token, "77") == 0){
		district = 0;
	} else if (strcmp(token, "52") == 0) {
		district = 1;
	} else {
		fprintf(stderr, "Unknown district %s\r\n", token);
		return;
	}

	strtok(NULL, "\";"); // адрес голоса в блокчейне
	token = strtok(NULL, "\";#"); // блок голоса
	int block = atoi(token);

	token = strtok(NULL, "\";"); // время записи блока голоса
	int time = gettime(token);

	strtok(NULL, ";"); // зашифрованный голос
	token = strtok(NULL, "\";"); // расшифрованный голос
	if (strcmp(token, "2212294583") == 0){
		res = 0;
	} else if (strcmp(token, "450215437") == 0) {
		res = 1;
	} else {
		fprintf(stderr, "Unknown vote result %s\r\n", token);
		return;
	}

	strtok(NULL, "\";"); // блок расшифровки
	strtok(NULL, "\";"); // время записи блока расшифровки

	strtok(NULL, "\";"); // транзакция

	votes[block].time = time;
	votes[block].res[district][res]++;
}

void print_votes_table(){
	int day = 0;
	int starttime = 7 * 3600; // 10:00:00 MSK = 7:00:00 UTC
	int delta = 10 * 60; // 10 minutes granularity
	int allvotes[2][2] = { 0 };

	// to put the last line
	votes[sizeof(votes) / sizeof(voteblock) - 1].time = INT_MAX;

	for (int i = 0; i < sizeof(votes) / sizeof(voteblock); i++){
		if (votes[i].time >= 0){
			if ((votes[i].time > starttime + delta) || (votes[i].time < starttime)) {
				/* either end of current stats block or end of day*/
				if (votes[i].time < starttime)	{
					starttime = 0;
					day++;
				} else {
					starttime += delta;
				}

				// finalize this line
				printf("%i\t%i\t%i\t%i\t%i\t%i\r\n", day, starttime, allvotes[0][0], allvotes[0][1], allvotes[1][0], allvotes[1][1]);
			}

			allvotes[0][0] += votes[i].res[0][0];
			allvotes[0][1] += votes[i].res[0][1];
			allvotes[1][0] += votes[i].res[1][0];
			allvotes[1][1] += votes[i].res[1][1];
		}
	}
}

int main(void){
	char buf[1024]; // should be enough

	fgets(buf, sizeof(buf), stdin); // skip first line

	while (!feof(stdin)){
		fgets(buf, sizeof(buf), stdin);
		process_vote(buf);
	}

	print_votes_table();
	return 0;
}

Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).

Subscribe

  • Two-pizza team

    Интересно, а «тупица-тим» я в этом выражении один вижу? Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои…

  • Я не эстонец, но торможу

    Спустя почти год после вынужденного перехода на удаленку решил проблему сосуществования на одном рабочем столе «рабочего» и…

  • А помните Альтависту?

    Пока писал в ЖЖ коммент — подумалось — вот помните такой древнючий поисковик Altavista? Времен «раннего интернета», когда еще…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments