Позначки

,

Замітка: стаття оновлювалась через те, що оновлювались дані на сайті ЦВК. Наразі реєстрація кандидатів завершена, в ЦВК зареєстрували 23 кандидати в президенти, ще 23-м відмовили в реєстрації. Стаття поновлена на основі даних 23-х кандидатів, тобто всіх зареєстрованих. Отже більше оновлюватись мабуть вже не буде.

Як відомо, 25 травня 2014-го заплановані вибори Президента України.

На сайті ЦВК є інформація про зареєстрованих кандидатів на основі якої я вирішив зібрати якусь статистику (по принципу “щоб було”). Наразі є інформація про 23 кандидати, можливо з часом додасться ще.

Але менше прелюдій – вйо до статистики (-:


Статистика по 23 кандидатам в Президенти України 2014-го року, на основі даних сайту ЦВК:

– За даними ЦВК всі кандидати є громадянами України і проживають в Україні протягом останніх 10 років (інше ніби і не дозволено кандидату в президенти – тому ЦВК тут в ролі Капітана Очевидність).
Освіта: вища у всіх, крім Рабіновича (загальна середня).
– Робота: “тимчасово не працює” 6 кандидатів – Бойко, Королевська, Ярош, Добкін, Цушко, Шкіряк. 9 – працюють як нардепи (Тягнибок, Ляшко, Гриценко, Царьов, Тігіпко, Порошенко, Симоненко та Клименко – останній за посадою вказаний як голова партії УНП, а Тимошенко – як голова партії ВО “Батьківщина”. Не знаю чи голова партії це повноцінна “робота” (-: ).
– Суб’єкти висування: 16 самовисуванців, Симоненко – КПУ, Гриценко – Партія “Громадянська Позиція”, Ляшко – Радикальна Партія О.Ляшка, Тимошенко – В.О. “Батьківщина”, Тягнибок – В.О. “Свобода”, Клименко – Українська Народна Партія, Куйбіда – Народний Рух України.
– Партійність: 10 безпартійних, 4 регіоналів (Бойко, Царьов, Тігіпко, Добкін), ще 9 з різних партій.
– Місце народження: для Царьова не вказано на сайті ЦВК (вікіпедія каже що Дніпропетровськ – це двоє разом з Тимошенко + Ярош з області – Дніпродзержинсьй), 3 з донецька (Коновалюк, Кузьмин, Симоненко) + Бойко та Клименко з області (Горлівка та Мар’їнка відповідно), 3 з Харкова (Рабіновіч, Гриненко Андрій – не плутати з Гриценко Анатолієм, Добкін). В Молдавії народився Тігіпко. Пара людей є з Черкаської області, є з Одеської та Чернігова, але справжній західняк лише один – Тягнибок (Львів). Поправка – ще додався закарпатець Шкіряк з Ужгорода.
– Вік – найстарші кандидати (55 і більше): 6 – 61 Симоненко, 60 Рабінович, 58 Маломуж, 56 Гриценко, 55 рівно Бойко та Куйбіда.
– Вік – наймолодші (до 45 включно): 8 – 38 Королевська, 41 Ляшко, 42 Ярош, 43 Царьов та Шкіряк, 44 Гриненко (не Гриценко) та Добкін, 45 рівно Тягнибок.
– Стать: 3 кандидати жіночої статі – Тимошенко, Богомолець та Королевська.

Доречі, найпершими встигли зареєструватись саме регіонали та всілякі неприємні мені персонально особи на кшталт Допи та ТиГібок-а. Поглянем на хронологію реєстрацій.


Хронологія прийняття рішень ЦВК про реєстрацію кандидата:

2014-03-17
– Кузьмін Ренат Равелійович

2014-03-27
– Бойко Юрій Анатолійович

2014-03-28
– Добкін Михайло Маркович
– Рабінович Вадим Зіновійович
– Тігіпко Сергій Леонідович

2014-03-30
– Коновалюк Валерій Ілліч
– Саранов Володимир Георгійович

2014-03-31
– Гриненко Андрій Валерійович
– Ляшко Олег Валерійович
– Маломуж Микола Григорович
– Порошенко Петро Олексійович
– Симоненко Петро Миколайович
– Тимошенко Юлія Володимирівна
– Царьов Олег Анатолійович

2014-04-01
– Богомолець Ольга Вадимівна
– Гриценко Анатолій Степанович
– Королевська Наталія Юріївна
– Тягнибок Олег Ярославович
– Ярош Дмитро Анатолійович
– Цушко Василь Петрович
– Клименко Олександр Іванович

2014-04-02
– Шкіряк Зорян Несторович
– Куйбіда Василь Степанович

Найцікавіші як на мене кандидати – зареєстровані передостанніми.


Код!

Т.я. я є програміст по професії, то звичайно рахував статистику не руками. Для считування даних з сайту ЦВК та підрахунку статистики був написаний скріпт для GroovyShell з використанням чудової бібліотеки для парсання HTML під назвою JSoup.

Для повноти коду потрібні також деякі “макроси” якими я користуюсь в GroovyShell і відповідно тримаю в своєму groovysh.rc – копію якого маю на github.

Сам код в поточному вигляді (без гарного форматування бо це лише скріпт для groovyshell а не повноцінний софт – вибачайте):

mv_LD("/Users/mvmn/_my/_prog/_dev/_lib/jsoup-1.7.3.jar");

def calcAge(date) {
Calendar dobDate = Calendar.getInstance();
dobDate.setTime(date);
Calendar today = Calendar.getInstance();
int curYear = today.get(Calendar.YEAR);
int curMonth = today.get(Calendar.MONTH);
int curDay = today.get(Calendar.DAY_OF_MONTH);
int year = dobDate.get(Calendar.YEAR);
int month = dobDate.get(Calendar.MONTH);
int day = dobDate.get(Calendar.DAY_OF_MONTH);
int age = curYear - year;
if (curMonth < month || (month == curMonth && curDay < day)) {
 age--;
}
return age;
}

baseurl = "http://www.cvk.gov.ua/pls/vp2014/";
url = baseurl+"wp003?PT001F01=702";
def getDetailsUrls(baseurl, url) {
detailsurls = new HashSet();
org.jsoup.Jsoup.connect(url).timeout(15000).get().select(".a1").each{ detailsurls.add(baseurl+it.attr("href")); }
return detailsurls;
}

detailsurls = getDetailsUrls(baseurl, url); println "#### Candidate details URLs: "+detailsurls.size();

def makeRetriever(final url) {
retriever = new java.util.concurrent.Callable() { public Object call() throws Exception {
 Map result = new HashMap();
 Object doc = org.jsoup.Jsoup.connect(url).timeout(15000).get();
 doc.select(".t2 tr").each{ result.put(it.select(".td2").text().trim(), it.select(".td3").text().trim()); };
 result.put("name", doc.select(".p4").text())
 result.put("imageurl", doc.select("img[alt=Фото кандидата]").attr("src"));
 result.remove("");
 return result;
}}}

execSvc = java.util.concurrent.Executors.newCachedThreadPool();

dataprov = new ArrayList();
detailsurls.each{ dataprov.add(execSvc.submit(makeRetriever(it))); }
data = new ArrayList();
sdf = new java.text.SimpleDateFormat("d.M.yyyy");
ssdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
dataprov.each{ 
 res = it.get(); 
 dob = sdf.parse(res.get("Дата народження"));
 res.put("Вік", calcAge(dob));
 wrk = res.get("Місце роботи");
 chr = res.remove("Посада (заняття)");
 res.put("Місце роботи", [wrk, chr].grep{it!=null}.join(": "));
 res.put("Дата народження", ssdf.format(dob));
 res.put("Дата прийняття рішення ЦВК про реєстрацію", ssdf.format(sdf.parse(res.get("Дата прийняття рішення ЦВК про реєстрацію"))));
 res.put("Номер рішення ЦВК про реєстрацію", new Integer(Integer.parseInt(res.get("Номер рішення ЦВК про реєстрацію"))));
 res.put("image", new javax.swing.ImageIcon(new URL(baseurl+res.remove("imageurl"))));
 data.add(res); 
}

columns = new HashSet();
data.each{ columns.addAll(it.keySet()); }
columns = columns.sort().toArray();

def toArrayByRef(columns, map) {
result = new Object[columns.length];
for(int i=0;i<columns.length;i++) {
result[i]=map.get(columns[i]);
}
return result;}

dataArrays=new Object[data.size()][];
i=0;
data.each{ dataArrays[i++]=toArrayByRef(columns, it); }
tableModel = new javax.swing.table.DefaultTableModel(dataArrays, columns) {
public Class getColumnClass(int columnIndex) {
return columnIndex>0?String.class:javax.swing.ImageIcon.class;
}
}

table = new javax.swing.JTable(tableModel);
table.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF );
initialRowHeight = table.rowHeight;
fullRowHeight = data.max{ it.get("image").iconHeight }.get("image").iconHeight;

table.tableHeader.addMouseListener(new java.awt.event.MouseAdapter() {
 Object[][] dataArrays;
 Object[] columns;
 int initialRowHeight;
 int fullRowHeight;
 public java.awt.event.MouseAdapter init(Object[][] dataArrays, Object[] columns, int initialRowHeight, int fullRowHeight) {
 this.dataArrays=dataArrays;
 this.columns=columns;
 this.initialRowHeight=initialRowHeight;
 this.fullRowHeight=fullRowHeight;
 return this;
 }
 public void mouseClicked(java.awt.event.MouseEvent mouseEvent) {
 int index = mouseEvent.source.columnAtPoint(mouseEvent.getPoint());
 if (index > 0) { 
 Arrays.sort(dataArrays, new Comparator() { 
 public int compare(Object a, Object b){ return (a[index]!=null && b[index]!=null)? a[index].compareTo(b[index]) : (a[index]!=null)?-1:0; }});
 mouseEvent.source.table.model.setDataVector(dataArrays, columns); 
 } else if(index==0) {
 if(mouseEvent.source.table.rowHeight<fullRowHeight) {
 mouseEvent.source.table.setRowHeight(fullRowHeight);
 } else {
 mouseEvent.source.table.setRowHeight(initialRowHeight);
 }
 }
 }
}.init(dataArrays, columns, initialRowHeight, fullRowHeight));

def tableModelToTreeModel(tableModel) {
 rootnode = new javax.swing.tree.DefaultMutableTreeNode("All");
 for(int ci=0;ci<tableModel.columnCount;ci++) {
 colnode = new javax.swing.tree.DefaultMutableTreeNode(tableModel.getColumnName(ci));
 rootnode.add(colnode);
 values = new ArrayList(tableModel.rowCount);
 for(int ri=0;ri<tableModel.rowCount;ri++) { values.add([tableModel.getValueAt(ri,ci),tableModel.getValueAt(ri,1)]); }
 grouped=values.groupBy{ it[0]; }
 grouped.sort{ it.key }.each{
 valnode = new javax.swing.tree.DefaultMutableTreeNode(it.key.toString()+" ("+it.value.size()+")");
 it.value.each{
 valnode.add(new javax.swing.tree.DefaultMutableTreeNode(it[1]));
 }
 colnode.add(valnode);
 }
 }
 return rootnode;
}

frame = mv_enframe(new javax.swing.JSplitPane(javax.swing.JSplitPane.HORIZONTAL_SPLIT, new javax.swing.JScrollPane(new javax.swing.JTree(tableModelToTreeModel(tableModel))), new javax.swing.JScrollPane(table)));
frame.contentPane.add(new javax.swing.JLabel("Total: "+dataArrays.length), java.awt.BorderLayout.SOUTH);
frame.pack();

["Проживання в Україні","Громадянство","Освіта","Вік","Дата прийняття рішення ЦВК про реєстрацію","Партійність","Суб’єкт висування або самовисунення","Місце народження","Місце роботи"].each{ col -> println "\n\n---- "+col+" ----"; data.groupBy{ it.get(col); }.sort{ it.key; }.each{ println "# "+it.key+" ("+it.value.size()+")"; it.value.each{ println " - "+it.get("name"); } } }
Advertisements