Выборы и Programming

Список разделов Прочее Свои темы

Описание: Раздел, аналогичный разделу Беседка, в котором автор созданной темы автоматически назначается Куратором темы, имеющим право удалять сообщения, а также закрывать и открывать свои темы.
Просьба к авторам тем: не злоупотреблять этими правами.

Куратор темы: unicorn55

#1 unicorn55 » Ср, 25 января 2012, 17:32

В этой теме я попробую написать программку которая анализирует данные голосования на выборах 4 декабря 2011 года.
Цель — установить реальные причины возникновения так называемой "лестницы Чурова".

Предполагается что это будет тема-блог. То есть я буду все постить по ходу пьесы.
Последний раз я писал программки больше года назад. Так что буду вспоминать :)
Почему здесь? потому что одному не интересно и скучно. :)

Итак, примерный план у меня уже есть.
Язык программирования — C (как самый простой и прозрачный)
Среда разработки (IDE) — Pelles C (бесплатная, быстрая, удобная)
Дополнительные библиотеки — Glut (для вывода графики, она кроссплатформенная)
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц


Re: Выборы и Programming

#3 unicorn55 » Ср, 25 января 2012, 17:52

Начнем с установки IDE Pelles C.

http://www.pellesc.de/index.php?page=start&lang=en

Изображение

Скачиваем последнюю версию 6.5
http://www.pellesc.de/download_start.php?file=650/setup.exe

И я ставлю ее в C:\PellesC
Запускаем IDE (это файл C:\PellesC\bin\poide.exe)
Программа попросит разрешение на создание базы символов заголовочных файлов (инклудников (не знаю точно как их назвать по-русски), это файлы включаемые с помощью макрокоманды #include). В общем соглашаемся, потому что с ней удобней.
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#4 unicorn55 » Ср, 25 января 2012, 18:27

Как я уже сказал для вывода графики нам нужна будет библиотека Glut
Скачиваем ее здесь
http://user.xmission.com/~nate/glut/glut-3.7.6-bin.zip
В архиве 5 файлов.
1. glut32.lib копируем в C:\PellesC\lib
2. glut.h копируем в C:\PellesC\include\win\gl
3. glut32.dll копируем в C:\Windows\System32

Берем какой-нибудь простенький пример и убеждаемся что он работает.
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#5 unicorn55 » Ср, 25 января 2012, 18:39

До графики нам еще далеко.
Нам нужны исходные данные — это результаты голосования.
Скачать их можно здесь.
http://files.kartaitogov.ru/results2011/p2011.zip?1323819203
Распаковываем архив p2011.zip
И получаем около 30 мегабайт таблицу p2011.csv

Открываем ее с помощью Excel и смотрим что она из себя представляет.
Это таблица из 30 столбцов и 95186 строк
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#6 unicorn55 » Ср, 25 января 2012, 19:41

Нас интересуют столбцы под номерами

14 Число недействительных избирательных бюллетеней (сокращенно НИБ)
15 число действительных избирательных бюллетеней (сокращенно ДИБ)
...
24 СПР
25 ЛДПР
26 ПР
27 КПРФ
28 ЯБЛ
29 ЕР
30 ПД

Как считаются проценты.

Числа действительных и недействительных складываются, получается общее число бюллетеней (ЧБ)
а потом число проголосовавших за партию делится на это число
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#7 unicorn55 » Ср, 25 января 2012, 19:54

Чтобы обрабатывать данные мы экспортируем их в удобный для нас вид.
Например в текст. Для этого в меню Excel выбираем "сохранить как" -> "другие форматы" -> "текстовые файлы (с разделителями табуляции)"
Получаем на выходе текстовый файл "p2011.txt" состоящий из 95186 строк.
Каждая строка — это данные по отдельному УИКу.
Наша задача написать программку которая считывает этот текст и заносит данные в оперативную память (в массив)
Чтобы потом уже можно было эти данные свободно обрабатывать без всяких посредников.
На этом я объявляю перерыв :)
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#8 unicorn55 » Ср, 25 января 2012, 22:22

unicorn55 писал(а):Наша задача написать программку которая считывает этот текст и заносит данные в оперативную память (в массив)
Сделано :smile:

Код: Выделить всё
#include <stdlib.h>
#include <stdio.h>


// число УИКов
#define NUIK 95185

// имя исходного текстового файла, откуда будем считывать данные
char* txt_filename = "p2011.txt";
// сам файл
FILE* txt_file;

// буфер для скачивания сюда первой ненужной строки
char str[2000];
// фиктивная переменная для записи в нее ненужных данных
int t;


// Тип из которых будет состоять большой массив по всем УИКам

typedef struct {
   int nib;    // число недействительных избирательных беллютеня
   int dib;    // число действительных избирательных беллютеня
   int spr;   // число проголосовавших за Справедливую Россию
   int ldpr;   // число проголосовавших за ЛДПР
   int pr;      // число проголосовавших за Правое Дело
   int kprf;   // число проголосовавших за КПРФ
   int yabl;   // число проголосовавших за Яблоко   
   int er;      // число проголосовавших за Единую Россию
   int pd;      // число проголосовавших за Правое Дело
} t_uik;


// Большой массив данных по всем 95185 УИКам
// первые две строчки не используются чтобы номера элементов массива
// соответствовали номерам строк в исходной Excel-таблице

t_uik All[NUIK+2];


// функция считывает символы из текстового файла f пока не считает символ табуляции
// таким образом она пропускает одно значение в таблице и переходит к следующему

void skip_to_tab(FILE* f) {
    while (fgetc(f) != '\t');
}

//=====================================//
//======= Главная программа ===========//
//=====================================//

int main() {

    int i; // счетчик для цикла от 2 до 95186

    txt_file = fopen(txt_filename,"r"); // открываем текст для чтения
    if (txt_file==NULL) {printf("Error: fopen\n"); exit(1);}

    fgets(str,2000,txt_file);   // считываем первую строку, это заголовки столбцов, они нам не нужны

    // цикл считывания данных по всем УИКам

    for (i=2;i<2+NUIK;i++) {
 
     // пропускаем первые 4 текстовые значения таблицы (они нам не нужны)

        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);

     // а дальше идут числа, считываем их с помощью fscanf

        fscanf(txt_file,
       
            "%d%d%d%d%d%d%d%d%d" // 9 ненужных
            "%d%d"               // 2 нужных (это NIB и DIB)
            "%d%d%d%d%d%d%d%d"   // 8 ненужных
            "%d%d%d%d%d%d%d",    // 7 нужных — это голоса за каждые из 7 партий
            &t,&t,&t,&t,&t,&t,&t,&t,&t,  // ненужные, считываем в фиктивную переменную
            &(All[i].nib),&(All[i].dib), // заполняем NIB и DIB
            &t,&t,&t,&t,&t,&t,&t,&t,     // ненужные, считываем в фиктивную переменную
        // считываем голоса за 7 партий
            &(All[i].spr),      // СПР
            &(All[i].ldpr),     // ЛДПР
            &(All[i].pr),       // Патриоты России
            &(All[i].kprf),     // КПРФ
            &(All[i].yabl),     // Яблоко
            &(All[i].er),       // ЕР
            &(All[i].pd));      // Правое Дело


    }

    // данные считаны, закрываем файл

    fclose(txt_file);

// Выводим данные любой строчки для сверки с данными в Excel, чтобы удостоверится что
// данные считались успешно
// Например, возьмем самую последнюю строчку.
    i = 95186;
    printf("i=%d NIB=%d DIB=%d spr=%d ldpr=%d pr=%d kprf=%d yabl=%d er=%d pd=%d\n",
            i, All[i].nib, All[i].dib,
            All[i].spr, All[i].ldpr, All[i].pr, All[i].kprf, All[i].yabl, All[i].er, All[i].pd);
}


Следующая задача — посчитать проценты на каждом УИК, округлить их до определенного значения
(скажем до полупроцента) и построить столбчатую диаграмму. Где высота столбика будет соответствовать числу УИКов с данным округленным процентом. :)
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#9 unicorn55 » Чт, 26 января 2012, 0:31

unicorn55 писал(а):Нас интересуют столбцы под номерами

14 Число недействительных избирательных бюллетеней (сокращенно НИБ)
15 число действительных избирательных бюллетеней (сокращенно ДИБ)
...
24 СПР
25 ЛДПР
26 ПР
27 КПРФ
28 ЯБЛ
29 ЕР
30 ПД

Еще забыл добавить, столбец под номером
6 — это число избирателей, внесенных в список. (назовем это число ИЗБ)
Оно будет нужно для подсчета явки. Явку будем считать как отношение полученных бюллетеней к числу избирателей в списке
(НИБ+ДИБ) / ИЗБ

С учетом этого внесем небольшие изменения в программу.

Код: Выделить всё

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


// число УИКов
#define NUIK 95185

// имя исходного текстового файла, откуда будем считывать данные
char* txt_filename = "p2011.txt";
// сам файл
FILE* txt_file;

// буфер для скачивания сюда первой ненужной строки
char str[2000];
// фиктивная переменная для записи в нее ненужных данных
int t;


// Тип из которых будет состоять большой массив по всем УИКам

typedef struct {
    int izb;    // число избирателей в списке
   int nib;    // число недействительных избирательных беллютеня
   int dib;    // число действительных избирательных беллютеня
   int spr;   // число проголосовавших за Справедливую Россию
   int ldpr;   // число проголосовавших за ЛДПР
   int pr;      // число проголосовавших за Правое Дело
   int kprf;   // число проголосовавших за КПРФ
   int yabl;   // число проголосовавших за Яблоко   
   int er;      // число проголосовавших за Единую Россию
   int pd;      // число проголосовавших за Правое Дело
} t_uik;


// Большой массив данных по всем 95185 УИКам
// первые две строчки не используются чтобы номера элементов массива
// соответствовали номерам строк в исходной Excel-таблице

t_uik All[NUIK+2];


// функция считывает символы из текстового файла f пока не считает символ табуляции
// таким образом она пропускает одно значение в таблице и переходит к следующему

void skip_to_tab(FILE* f) {
    while (fgetc(f) != '\t');
}

//=====================================//
//======= Главная программа ===========//
//=====================================//

int main() {

    int i; // счетчик для цикла от 2 до 95186

    txt_file = fopen(txt_filename,"r"); // открываем текст для чтения
    if (txt_file==NULL) {printf("Error: fopen\n"); exit(1);}

    fgets(str,2000,txt_file);   // считываем первую строку, это заголовки столбцов, они нам не нужны

    // цикл считывания данных по всем УИКам

    for (i=2;i<2+NUIK;i++) {
 
     // пропускаем первые 4 текстовые значения таблицы (они нам не нужны)

        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);

     // а дальше идут числа, считываем их с помощью fscanf

        fscanf(txt_file,
       
            "%d"                // 1 ненужный (номер уика)
            "%d"                // 1 нужный — число избирателей в списке
            "%d%d%d%d%d%d%d"    // 7 ненужных
            "%d%d"               // 2 нужных (это NIB и DIB)
            "%d%d%d%d%d%d%d%d"   // 8 ненужных
            "%d%d%d%d%d%d%d",    // 7 нужных — это голоса за каждые из 7 партий
            &t,                     // ненужный считываем в фиктивную переменную
            &(All[i].izb),          // число избирателей в списке
            &t,&t,&t,&t,&t,&t,&t,  // ненужные, считываем в фиктивную переменную
            &(All[i].nib),&(All[i].dib), // заполняем NIB и DIB
            &t,&t,&t,&t,&t,&t,&t,&t,     // ненужные, считываем в фиктивную переменную
        // считываем голоса за 7 партий
            &(All[i].spr),      // СПР
            &(All[i].ldpr),     // ЛДПР
            &(All[i].pr),       // Патриоты России
            &(All[i].kprf),     // КПРФ
            &(All[i].yabl),     // Яблоко
            &(All[i].er),       // ЕР
            &(All[i].pd));      // Правое Дело


    }

    // данные считаны, закрываем файл

    fclose(txt_file);

// Выводим данные любой строчки для сверки с данными в Excel, чтобы удостоверится что
// данные считались успешно
// Например, возьмем самую последнюю строчку.
    i = 95186;
    printf("i=%d IZB=%d NIB=%d DIB=%d spr=%d ldpr=%d pr=%d kprf=%d yabl=%d er=%d pd=%d\n",
            i, All[i].izb, All[i].nib, All[i].dib,
            All[i].spr, All[i].ldpr, All[i].pr, All[i].kprf, All[i].yabl, All[i].er, All[i].pd);
}
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#10 unicorn55 » Чт, 26 января 2012, 15:03

Итак, получены первые графические данные. Это "облачные диаграммы" как я их назвал.
Каждая точка соответствует одному или нескольким УИКам.
По горизонтали откладывается явка. По вертикали процент проголосовавших за данную партию.
Все это масштабируется в окошко 700 на 700 точек.


ЕР
Изображение

КПРФ
Изображение


ЛДПР
Изображение

ПД
Изображение

ПР
Изображение

СПР
Изображение

Яблоко
Изображение
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#11 unicorn55 » Чт, 26 января 2012, 15:22

unicorn55 писал(а):Дополнительные библиотеки — Glut (для вывода графики, она кроссплатформенная)

Я отказался от использования Glut, вследствие ее сложности и навороченности.
Именно — это оболочка OpenGL то есть заточена на трехмерную графику.
Мне же нужна обычная, двумерная.
Поэтому я взял другую библиотеку — SDL.
Как ее установить в Pelles C http://www.friedspace.com/cprogramming/sdlsetup.php

Поясню, почему я использую библиотеки для работы с графикой. Я не хочу въезжать в Win32 API. То есть всякие функции типа RegisterClass, CreateWindowEx.

В итоге получилось такая программка

Код: Выделить всё
#include <SDL.h>  // Нужно для графики
#include <stdlib.h>
#include <stdio.h>


SDL_Surface* screen = 0;
SDL_Event event;
int running = 0;

#define WIDTH 700  // Ширина экрана
#define HEIGHT 700  // Высота экрана

void putpixel(SDL_Surface* screen, int x, int y, int color) {
   int* pixels=(int*)screen->pixels;
    y=HEIGHT-y-1;
    if (x>=WIDTH || y>=HEIGHT || x <0 || y <0) {printf("%d %d\n", x,y); return;}
   pixels[WIDTH*y+x]=color;
   SDL_UpdateRect(screen, x, y, 1, 1);
}



// число УИКов
#define NUIK 95185

// имя исходного текстового файла, откуда будем считывать данные
char* txt_filename = "p2011.txt";
// сам файл
FILE* txt_file;

// буфер для скачивания сюда первой ненужной строки
char str[2000];
// фиктивная переменная для записи в нее ненужных данных
int t;

int total_izb;
int total_golos;

// Тип из которых будет состоять большой массив по всем УИКам

typedef struct {
    int izb;    // число избирателей в списке
   int nib;    // число недействительных избирательных беллютеня
   int dib;    // число действительных избирательных беллютеня
   int spr;   // число проголосовавших за Справедливую Россию
   int ldpr;   // число проголосовавших за ЛДПР
   int pr;      // число проголосовавших за Правое Дело
   int kprf;   // число проголосовавших за КПРФ
   int yabl;   // число проголосовавших за Яблоко   
   int er;      // число проголосовавших за Единую Россию
   int pd;      // число проголосовавших за Правое Дело
} t_uik;


// Большой массив данных по всем 95185 УИКам
// первые две строчки не используются чтобы номера элементов массива
// соответствовали номерам строк в исходной Excel-таблице

t_uik All[NUIK+2];


// функция считывает символы из текстового файла f пока не считает символ табуляции
// таким образом она пропускает одно значение в таблице и переходит к следующему

void skip_to_tab(FILE* f) {
    while (fgetc(f) != '\t');
}

//=====================================//
//======= Главная программа ===========//
//=====================================//

int main(int argc, char *argv[]) {

    int i; // счетчик для цикла от 2 до 95186
    int bull; // число бюллетеней действительных плюс недействительных

    txt_file = fopen(txt_filename,"r"); // открываем текст для чтения
    if (txt_file==NULL) {printf("Error: fopen\n"); exit(1);}

    fgets(str,2000,txt_file);   // считываем первую строку, это заголовки столбцов, они нам не нужны

    // цикл считывания данных по всем УИКам

    for (i=2;i<2+NUIK;i++) {
 
     // пропускаем первые 4 текстовые значения таблицы (они нам не нужны)

        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);

     // а дальше идут числа, считываем их с помощью fscanf

        fscanf(txt_file,
       
            "%d"                // 1 ненужный (номер уика)
            "%d"                // 1 нужный — число избирателей в списке
            "%d%d%d%d%d%d%d"    // 7 ненужных
            "%d%d"               // 2 нужных (это NIB и DIB)
            "%d%d%d%d%d%d%d%d"   // 8 ненужных
            "%d%d%d%d%d%d%d",    // 7 нужных — это голоса за каждые из 7 партий
            &t,                     // ненужный считываем в фиктивную переменную
            &(All[i].izb),          // число избирателей в списке
            &t,&t,&t,&t,&t,&t,&t,  // ненужные, считываем в фиктивную переменную
            &(All[i].nib),&(All[i].dib), // заполняем NIB и DIB
            &t,&t,&t,&t,&t,&t,&t,&t,     // ненужные, считываем в фиктивную переменную
        // считываем голоса за 7 партий
            &(All[i].spr),      // СПР
            &(All[i].ldpr),     // ЛДПР
            &(All[i].pr),       // Патриоты России
            &(All[i].kprf),     // КПРФ
            &(All[i].yabl),     // Яблоко
            &(All[i].er),       // ЕР
            &(All[i].pd));      // Правое Дело


    }

    // данные считаны, закрываем файл

    fclose(txt_file);

// Выводим данные любой строчки для сверки с данными в Excel, чтобы удостоверится что
// данные считались успешно
// Например, возьмем самую последнюю строчку.
    i = 95186;
    printf("i=%d IZB=%d NIB=%d DIB=%d spr=%d ldpr=%d pr=%d kprf=%d yabl=%d er=%d pd=%d\n",
            i, All[i].izb, All[i].nib, All[i].dib,
            All[i].spr, All[i].ldpr, All[i].pr, All[i].kprf, All[i].yabl, All[i].er, All[i].pd);

// Посчитаем сколько всего было избирателей в списках и
// Сколько всего проголосовавших, таким образом мы узнаем общую явку по стране

    total_izb = 0;
    total_golos = 0;
    for (i=2;i<NUIK+2;i++){
        total_izb+=All[i].izb;
        total_golos+=All[i].nib + All[i].dib;
    }

    printf("total_izb = %d\ntotal_golos = %d\nyavka = %f\n",
            total_izb, total_golos, (double)total_golos/(double)total_izb);


//---------------- Графика --------------------------//


    printf("Initializing SDL.\n");
   
    /* Initialize defaults, Video and Audio */
    if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
        printf("Could not initialize SDL: %s.\n", SDL_GetError());
        exit(-1);
    }

    printf("SDL initialized.\n");

    SDL_WM_SetCaption("unicorn55 for FDK",NULL);

   screen = SDL_SetVideoMode(WIDTH, HEIGHT,32,SDL_SWSURFACE);



    for (i=2;i<NUIK+2;i++){
        bull = All[i].nib+All[i].dib;
        if (All[i].izb && bull)
           putpixel(screen,(double)bull*(WIDTH-1)/(double)All[i].izb,
           
           (double)All[i].er  // Именно здесь определяется график какой партии рисуем
           
           *(HEIGHT-1)/(double)bull, 0xFFFFFFFF);
    }


    printf("ok\n");


// Ждем когда пользователь закроет окошко
   
   running = 1;
   while (running) {
      if (SDL_PollEvent(&event)) {
         if (event.type == SDL_QUIT) {
            running = 0;
         }
      }
   }


    printf("Quiting SDL.\n");
   
    /* Shutdown all subsystems */
    SDL_Quit();
    exit(0);
}
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#12 unicorn55 » Чт, 26 января 2012, 22:28

Лестница Чурова построена! :smile:

Изображение

Код: Выделить всё
#include <SDL.h>  // Нужно для графики
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <fenv.h>


SDL_Surface* screen = 0;
SDL_Event event;
int running = 0;

int povtor = 0;

#define WIDTH 1001  // Ширина экрана
#define HEIGHT 800  // Высота экрана

int diagram[WIDTH]; // Массив по которому будет строиться столбчатая диаграмма
double yavka = 0;   // явка на данном УИК
double vote = 0;    // процент проголосовавших за конкретную партию


// рисует пиксел

void putpixel(SDL_Surface* screen, int x, int y, int color) {
   int* pixels=(int*)screen->pixels;
    y=HEIGHT-y-1;
    if (x>=WIDTH || y>=HEIGHT || x <0 || y <0) {printf("%d %d\n", x,y); return;}

   pixels[WIDTH*y+x]=color;
   SDL_UpdateRect(screen, x, y, 1, 1);
}


// рисует ветрикальную линию из точки (x,y) вверх на длину length

void vert_line(SDL_Surface* screen, int x, int y, int length, int color) {
    int i=0;
    if (y+length>=HEIGHT) {
        printf("x=%d y=%d length=%d\n",x,y,length);
        length = HEIGHT-y;
    }
    while (i<length) {
        putpixel(screen,x,y+i,color);
        i++;
    }
}



// число УИКов
#define NUIK 95185

// имя исходного текстового файла, откуда будем считывать данные
char* txt_filename = "p2011.txt";
// сам файл
FILE* txt_file;

// буфер для скачивания сюда первой ненужной строки
char str[2000];
// фиктивная переменная для записи в нее ненужных данных
int t;

int total_izb;
int total_golos;

// Тип из которых будет состоять большой массив по всем УИКам

typedef struct {
    int izb;    // число избирателей в списке
   int nib;    // число недействительных избирательных беллютеня
   int dib;    // число действительных избирательных беллютеня
   int spr;   // число проголосовавших за Справедливую Россию
   int ldpr;   // число проголосовавших за ЛДПР
   int pr;      // число проголосовавших за Правое Дело
   int kprf;   // число проголосовавших за КПРФ
   int yabl;   // число проголосовавших за Яблоко   
   int er;      // число проголосовавших за Единую Россию
   int pd;      // число проголосовавших за Правое Дело
} t_uik;


// Большой массив данных по всем 95185 УИКам
// первые две строчки не используются чтобы номера элементов массива
// соответствовали номерам строк в исходной Excel-таблице

t_uik All[NUIK+2];


// функция считывает символы из текстового файла f пока не считает символ табуляции
// таким образом она пропускает одно значение в таблице и переходит к следующему

void skip_to_tab(FILE* f) {
    while (fgetc(f) != '\t');
}

//=====================================//
//======= Главная программа ===========//
//=====================================//

int main(int argc, char *argv[]) {

    int i; // счетчик для цикла от 2 до 95186
    int bull; // число бюллетеней действительных плюс недействительных

    txt_file = fopen(txt_filename,"r"); // открываем текст для чтения
    if (txt_file==NULL) {printf("Error: fopen\n"); exit(1);}

    fgets(str,2000,txt_file);   // считываем первую строку, это заголовки столбцов, они нам не нужны

    // цикл считывания данных по всем УИКам

    for (i=2;i<2+NUIK;i++) {
 
     // пропускаем первые 4 текстовые значения таблицы (они нам не нужны)

        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);
        skip_to_tab(txt_file);

     // а дальше идут числа, считываем их с помощью fscanf

        fscanf(txt_file,
       
            "%d"                // 1 ненужный (номер уика)
            "%d"                // 1 нужный — число избирателей в списке
            "%d%d%d%d%d%d%d"    // 7 ненужных
            "%d%d"               // 2 нужных (это NIB и DIB)
            "%d%d%d%d%d%d%d%d"   // 8 ненужных
            "%d%d%d%d%d%d%d",    // 7 нужных — это голоса за каждые из 7 партий
            &t,                     // ненужный считываем в фиктивную переменную
            &(All[i].izb),          // число избирателей в списке
            &t,&t,&t,&t,&t,&t,&t,  // ненужные, считываем в фиктивную переменную
            &(All[i].nib),&(All[i].dib), // заполняем NIB и DIB
            &t,&t,&t,&t,&t,&t,&t,&t,     // ненужные, считываем в фиктивную переменную
        // считываем голоса за 7 партий
            &(All[i].spr),      // СПР
            &(All[i].ldpr),     // ЛДПР
            &(All[i].pr),       // Патриоты России
            &(All[i].kprf),     // КПРФ
            &(All[i].yabl),     // Яблоко
            &(All[i].er),       // ЕР
            &(All[i].pd));      // Правое Дело


    }

    // данные считаны, закрываем файл

    fclose(txt_file);

// Выводим данные любой строчки для сверки с данными в Excel, чтобы удостоверится что
// данные считались успешно
// Например, возьмем самую последнюю строчку.
    i = 95186;
    printf("i=%d IZB=%d NIB=%d DIB=%d spr=%d ldpr=%d pr=%d kprf=%d yabl=%d er=%d pd=%d\n",
            i, All[i].izb, All[i].nib, All[i].dib,
            All[i].spr, All[i].ldpr, All[i].pr, All[i].kprf, All[i].yabl, All[i].er, All[i].pd);

// Посчитаем сколько всего было избирателей в списках и
// Сколько всего проголосовавших, таким образом мы узнаем общую явку по стране

    total_izb = 0;
    total_golos = 0;
    for (i=2;i<NUIK+2;i++){
        total_izb+=All[i].izb;
        total_golos+=All[i].nib + All[i].dib;
    }

    printf("total_izb = %d\ntotal_golos = %d\nyavka = %f\n",
            total_izb, total_golos, (double)total_golos/(double)total_izb);


//---------------- Графика --------------------------//


    printf("Initializing SDL.\n");
   
    /* Initialize defaults, Video and Audio */
    if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
        printf("Could not initialize SDL: %s.\n", SDL_GetError());
        exit(-1);
    }

    printf("SDL initialized.\n");

    SDL_WM_SetCaption("unicorn55 for FDK",NULL);

   screen = SDL_SetVideoMode(WIDTH, HEIGHT,32,SDL_SWSURFACE);


 // Обнуняем диаграмму
    for (i=0;i<WIDTH;i++) diagram[i]=0;


fesetround(FE_TONEAREST); // задаем направление округления — к ближайшему целому

    for (i=2;i<NUIK+2;i++){
        bull = All[i].nib+All[i].dib;
        if (All[i].izb && bull) {
           yavka = (double)bull/(double)All[i].izb;
           vote = (double)All[i].er  // Именно здесь определяется график какой партии рисуем
                      /(double)bull;
           t=round((WIDTH-1)*vote);
           diagram[t]++;
           //putpixel(screen, yavka*(WIDTH-1), vote*(HEIGHT-1), 0xFFFFFFFF);
        }
    }

    for (i=0;i<WIDTH;i++) {
        //putpixel(screen, i,diagram[i], 0xFFFFFFFF);
        vert_line(screen,i,0,diagram[i], 0xFFFFFFFF);
    }


    printf("povtor = %d\n", povtor);


// Ждем когда пользователь закроет окошко
   
   running = 1;
   while (running) {
      if (SDL_PollEvent(&event)) {
         if (event.type == SDL_QUIT) {
            running = 0;
         }
      }
   }


    printf("Quiting SDL.\n");
   
    /* Shutdown all subsystems */
    SDL_Quit();
    exit(0);
}


unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц

Re: Выборы и Programming

#13 unicorn55 » Пт, 27 января 2012, 0:06

Итак, посмотрим внимательней на эту диаграмму. Для этого я открыл картинку в графическом редакторе, и посмотрел где находятся пики (резко выступающие столбики).

Изображение
unicorn55
Автор темы
Сообщения: 8347
Темы: 124
Зарегистрирован: Ср, 18 марта 2009
С нами: 15 лет 1 месяц


Вернуться в Свои темы

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 13 гостей

cron
Fatal: Not able to open ./cache/data_global.php