Страницы

Поиск по вопросам

понедельник, 15 июля 2019 г.

Связать событие Filereader().onprogress с множественными элементами progress

В проекте есть загрузчик картинок с "превьюшками" и есть несколько элементов progress для отображения процесса загрузки по каждой картинке отдельно. Но приведенный код отображает прогресс только на последнем, созданном элементе progress. Подскажите пожалуйста как сделать так чтобы процесс загрузки каждой картинки отображался в соответствующем элементе progress?
function processFiles(files) { var numFiles = files.length;
for (var i = 0, numFiles = files.length; i < numFiles; i++) { var f = files[i];
// Обрабатываем только графические файлы ! if (!f.type.match('image.*')) { continue; }
//Проверяем существует ли элемент img если нет то запишем следующую картинку в него for (var e = 0; e < image_amount_restriction; e++) { if (document.getElementById("img"+e)==null) { element_id=e; break; } }
var last = image_amount_restriction - element_id; console.log(last); if ( last < 2) {return false;}

//создем обьекты UI var parent = document.getElementById("photos"); var div = document.createElement("div"); div.id = ("block"+element_id); div.className = "editbox";
parent.appendChild(div);
var parentE2 = document.getElementById("block"+element_id); var edit_panel = document.createElement("span"); edit_panel.className = "edit_panel"; edit_panel.id = ("edit_panel"+element_id);
var hiddenfield = document.createElement("input"); hiddenfield.type = "hidden"; hiddenfield.name ="output[]"; hiddenfield.id =("out"+element_id);
parentE2.appendChild(hiddenfield);
var img = document.createElement("img"); img.classList.add("obj"); img.id = ("img"+element_id);
parentE2.appendChild(edit_panel); parentE2.appendChild(img);
//прогрессбар var progressbar = document.createElement("progress"); progressbar.id = ("my-progress"+element_id); progressbar.className = "progressbar"; parentE2.appendChild(progressbar);
var parentE3 = document.getElementById("edit_panel"+element_id); var trash_can = document.createElement("a"); trash_can.className = "foto_n1"; trash_can.id = element_id; trash_can.href = "#"; trash_can.onclick = remove;
parentE3.appendChild(trash_can);

var reader = new FileReader();
//Недоделанный прогрессбар! reader.onprogress = function(event) {
if (event.lengthComputable) { console.log(progressbar.id); progressbar.max = event.total; progressbar.value = event.loaded; } }
reader.onloadend = function(event) { var contents = event.target.result, error = event.target.error; if (error != null) { console.error("File could not be read! Code " + error.code); } else { progressbar.max = 1; progressbar.value = 1; } }

// Пишем картинки после загрузки в соответсвующие контейнеры reader.onload = (function(aImg,hiddenfield,progressbar) { return function(e) { aImg.src = e.target.result; hiddenfield.value=e.target.result; //когда загрузились, скрываем прогресс бар progressbar.className += " hidden"; }; }) (img,hiddenfield,progressbar);
reader.readAsDataURL(f); }


Ответ

Скорее всего, это связано с тем, что не использовано замыкание при привязке обработчика. Т.к. не видно необходимого кода, то попробую посоветовать "на глаз":
for (i=0; iВ функцию progressHook(event, i) первым параметром передаётся событие, а вторым - порядковый номер файла, прогресс, которого хотите отслеживать.

Как применить анимацию к блоку при скроллинге ниже определенной точки?

Проблема с анимацией.
Планируется, что меню navBar при скроллинге ниже header будет плавно менять прозрачность и становиться fixed, а при возвращении назад всё так же плавно убирается.
На деле происходит единственная анимация. Появление анимируется как надо, а вот остальные анимации происходят как если бы не было вызова .animate() Подскажите, как сделать действие обратное появлению и почему анимация происходит только первый раз?
$(window).scroll(function(){
if(($(window).scrollTop()>$navBarHeight)&&($(window).scrollTop()<$headerHeight+17)){ $(".navBar").css({"opacity":"0"}); }else if($(window).scrollTop()<$navBarHeight){ $(".navBar").css({"opacity":"1"}); }
if (($(window).scrollTop()>$headerHeight)){ $(".navBar").animate({ opacity:1 },1500); $("header").css({"margin-top":$(".navBar").height()}); $(".navBar").addClass("stick");
}else { $(".navBar").removeClass("stick"); $("header").css({"margin-top":0}); } });


Ответ

Чтобы исключить выставления свойства opacity в стиле у конкретного элемента, лучше использовать css-классы вместо js функций.
В данном случае можно просто добавить класс, например
.inv { opacity: 0; }
который надо использовать, когда нужно скрыть элемент
и добавить в класс, например stick, transition для свойства opacity
transition: opacity 1.5s ease;
Пример
$(document).ready(function() { $headerHeight = $("header").height(); $navBarHeight = $(".navBar").height(); $(window).resize(function() { $navBarHeight = $(".navBar").height(); $headerHeight = $("header").height(); }); $(window).scroll(function() { if (($(window).scrollTop() > $navBarHeight) && ($(window).scrollTop() < $headerHeight + 17)) { $(".navBar").addClass('inv'); } else if ($(window).scrollTop() < $navBarHeight) { $(".navBar").removeClass('inv'); } if (($(window).scrollTop() > $headerHeight)) { $("header").css({ "margin-top": $(".navBar").height() }); $(".navBar").addClass("stick"); } else { $(".navBar").removeClass("stick", 1000); $("header").css({ "margin-top": 0 }); } }); }); section { height: 400px; } body { font-family: "RobotoRegular"; } a, a:active, a:link, a:visited { text-decoration: none; color: #679FD2; } nav { background-color: black; } nav .current, nav a:hover { color: #BF8430; border-left: 1px solid #BF8430; border-right: 1px solid #BF8430; transition: 0.5s ease; } nav a:not(:hover) { transition: 0.5s ease; } nav a { display: block; border-left: 1px solid black; border-right: 1px solid black; padding: 10px; } nav ul { height: 100%; font-size: 25px; margin: 0 0; list-style: none; } nav ul li { height: 100%; text-align: center; } .inv { opacity: 0; } .stick { position: fixed; width: 100%; top: 0; left: 0; opacity: 1; z-index: 5; transition: opacity 1.5s ease; } header { background-color: #FF4540; color: white; padding-top: 20px; font-size: 30px; } header .logoBlock { margin: 0 auto; } header #firstWords { font-family: "AdineKirnbergRegular", Times, sans-serif; font-size: 70px; } header #secondWords { font-family: "AdineKirnbergRegular", Times, sans-serif; font-size: 50px; margin-left: 40px; margin-top: -30px; margin-bottom: 60px; } header .face { border-radius: 300px; width: 100%; height: auto; } .something { font-size: 40px; }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem id voluptate nulla incidunt voluptas quo nesciunt, explicabo, qui aut dolorum esse commodi inventore veritatis hic modi nam dolorem placeat sit!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vel earum consectetur minus, aliquam nostrum odio molestias odit officia, fugit tempora amet perspiciatis nemo dicta repellat magni quisquam vitae nobis quidem.
Magnam quae, laboriosam dignissimos eligendi! Atque exercitationem harum aperiam provident non illum tempore eos incidunt obcaecati, ut adipisci explicabo blanditiis iste ducimus dolore fuga magni odit cupiditate voluptatibus quis facere!
Inventore sapiente omnis autem id ullam, cumque accusantium, nemo doloremque enim voluptas iste vitae. Eligendi delectus ipsam voluptate! Libero quam itaque eum nobis quia numquam corporis, tenetur officiis facilis deleniti?
Est vitae vero culpa corporis ex ipsa, atque, illum quas illo quibusdam cum beatae magni eum quidem magnam iste laboriosam distinctio sequi temporibus tenetur. Non eum nesciunt excepturi, eaque libero!
Quibusdam accusantium nemo minus praesentium eligendi quis, placeat quo. Ab eum fugit nesciunt labore qui eius iure ex. Ab excepturi labore distinctio delectus ullam vitae architecto unde culpa repellat ipsum?
Vero dolores aspernatur repudiandae iure consequatur laudantium sapiente impedit quas at facilis illum modi similique quidem asperiores sint vitae voluptate consequuntur consectetur tenetur, voluptates eligendi numquam! Magni nam, voluptate voluptatibus.
Atque ducimus, repellat, nulla quae magnam iure eius ad quo ab at, quod dolor. Enim at quisquam, itaque aspernatur quam adipisci iusto consectetur consequuntur ducimus! Quaerat aspernatur ipsam earum vero.
Quibusdam sunt maxime magni temporibus, velit fugit ducimus sed eum rem doloremque voluptatem reprehenderit dignissimos, aut inventore vero. Iste ipsam at in velit, doloribus, a. Distinctio accusamus, veniam ratione voluptatibus.
Asperiores temporibus quae aspernatur quos. Enim doloribus nesciunt nihil dignissimos consequuntur officiis. Quia possimus molestias iusto dicta atque, modi officia, assumenda beatae quod, minus repudiandae? Molestias nihil deleniti, aut asperiores?
A, tempore dignissimos eaque laudantium asperiores explicabo perferendis. Accusantium necessitatibus beatae, laboriosam fugit dolor tempora! Totam quod doloribus porro ad beatae quae pariatur perspiciatis, esse nihil iste tenetur quidem voluptatum?
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos ratione odit, laboriosam delectus maxime quod quisquam ipsum iste sit impedit excepturi consequatur eaque eos vel molestias tempore atque commodi, voluptate.
Similique consectetur ducimus quo tempora. Ad dolorum molestias nostrum, aspernatur reiciendis a provident sed consequatur quod ullam vero fuga quia ratione quam eligendi magnam debitis consequuntur eos quae, esse odio.
Magnam ad tempora animi sint officiis iure quibusdam optio ullam libero cumque vitae aperiam dolores molestias architecto temporibus dolor mollitia sunt consequuntur eveniet molestiae, esse sed! Sapiente, error vero aperiam.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias, veritatis optio suscipit at odio enim, velit dolores quaerat placeat incidunt excepturi, nisi veniam, recusandae nobis tempore? Ab aliquam enim nobis.
Sequi magni, veniam omnis, soluta facere saepe deserunt harum a quasi tenetur quibusdam! At doloribus inventore molestiae debitis alias ipsum commodi, natus explicabo accusantium a non, dicta blanditiis necessitatibus hic!
Quos nemo praesentium expedita veritatis. Repellendus quod accusantium autem, odio perspiciatis. Cum sit, unde velit recusandae in tenetur, tempora eveniet sapiente molestias. Dolores amet, fugiat debitis perferendis, mollitia deleniti corporis!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum tempore in sed consequuntur non facere rerum aliquid, modi voluptas explicabo. Accusamus quibusdam rem doloremque, sed rerum unde repudiandae blanditiis et.
Ipsa dolore natus accusamus aperiam consequuntur tempora ut repellat ullam esse, ea reiciendis magnam cupiditate nobis labore cum nostrum voluptatibus possimus soluta. Magnam quisquam iste necessitatibus cum soluta cupiditate reiciendis.
Dolor, labore esse dicta quibusdam hic totam, ipsum obcaecati voluptate quaerat blanditiis ab aliquid cumque quia veritatis voluptatum rerum consequuntur quisquam, vero maxime nobis repellendus architecto minus aspernatur sapiente. Eos!

как остановить CountDownTimer при нажатии клавиши ввод на клавиатуре

Есть таймер (прописан в OnCreate):
CountDownTimer timer; timer = new CountDownTimer(10000, 1000) { public void onTick(long millisUntilFinished) { text_d1.setText("Осталось: "+ millisUntilFinished / 1000);
public void onFinish() { text_d1.setText("Время вышло"); } }.start();
Есть метод обработки нажатия клавиши ввод на виртуальной клавиатуре:
public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && (keyCode == KeyEvent.KEYCODE_ENTER)) { // тут разные условия, в зависимости от того, в каком edittext нажата клавиша ввод
return true; } return false; }
Логика такая:
Как только открывается активити, таймер запускается.
Таймер автоматически останавливается через 10 сек.
Как добавить условие, что таймер также останавливается, если клавиша ввод на клавиатуре нажата?


Ответ

Скорее всего вам надо просто вызвать timer.cancel() в нужном месте. Но для этого вам надо иметь доступ к переменной timer. А доступ к ней в обработчиках разных можно получить, если она будет объявлена не внутри метода onCreate, а на уровне активити. Т.е., примерно, так:
CountDownTimer timer;
public void onCreate(Bundle b) { ... }

swing KeyListener не отлавливает нажатие

import javax.swing.*; import java.awt.*;
public class Main { public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() { public void run() {
JFrame frameMain = new JFrame(); frameMain.setLayout(new BorderLayout()); JPanel label = new JPanel(); JButton button = new JButton("Button"); label.add(button); // Вопрос 3
frameMain.add(label, BorderLayout.NORTH); HelloComponent helloComponent = new HelloComponent(); frameMain.add(helloComponent, BorderLayout.CENTER); frameMain.addKeyListener(helloComponent); // Вопрос 2
frameMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frameMain.setSize(400, 400); frameMain.setVisible(true);
} });
} }

import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class HelloComponent extends JComponent implements KeyListener, MouseMotionListener {
String theMessage = "Hello"; int x = 10; int y = 10;
public HelloComponent() {
//addKeyListener(this); // Вопрос 1 addMouseMotionListener(this); }
public void paintComponent (Graphics g){ g.drawString(theMessage, x, y); }
@Override public void keyTyped(KeyEvent e) { }
@Override public void keyPressed(KeyEvent e) { }
@Override public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_LEFT){ theMessage = "olleH"; repaint(); } else if(e.getKeyCode() == KeyEvent.VK_RIGHT){ theMessage = "Hello"; repaint(); } }
@Override public void mouseDragged(MouseEvent e) { x = e.getX(); y = e.getY(); repaint();
}
@Override public void mouseMoved(MouseEvent e) { } }
Вопрос 1
Если в конструкторе добавлять addKeyListener(this), то он не работает и при этом addMouseMotionListener(this) работает нормально.
Вопрос 2
Если добавлять во Farame frameMain.addKeyListener(helloComponent); все работает, но перестает если добавлять кнопку.
Вопрос 3
Потом не удается установить фокус. При этом мышка перерисовывает как нужно.
Подскажите где и что не так?


Ответ

Компонент порождает KeyEventы, только когда находится в фокусе. Чтобы ваш компонент мог получить фокус автоматически, нужно вызвать для него setFocusable( true ), или сделать привязку клавиш через Input Map (да, isFocusable() возвращает true, но фокус не передается, так задумано (JDK-6530201)). Поскольку окно не содержит компонентов, которым может отдать фокус, оно оставляет его себе, поэтому ваш компонент получает события, порождаемые окном. Кнопка может получить фокус и получает, а ваш компонент снова не видит нажатия.
Небольшие доработки для иллюстрации:
public HelloComponent() { setFocusable( true );
addKeyListener(this); // Вопрос 1 addMouseMotionListener(this);
addFocusListener( new FocusListener() { // перерисовка при получении и потере фокуса @Override public void focusLost(FocusEvent e) { repaint(); } @Override public void focusGained(FocusEvent e) { repaint(); } });
addMouseListener( new MouseAdapter() { // запрос фокуса при нажатии мыши @Override public void mousePressed( MouseEvent e ) { requestFocusInWindow(); } }); }
public void paintComponent (Graphics g){ g.setColor( isFocusOwner() ? Color.RED : Color.ORANGE ); g.fillRect(0, 0, getWidth(), getHeight() ); g.setColor( Color.BLACK ); g.drawString(theMessage, x, y); }
Java Turtorials: How to use focus subsystem

Progressbar выводит только background изображение

Подскажите в чем ошибка при стилизации progressBarStyleHorizontal? Подменил у ProgressBar свойство progressDrawable, но выставление значений для контрола к видимым изменениям не приводит. Показывается только пустой ProgressBar.
Вот часть хмл из layout-а:

вот кастомный drawable:

изображения - nine-patch png: в коде значения:
mFullProgress.setMax(100); mFullProgress.setProgress(70);
стиль приложения:

скриншот пустого прогрессбара:

Update (результат правок):
В приницпе похоже на правду (см ответ), но результат странный, вот скриншот
Update (добавлен clip элемент в drawable): После добавления clip для progress

контрол реагирует на изменение значений (progress и max):
Update (рабочее решение): Проблема была в отсутсвии у nine-patch background изображения отметок об области контента. При рендеринге layer-list все слои после первого сжимались в 0 (при некоторых размерах контрола можно было видеть тонкую полоску). поправленный бекграунд

верстка

скриншот


Ответ

Проблема, возможно, в конфликте стиля виджета и присвоенного drawable
Попробуйте определить собственную тему для него как описано тут
В стилях: res/values/styles.xml

И назначаем наш кастомный стиль:

Как перенести уже написанный код на Фрагменты?

Допустим, я создал какую-то программу. Но запутался в файлах активити. Одна часть отображается правильно, а другая совсем иначе. Не могу отображать нужную вещь в нужном месте. Всё превратилось в кашу.
Погуглив, прочитал о фрагментах. Но не знаю как разбить уже готовый код на куски.
Как это сделать? Как перенести готовую рабочую программу на фрагменты?


Ответ

Поможет или нет, не знаю. Совсем недавно, неделю назад, я переписывал свою программу под фрагменты. Раньше было все в MainActivity. Захотелось все перенести на отдельные листы где в каждом была какая то часть из старого активити. Что я делал? Сначала просто добавил эти самые фрагменты и все что вызывало ошибку закоменитровал. Далее частями переносил. Возникали проблемы-вопросы как обращаться к методам активити из фрагмента или наоборот. При помощи поиска находил все ответы. Медленно но верно все перенеслось. Думал, что не получится, но за 3 дня справился, чего и вам желаю.

Переадресация всех страниц на одну в .htaccess

Испльзую код
RewriteEngine on RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
все работает пока не создаю папку с таким же названием как и у ссылки
mysite.ru/catalog/ - работает mysite.ru/catalog - работает
создаю папку catalog
mysite.ru/catalog/ - работает mysite.ru/catalog - работает, но в строке браузера превращается в mysite.ru/catalog/?route=catalog
Под работает я подразумеваю, что переменная $_GET['route'] содержит корректные данные. Даже когда добавляет в конец /?route=catalog
Удалил все из index.php. Он теперь пустой, но проблема осталась.
Сделал чистый проект test.loc пустая папка catalog, .htaccess(смотри выше), index.php(пустой) если ссылка без слеша он добавляет его, а не /?route=catalog (Поправка после нескольких тестов в тестовом проекте тоже стал выдавать /?route=catalog, получается весь проект две строчки в которых нет ошибки значит дело в настройках сервера?)
Тестирую на локальной машине (Версия: Денвер-3 2012-09-16)
Подскажите пожалуйста почему и как исправить


Ответ

Насколько мне удалось понять, когда Apache встречает путь, который указывает на каталог, он посылает клиенту ответ с перенаправлением, причём делает это после обработки модулем mod_rewrite. Именно поэтому правило
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
добавит параметр к GET-запросу, а затем Apache выполнит перенаправление.
Избежать такого поведения можно, запретив серверу дописывать / в адресе, ссылающемся на каталог. Делается это при помощи директивы
DirectorySlash Off
Для решения задачи файл .htaccess должен иметь следующий вид:
DirectorySlash Off
RewriteEngine On
RewriteCond %{REQUEST_URI} !/index.php RewriteRule (.*) /index.php?route=$1 [L,QSA]
Обратите внимание на предпоследнюю строку. Она предотвращает зацикливание.

Ревью библиотеки двусвязных списков

Давеча написал зачаток библиотеки для работы с двусвязными списками. Товарищи, дайте критику:
// ---------------------------------------------- // // Doubly linked list implementation by maksspace // // ---------------------------------------------- //
#ifndef maksspace_list_h #define maksspace_list_h
typedef struct { void *prev, *next; } node_link_t;
/* this macros through the list starting from the $head while maintaining the current node in $current */ #define list_foreach(head, current) \ for(typeof(head) current = head; current != NULL; current = current->next)
/* insert $node before $head, and return pointer on new head of list */ void* list_prepend(void* node, void* head) { *(node_link_t*)node = (node_link_t){NULL, head}; return ((node_link_t*)head)->prev = node; }
/* insert $node after $tail, and return pointer on new tail of list */ void* list_append(void* tail, void* node) { *(node_link_t*)node = (node_link_t){tail, NULL}; return ((node_link_t*)tail)->next = node; }
/* insert $new_node between $prev and $next, return pointer on $new_node */ void* list_insert(void* new_node, void* prev, void* next) { *(node_link_t*)new_node = (node_link_t){prev, next}; return ((node_link_t*)prev)->next = ((node_link_t*)next)->prev = new_node; }
/* delete nodes between $from and $to */ void list_nodes_del(void* from, void* to) { ((node_link_t*)from)->next = to; ((node_link_t*)to)->prev = from; }
/* ----------------------------------- * Each node of the list must contain: * struct node_name *prev, *next; * at the beginning. * ----------------------------------- * Example:
typedef struct your_node_name { struct your_node_name *prev, *next; int my_cool_int; float my_cool_float; ... struct { ... } name; } me_node_name; */
#endif /* maksspace_list_h */


Ответ

Посмотрел ваш https://github.com/maksspace/mylist
list_insert(void* new, void* prev, void* next), возвращающий new, какой-то неочевидный.
Понимаете, если между prev и next есть элементы списка, то они теряются. Я бы подумал над тем, чтобы возвращать исключаемый подсписок (причем с аккуратно модифицированными головой и хвостом) и переименовал этот insert во что-то более отражающее суть дела.
В таком случае аналогичные изменения надо внести и в void list_nodes_del(void* from, void* to)
И мелочь, конечно, но new я бы заменил, поскольку в крестах это ключевое слово.
(за смелость +1)
И еще, а почему, собственно
Each node of the list must contain: struct node_name *prev, *next; at the beginning.
IMHO Ваш код позволяет вставлять эти структуры связи в любое место структур, образующих список (и также, как и linux/list.h, иметь в структуре много разных связей, т.е. одна структура может входить в несколько разных списков).

Тег Video отключение предыдущего плеера если запускается новый

На html странице существует обычные стандартные плееры html5 но проблема в том что если к примеру запущен 1 плеер т.е воспроизводится видео и при клике на плеер другой оно тоже начинает воспроизводится ! Как реализовать что бы при клике на другой плеер останавливался тот что играет ?


Ответ

Для этого нужно использовать JavaScript, который вначале остановит ненужные плееры (например, все плееры на странице), а потом запустит текущий.
Тут есть две стороны вопроса - как это сделать правильно, и буквально как вы попросили в вопросе ("при щелчке на плеер").
Если у вас включено отображение controls, правильно делается это с помощью media events. Вот пример кода на JavaScript с использованием библиотеки jQuery:
$(function() { $("video")[0].onplay = function () { var that = this; $('video').each(function () { if (this !== that) { this.pause(); } }); }; })
Пример работы можно посмотреть вот в этом фидле на JSFiddle
Если же у вас нет никакой другой возможности, кроме как отслеживать клики мышки, нужно ловить событие onclick:
$(function() { //При щелчке на любой элемент video $('video').on('click', function () {
//Останавливаем все другие video $('video').each(function () { this.pause(); });
//И запускаем только текущий this.play(); }); })
Пример работы можно посомотреть вот в этом фидле на JSFiddle
В зависимости от механики вашего веб-интерфейса, реализация может различаться, но идея останется прежней.
В некоторых случаях (проблемы с тэгом video со включенными controls), возможно, стоит отслеживать не click, а включать проигрывание на событие mouseover:
$(function() { $('video').on('mouseover', function () { $('video').each(function () { this.pause(); }); this.play(); }); })

Отступы внутри ListView

android:divider="@null" android:dividerHeight="0dp"
Они используются дляя отступа между Item! Но мне нужно сделать отступ поменьше В Item то есть внутри паддинг уменьшить, подскажите пожалуйста...


Ответ

Скорее всего вам надо создать свой вариант разметки для элемента и в нём задать нужные вам параметры. Вы, видимо, используете простейший адаптер из коробки, в конструктор коего передаёте встроенный же ресурс разметки. Вот его и замените на описанный вами в res/layout файл, содержащий нужным образом сформированный TextView

Как считать общую стоимость, когда цена единицы меняется шагами?

Пользователь вводит количество писем, и получает общую стоимость рассылки. Есть массив количеств писем post и массив цен за отправку одного письма из этих диапазонов prescurant
var post = [1000, 3000, 5000, 10000, 20000]; var prescurant = [0, 0.08, 0.07, 0.06, 0.05, 0.04];
за первые 1000 писем пользователь отдаст по 0 руб.; за письма с 1001 по 3000-е он отдаст по 0.08 руб. за письмо; с 3001 до 5000 – по 0.07 руб.; и т.д. каждое письмо свыше 20000 стоит по 0.04 рубля.
Как рассчитать общую стоимость, когда цена единицы меняется шагами и заданы эти пороги?

Пытался так:
var val=2000//введеные пользователем кол-во писем for(i=0;i

Ответ

Вот как надо на такие вопросы отвечать
var post=[1000,3000,5000,10000,20000],prescurant=[0,0.08,0.07,0.06,0.05,0.04],val=5001; for(var i=0,otv=0;val>0;otv+=prescurant[i]*(val>(i?(post[i]-post[i-1]):post[i])?i?(post[i]-post[i-1]):post[i]:val),val-=i?(post[i]-post[i-1]):post[i],i++); console.log(otv);

fetchmail получает почту только для одного пользователя

Настроил fetchmail, вот что у меня в ~/.fetchmailrc
defaults mda "procmail -d %T" ssl set logfile=/home/firefedot/log/fetchmail.log poll pop.yandex.ru proto POP3 user 'ya.user1' password 'passwd1'
poll pop.yandex.ru proto POP3 port 995 user 'ya.user1' password 'passwd1'
Вот так выглядит ~/.procmailrc
# .procmailrc - конфиг для procmail # Переменные # MAILDIR=/home/firefedot/Mail # каталог с почтой LOGFILE=/home/firefedot/Mail/procmail.log # лог для записи всех операций DEFAULT=/home/firefedot/Mail/mbox # файл для не отсортированных сообщений # # Правила сортировки почты # # Пример: сортировка почты, приходящей на e-mail user_name@host.ru :0 * ^To.*ya.user1@yandex.ru # условие (To: user_name@host.ru) host_mail # файл host_mail в каталоге MAILDIR
# # Пример: автоматическая отсылка PGP-ключа 0: * ^Subject.*PGP # условие (Subject: PGP) | (formail -r ; cat /home/ашкуаувще/key.asc) # вывести PGP-ключ | sendmail -t # отправить его
Если введен в конфиге ya.user1 - это одна учетная запись, то в принципе все работает, и файл ~/Mail/mbox - заполняется письмами.
А если поменять учетку на ya.user2 или любую другую, в которой заведомо есть письма, то в логе пишется, что подключение прошло успешно, новых писем нет.
запускаю так: fetchmail -vk
В логе при пользователе ya.user2:
fetchmail: 6.3.26 запрашивает pop.yandex.ru (протокол POP3) на Чт 04 фев 2016 17:47:11: опрос начат fetchmail: Попытка подключения к 213.180.193.37/995...соединение установлено. fetchmail: Server certificate: fetchmail: Запрашивающая организация: Unizeto Technologies S.A. fetchmail: Общепринятое имя: Certum Level IV CA fetchmail: Subject CommonName: pop.yandex.ru fetchmail: Subject Alternative Name: pop3.yandex.kz fetchmail: Subject Alternative Name: pop.yandex.com fetchmail: Subject Alternative Name: pop3.yandex.ua fetchmail: Subject Alternative Name: pop.yandex.by fetchmail: Subject Alternative Name: pop3.yandex.by fetchmail: Subject Alternative Name: pop.ya.ru fetchmail: Subject Alternative Name: pop.yandex.kz fetchmail: Subject Alternative Name: pop3.yandex.com.tr fetchmail: Subject Alternative Name: pop3.yandex.ru fetchmail: Subject Alternative Name: pop3.yandex.com fetchmail: Subject Alternative Name: pop.yandex.ua fetchmail: Subject Alternative Name: pop3.ya.ru fetchmail: Subject Alternative Name: pop.yandex.com.tr fetchmail: Subject Alternative Name: pop.yandex.ru fetchmail: Отпечаток ключа pop.yandex.ru: B1:91:A1:78:14:7B:0C:DB:1F:8D:B7:F3:B2:F2:0D:11 fetchmail: POP3< +OK POP Ya! na@26 MoLmjWCfvOsg fetchmail: POP3> CAPA fetchmail: POP3< +OK Capability list follows fetchmail: POP3< STLS fetchmail: POP3< TOP fetchmail: POP3< USER fetchmail: POP3< LOGIN-DELAY 60 fetchmail: POP3< PIPELINING fetchmail: POP3< EXPIRE NEVER fetchmail: POP3< UIDL fetchmail: POP3< RESP-CODE fetchmail: POP3< AUTH-RESP-CODE fetchmail: POP3< IMPLEMENTATION Yandex fetchmail: POP3< . fetchmail: POP3> USER ya.user2 fetchmail: POP3< +OK password, please. fetchmail: POP3> PASS * fetchmail: POP3< +OK 0 0 fetchmail: POP3> STAT fetchmail: POP3< +OK 0 0 fetchmail: Для ya.user2 на pop.yandex.ru почты нет fetchmail: POP3> QUIT fetchmail: POP3< +OK shutting down. fetchmail: 6.3.26 запрашивает pop.yandex.ru (протокол POP3) на Чт 04 фев 2016 17:47:11: опрос завершен fetchmail: нормальное завершение, статус 1
По какой причине при одном логине/пароле он вроде как работает, а при другом(-их) не работает, при этом соедиенние создает, но писем не видит?
Вот тот-же кусок лога для ya.user1
fetchmail: считывается сообщение ya.user1@pop.yandex.ru:257 из 764 (32481 октетов) не очищено fetchmail: POP3> LIST 258 fetchmail: POP3< +OK 258 37434463 fetchmail: POP3> RETR 258 fetchmail: POP3< +OK 37434463 octets.
Система archlinux*64.


Ответ

запрос статистики почтового хранилища:
fetchmail: POP3> STAT fetchmail: POP3< +OK 0 0
сервер ответил: ноль писем, ноль байт.

По какой причине при одном логине/пароле он вроде как работает, а при другом(-их) не работает, при этом соедиенние создает, но писем не видит?
возможно потому, что взаимодействие по протоколу pop3 не разрешено пользователем (насколько я знаю, по умолчанию — запрещено).

если взаимодействие по протоколу pop3 разрешено в web-интерфейсе, то имеет смысл обратиться в техподдержку сервиса, приведя лог взаимодействия с сервером и упомянув, что взаимодействие разрешено.

PHP. Получить бб-теги из текста регуляркой. Что не так?

Есть пример текста:
[BB1:description]data[/BB1] asdfasf [BB2]data[/BB2] asfasfasf [BB3:description]data [BB4]data[/BB4] asfasfasf [/BB3] asfasfasf
Нужно из него дернуть теги (заголовки), их содержимое и описание.
Написал:
$text = '[BB1:description]data[/BB1] asdfasf [BB2]data[/BB2] asfasfasf [BB3:description]data [BB4]data[/BB4] asfasfasf [/BB3] asfasfasf '; $pattern = "/\[(\w+)(?:[\:]([\w]+))?\](.*)\[\/\1\]/iu"; preg_match_all($pattern, $text, $matches); print_r($matches);
На regex101.com все работает. В пхп, получаю:
Array ( [0] => Array ( ) [1] => Array ( ) [2] => Array ( ) [3] => Array ( ) )
Почему пустой вывод? Что не так?


Ответ

После некоторых экспериментов нашлось решение:
"/\[(\w+)(?:[\:]([\w]+))?\](.*)\[\/\\1\]/iu"
(два слеша, вместо одного = \\1)

Круглый progress bar с анимацией

Пытаюсь сделать круглый progress bar. Идея такая, что progress - служит фоном, а secondaryProgress отображает само значение.
Код из layout:

Код progressbarstyle.xml:


На превью отображается верно, но если запустить на телефоне, то всегда показывает 100%. В чем ошибка? И как добавить анимацию при изменении значения secondaryProgress?


Ответ

Согласно en-SO можно заменить содержимое вашего progressbarstyle.xml на вот это и оно будет работать:

Также, по ссылке помянуто как это заставить работать на API<21 и как анимировать.

Как оптимизировать код objective-c?

Проблема заключается в том, что моё приложение жрёт много оперативной памяти (300 мб). На 4s приложение вылетает, на остальных, кроме 6 и 6+ виснет. В приложении много картинок и таблиц с картинками. Мне нужно снизить нагрузку на оперативную память, как-то иначе грузить картинки с сервера. Вот код, как сейчас реализована загрузка картинок:
NSString *filePath1 = [NSString stringWithFormat:@"%@",responsePhotos[0]]; NSURL *imgurl=[NSURL URLWithString:filePath1]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSData *dataimage1 = [NSData dataWithContentsOfURL:imgurl]; UIImage *imim1 = [UIImage imageWithData:dataimage1]; dispatch_async(dispatch_get_main_queue(), ^{ if (imim1==nil) { cell.imgauto1.image=[UIImage imageNamed:@"camera_a.gif"]; }else{ cell.imgauto1.image=imim1; } }); });


Ответ

Вы очень плохо все делаете,так нельзя делать, делать загрузку картинки, потом сразу же ее в ячейку ложить. Для загрузки изображений и их кеширования используйте SDWebImageCash, очень простая библиотека, и очень хорошо написана, либо же, напишите свое кеширование, но записывать картинки вручную, тем более как я понимаю в методе делегата таблицы, это очень плохо. Можно еще использовать CoreData, для хранения тех же изображений. Теперь по поводу архитектуры, и как правильно сделать, вы загружаете изображения в методе создания ячеек - убираем это от туда, это метод только для передачи в ячейки уже готовой информации. В методе viewDidLoad вы должны загрузить часть изображений, и уже передать их скачанные в ячейку, и назначить. Почему часть, потому что качать например 100 картинок, это значит что пользователь будет все это время ждать их загрузки, тоже плохо, используйте infinityscroll и pulltorefresh, принцип такой:дойдя до конца таблицы, 10 ячейки, например, начните загрузку еще 10 штук, и потом обновите таблицу.

Зачем нужно знать список доступных разрешений при работе с Camera2API?

Разбираю пример по работе с камерой и наткнулся на метод который возвращает список доступных разрешений
Size[] sizesJPEG = configurationMap.getOutputSizes(ImageFormat.JPEG);
for (Size item : sizesJPEG) { System.out.println("w:" + item.getWidth() + " h:" + item.getHeight()); }
и на выходе вот так
I/System.out: w:640 h:480 I/System.out: w:352 h:288 I/System.out: w:320 h:240 I/System.out: w:176 h:144
кто работал с камерой скажите для чего нам может понадобиться эта информация?


Ответ

Очевидно, что эта информация может понадобиться для того, чтобы узнать, какие доступны разрешения. Если вам, в конкретном приложении, не требуется данная информация, то вы не будете запрашивать ее, если же такая информация вам вдруг понадобится, для любых целей, то вы знаете где ее взять.
Практический момент может быть в том, чтобы, например, узнать, поддерживает ли камера съемку в JPEG вообще, то есть, если ни одного разрешения не вернул метод, то в JPEG камера не снимает. Потом, вы можете предложить пользователю выбрать собственные настройки, в каком разрешении снимать - чтобы он не натыкал там чего отсебятины при съемке, когда либо качество слишком низкое, либо слишком высокое, либо аспект не подходящий для фото, которе требуется в вашем приложении. Данный метод может пригодиться как тем, что поможет вывести, собственно, список доступных вариантов, так и тем, чтобы проверить, есть ли такое разрешение, если, скажем, у вас фиксированный список для всех устройств, но, как вы знаете, не все разрешения поддерживаются всеми камерами. Так же можно скомбинировать оба варианта и на основе полученной информации о разрешениях конкретной камеры,сформировать список из желаемых вами возможностей выбора в настройках (например, только широкоформатные) с теми, которые поддерживает именно эта камера.
Затем вы устанавливаете фиксированное разрешение, точно зная, что камера такое поддерживает.
Или вы можете получить эту информацию, чтобы установить размеры виджета для вывода снятого, точно по размерам фото.
Вообще, всевозможные API содержат большое количество классов и методов, многие из которых вам могут никогда не понадобиться и вы не будете ими пользоваться, так как для решения именно вашей задачи они не требуются - это вполне нормально. Наличие каких-то функций в API не подразумевает их непременного использования, особенно если вам трудно придумать, как именно их можно было бы использовать.
Не стоит на этом зацикливаться. Хорошо, что вы знаете, что такая возможность есть и когда-нибудь она и сможет вам пригодится. Если вы не знаете, как бы можно было использовать эту информацию, значит лично вам она в данном проекте не нужна. Оставьте ее в покое и решайте, те проблемы, которые требует текущий проект.
Если вам очень интересно, кто, как, где и для чего использует этот метод, вы можете посмотреть проекты, где он используется и сделать для себя какие то выводы.

Как получить список текущих уведомлений в статус баре на 17 API?

Задача состоит в извлечении текста из уведомлений в статус баре через adb. На данный момент написал Service, который следит за уведомлениями, наследующийся от NotificationListenerService и Broadcast, который по запросу с adb отдает данные уведомления от определенного пакета. Но сам NotificationListenerService доступен только с 18 API, а поле extras класса Notification (я с него беру текст и заголовок) - с 19го.
Может есть какая-то возможность получить те же данные, но на 17ом API?


Ответ

К счастью, ответ найден!
Решение довольно банально - данные обо всех уведомлениях можно получить через команду shell dumpsys notification. Но extras получить пока не удалось. Правда у меня все устройства рутованные, отпишите, пожалуйста, в комментариях, работает ли без рута.

Ограничить количество post запросов

Есть код:

Нужно ограничить отправку post запроса при клике на кнопку не чаще, чем раз в 5 секунд.


Ответ

Задаем переменной fire значение true в начале работы скрипта. Перед post отправкой проверяем, если fire = true, выполняем post, задаем fire = false и вешаем таймер назначить fire = true через 3 секунды. Итоговый код:

Выбрать из 4-х массивов по элементу с минимальной разницей между наибольшим и наименьшим из них

Даны 4 массива, надо выбрать из каждого из них по одному числу x_i, чтобы разница между x_min и x_max (наиб. и наим. среди 4х выбранных элементов x_i) была минимальной. Если таких наборов несколько, можно использовать любой из них.
Сложности возникли не с реализацией, а с созданием алгоритма. Я хотел использовать жадный алгоритм, но не могу понять, как может помочь для получения ответа решение подзадач для двух массивов.
UPD : Написал алгоритм, работает верно, но не проходит по времени. Не из-за того-ли что я вынес поиск ближайшего элемента в отдельную функцию dist и вызываю ее потом по три раза на каждую группу?
int dist(const std::vector& A, int x) { int sec = binary_search(A, x), ans; if (sec == 0) { ans = 0; } else if (sec == A.size()) { ans = sec - 1; } else if ((abs(A[sec] - x) < abs(A[sec - 1] - x))) { ans = sec; } else { ans = sec - 1; } return ans; }
int diff(const std::vector& A) { return *std::max_element(A.begin(), A.end()) - *std::min_element(A.begin(), A.end()); } int main() { // здесь считываю, сортирую вектора. std::vector ans(4); int min = 100000000000; for (int i = 0; i != n1; i++) { //прохожусь по первому for (int i2 = 0; i2 <= 2; ++i2) { //рассматриваю 2^3 смежных случаев for (int i3 = 0; i3 <= 2; ++i3) { for (int i4 = 0; i4 <= 2; ++i4) { std::vector temp(4); temp[0] = v1[i]; //здесь рассматриваю случаи, чтобы не было выходов за вектор temp[1] = v2[i_2 - 1 + dist(v2, v1[i])]; temp[2] = v3[i_3 - 1 + dist(v3, v1[i])]; temp[3] = v4[i_4 - 1 + dist(v4, v1[i])]; if (diff(temp) < min) { min = diff(temp); ans = temp; } } } } } for (auto elem : ans) { std::cout << elem << " "; } return 0;
}


Ответ

По идее, должна сработать следующая идея: вы просто обобщаете алгоритм для двух массивов на более общий случай.
Например, так:
Сортируете все массивы. Проходитесь по первому массиву. Запоминаете текущий индекс 0 во всех 4 массивах. На каждом шагу, продвигаете индекс в первом массиве, и находите ближайший элемент к нему во остальных массиве. Для этого вам придётся продвинуться вперёд в этих массивах. При этом вы получаете для каждого из массивов ближайший элемент к элементу первого массива.
На этом шаге мы ищем группу элементов с оптимальным расстоянием между ними, которая включает данный элемент первого массива Это ещё не гарантирует, что мы нашли оптимум. Нам нужно перебрать 2^3 вариантов из { «ближайший снизу», «ближайший сверху» } для каждого из массивов, каждый из них может дать оптимум. Находите расстояние между наибольшим и наименьшим из них. Сравниваете его с текущим максимумом и продвигаетесь дальше по первому массиву.
Мы проходимся по каждому из массивов один раз, общая асимптотика — сумма длин массивов.

Как реализовать динамичную смену языка? JavaFX

Хочу реализовать адекватное переключение языков в приложении, чтобы сразу после нажатие кнопки "сменить язык" все компоненты автоматически поменяли название. Пока что сделал так:
public void setEnglish(ActionEvent actionEvent) {
Main.locale = new Locale("en"); rb = ResourceBundle.getBundle("ua.javaFX.myprograms.address_book.bundles.Locale", Main.locale);
mainStage.setTitle(rb.getString("key.address_book")); btnAdd.setText(rb.getString("key.add")); btnEdit.setText(rb.getString("key.change")); btnDelete.setText(rb.getString("key.delete")); btnSearch.setText(rb.getString("key.search")); btnLanguage.setText(rb.getString("key.language")); btnEnglish.setText(rb.getString("key.english")); btnRussian.setText(rb.getString("key.russian")); }
Суть вопроса: есть какой-то цивилизованный способ для обновления содержания страницы? Если я не ошибаюсь, в SWING таким является:
SwingUtilities.updateComponentTreeUI(frame);


Ответ

Для того, чтобы вам сделать такое, необходимо использовать bindings
Вам нужна resources factory :
public class ObservableResourceFactory {
private ObjectProperty resources = new SimpleObjectProperty<>(); public ObjectProperty resourcesProperty() { return resources ; } public final ResourceBundle getResources() { return resourcesProperty().get(); } public final void setResources(ResourceBundle resources) { resourcesProperty().set(resources); }
public StringBinding getStringBinding(String key) { return new StringBinding() { { bind(resourcesProperty()); } @Override public String computeValue() { return getResources().getString(key); } }; } }
Далее, в своем коде можете написать такое
ObservableResourceFactory resourceFactory = .... ;
resourceBundle.setResources(...);
Label greetingLabel = new Label(); greetingLabel.textProperty().bind(resourceFactory.getStringBinding("greeting"));
И в любой момент, когда вы будет обновлять ресурсы
resourceFactory.setResources(...);
на лейбле текст будет меняться.
Вот пример, как это работает
import java.util.ListResourceBundle; import java.util.Locale; import java.util.ResourceBundle;
import javafx.application.Application; import javafx.beans.binding.StringBinding; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.layout.BorderPane; import javafx.stage.Stage;
public class ResourceBundleBindingExample extends Application {
private static final String RESOURCE_NAME = Resources.class.getTypeName() ;
private static final ObservableResourceFactory RESOURCE_FACTORY = new ObservableResourceFactory();
static { RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME)); }
@Override public void start(Stage primaryStage) { ComboBox languageSelect = new ComboBox<>(); languageSelect.getItems().addAll(Locale.ENGLISH, Locale.FRENCH); languageSelect.setValue(Locale.ENGLISH); languageSelect.setCellFactory(lv -> new LocaleCell()); languageSelect.setButtonCell(new LocaleCell());
languageSelect.valueProperty().addListener((obs, oldValue, newValue) -> { if (newValue != null) { RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME, newValue)); } });
Label label = new Label(); label.textProperty().bind(RESOURCE_FACTORY.getStringBinding("greeting"));
BorderPane root = new BorderPane(null, languageSelect, null, label, null); root.setPadding(new Insets(10)); Scene scene = new Scene(root, 400, 400); primaryStage.setScene(scene); primaryStage.show(); }
public static class LocaleCell extends ListCell { @Override public void updateItem(Locale locale, boolean empty) { super.updateItem(locale, empty); if (empty) { setText(null); } else { setText(locale.getDisplayLanguage(locale)); } } }
public static class ObservableResourceFactory {
private ObjectProperty resources = new SimpleObjectProperty<>(); public ObjectProperty resourcesProperty() { return resources ; } public final ResourceBundle getResources() { return resourcesProperty().get(); } public final void setResources(ResourceBundle resources) { resourcesProperty().set(resources); }
public StringBinding getStringBinding(String key) { return new StringBinding() { { bind(resourcesProperty()); } @Override public String computeValue() { return getResources().getString(key); } }; }
}
public static class Resources extends ListResourceBundle {
@Override protected Object[][] getContents() { return new Object[][] { {"greeting", "Hello"} }; }
}
public static class Resources_fr extends ListResourceBundle {
@Override protected Object[][] getContents() { return new Object[][] { {"greeting", "Bonjour"} }; }
}
public static void main(String[] args) { launch(args); } }
P.S. ответ взят с английского SO

Как использовать Protocol Buffer без файлов

Есть примеры где наглядно показывается как мне сохранить данные в файл и считать их, не могу понять как мне эти данные просто передать к примеру просто закрепив в посте, или просто передать этот класс в другой метод.
AddressBook.Builder addressBook = AddressBook.newBuilder();
// Read the existing address book. try { addressBook.mergeFrom(new FileInputStream(args[0])); } catch (FileNotFoundException e) { System.out.println(args[0] + ": File not found. Creating a new file."); }
// Add an address. addressBook.addPerson( PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out));
// Write the new address book back to disk. FileOutputStream output = new FileOutputStream(args[0]); addressBook.build().writeTo(output); output.close();


Ответ

Используйте не FileInputStream/FileOutputStream, а другие уместные в вашем случае потоки ввода/вывода. Например это могут быть ByteArrayInputStream и ByteArrayOutputStream
// пишем ByteArrayOutputStream baos = new ByteArrayOutputStream(); addressBook.build().writeTo(baos); byte[] data = baos.toByteArray();
// читаем AddressBook addressBook = AddressBook.parseFrom(new ByteArrayInputStream(data));
Или, например, OutputStream HTTP-соединения:
HttpURLConnection conn = (HttpURLConnection) new URL("http://...").openConnection(); conn.setRequestMethod( "POST" ); conn.setRequestProperty("Content-Type", "application/octet-stream"); addressBook.build().writeTo(conn.getOutputStream());

Впрочем, для работы именно с байт-массивом документация предлагает готовые методы:
byte[] toByteArray();: сериализует сообщение и возвращает массив байтов. static Person parseFrom(byte[] data);: парсит сообщение из массива байтов.
То есть что-то вроде:
// пишем byte[] data = addressBook.toByteArray();
// читаем addressBook = AddressBook.parseFrom(data);

Привязка класса css к первой новости в цикле , на движке wordpress

В цикле указывается класс ко всем новостям, которые будут выводится. Я взял шаблон, где к первой новости идет класс post1


Нужно, чтобы к последующим новостям выводился класс post

Если задать функцию в functions.php
current_post) { $classes[] = 'first'; } return $classes; } add_filter('post_class', 'wph_first_post_in_query'); //свой класс у первой записи в цикле end ?>
и вместо
задать функцию wp
id="">, у меня получается задать отдельный стиль для первой новости , но проблема заключается в том, что стиль применяется ко всем новостям полностью , а потом еще к первой отдельно. Мне необходимо, чтобы у первой новости стиль был абсолютно другой.


Ответ

Можно просто ввести в цикл вывода постов счётчик, по значению которого определять, какой по счёту пост вы выводите

...
$i++; //не забывайте про инкремент счётчика в каждой итерации } }
Обновление для частного случая:
контент

Как сделать поведение переносов строк в div аналогичным поведению в textarea?

Есть textarea в которую вручную вбивается текст, после чего можно нажать кнопку и данные выводятся в div блоке. Все переносы строк отступы и т.д. переносятся без проблем. Реализовано с помощью elem.value.replace(/(
|
)+/g, '
');.
Проблема заключается в том, что если в textarea написать длинное неразрывное слово или просто набор символов, но без пробелов, то в textarea текст автоматически переноситься на другую строку при достижении края поля, а при переносе в div этот перенос не сохраняется и содержимое вылезает за пределы блока.
Как сделать так, чтобы эти переносы строк отображались в div?


Ответ

document.addEventListener('input', function (e) { document.querySelector("div").textContent = document.querySelector("textarea").value; }) textarea, div { font-family: monospace; font-size: 1rem; display: block; width: 100%; box-sizing: border-box; border: 1px solid; padding: .5em; } textarea { margin-bottom: 1em; height: 7em; } div { white-space: pre-line; word-wrap: break-word; overflow-wrap: break-word; }


Есть ли утилита для проверки совместимости Pc железа с Mac os?

Заинтересовался в установке os x на ноутбук. Не знаю нужно ли мне это, но хотелось бы знать поддерживает ли ос ноут или не париться и сидеть на линуксе .


Ответ

Очень много проблем может быть связано с установкой OS X на ноутбук. Если стационарный компьютер можно собрать с практически идентичными характеристиками к Mac и с полпинка завести OS X, то с ноутбуками намного сложнее. Даже если практически все характеристики идентичные. Главная проблема - в конфигурациях с переключаемой графикой (Intel+nVidia или Intel+AMD) в OS X работает только Intel. Подходят только видеокарты Intel HD3xxx,4ххх,5ххх.
Пример из жизни. Сотрудник ставил на свой ноутбук OS X, который схож с MacBook 15" по характеристикам - все прошло нормально, но как ни старался, клавиатура так и не заработала. А с внешней USB клавиатурой, ясное дело, это не то.

Какую модель структуры БД выбрать, чтобы Django справился?

Задача: вести учет движения чего-нибудь. К примеру, бункеров.
Бункеры перемещаются между разными объектами Важно иметь возможность получить следующие отчеты:
А) В одной строке Объект "исходящий" и объект "назначения". В примере на картинке передвижение бункеров между морскими портами.
тут порты и корабли это объекты Б) Отчет по количеству бункеров на данный момент на каждом из объектов В) отчет по количеству объектов на каждом типе объекта (наш порт, корабль, порт заказчика)
Можно было бы использовать такой дизайн таблицы: +---------------+ | Field | +---------------+ | id | | object_out_id | | object_in_id | | qty | +---------------+ ..тогда отчет А) вытягивается из базы средствами ORM простым запросом FLow.Objects.all(), а для остальных отчетов пришлось бы использовать не самые простые SQL запросы, с которыми ORM не справится.
Второй вариант записывать одно перемещение бункера в две строки в базе. +----------------+ | Field | +----------------+ | id | | transaction_id | | object_id | | qty | +----------------+
С большинством запросов тогда справится ORM, все работает быстро, НО - отчет А) как на рисунке простым запросом не вытянуть... Хочется его сериализовать в JSON средствами Django REST Framework. RAW запросы в DRF не поддерживают пагинацию..
Посоветуйте, какую модель хранения данных выбрать, что бы не было проблем с выводом в JSON отчета А) и при больших объемах данных не было слишком долгих обработок для прочих запросов?


Ответ

Я бы сделал так... Если типы объектов известны заранее и неизменны, то в таблице Object поле type_id лучше сделать с choices. Если нет, то сойдет и таблица:
Type - типы объектов
id name
Object - объекты
id name type_id count - количество объектов на данный момент
Transaction - транзакции
id date object_id_1 object_id_2 count
При записи (изменении, удалении) транзакции увеличиваете/уменьшаете count в связаных оъектах. Все нужные Вам запросы тривиальны. (имена таблиц даны только для примера, в Django, возможно, придется использовать другие)

Сервер рандомно падает с ошибкой

Пишу програмку на C# с использованием WCF. рандомно сервер падает с ошибкой:

кроме скриншрта, не могу получить информации, т.к. баг происходит в не менеджмент коде и сервак виснет в ожидании мертвого потока. исключение по стэку не поднимается, и отловить его не могу. я понимаю, что информации маловато, но очень прошу помощи, т.к. идеи кончились и гугление не дало результатов.
пишите, какую информацию предоставить... OS: Windows Server 2008 R2 ENT Framework 4.5.2


Ответ

помог переход на 2012 сервер. UseSynchronizationContext =false. всем спасибо.

Создание контекстного меню на нажатие объекта в ListView с кастомным адаптером

После создания своего адаптера, и применения его к ListView перестал работать клик на элемент и перестало открываться контекстное меню элемента при долгом тапе.
package com.vkdocs;
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.TextView;
import java.util.ArrayList;
public class DocsAdapter extends BaseAdapter implements AdapterView.OnItemClickListener { Context ctx; LayoutInflater lInflayter; ArrayList objects;
DocsAdapter(Context context, ArrayList docs) { ctx = context; objects = docs; lInflayter = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
@Override public int getCount() { return objects.size(); }
@Override public Object getItem(int position) { return objects.get(position); }
@Override public long getItemId(int position) { return position; }
@Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null) { view = lInflayter.inflate(R.layout.item, parent, false); }
DocsElement d = getDoc(position);
((TextView) view.findViewById(R.id.tvName)).setText(d.name);
CheckBox checkDoc = (CheckBox) view.findViewById(R.id.cbBox);
checkDoc.setOnCheckedChangeListener(myChangeListener); checkDoc.setTag(position); checkDoc.setChecked(d.box);
return view; }
DocsElement getDoc(int position) { return ((DocsElement)getItem(position)); }
ArrayList getBox() { ArrayList box = new ArrayList(); for(DocsElement d : objects) { if(d.box) box.add(d); } return box; }
CompoundButton.OnCheckedChangeListener myChangeListener = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { getDoc((Integer) buttonView.getTag()).box = isChecked; } };
@Override public void onItemClick(AdapterView parent, View view, int position, long id) {
} }
Layout для отображения списка


Ответ

Повесьте слушатель в getView адаптера:
view.setOnLongClickListener(...); Анимация риппл эфекта для кастомной разметки сама собой не включится. Можно подключить её сторонней библиотекой
UPD_0:
В адаптере создайте интерфейс, передайте его в него через конструктор и вызовете в момент долгого нажатия:
public class DocsAdapter extends BaseAdapter implements { public interface MyOnLongClick { public void onClick(View v, int position); }
... MyOnLongClick interface;
DocsAdapter(Context context, ArrayList docs, MyOnLongClick interface) { ... this.interface = interface; }
@Override public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null) { view = lInflayter.inflate(R.layout.item, parent, false); } view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { Log.d("TAG", "onLongClick in adapter"); interface.onClick(v, position); return false; } }); ... } }
В актвити реализуйте этот интерфейс и передайте ссылку на него в адаптер при его создании:
public class ActivityMain extends AppCompatActivity implements DocsAdapter.MyOnLongClick { ... @Override onClick(View v, int position) { Log.d("Tag", "onClick method from intercace called in activity class for position: "+position); }
@Override public void onCreate(Bundle b) { ... DocsAdapter adapter = new DocsAdapter(context, docs, this); } }

DMIDecode product_uuid и product_serial, в чем разница?

В директории /sys/class/dmi/id/ лежат два файла product_uuid и product_serial
Как эти файлы генерируются, чем отличаются? Каким образом они меняются? При переустановке системы они изменяются? Почему права на чтение у этих файлов есть только у root? У остальных файлов в этой директории есть права на чтение для всех пользователей?


Ответ

Как эти файлы генерируются, чем отличаются?
генерируются эти псевдо-файлы кодом из файлов dmi-id.c, dmi_scan.c и dmi-sysfs.c из каталога drivers/firmware. содержимое берётся из bios-а в соответствии со спецификацией smbios, к документации по которой в первую очередь и следует обращаться по поводу «что означает и чем отличается та или иная возвращаемая информация». во вторую очередь (например, если возвращаемая информация противоречит спецификации), следует обращаться к производителю bios-а и/или материнской платы.
в моей системе, например, очень сложно не заметить различий между содержимым этих двух файлов:
$ sudo tail /sys/class/dmi/id/product_{serial,uuid} ==> /sys/class/dmi/id/product_serial <== System Serial Number
==> /sys/class/dmi/id/product_uuid <== 0F0914E0-5BCB-11D9-AE58-5404A6CC1207
Каким образом они меняются? При переустановке системы они изменяются?
вероятно, эту информацию можно почерпнуть из упомянутого выше описания спецификации smbios.
Почему права на чтение у этих файлов есть только у root?
права на псевдо-файлы в обсуждаемом каталоге /sys/class/dmi/id/ определяются в файле dmi-id.c с 42 по 59 строки (во втором поле в вызове макроса DEFINE_DMI_ATTR_WITH_SHOW). коммит, добавивший эти строки, сделал Lennart Poettering (ага, тот самый). подробности, вероятно, можно спросить прямо у него, или в рассылке lkml
У остальных файлов в этой директории есть права на чтение для всех пользователей?
да, у большинства есть. в чём можно убедиться, и рассмотрев те самые строки (с 42 по 59), и просто выполнив:
$ ls -l /sys/class/dmi/id/

UserControlVIewModel работа со свойствами UserControl

Имеется главная MainViewModel и MyUserControl(у него своя ViewModel).
public class MainViewModel { public ObservableCollection StringList; public MainViewModel() { StringList = new ObservableCollection(); } }
Допустим необходимо передать коллекцию строк из MainViewModel в UserControl.

как получить коллекцию StringList во ViewModel-и MyUserControl-а?
public class MyUserControlVM { //здесь работать с Items который приходит от MyUserControl }
UPD1
Но вопрос ещё вот в чём: зачем другому контролу видеть те же Items? Какой объект этот контрол визуализирует? Если это тот же объект, то и VM та же. Если это другой объект, почему у двух объектов общая часть?
Отвечаю на вопрос, да это другой объект.
Может быть такое что несколько UserControl-ов принимают одни и те же данные и обрабатывают их по своему в своих VM, затем выводят результат во View

Добавим еще один MyUserControl2(со своей VM), который также принимает коллекцию StringList из MainVM. Каждый контрол по-своему обрабатывает принимаемую коллекцию, и выводит во View результат обработки.
Первый UserControl


Второй UserControl


В итоге для того чтобы работал UserControl ему нужно передать некую информацию из MainVM, затем работать с ней во VM-контрола. Собственно как обращаться к этой некой информации во VM контрола? Или как получить данные от DependecyProperty(определенные в контроле) во VM контрола.


Ответ

Проблема вот в чём: вы задаёте DataContext прямо внутри контрола! Так делать не стоит, ведь при этом он у вас будет не связан с внешним миром. Вы должны устанавливать DataContext снаружи, как-то так:

где SubVM — свойство типа MyUserControlVM в MainViewModel
Если несколько контролов должны иметь доступ к общей коллекции, положите ссылку на одну и ту же коллекцию в их VM. Если вы создаёте подчинённые VM не из XAML'а, а вручную, вы можете правильно инициализировать их и связать нужным вам образом.

Overflow при загрузке страницы отображать низ

Имеется 2 вложенных div

...

.primer1 { height: 100px; overflow-y:scroll; scrollbar-arrow-color:#000000; scrollbar-base-color: #228B22; }
Содержимое primer2 по высоте больше, у него показывается верхняя часть и мы можем двигать ползунок вниз. А нужно, что бы изначально отображался низ и мы могли бы двигаться вверх.
По примеру чатов: мы должны видеть последние сообщения, а если нужно посмотреть более ранние сообщения, то прокручиваем вверх.
Как это можно реализовать?


Ответ

На чистом CSS, скорее всего такого результата легко не достичь, а если использовать JS, то для этого достаточно двух строк:
var scrollDiv = document.getElementById("scroll_div"); scrollDiv.scrollTo(0, scrollDiv.scrollHeight); .primer1 { height: 100px; overflow-y:scroll; scrollbar-arrow-color:#000000; scrollbar-base-color: #228B22; border: 1px solid black; } .primer2 { height: 300px; border: 1px solid red; }

...

Проверено в Firefox, для других браузеров может не сработать, в таком случае можно воспользоваться jQuery библиотекой

Плавная прокрутка страницы без jQuery

У меня два вопроса, реализовать которые нужно без jQuery
Как плавно прокручивать страницу колесиком на JavaScript? Как плавно прокрутить страницу на несколько пикселей?


Ответ

var get = function(obj) { return document.getElementById(obj) }; get('scrollbox').onwheel = function(e) { var delta = e.deltaY; delta = (delta > 0) ? 30 : -30; get('scrollbox').style.top = delta + get('scrollbox').offsetTop + 'px'; e.preventDefault(); } get('scroll').onclick = function() { get('scrollbox').style.top = -30 + get('scrollbox').offsetTop + 'px'; } #block { width: 300px; height: 300px; background-color: #dddddd; position: absolute; padding: 5px; } #scrolling { width: 100%; overflow: hidden; height: 100%; } #scrollbox { position: relative; transition: 0.2s; } #scroll { right: 0%; top: 0%; position: absolute; width: 100px; height: 25px; background-color: white; }

la
ga
ha
aa
lj
va
ja
la
va
aa
lm
la
ga
ha
aa
lj
va
ja
la
va
aa
lm
la
ga
ha
aa
lj
va
ja
la
va
aa
lm
la
ga
ha
aa
lj
va
ja
la
va
aa
lm
la
ga
ha
aa
lj
прокрутить

Как проанализировать код на наличие неиспользуемых функций?

Код написан на языке C.
Флаг -Wall может показать только локальные функции. Как быть с глобальными?
Какие средства анализа кода существуют? Насколько я понимаю, мы ведь это можем увидеть на этапе линовки всех объектников в один? Может это может показать линковщик?


Ответ

Уточню, что это для случая статического анализа кода - поиск функций, к которым по коду нет обращений. Вам может помочь утилита cppcheck, она так же имеет очень большой список различных проверок, кроме поиска неиспользуемых функций.
Если же хотите посмотреть какие методы вызывались в процессе выполнения, то их список может отличаться в зависимости от входных данных, для их просмотра можно использовать valgrind

Не хочет обрабатывать события jquery

jquery не хочет обрабатывать события. Не могу понять в чем проблема.

$('#mybutton').click(function() { alert('Вы нажали на элемент "button"'); }); $('#mybutton').click();
Никак не реагирует на событие click у элемента #mybutton
Связи, ссылки везде прописаны. Зато реагирует на событие $(window).scroll.
Что может быть?


Ответ

Возможно, JavaScript-код срабатывает раньше, чем успевает загрузиться элемент

Это весь код или его фрагмент? Попробуйте следующий код, который дожидается загрузки DOM-структуры и лишь затем назначает события

Отсутствующий SelectedItem в ListBox

Есть форма. Вот ее содержимое

Вот ее бэкграунд (оно же вьюха)
public partial class MainWindow : Window, INotifyPropertyChanged { Output _selected;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection Col1 { get; set; } public ObservableCollection Col2 { get; set; } public Output Selected { get { return _selected; } set { _selected = value; OnPropertyChanged(nameof(Selected)); } } public MainWindow() { Col1 = new ObservableCollection { new Output {Name="name_1", Sum=1 }, new Output {Name="name_2", Sum=2 }, new Output {Name="name_3", Sum=3 }, new Output {Name="name_4", Sum=4 } };
Col2 = new ObservableCollection { Col1[2], Col1[3], new Output {Name="name_5", Sum=5 }, new Output {Name="name_6", Sum=6 } }; DataContext = this; InitializeComponent(); }
private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e) { Selected = null; }
void OnPropertyChanged(string name) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } }
Запускаю, выделяю в левом листе первый айтем. Все норм. Выделяю в левом листе последний айтем (нэйм 4). Соответствующий айтем выделяется и во втором листе. Теперь выделяю во втором листе последний айтем...
Ожидалось, что при этом в левом листе выделение снимется, потому что данного айтема нет в привязанной коллекции. Но выделение остается. Почему?
UPD:
Но самое печальное оказалось даже не в этом, а в том, что при перемещении табом по листам (или мышкой, нажимая на уже выделенные визуально айтемы) свойство Selected не изменяется. Это будет видно, если привязать к нему заголовок окна.
Title="{Binding Selected.Name}"


Ответ

Вроде как при проблемах с биндингом - то он просто игнорируется, т.е. в данном случае не будет изменения селекта в листбоксе, если попытаться указать несуществующий в ItemsSource элемент. Если приведенное автором вопроса поведение листбоксов действительно необходимо, то нужно делать 2 поля Selected, т.е. каждому листбоксу своё, и немного логики в блоках set. например переустановку или обнуление соседнего Select при необходимости (ну и победить зацикливание установки этих полей друг из друга)
По поводу "самого печального" - думаю это просто следствие нарушенного биндинга.

Как разлогиниться из VK API в iOS приложении?

Я добавил кнопку Войти через ВК. И хочу добавить возможность разлогиниться и поменять аккаунт.
Пробовал запустить этот запрос http://api.vk.com/oauth/logout. Но он выводит wrong logout hash
Использовал этот код:
let logoutUrl = "http://api.vk.com/oauth/logout"
let request = NSMutableURLRequest(URL: NSURL(string: logoutUrl)!, cachePolicy:.ReloadIgnoringLocalCacheData, timeoutInterval:60.0) let responseData = try! NSURLConnection.sendSynchronousRequest(request, returningResponse: nil)
Также пробовал почистить NSDefaults, после logout:
let defaults = NSUserDefaults.standardUserDefaults() defaults.removeObjectForKey("VKAccessUserId") defaults.removeObjectForKey("VKAccessToken") defaults.removeObjectForKey("VKAccessTokenDate") defaults.synchronize()
И почистить кукисы:
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage() for cookie in storage.cookies ?? [] { let domainName = cookie.domain let domainRange = domainName.rangeOfString("vk.com")
if let range = domainRange where range.count > 0 { storage.deleteCookie(cookie) } }
Не помогло


Ответ

Я нашел решение. Нужно вызвать VKSdk.forceLogout()

Загрузка и замена содержимого в модальном окне

Есть ссылки вида (data внутри отличаются)
Смотреть
и js

Сюда все выводится


Вопрос заключается в том как сделать загрузку разного содержимого в модальное окно и очистку при закрытии модального окна. Сейчас почему то получается просто замена.
Другими словами как мне загружать несколько фотографий по одной ссылке, а при нажатии на другую я бы мог грузить только 1 фотографию и текст.


Ответ

К сожалению не нашел пока решения всех проблем, но для вывода дополнительных изображений в кнопку добавил новую data для каждого нужного изображения. То есть если при клике на кнопку в модали должно быть 3 изображения, то к кнопке прикрепляем 3 разные data
Пример
Приобрести
После редактируем js

Где var bimg2 = null; мы обнулили переменную (или как правильно называется)
bimg2 = $(this).attr('data-bimg2');
Забрали все из нашей data и поместили в переменну
$(".k img").attr('src', bimg2);
Тут мы указали что все что есть в bimg2 должно появляться в классе к внутри img
И теперь добавляем в модальное окно место, где появится наша картинка

Можно ли ограничить количество записей в таблице?

Можно ли в SQLite ограничить размер таблицы на количество записей и как это организовать? Например таблица набирает суммарно 100 строк, после чего самые старые записи удаляются и записываются новые.


Ответ

Можно написать триггер на вставку новых записей в таблицу. Предположим, у вас имеется таблица _table с полями
_id(ключ какой-то) _time(время создания записи)
Тогда триггер будет выглядеть следующим образом
CREATE TRIGGER delete_till_50 INSERT ON _table WHEN (select count(*) from _table)>100 BEGIN DELETE FROM _table WHERE _table._id IN (SELECT _table._id FROM _table ORDER BY _table._time limit (select count(*) - 100 from _table )); END;
При вставке новой записи самые старые записи будут удаляться. В базе всегда будет не более 100 записей.

ServerSocket в веб-приложении

Как можно в веб-приложение встроить ServerSocket на определенному порту? Когда, как и где нужно его запускать?


Ответ

Вы можете создать самый обычный socket-сервер:
ServerSocket ss = new ServerSocket(port);
Если вам просто нужна точка входа в веб-приложении, стартующая при старте приложения, то напишите класс, реализующий интерфейс javax.servlet.ServletContextListener и в методе contextInitialized() вызывайте инициализацию вашего socket-сервера.
Действия, которые должны быть произведены при остановке web-приложения, выполняются в методе contextDestroyed()
public class SocketServerListener implements ServletContextListener { private static final int PORT = 3333; private ServerSocket server;
@Override public void contextInitialized(ServletContextEvent servletContextEvent) { server = new ServerSocket(PORT); // ... }
@Override public void contextDestroyed(ServletContextEvent servletContextEvent) { server.close(); } }
Если вы используете Servlet API старше, чем 3.0 - добавьте listener в web.xml
my.package.SocketServerListener
Начиная с Servlet API 3.0, вам достаточно пометить ваш класс аннотацией @WebListener
@WebListener public class SocketServerListener implements ServletContextListener { //... }

Как прокрутить GridView на весь экран?

GridView отверстан на нижнюю половину экрана, вверху располагаются картинка с описанием(статичные), но когда возникает необходимость прокрутить GridView, он прокручивается только на пол нижнего экрана. Как сделать так, чтобы при прокрутки GridView верхние элементы страницы плавно убирались, а грид становился прокручиваемым на весь экран?


Ответ

https://stackoverflow.com/questions/8481844/gridview-height-gets-cut
Тут есть ответ. Все решают scrollview + усовершенствованный gridview ))

Метод минимальной степени. Оптимизировать реализацию

Работаю с разреженными матрицами. Возникала необходимость перестановки строк и столбцов с целью сократить "заполненность" матрицы после разложения Холецкого. Итак сам алгоритм:
1) Для матрицы построить граф, вершины которого - номера строк, если в i-той строке есть не нулевой элемент, то это отображается ребром в графе между i-й вершиной и вершиной, значением которой является номер ненулевого элемента в i-й строке. (Матрица симметричная, диагональные элементы все не нулевые, дуги для диагональных элементов не строятся.) Получается граф "смежности", если так его можно назвать.
2)В графе находим вершину с минимальной степенью, ее значение записывается в вектор перестановки. (Минимальная степень - вершина соединена с минимальным количеством других вершин. Если таких вершин несколько, берется первая.) Сама вершина удаляется вместе с ребрами.
3) Алгоритм повторяется пока в графе остаются вершины.
Граф храню через списки смежности: std::vector< std::set > G;
Реализация:
std::vector tmp; tmp.resize(n); for (auto &t : tmp) t = 1; unsigned index; int min; // ПОЛУЧЕНИЕ ПЕРЕСТАНОВКИ for (unsigned i = 0; i < n; i++) { // поиск мин min = n + 1; for (unsigned k = 0; k < n; k++) { if (tmp[k]) { if (G[k].size() < min) { min = G[k].size(); index = k; } } } for (auto &Node : G[index]) if (tmp[Node]) G[Node].erase(index); p[i] = index; tmp[index] = 0; }
Не нравится тот момент, что приходится использовать дополнительный массив, который показывает была ли удалена i-я вершина или нет. Из-за этого поиск минимума идет по всем вершинам, но учитываются только не удаленные. Можно ли поправить этот момент?


Ответ

А вы сделайте наоборот, в temp храните не признаки наличия вершины а, индексы существующих вершин. Кроме того следует хранить не сами индексы, а диапазоны индексов, то есть:
typedef std::pair Range ; typedef std::vector Ranges;
std::vector ranges; ranges.reserve(n \ 2); // в худшем случае будет n\2 диапазонов // если узлы станут удалятся через один ranges.push_back(Range(0, n));
Ranges::iterator min_range; size_t min_index; size_t min;
// ПОЛУЧЕНИЕ ПЕРЕСТАНОВКИ for (size_t i = 0; i < n; ++i) { // поиск мин min = n + 1; for(auto r = ranges.begin(); r != ranges.end(); ++r) { for(auto k = r->first; k < r->second; ++k) { if (G[k].size() < min) { min = G[k].size(); min_index = k; min_range = r; } } }
for(auto & node : G[min_index]) { // здесь не проверяется удалена ли вершина node // так как это избыточно, node всегда "живая" // если G построен корректно G[node].erase(min_index); } p[i] = min_index;
// удаляем найденный индекс if(min_index == min_range->first) { if(min_range->first + 1 == min_range->second) { ranges.erase(min_range); } else { min_range->first++; } } else if(min_index + 1 == min_range->second) { min_range->second--; } else // min_index где-то в середине диапазона { auto left = ranges.insert ( min_range , Range(min_range->first, min_index) ); (left + 1)->first = min_index + 1; // после insert справа остался // старый диапазон, укоротим его } }