Страницы

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

пятница, 19 октября 2018 г.

не пойму реализацию strlen

здравствуйте, нарыл тут на просторах реализацию сишной функции strlen :
/* Magic numbers for the algorithm */ #if LONG_BIT == 32 static const unsigned long mask01 = 0x01010101; static const unsigned long mask80 = 0x80808080; #elif LONG_BIT == 64 static const unsigned long mask01 = 0x0101010101010101; static const unsigned long mask80 = 0x8080808080808080; #else #error Unsupported word size #endif
#define LONGPTR_MASK (sizeof(long) - 1)
/* * Helper macro to return string length if we caught the zero * byte. */ #define testbyte(x) \ do { \ if (p[x] == '\0') \ return (p - str + x); \ } while (0)
size_t strlen(const char *str) { const char *p; const unsigned long *lp;
/* Skip the first few bytes until we have an aligned p */ for (p = str; (uintptr_t)p & LONGPTR_MASK; p++) if (*p == '\0') return (p - str);
/* Scan the rest of the string using word sized operation */ for (lp = (const unsigned long *)p; ; lp++) if ((*lp - mask01) & mask80) { p = (const char *)(lp); testbyte(0); testbyte(1); testbyte(2); testbyte(3); #if (LONG_BIT >= 64) testbyte(4); testbyte(5); testbyte(6); testbyte(7); #endif }
/* NOTREACHED */ return (0); }
можете прокомментировать зачем такой треш?


Ответ

Это реализация strlen, которая работает не побайтно, а пословно. Для того она и сделана: чтобы ради пущей эффективности читать и анализировать данные из памяти не одиночными байтами, а сразу выровненными словами длиной 32 или 64 бита.
Для достижения выравнивания начальная часть строки (до требуемой границы выравнивания), обрабатывается побайтно, то есть обычным способом.
Далее строка читается пословно. Каждое прочитанное слово обрабатывается при помощи следующего бит-хака
if ((*lp - mask01) & mask80)
который анализирует все прочитанное слово (т.е. фактически "параллельно" анализирует все его байты) и приблизительно отвечает на вопрос о том, есть ли в слове *lp нулевой байт. Если данная проверка дает положительный ответ, то код под этим if при помощи макро testbyte выясняет уже, в какой точной позиции он находился.
"Приблизительность" проверки в данном случае заключается в том, что условие в if иногда может дать положительный ответ даже в случае слова без нулевого байта - если в слове присутствуют байты с единицей в старшем бите. Т.е. эта проверка допускает "ложные срабатывания" и, как следствие, вызывает ненужную побайтовую проверку через testbyte, но на корректность результата это не влияет. Строки, составленные из символов с кодами не выше 128 будут обрабатываться эффективно.
Слова же, в которых нулевой байт содержится, этой проверкой будут заведомо обнаружены.
Более сложная версия условия, основанная на тех же масках
if ((*lp - mask01) & ~*lp & mask80)
гарантировала бы точное определение наличия нулевого байта в слове, но авторы, очевидно, решили, что эффективнее будет работать именно их приближенный вариант (скорее всего потому, что код рассчитан на строки из символов латинского алфавита).
Теоретически, такая реализация обладает одной формальной проблемой: при пословном чтении содержимого строки может получиться так, что последнее читаемое слово будет "торчать" за пределы самой строки и выделенной для нее памяти. На практике это не приводит к проблемам, так как выделение и/или защита памяти обычно делаются по границам, выровненным как минимум до размера полного слова. Однако подобные "вылеты" могут вызвать жалобы от средств динамического анализа кода, типа valgrind.

Классификация ip адресов

Что такое адрес произвольной рассылки (anycast)? Для чего он нужен?


Ответ

Any - любой, cast - бросать
Anycast - технология маршрутизации, предоставляет отправку пакета "первому попавшемуся" в anycast группе. Т.е. кто первый получил пакет - его и обрабатывает. Остальные участники Anycast группы этого пакета уже не увидят.
Если простым языком, то один и тот же IP-адрес назначается нескольким серверам, расположенным в разных местах и когда делается запрос по адресу - выбирается ближайший (чем меньше точек прохода пакета, тот ближе)
Более подробно в статье с Habrahabr:
Смысл метода Anycast заключается в анонсировании одинакового префикса IP-адресов одновременно из нескольких точек сети через протокол BGP. В результате данные передаются по наиболее короткому маршруту — на ближайший узел, которому присвоен анонсированный IP-адрес. При этом понятие «короткий маршрут» в данном случае трактуется не в географическом, а в топологическом смысле.

В чем смысл текстовых шаблонов T4 и когда их имеет смысл использовать?

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


Ответ

Если вы имеете в виду T4, то их смысл — встроенный в систему шаблонизатор/DSL. T4 используется в двух вариантах: времени компиляции и времени выполнения.
T4 времени выполнения обычно используется как шаблонизатор, и означает, что вы можете легко генерировать текстовые файлы, в которых большая часть текста постоянна, а куски необходимо генерировать программно. Простой пример — шаблон письма, в который нужно вставить имя адресата, адрес и наименование товара.
Но гораздо более интересным является T4 времени разработки. Эта штука позволяет вам генерировать код на этапе компиляции (точнее, даже до неё). То есть, у вас появляется ещё одно прекрасное (хотя и немного неуклюжее — если не сравнивать с шаблонной магией Александреску) средство для настоящего метапрограммирования. Причём в отличие от решений, которые вы могли бы соорудить на коленке, T4 встроен в Visual Studio, и сгенерированные файлы просто видны в дереве Solution Explorer'а, и подхватываются компилятором.
T4 используется для кодогенерации многими проектами, начиная с Entity Framework. Вот здесь ещё достаточно впечатляющий список. Вот, например, пример того, как автоматически генерировать определения Dependency Property. (Я тоже использовал T4 для генерации из текстового представления XAML-словарей для локализации.)

Кодогенерация времени выполнения и правда не лучший метод использования T4. Для этих целей лучше подходит CodeDOM (или, кажется, Roslyn API). А для кодогенерации времени компиляции доступ к сгенерированным исходникам очень важен, например, для отладки.

Дополнение к вопросу из комментария. Да, можно в шаблоне генерировать другой шаблон.
Например, такой вот шаблон
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".tt" #>
<# string open = "<" + "#" + "@", close = "#" + ">"; #>
<#= open #> template debug="false" hostspecific="false" language="C#" <#= close #> <#= open #> assembly name="System.Core" <#= close #> <#= open #> import namespace="System.Linq" <#= close #> <#= open #> import namespace="System.Text" <#= close #> <#= open #> import namespace="System.Collections.Generic" <#= close #> <#= open #> output extension=".cs" <#= close #>
class Test { public int i; }
порождает подчинённый шаблон
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #>
class Test { public int i; }
который в свою очередь порождает класс
class Test { public int i; }
Никаких специальных действий выполнять не нужно, просто добавьте шаблон T4 через Add → New item → Text Template (не Runtime Text Template!)

В T4-файл положите текст шаблона, как он представлен выше, и вы получите такую вот необычную структуру вашего solution'а:

Python len() и .__len__() в чем разница?

В чем разница между len() и .__len__()? И могут ли они возвращать разные значения?


Ответ

__len__ это магический метод, который реализует len операцию. Как и любой другой специальный метод, он вызывается специальным образом (должен быть определён в самом классе), то есть len(o) не всегда эквивалентно o.__len__(). Подробнее в ответе о магических методах
Дополнительно, значения len() ограничены sys.maxsize
>>> import sys >>> class Big: ... def __len__(self): ... return sys.maxsize + 1 ... >>> len(Big()) Traceback (most recent call last) ... OverflowError: cannot fit 'int' into an index-sized integer >>> Big().__len__() 9223372036854775808
На практике, иногда полезно иметь последовательность с большой длиной:
Get the highest possible gmtime for any architecture Weighted random sample in python

Как правильно реализовать тестовое задание на должность PHP developer?

HR менеджер дал тестовое задание. Я выполнил. В ответ он сказал, что
я получил только краткий фидбек - не понравилось качество и стиль реализации.
Хочу вашего совета, что я не так написал. Вот задание:
Тестовое задание #1:
Версии ПО: PHP 5.3-5.6
Необходимо реализовать функцию, которая произведет чтение данных файла и вернет обработанные данные в указанном виде.
Функция должна: - Считать данные с файла - Разбить данные по строкам в массив - Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа - Суммировать числа в каждой строке - Отсортировать полученные суммы в порядке убывания - Вернуть результат
Пример кода:
# Путь к файлу данных $file = __DIR__ . '/datalist.txt'; # Передаем данные в функцию и получаем результат $result = getResult( $file ); # Отображаем результат echo '

'; 
     var_export( $result );
function getResult ( $file ) { # @TODO Реализовать... }
Пример результата работы функции: array ( 82 => 16396, 19 => 16169, 71 => 15864, 73 => 15224, 81 => 14244 ...
Кусок файла datalist.txt:
55 NTfy 591 405 kLj 48 644 768 164 ubd 837 oTft GPQV 163 ja 445 961 431 574 168 375 380 427 670 610 284 765 48 687 660 377 333 914 70 146 328 301 925 266 620 237 137 584 427 308 939 660 917 59 864 j hHo 279 tqpg 617 870 CoNJ 173 czgW 301 299 134 820 625 U 369 165 hutPN jiq 31 575 46 NS 397 378 954 764
Как я это реализовал:
# Путь к файлу данных $file = __DIR__ . '/datalist.txt'; # Передаем данные в функцию и получаем результат $result = getResult($file); # Отображаем результат echo '
';
var_export($result);
function getResult($file) { #Считать данные с файла. #Разбить данные по строкам в массив $line = file($file); $i = 0; foreach ($line as $value) { $ArrayLine = explode(' ', $value); foreach ($ArrayLine as $Record) { $result[$i] = 0; #Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа $CheckString = preg_replace('~[^A-Za-z]+~', '', $Record); if (strlen($CheckString) > 0) { unset($result[$i]); break; }; $res = (int) $Record; #Суммировать числа в каждой строке $result[$i] += $res; } $i++; } #Отсортировать полученные суммы в порядке убывания arsort($result); return $result; }


Ответ

Код
/** * Функция производит чтение данных из файла и возвращает обработанные данные согласно алгоритму * - Считать данные с файла * - Разбить данные по строкам в массив * - Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа * - Суммировать числа в каждой строке * - Отсортировать полученные суммы в порядке убывания * - Вернуть результат * * @param string $file * @return array */ function getResult($file) { $numbers = [];
$handle = @fopen($file, 'r'); if ($handle) { // Читаем файл построчно while (($buffer = fgets($handle, 4096)) !== false) { // Удаляет пробелы (или другие символы) из начала и конца строки $buffer = trim($buffer);
if (preg_match('/^[\d ]+$/', $buffer)) { // Разбиваем строку на числа, складываем получившийся массив чисел и записываем в массив $numbers[] = array_sum(explode(' ', $buffer)); } } }
// Сортируем массив по возрастанию (без сохранения отношений с ключами) rsort($numbers);
return $numbers; }
$result = getResult(__DIR__ . '/datalist.txt');
print_r($result);
Комментарии к коду:
По входному файлу, в примере, делаю следующий вывод. Функция разработана с учетом того, что числа только положительные и целые, и внутри слов нету чисел, например, oT89ft. И число не может идти рядом со словом, например, 200NTfy (то есть будет ли он считаться числом после удаление «нечисел»). Хоть в алгоритме указан шаг Разбить данные по строкам в массив, он пропускается, чтобы не «забивать» память (не происходило переполнение памяти). Потом что строк в файле может быть очень много. Чтение происходит построчно и в массив сразу вычисляется и записывается сумма. Длина строки при чтении ограничена length - 1 байт Не стал «доходить по паранойи»: сортирую массив встроенной в PHP функцией и не стал делать какой-нибудь composer-пакет с тестами. Комментарии на русском... Желательно на англ. писать, если компании не против, где работать будете — потом пригодится :)
Дополнительная информация
При написании (форматировании кода) я стараюсь следовать PHP Standards Recommendations, в частности:
PSR-1: Basic Coding Standard PSR-2: Coding Style Guide
Изучите информацию на сайте — пригодится.
И всегда обращайтесь и изучайте информацию по PHP на официальном сайте. Документация на русск. или англ. языках.
И не бойтесь ошибаться! Задавать любые вопросы на Stack Overflow!

c# результат быстрейшего потока

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


Ответ

Судя по метке, метод у вас асинхронный. В таком случае можно воспользоваться Task.WhenAny()
public async Task FooAsync(int x) { //... }
...
var task1 = FooAsync(1); var task2 = FooAsync(2); var fastestTask = await Task.WhenAny(task1, task2); var result = fastestTask.Result;
Однако может так случиться, что какой-либо таск завершится быстрее из-за исключения. В таком случае нужно снова вызвать Task.WhenAny() для оставших тасков. В общем случае решение может выглядеть так:
var task1 = FooAsync(1); var task2 = FooAsync(2); var task3 = FooAsync(3); var tasks = new List>() { task1, task2, task3 }; int result; while (tasks.Count > 0) { var fastestTask = await Task.WhenAny(tasks); if (fastestTask.IsCompleted) { result = fastestTask.Result; break; } else // если таск упал или был отменен { tasks.Remove(fastestTask); } }
Ждать или отменять оставшиеся таски, если один из них упал -- зависит от задачи. Например, если вы хотите получить цену одной и той же акции из нескольких источников, то даже если один из источников недоступен, вы дождетесь ответа другого источника. В случае если вы хотите получить цену разных акций из одного и того же источника, то, вероятно, имеет смысл отменить оставшиеся таски, поскольку понятно, что если источник недоступен, то остальные задачи тоже упадут.

Вывод результата побитовой операции в Bash

Хочу реализовать простейший пример. Есть два числа в двоичной системе 0011 и 0101. Хочу применить к ним операцию "ПОБИТОВОЕ ИЛИ". Результат вывести в виде двоичного числа. Должно получиться 0111, получаю 73. Почему так?
#!/bin/bash AA=0011 BB=0101 CC=$(($AA | $BB)) echo "Result: " $CC


Ответ

Двоичные числа в bash задаются как 2#число. Выводить в двоичном виде результат bash не умеет, можно воспользоваться bc
#!/bin/bash AA=2#0011 BB=2#0101 CC=$(($AA | $BB)) echo -n "Result: " printf "%04d" `echo "obase=2;$CC" | bc`

Как куда-нибудь передать функцию // почему событие вызывается сразу же?

Допустим, я написал функцию:
function foo() { alert("Hello, world!"); }
Почему когда я пытаюсь вызвать ее спустя некоторое время, она вместо этого вызывается сразу же?
setTimeout(foo(), 10000);
И то же самое - с обработчиками событий? Пытался делать вот так:
el.onclick = foo(); el.addEventListener("click", foo()); createButton({ name: "show alert", onClick: foo(), });


Ответ

Возможно, вы написали скобки около имени функции - foo() - случайно. А возможно, вы думаете что именно этими скобками функция отличается от переменной. В любом случае, ошибка скрыта именно тут.
Кратко: уберите лишние скобки и все заработает.

Javascript вычисляет выражения изнутри-наружу (как и многие другие языки). Очевидные примеры из математики: в выражении 2 + 2 * 2 сначала выполняется умножение, а потом - сложение, а в выражении (2 + 2) * 2 - наоборот.
Когда вы пишите foo() - это оператор вызова функции. Это- такая же часть выражения как и любая математическая операция. И если где-то внутри выражения есть вызов foo() - то функция foo будет вызвана независимо от того что написано снаружи.
Так, в примере setTimeout(foo(), 10000); сначала вызывается foo(), а потом результат вызова foo() (обычно это какой-нибудь undefined) передается в setTimeout: setTimeout(undefined, 10000). С точки зрения интерпретатора Javascript это не ошибка: он же не знает что такое foo, он просто послушно делает что вы ему сказали.
Если вам не нужно вызывать функцию - то не надо ее вызывать. Просто убираем скобки около имени функции - и теперь она передается как есть, без вызова:
setTimeout(foo, 10000); el.onclick = foo; el.addEventListener("click", foo); createButton({ name: "show alert", onClick: foo, });
Вызовут ее уже в другом месте, когда придет время. (Кстати, такая переданная куда-то функция обычно называется колбеком, callback или функцией обратного вызова).
Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.

Классы, наследование

Создал 2 класса. От одного наследовал другой. Вот код:
class Program { static void Main(string[] args) { Manager man = new Manager("", "", 0, 0); } }
class Employee { public string Surname { get; set; } public string Name { get; set; } public int Age { get; set; }
public Employee(string sName, string MyName, int MyAge) { Surname = sName; Name = MyName; Age = MyAge; } }
class Manager : Employee { public int Pay { get; set; }
public Manager(string s, string n, int a, int p) { Surname = s; Name = n; Age = a; Pay = p; } }
В унаследованном классе заполняю напрямую свойства из первого. Но почему то ругается на конструктор класса Manager.
Error CS7036 There is no argument given that corresponds to the required formal parameter 'sName' of 'Employee.Employee(string, string, int)'
Что то не пойму что не так?


Ответ

В классе Employee у вас нет конструктора без параметров, так что вы должны явно указать конструктор Employee, соответствующий конструктору Manager, и передать в него параметры. Создать объект класса Employee без вызова конструктора (и, соответственно, без передачи в него параметров) не получится:
public Manager(string s, string n, int a, int p) : base(s, n, a) // будет вызван Employee(string, string, int) { // все свойства, кроме Pay, инициалируются в конструкторе базового типа Pay = p; }

Как создать многомерный массив java типа ключ-значение?

Как на java создать такой массив как здесь в примере на пхп?
$arr2 = array( 'Авто' => array( 'KIA', 'BMW', 'MAZDA', 'OPEL' ), 'Краска' => array( 'Красная', 'Зеленая', 'Черная' ) );


Ответ

С помощью Map и List
Map> arr2 = new HashMap<>(); arr2.put("Авто", Arrays.asList("KIA", "BMW", "MAZDA", "OPEL")); arr2.put("Краска", Arrays.asList("Красная", "Зелёная", "Чёрная"));

Список из двух и более значений

Как создать в классе список, который имеет несколько значений? Грубо говоря, сделать что-то, на подобие:
List array = new List(); array.Add(4,5,4.3,5); Console.WriteLine(array[0][2]);


Ответ

Tuple
List> array = new List>(); array.Add(Tuple.Create(4,5,4.3,5)); Console.WriteLine(array[0].Item3);

ValueTuple:
List<(int,int,double,int)> array = new List<(int,int,double,int)>(); array.Add((4,5,4.3,5)); Console.WriteLine(array[0].Item3);

C# Удалённая запись в массив другого приложения

Есть основное приложение WinForms в котором ведётся парсинг интернет ресурса с записью необходимых данных в двумерный массив string[5000, 50]
Где 1й столбец строки это ссылка, а остальные столбцы данные с ресурса.
Как только набирается строка c данными , данные этой строки сгруппировано выводятся в окне приложения.
Как мне эти данные передавать в массив другого приложения WinForms по интернету и так же выводить ?
Главный вопрос, как передавать эти данные c записью в массив ?
Самостоятельно искал, читал немного про сокеты, но пока каша в голове и не знаю про подводные камни.
Хотелось бы как то тупо, при заполнении строки массива в главном приложении, сразу эту строку массива передавать в массив удалённого приложения.


Ответ

Я мог бы вам предложить один из вариантов организации данного функционала:
Логика :
1) Серверная часть
Ваш Parser после анализа полученных данных и формирования массива значений (рекомендую использовать коллекции в место статичного массива) сериализуется в json(или XML формат) строку и добавляет их в базу данных MySQL (локальную или удалённую) (с одновременной проверкой наличия там таких данных) - SQL запрос для организации структуры базы данных для ваше случая должна быть примерно таковой
CREATE DATABASE IF NOT exists parsersystem; use parsersystem; CREATE TABLE IF NOT exists Procedures ( number int AUTO_INCREMENT, id int, jsonData TEXT, ts_create timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', ts_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (number) );
где number это автоинкриментное поле (уникальный номер записи в БД)
id - уникальный специфичный номер записи (заданный пользователем)
jsonData - сериализация любых данных в том числе и массива ваших значений
ts_create - дата и время создание записи
ts_update - дата и время обновления записи
MySQL сервер настраивается таким образом чтобы к нему имели доступ клиенты через интернет либо локальную сеть (в зависимости от ваших нужд)
2) Клиенты
Клиентское приложение будь то Desktop, Android или другое, не имеет связи непосредственно с вашим серверным Parser приложением, а обращается к открытой MySQL базе (закрытой по желанию паролем), на предмет наличия новых записей, это становится возможным при использовании поля ts_create - которое отражает время создание записи Логика:
клиент периодически делает запрос к базе данных примерно такой
SELECT * FROM Procedures WHERE ts_create > TIMESTAMP (время последней добавленной клиентом записи) ORDER BY ts_create DESC
таким образом клиент получит только новые записи из таблицы на стороне клиента происходит десереализация jsondata и формирование своей локальной копии массива (идентичного тому что на стороне сервера) клиенту следует хранить дату и время последней добавленной записи для последующих запросов
Преимущество такого подхода :
независимость клиентской и серверной части приложения, (данные хранятся отдельно в БД) нет необходимости в организации специфического протокола общения (сервер -клиент) при использовании подхода передачи при помощи сокетов
Предположим что мы имеем некий класс описывающий модель наших данных
public class Procedure(){ public String Name { get; set; } public List Data { get; set; } }
А также мы на стороне сервера имеем набор данных (коллекцию)
public List procedures;
Для записи в базу данных такой конструкции стоит применять примерно такой метод:
public AddProceduresToDataBase(List procedureList) { string Connect = "Port=3306; Database=parsersystem;Data Source=127.0.0.1;Password=mysql_password; MySqlConnection myConnection = null; try { myConnection = new MySqlConnection(Connect);
myConnection.Open(); } catch (Exception e) { myConnection.Close(); Console.Out.WriteLine("Ошибка доступа к базе данных"); }
foreach (var proc in procedureList) { var json = new JavaScriptSerializer().Serialize(proc); // Экранируем спец символы json = json.Replace(Convert.ToChar(0171) + "", "") .Replace(Convert.ToChar(0187) + "", "") .Replace("\\\"", "") .Replace("\\","\\\\"); MySqlCommand myCommand_add = new MySqlCommand(@"INSERT INTO Procedures(id,jsondata,ts_create,ts_update) VALUE (" + сгенерить нужно ID + "+ json + "',null,null);", myConnection); myCommand_add.ExecuteNonQuery(); }
myConnection.Close(); //Обязательно закрываем соединение!
}
Для чтения коллекции из базы данных стоит использовать примерно такой метод
public List GetProcedures() { string Connect = "Port=3306; Database=parsersystem;Data Source=127.0.0.1;Password=mysql_password; MySqlConnection myConnection = null; try { myConnection = new MySqlConnection(Connect);
myConnection.Open(); } catch (Exception e) { myConnection.Close(); Console.Out.WriteLine("Ошибка доступа к базе данных"); }
string CommandText = "SELECT * FROM Procedures "; MySqlCommand myCommand = new MySqlCommand(CommandText, myConnection);
MySqlDataReader MyDataReader; MyDataReader = myCommand.ExecuteReader();
List procedures = new List(); String jsonData;
while (MyDataReader.Read()) { try { jsonData = MyDataReader.GetString(2); // Читаем jsondata из 2го столбца таблицы Procedure newProcedure = new JavaScriptSerializer().Deserialize(jsonData); procedures.Add(newProcedure); } catch { Console.Out.WriteLine("Ошибка разбора JSON данных о процедуре"); } } MyDataReader.Close(); myConnection.Close(); return procedures;
}
ПС. естественно методы нужно дорабатывать, внедрить проверку на наличие уже такого рода данных в БД, расширить функционал чтения для получения новых записей , но это я уже оставляю вам. ПС. так же тут в принципе показаны примеры сериализации и десиарилизации данных в JSON

Свой css для сайтов в браузере

Подскажите, пожалуйста, расширение или что-то подобное, что сможет сохранить мои личные CSS для сторонних сайтов. К примеру, у ВКонтакте background: #edeef0;, а я хочу поменять на свой цвет, чтобы при перезагрузке страницы дописывались стили через !important или inline


Ответ

Расширения для браузера - Stylish
Ответ дан пользователем: diraria

Как вернуть все элементы с querySelectorAll

У меня есть 5 инпута, нужно сделать так, чтобы если одно из них не заполнить, то сообщение не должно быть отправлено.
document.querySelector(".btn-info").addEventListener("click", function(){ var required = document.querySelectorAll(".required"); if (required.val == "") { alert("please fill all the columns"); } }); .required { display:block; padding-bottom:10x; }



Ответ

Так как querySelectorAll возвращает коллекцию элементов, то проверка required.val == "" бессмысленна, ибо берется val (которого и одиночного-то элемента нет), которого в коллекции нет. Соответственно можно пробежать по коллекции и просмотреть значение value у элементов:
document.querySelector(".btn-info").addEventListener("click", function(){ let required = document.querySelectorAll(".required"); let isAllFilled = true; for (let i = 0; i < required.length; ++i) { if (required[i].value.trim() == "") { isAllFilled = false; break; } } if (!isAllFilled) alert("please fill all the columns"); }); .required { display:block; padding-bottom:10x; }


Зачем нужен спецификатор PRIVATE в C++

Зачем нужен спецификатор private в C++, если по умолчанию итак все функции и переменные являются закрытыми?


Ответ

Например, потому, что в структуре по умолчанию все функции и поля являются открытыми
Кроме того, текстовый порядок полей влияет на порядок их инициализации в конструкторе! Поэтому просто так переставлять поля класса нельзя, это может изменить смысл программы.
Пример. Допустим, что мы хотим, чтобы поле len было открытым, а поле data — закрытым.
class MyString { public: unsigned len; private: char* data; public: MyString(const char* s) : len(std::strlen(s)), data(new char[len + 1]) { std::memcpy(data, s, len + 1); } // ... };
Мы не можем переставить местами len и data, потому что инициализаторы в конструкторе выполняются в том порядке, в котором указаны поля, а не в том порядке, в котором они написаны в коде! А значит, без private не обойтись.

Выделение нетипизированной памяти для массива произвольного типа

Если я выделяю память для некоторого типа T - пусть это в шаблоне, скажем -
template char* alloc(size_t n) { return new char[n*sizeof(T)] ; }
то места гарантированно хватит для n элементов с типом T или нет? Какие-то проблемы из-за выравнивания могут быть? И если могут - то как их правильно решить?
Дополнение - по совету @VladD я ппробовал выделить память с особыми требованиями к выравниванию:
#include #include
using namespace std;
struct alignas(256) D { char a; char b; };
template void* alloc(size_t n) { return reinterpret_cast(new aligned_storage[n]); }
template int allocSize() { cout << "sizeof = " << sizeof(T) << ", alignof = " << alignof( T) << endl; cout << "type = " << typeid(typename aligned_storage::type).name() << endl; return sizeof(typename aligned_storage::type); }
int main() { cout << allocSize() << endl; cout << alloc(5) << endl; }
GCC это не смог отработать - https://ideone.com/dgo75h. Но Visual Studio нормально отработал, но выдал:
sizeof = 256, alignof = 256 type = union std::_Align_type 256 004A1258
т.е. понял и размер, и выравнивание, но адрес дал выровненный явно не на 256. Мне это выравнивание не нужно, это так, игры - но тем не менее получается, что так выделять память не получается?


Ответ

По идее, вам нужно std::aligned_storage
Должно по идее работать так:
template char* alloc(size_t n) { return new aligned_storage[n]; }

Проблемы из-за выравнивания с простым подходом очевидны: new char[] не знает ваших требований по выравниванию, и может выделить неправильно выровненную память.

Для выделения объектов в вашей памяти вам понадобится placement new. Вам должен пригодится std::align, использование которого описано здесь

Обновление: я перепроверил, и на самом деле new не соблюдает кастомные требования по выравниванию. Поэтому нужно делать выравнивание самостоятельно, при помощи std::align. Получается вот что:
// подсчёт длины нужной аллокации template size_t aligned_char_size(size_t n) { size_t result = n * sizeof(T); bool is_overaligned = alignof(T) > alignof(std::max_align_t); if (is_overaligned) result += alignof(T) - 1; return result; }
Применяем:
struct alignas(1024) S { };

// выделёем память на 3 экземпляра size_t total_space = aligned_char_size(3); void* p = new char[total_space]; std::cout << p << std::endl;
// получаем выровненный указатель при помощи std::align void* allocated_item = p; size_t remaining_space = aligned_char_size(3); if (std::align(alignof(S), sizeof(S), allocated_item, remaining_space)) { std::cout << allocated_item << std::endl; std::cout << (size_t)allocated_item % alignof(S) << std::endl; } else { std::cout << "Impossible" << std::endl; }
Результат на Visual Studio 2017:
000002333DF15950 000002333DF15C00 0
Если убрать alignas(1024), получаем
000002A27FD2ECD0 000002A27FD2ECD0 0

Создание dll для 1С

Есть dll без исходников, для нее есть интерфейс на delphi. Стоит задача подружить эту библиотеку с 1С. На сколько понял с прочитанного в интернете, на основе интерфейса можно сделать dll по COM технологии.
Пример интерфейса:
unit Unit1; interface
uses Windows, Messages, Classes, SysUtils, Forms;
type TBonusCountersPrintQuery = packed record Card: array[0..15] of char; end;
TListCountersPrint = packed record Lines: array[0..PACKET_COUNTERS_PR_MAX_LINE_COUNT - 1] of TCounterLine; end;
TCounterLine = packed record LineNo: word; IsLast: byte; Num_Counter: word; N_Counter: array[0..9] of char; Value_Counter: Cardinal; end;
type THWE_ProcessBonusListCountersPrint = function(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; stdcall;
function ProcessBonusListCountersPrint(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; stdcall;
implementation
var HWE_ProcessBonusListCountersPrint : THWE_ProcessBonusListCountersPrint;
function init_dynamic(ALibrary: string): Boolean; begin hLib := SafeLoadLibrary(ALibrary);
Result := (hLib <> 0);
if Result then begin
@HWE_ProcessBonusListCountersPrint := GetProcAddress(hLib, 'ProcessBonusListCountersPrint');
Result := Assigned(HWE_ProcessBonusListCountersPrint); end; end;
function ProcessBonusListCountersPrint(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; begin result := HW_FAILURE; if hLib <> 0 then result := HWE_ProcessBonusListCountersPrint(vBonusCountersPrintQuery, vListCountersPrint); end;
initialization
finalization
end.
Как правильно написать такую dll, чтобы функция из примера была доступна из 1С?


Ответ

Ваша библиотека будет связующим звеном между 1C и сторонней библиотекой без исходного кода:
1C -> ВашаБиблиотекаCOM -> СтороняяБиблиотека
То, что вы описали - попытка реализовать связь:
ВашаComБиблиотека -> СтороняяБиблиотека
Осталось реализовать связь между 1C и вашей библиотекой.
Чтобы начать разработку библиотеки по технологии COM в Delphi нужно выбрать: File -> New -> Other и там найти ActiveX Library, новый проект будет выглядить приблизительно так:

Далее к проекту добавить COM-сервер: File -> New -> Other и найти COM Object, выглядеть в новых версиях Delphi будет как-то так:

В старых версиях Delphi так:

В полях ClassName (CoClassName) нужно ввести английское название, по которому 1C и будет загружать вашу библиотеку после регистрации в системе, например: MaximLibrary1C
Подробнее о пошаговом создании COM-библиотеки можете почитать здесь: http://www.introligator.org/articles/3/78
После написания прослойки (куда вы перенесете свой вышеописанный код) и окончания разработки на целевой машине вашу новую .dll нужно зарегистрировать в системе, как-то так:
regsvr32 c:\Library\Project1.dll
Конечно, имя проекта лучше задать более вменяемое, а не Project1. На машине с Delphi зарегистрировать можно из среды в меню "Run". Из самой 1C вашу библиотеку после регистрации в системе можно будет загружать как-то так:
МояБиблиотека = Новый COMОбъект("MaximLibrary1C"); // вызываем метод в библиотеке МояБиблиотека.1C_ProcessBonusListCountersPrint();

Зачем нужны разные типы ссылок в Java?

Углубляю познания о джаве. Наткнулся на статью о типах ссылок. Понял, что существуют 4 типа ссылок:
Strong reference Weak Reference Soft Reference Phantom Reference
Незнаю, правильно ли я понял, поэтому прошу подправить.
1 Тип сильная ссылка (Strong reference)
Object object = new Object();//создал обьект object = null;//теперь может быть собран сборщиком мусора
2 Тип слабая ссылка (Weak Reference)
// какой-то объект Object object= new Object ();
// слабая ссылка на него WeakReference weakStudent = new WeakReference(object);
// теперь объект Object может быть собран сборщиком мусора object= null;
3 Тип мягкая ссылка (Soft Reference)
// какой-то объект Object object= new Object ();
// слабая ссылка на него SoftReference softStudent = new SoftReference(object)
// теперь объект Student может быть собран сборщиком мусора // но это случится только в случае сильной необходимости JVM в памяти object= null;
4 Тип фантомная ссылка (ничего не понял про него)


Ответ

Более-менее рассказано в документации к пакету java.lang.ref
Soft references are for implementing memory-sensitive caches, weak references are for implementing canonicalizing mappings that do not prevent their keys (or values) from being reclaimed, and phantom references are for scheduling post-mortem cleanup actions. Post-mortem cleanup actions can be registered and managed by a Cleaner

Подробнее и по-русски, в порядке убывания жёсткости:
Сильные, они же обычные, нужны для указания на объекты, которые должны обязательно оставаться в памяти всё то время, что эти ссылки на него существуют. Если не складывается, получите OutOfMemoryError Мягкие ссылки полезны для кэшей, чувствительных к доступному объёму оперативной памяти. Объекты по ним могут зачиститься, но только в случае необходимости. Например, если нужно насоздавать ещё объектов с сильными ссылками, а уже негде, лучше освободить кэш и замедлить работу, чем уронить процесс напрочь. Слабые ссылки полезны для сопоставления объектов чему-нибудь без удерживания их от зачистки когда они больше не нужны (а-ля Map<Ключ, WeakRef<Значение>>). На возможность зачистки они не влияют вообще никак, слабые ссылки будут очищены при очередном запуске сборщика. Фантомные ссылки возникают, когда объект уже признан мусором, финализирован и находится в процессе зачистки, о чём можно узнать с помощью класса Cleaner и выполнить в это время какие-то собственные действия.
Плюс общее правило: политика зачистки для некоего объекта и очистки ссылок на него определяется самыми жёсткими из всех ссылок, что на него указывают.

Глоссарий не вполне очевидных переводов:
зачистить, зачистка — reclaim, reclamation очистить — clear

Невозможно выделить память более 2 Гб для класса TMemoryStream даже в 64-битном режиме

В Delphi, в том числе в последних версиях (могу проверить только до 10.1 Berlin, хотя негативные отзывы есть и о 10.2 Tokyo), класс TMemoryStream не может выделить под данные более 2 Гб даже при компиляции в 64-битном режиме. Попытки записать в поток большие объёмы приводят к ошибке "Out of memory while expanding memory stream".
Можно ли решить эту проблему без создания собственного класса, реализующего поток в памяти?


Ответ

Давайте взглянем в определение класса TMemoryStream в файле System.Classes.pas:
TMemoryStream = class(TCustomMemoryStream) private FCapacity: Longint; procedure SetCapacity(NewCapacity: Longint); protected function Realloc(var NewCapacity: Longint): Pointer; virtual; property Capacity: Longint read FCapacity write SetCapacity; public destructor Destroy; override; procedure Clear; procedure LoadFromStream(Stream: TStream); procedure LoadFromFile(const FileName: string); procedure SetSize(const NewSize: Int64); override; procedure SetSize(NewSize: Longint); override; function Write(const Buffer; Count: Longint): Longint; override; function Write(const Buffer: TBytes; Offset, Count: Longint): Longint; override; end;
Сразу отмечаем, что для адресации памяти используются переменные типа longint, что, естественно, объясняет невозможность использования более 2 Гб. Более того, если взглянуть на методы Read (их два) непосредственного предка TMemoryStream - TCustomMemoryStream
function TCustomMemoryStream.Read(var Buffer; Count: Longint): Longint; begin if (FPosition >= 0) and (Count >= 0) then begin Result := FSize - FPosition; if Result > 0 then begin if Result > Count then Result := Count; Move((PByte(FMemory) + FPosition)^, Buffer, Result); Inc(FPosition, Result); Exit; end; end; Result := 0; end;
function TCustomMemoryStream.Read(Buffer: TBytes; Offset, Count: Longint): Longint; begin if (FPosition >= 0) and (Count >= 0) then begin Result := FSize - FPosition; if Result > 0 then begin if Result > Count then Result := Count;
Move((PByte(FMemory) + FPosition)^, Buffer[Offset], Result); Inc(FPosition, Result); Exit; end; end; Result := 0; end;
, то заметим, что результат может быть посчитан неправильно.
Поэтому решением было: заменить тип переменных внутри TMemoryStream на NativeInt и Int64, в том числе локальных переменных, а методы TCustomMemoryStream.Read переписать, например, так:
function TCustomMemoryStream.Read(var Buffer; Count: Longint): Longint; var diff: Int64; begin if (FPosition >= 0) and (Count >= 0) then begin diff := FSize - FPosition; if diff > 0 then begin if diff > Count then Result := Count else Result := diff; Move((PByte(FMemory) + FPosition)^, Buffer, Result); Inc(FPosition, Result); Exit; end; end; Result := 0; end;
function TCustomMemoryStream.Read(Buffer: TBytes; Offset, Count: Longint): Longint; var diff: Int64; begin if (FPosition >= 0) and (Count >= 0) then begin diff := FSize - FPosition; if diff > 0 then begin if diff > Count then Result := Count else Result := diff;
Move((PByte(FMemory) + FPosition)^, Buffer[Offset], Result); Inc(FPosition, Result); Exit; end; end; Result := 0; end;
Это позволяет работать с объёмами памяти более 2 Гб (тестовый пример спокойно обработал 5-гигабайтный файл, полностью скопировав его в поток.
Для тех, кто захочет внести изменения у себя в System.Classes, напомню, что предварительно необходимо сохранить резервную копию этого файла - на всякий случай :)
Update 1
Для тех, кто по какой-то причине не хочет идти по предложенным выше вариантам, могу предложить класс TSegmentedMemoryStream - он доступен для скачивания и работает (проверено!).

Простая нейросеть выдает результат ~0.5

Пытаюсь реализовать простую нейронную сеть прямого распространения. Но результат, который она выдает после обучения(методом обратного распространения ошибки) стремиться к значению 0.5. Хоть после 1000 эпох обучения, хоть после 10000. Она имеет 3 входа, 2 нейрона в скрытом слое и 1 нейрон результирующий.
А если не обучать её, а с только что сгенерированными весами заставить принимать решение, то её ответ колебается в диапазоне от 0.5 к 1.
Вот код того, что есть на данный момент.
/*var weight_1 = [[0.79, 0.44, 0.43], [0.85, 0.43, 0.29]], weight_2 = [[0.5, 0.52]],*/ var weight_1 = randArr(2, 3), weight_2 = randArr(1, 2), learning_rate = 0.05, data = [ [[0,0,0], 0], [[0,0,1], 1], [[0,1,0], 1], [[0,1,1], 0], [[1,0,0], 1], [[1,0,1], 0], [[1,1,0], 0], [[1,1,1], 1] ]; console.log("---------До тренировки---------"); console.groupCollapsed("Prediction before"); predictSet(data); console.groupEnd(); function randArr(rows, cols) { arr = []; for (var i = 0; i И моя проблема заключается в том, что все результаты, которые выдает этот алгоритм, близки к 0.5 и довольно случайны, независимо от того, какие аргументы я использую.
Было бы неплохо если у кого-нибудь найдется похожая, но рабочая нейронная сеть. Тогда я мог бы получить результат тренировки на определенных статичных весах и ориентироваться на правильности своей нейросети.


Ответ

Возьмём фреймворк для постройки сетей, воссоздадим архитектуру вашей сети и... Увидим что даже заведомо правильная работающая сеть не может выявить закономерности в ваших входных данных. Для заведомо отрицательного образца [1,1,0] сеть показывает результат в пределах 0.5. Если посмотреть на ошибку обучения, то на 20000 итерациях она будет порядка 0.2, из чего самого по себе можно сделать вывод что архитектуры сети недостаточно.
Вы можете сколько угодно пытаться исправить алгоритм, но у вас ничего не получится без изменения и усложнения архитектуры. В качестве эксперимента можно попробовать руками подобрать веса, которые бы давали правильный ответ. Уверен что это невозможно сделать даже человеку, что уж говорить об алгоритмах, которые даже с горы толком спуститься не могут
var myNetwork = new synaptic.Architect.Perceptron(3, 2, 1) var trainer = new synaptic.Trainer(myNetwork) var trainingSet = [ { input: [0,0,0], output: [0] }, { input: [0,0,1], output: [1] }, { input: [0,1,0], output: [1] }, { input: [0,1,1], output: [0] }, { input: [1,0,0], output: [1] }, { input: [1,0,1], output: [0] }, { input: [1,1,0], output: [0] }, { input: [1,1,1], output: [1] } ] var trainingOptions = { rate: .1, iterations: 20000, error: .005, } console.log(trainer.train(trainingSet, trainingOptions)); console.log(myNetwork.activate([0,0,1])); console.log(myNetwork.activate([1,0,0])); console.log(myNetwork.activate([1,1,1])); console.log(myNetwork.activate([1,1,0]));
Если усложнить структуру, добавив три нейрона в скрытом слое... То система для того же отрицательного образца [1,1,0] показывает результат близкий к 0.1, то есть - ожидаемо негативный. Ошибка обучения минимальная. Это, конечно, не обязательно хорошо, но для нашего минимального и исчерпывающего набора данных к ошибке нет вопросов.
(Хватило бы добавить и двух нейронов, но для надёжности - лучше больше.)
var myNetwork = new synaptic.Architect.Perceptron(3, 5, 1) var trainer = new synaptic.Trainer(myNetwork) var trainingSet = [ { input: [0,0,0], output: [0] }, { input: [0,0,1], output: [1] }, { input: [0,1,0], output: [1] }, { input: [0,1,1], output: [0] }, { input: [1,0,0], output: [1] }, { input: [1,0,1], output: [0] }, { input: [1,1,0], output: [0] }, { input: [1,1,1], output: [1] } ] var trainingOptions = { rate: .1, iterations: 20000, error: .005, } console.log(trainer.train(trainingSet, trainingOptions)); console.log(myNetwork.activate([0,0,1])); console.log(myNetwork.activate([1,0,0])); console.log(myNetwork.activate([1,1,1])); console.log(myNetwork.activate([1,1,0]));

Как узнать качество интернета на android?

У меня такой вопрос: Как можно узнать качество интернета на телефоне?
То есть, к примеру, на самом телефоне, сверху, показывается качество связи и там же, если есть 3G интернет - рисуется значок "3G", а можно ли узнать, есть ли 3g на данный момент из приложения?


Ответ

Можно таким методом проверять скорость интернета:
public static boolean isConnectionFast(int type, int subType){ if(type==ConnectivityManager.TYPE_WIFI){ System.out.println("CONNECTED VIA WIFI"); return true; }else if(type==ConnectivityManager.TYPE_MOBILE){ switch(subType){ case TelephonyManager.NETWORK_TYPE_1xRTT: return false; // ~ 50-100 kbps case TelephonyManager.NETWORK_TYPE_CDMA: return false; // ~ 14-64 kbps case TelephonyManager.NETWORK_TYPE_EDGE: return false; // ~ 50-100 kbps case TelephonyManager.NETWORK_TYPE_EVDO_0: return true; // ~ 400-1000 kbps case TelephonyManager.NETWORK_TYPE_EVDO_A: return true; // ~ 600-1400 kbps case TelephonyManager.NETWORK_TYPE_GPRS: return false; // ~ 100 kbps case TelephonyManager.NETWORK_TYPE_HSDPA: return true; // ~ 2-14 Mbps case TelephonyManager.NETWORK_TYPE_HSPA: return true; // ~ 700-1700 kbps case TelephonyManager.NETWORK_TYPE_HSUPA: return true; // ~ 1-23 Mbps case TelephonyManager.NETWORK_TYPE_UMTS: return true; // ~ 400-7000 kbps // NOT AVAILABLE YET IN API LEVEL 7 case Connectivity.NETWORK_TYPE_EHRPD: return true; // ~ 1-2 Mbps case Connectivity.NETWORK_TYPE_EVDO_B: return true; // ~ 5 Mbps case Connectivity.NETWORK_TYPE_HSPAP: return true; // ~ 10-20 Mbps case Connectivity.NETWORK_TYPE_IDEN: return false; // ~25 kbps case Connectivity.NETWORK_TYPE_LTE: return true; // ~ 10+ Mbps // Unknown case TelephonyManager.NETWORK_TYPE_UNKNOWN: return false; default: return false; } }else{ return false; } }
Здесь на вход принимаются параметры int type - значение, возвращаемое методом getType() класса NetworkInfo, и int subType - значение, возвращаемое методом getSubtype() того же класса. Однако следует учесть, что метод getType() объявлен устаревшим в API level 28, и вместо него следует использовать метод NetworkCapabilities.hasTransport(int), принимающий на вход одну из констант TRANSPORT_CELLULAR, TRANSPORT_WIFI, TRANSPORT_BLUETOOTH, TRANSPORT_ETHERNET, TRANSPORT_VPN, TRANSPORT_WIFI_AWARE или TRANSPORT_LOWPAN
C учётом этого обращение к методу isConnectionFast можно сделать примерно таким:
public static boolean isConnectedFast(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Network[] networks = cm.getAllNetworks(); NetworkInfo networkInfo; for (Network mNetwork : networks) { networkInfo = cm.getNetworkInfo(mNetwork); if (networkInfo.getState().equals(NetworkInfo.State.CONNECTED)) { NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(mNetwork); if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { isConnectionFast(NetworkCapabilities.TRANSPORT_WIFI, networkInfo.getSubtype()); } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { isConnectionFast(NetworkCapabilities.TRANSPORT_CELLULAR, networkInfo.getSubtype()); } return true; } } } else { if (cm != null) { //noinspection deprecation NetworkInfo[] info = cm.getAllNetworkInfo(); if (info != null) { for (NetworkInfo networkInfo : info) { if (networkInfo.getState() == NetworkInfo.State.CONNECTED) { return (networkInfo != null && networkInfo.isConnected() && isConnectionFast(networkInfo.getType(), networkInfo.getSubtype())); } } } } } return false; }

Проверить наличие скролла на JS

Подскажите, пожалуйста, как проверить, есть ли на странице скролл или нет?


Ответ

если document.scrollHeight равен document.offsetHeight то скрола нет

div элементы в одну строку

Как расположить div элементы в одну строку? .div1 { display: inline; }

Картинки выстраиваются в ряд. Но как быть, если например, под картиной нужно сделать описание? .div1 { display: inline; }
image1
image2
image3
То элементы div1 снова начинаются с новой строки. как быть?


Ответ

Просто .div1 {display:inline-block;} А вот так можно уменьшить количество кода: .about { display:inline-block; }
.about img { display:block; }


image1

image2

image3

Как реализовать фигурную линию в резиновой верстке

Добрый день!
Подскажите, пожалуйста, как можно такое реализовать при резиновой верстке?

Спасибо.


Ответ

Если честно, то я старался, но увы :D, как у вас на картинке не вышло, ибо займет очень много времени. Да, реализовано кривыми Безье, и сама общая кривая состоит из нескольких частей. Вот картинка для понимания, как вообще происходило строение: Как видно, метод bezierCurveTo() позволяет прорисовать только одну кривую Безье, по этому пришлось сделать несколько кривых (может быть я и не прав). В общем вот отладочный код, который выше на скриншоте: http://pastebin.com/fkRtBvA8 Вот пример: http://jsfiddle.net/Fw5Q9/ И собственно сам код:


Алсо, вам придется попотеть, находя идеальные значения для каждой кривой. Я делал всё на листочке: Но потом понял, что расчеты получились кривые и сохранить пропорции не получится, а переделывать уже не было времени.

Книги по написанию драйверов под Windows

Доброго времени суток. Задался я тут целью написать драйвер под Windows, да и вообще разобраться с этим, поэтому прошу у Вас помощи. Подскажите статьи, книги по написанию драйверов под Windows. Сразу оговорюсь я подхожу к этому серьезно, поэтому готов перелопатить кучу материала, который хоть как то связан с данной темой. Наверное, мне понадобиться знание asm и С++ (С я неплохо знаю). Поэтому прошу так же посоветовать дельные книги по asm.


Ответ

Начните с скачивания WinDDK и изучения сэмплов, идущих в поставке. Их довольно-таки много и они неплохо задокументированы. Это даст хороший толчок для старта, ну а дальше — MSDN, — содержит более чем исчерпывающую документацию по вопросам разработки драйверов. Часть вызовов недокументированна и относится к Private API, но использовать их, тем не менее, приходится часто. В этом случае вам понадобятся .dbg файлы соответствующих библиотек для извлечения информации о смещениях в структурах.

B-TREE и HASH индексы

Привет. Интересует что такое B-TREE, HASH индексы? Как они влияют на ускорение выборки? Каков их синтаксис?


Ответ

B-tree он же balanced tree индекс, это индекс сгруппированный по листьям сбалансированного дерева. Применяется для больших индексов, по сути это индекс индексов. Ну скажем индексы с величиной от 1 до 10 хранятся в одной ветке, от 11 до 20 в другой и т.д., когда приходит запрос на индекс с номером 35, идем к 3-й ветке и находим там 5-й элемент. В общем как то так. Подробнее здесь
Hash индекс применяется для сравнения/построения индексов строчных и/или двоичных данных. Каждому значению индексируемого выражения сопоставляется значение определенной хэш функции отображающей исходное значение на целое число (иногда на строку). Подробнее здесь
B-Tree индекс дает скорость выборки порядка log(N), hash дает линейную. В реальной жизни hash и B-Tree применяются совместно, то есть для вычисления значений B-Tree индекса все равно применяются хэши.

Где можно посмотреть исходный код .NET Framework?

Microsoft выложила исходные коды .NET Framework. Где можно посмотреть исходный код .NET Framework?


Ответ

Зависит от того, что именно вы хотите посмотреть. Думаю, вам будут полезны следующие ссылки:
.NET Framework BCL: http://referencesource.microsoft.com/ .NET Core: https://github.com/Microsoft/dotnet .NET Core Foundational Libraries (CoreFX): https://github.com/dotnet/corefx .NET Compiler Platform (Roslyn): https://github.com/dotnet/roslyn .NET Official Homepage на GitHub: https://github.com/Microsoft/dotnet .NET Micro Framework: https://netmf.codeplex.com/ .NET Foundation: http://www.dotnetfoundation.org/projects

Зачем нужен отдельный объект для блокировки?

Есть код
public class MyClass { private List nums; private object _syncRoot = new object();
public void Add1(int item) { lock(_syncRoot) { nums.Add(item); } }
public void Add2(int item) { lock(nums){ nums.Add(item); } } }
Почему правильно Add1 а не Add2


Ответ

В рамках вашего примера, формально оба варианта равноценны (лишь бы они не применялись одновременно). Вариант с отдельным приватным объектом является более идиоматичным, т. к. формально говоря, нет гарантии что кто-то ещё каким-то необычным образом не лочит List (например, конструктор самого List).
Разница будет в случае, когда nums может «утечь» наружу (например, вы выдаёте его через какой-то метод). В этом случае внешний код может для своих внутренних целей сделать lock(nums), и под ним ожидать окончания операции, выполняющейся в другом потоке. Если эта операция попытается вызвать Add2, вы получите deadlock.
К сожалению, это не такой уж и невероятный вариант развития событий.
Например, часто применяется форма lock(this), в которой объект, по которому ведётся блокировка, очевидно доступен снаружи, и таким образом, любой код может (случайно) организовать deadlock.
Для случая приватного объекта, который нужен лишь для блокировки, не возникает соблазна вынести его наружу. Ну и семантически правильнее, когда каждый объект выполняет лишь одну функцию.
Поэтому пользуйтесь вариантом с отдельным объектом для блокировки. Так вы ограждаете себя от потенциальных ошибок и необходимости думать о том, можете ли вы сделать именно этот объект публичным.

Официальная майкрософтовская документация говорит:
В общем случае избегайте блокировок по публичному типу, или по объектам, не находящихся под полным вашем контролем. Распространённые конструкции наподобие lock (this), lock (typeof (MyType)), или lock ("myLock") нарушают этот принцип: lock (this) может привести к проблемам, если этот экземпляр может быть доступен внешнему коду. lock (typeof (MyType)) может привести к проблемам, если тип MyType объявлен как public lock("myLock") может привести к проблемам, потому что любой код в пределах вашего процесса, использующий ту же строку, получит ту же блокировку. Лучше всего объявите приватный объект специально для блокировки по нему. Если вам нужно защитить данные, общие для всех объектов данного класса, используйте приватный статический объект.

Как работает Amazon EC2, как им воспользоваться?

Я мало пока чего еще понимаю в сфере облачных вычислений, поэтому хотел бы задать наверное глупый вопрос.
Вот у меня есть консольная программа на C++. Она распознает детали на изображении и кое-что с ними делает (обрабатывает). Не суть. Проблема в том, что этих изображений много и мощностей моего ноутбука для выполнения данного алгоритма мне не хватает.
Узнал, что существует такой сервис как Amazon EC2. Честно говоря, не пойму пока что как он в целом работает. Объясните, пожалуйста. Могу ли я послать ему, к примеру, вот такую задачу и получить ответ: отправляем переменную со значением true. Там проверяется, если true - то вернуть "Hello world"?


Ответ

фактически, вы запускаете на серверах amazon-а виртуальные машины.
причём запуск может осуществляться по требованию — на время вычислений.
управлять всем этим «хозяйством» можно с помощью соответствующего api. осуществлять запросы можно разными способами
обновление про «облачное» хранилище
вероятно, для вашей задачи потребуется и «облачное» хранилище, которое также предоставляется amazon-ом по протоколу s3
к нему тоже есть api, которое реализовано в разных клиентах, например, s3tools или euca2ools
пример использования такого клиента s3cmd из s3tools в операционной системе gnu/linux можно посмотреть, например, здесь (правда, там не на amazon-овские сервера осуществляется копирование, но по тому же самому протоколу s3).

по поводу «вернуть "hello world!"»: вот простой пример одновременного выполнения команды на нескольких машинах с операционной системой gnu/linux
здесь используется установленная на моей машине программа dsh и три машины с условными именами host1, host2, host3, уже настроенными на беспарольный доступ по протоколу ssh
$ cat ~/.dsh/machines.conf host1 host2 host3
$ export var=true $ dsh -a -c -- 'echo -n "$(hostname): "; if [ "'$var'" = "true" ]; then echo "hello world!"; else echo "not"; fi' host2: hello world! host1: hello world! host3: hello world!
$ export var=bum $ dsh -a -c -- 'echo -n "$(hostname): "; if [ "'$var'" = "true" ]; then echo "hello world!"; else echo "not"; fi' host2: not host1: not host3: not
dsh — это всего лишь одна из множества аналогичных по принципу действия программ.

Не работают регулярные выражения в MySQL

Здравствуйте. В БД установлена кодировка utf8. Когда я пишу запрос, используя регулярные выражения, они не работают.
Обычные запросы работают: SELECT * FROM verb.tableA WHERE rw LIKE 'небо';
Но когда пишу SELECT * FROM verb.tableA WHERE rw RLIKE '^неб[оа]$';, то ничего не выводится. Почему так происходит?


Ответ

Обновлено
Как правильно меня поправили в комментариях, выражение у вас правильное, а вот MySql не правильно его обрабатывает. В вашем случае можно такой вариант использовать:
'^неб(о|а)$'
Все дело в особенности обработки выражений в MySql. Обработка идет побайтово, и поэтому ваш вариант не работает.
Цитата из документации
Warning The REGEXP and RLIKE operators work in byte-wise fashion, so they are not multibyte safe and may produce unexpected results with multibyte character sets. In addition, these operators compare characters by their byte values and accented characters may not compare as equal even if a given collation treats them as equal.

Назначение RxJava, RxAndroid

Для чего нужны библиотеки RxJava и RxAndroid? Где их применяют?


Ответ

RxJava - либа для обработки событий как последовательностей. Надстройка над паттерном "наблюдатель", умеет по-всякому преобразовывать последовательности событий и так далее. Либу можно заюзать где угодно, но особо полезна когда нужно делать всякие сложные преобразования над событиями, типа смешать, сгруппировать, фильтровать, ограничивать и т.п.
RxAndroid - либа на базе RxJava, содержит всякие штуки для андроида типа шедулера для гуевого потока.
Всякая логика типа "получать символы в текстбоксах от юзера, отправлять запросы к серверу в другом потоке, но не слишком часто, с какой-то задержкой, обновлять интерфейс" пишутся на этих либах в пару строк, без гемороя с кучей служебного кода.

Почему при использовании text-transform: uppercase происходит некорректное преобразование в английскую букву I?

text-transform: uppercase для азербайджанского языка неправильно работает. Азербайджанская буква i должна смениться на İ (с точкой наверху), а она увеличивается на английскую I.
Как это исправить?


Ответ

Поведение text-transform зависит от языка текста. Что бы трансформация проходила по правилам азербайджанского языка, у корневого элемента(html/body), либо у отдельного блока должен быть обязательно указан правильный язык. Делается это при помощи атрибута lang:
.uppercase { text-transform: uppercase; }

Азербайджанский язык(lang='az'):

fincan, isti, şəkil

Без указания языка текста, или с неправильным языком:

fincan, isti, şəkil


Слов из азербайджанского я не знаю, поэтому вставил в пример первые найденные в поисковике.
Также это касается Немецкого, Нидерландского, Греческого, Турецкого, Татарского, Башкирского, и Шотландского(Кельтского) языка - там тоже используется латница с нестандартными правилам преобразований.

Неправильный конструктор копирования

В следующем фрагменте кода:
#include #include
using std::cout;
class Point { int x;
public: Point(int x) { this->x = x; }
Point(Point p) { x = p.x; }
int getX() { return x; } };
int main(int argc, char* argv[]) {
Point p1(10); Point p2 = p1;
printf("%d", p2.getX()); return 0; }
Компилятор выдает такую ошибку:
invalid constructor; you probably meant 'Point (const Point&)
Почему так происходит?


Ответ

В C++ конструктор копирования не может принимать копию объекта этого же класса, а вот по ссылке может (т.е. в вашем случае подойдет Point(Point& p), либо Point(const Point& p)).

Представим, что такое допустимо
Получается, что таким образом вы переопределяете конструктор копирования по умолчанию, тогда у компилятора не остается выбора (на самом деле просто запрещен такой вызов, но так звучит убедительнее) кроме как попытаться снова вызвать именно ваш конструктор копирования для передачи параметра в ваш же конструктор копирования и так далее (бесконечная рекурсия получается).

Поиск всех процедур и функций по названию конкретного столбца

Как можно вывести название всех процедур и функций, в которых используется конкретный столбец, точнее имя столбца? С поиском в таблицах и представлениях я разобрался, а с процедурами понимаю не так все просто.
Я не знаю как вывести (возможно через запрос) все названия процедур которые находятся в моей базе, по конкретному столбцу. То есть, все процедуры в которых мы или используем <Название столбца>для решения процедуры или используем для вывода в select. Решить проблему надеюсь с помощью запроса T-SQL, потому что вывод всех процедур из базы данных реализовать можно,думаю значить и можно от фильтровать, только не знаю как. В результате, в конце концов мне нужны названия процедур в которых встречается <Название столбца>


Ответ

Не знаю, возможно ли получить точный список процедур, где используется конкретный столбец конкретной таблицы. Для того, чтобы получить приблизительный список, можно воспользоваться следующим запросом:
SELECT SCHEMA_NAME(objects.schema_id), OBJECT_NAME(objects.object_id) FROM sys.sql_expression_dependencies JOIN sys.objects ON objects.object_id = sql_expression_dependencies.referencing_id AND objects.type IN ('P') WHERE sql_expression_dependencies.referenced_id = OBJECT_ID('MyTableName') AND OBJECT_DEFINITION(sql_expression_dependencies.referencing_id) LIKE '%MyColumnName%'
Соответственно, MyTableName - это имя таблицы, MyColumnName - это имя столбца этой таблицей.

Service не работает когда экран телефона выключен

Как сделать android.app.Service так, чтобы даже при выключенном экране телефона он работал? Вот его исходный код:
public class S extends Service {
@Override public void onStart(Intent i1, int i2) { new Timer().schedule(new TimerTask() { @Override public void run() { //..........// return; } }, 60000, 60000); }
@Override public IBinder onBind(Intent i1) { return null; }
}
Запускаю его так:
public class Main extends AppCompatActivity {
Intent i1;
@Override protected void onCreate(Bundle i1) { super.onCreate(i1); setContentView(R.layout.layout_main); this.i1 = new Intent(this, S.class); startService(this.i1); return; }
@Override protected void onDestroy() { stopService(this.i1); super.onDestroy(); return; }
}
В теории сказано: «В отличие от Activity службы в Android работают как фоновые процессы... Служба может продолжать работать до тех пор, пока кто-нибудь не остановит её или пока она не остановит себя сама.». Но как только я отключаю экран телефона, служба перестаёт работать. Она возобновляет свою работу только после того, как я разблокирую телефон. Как исправить эту ошибку?


Ответ

Для того, чтобы Service работал вне зависимости от экрана, необходимо его запускать не из под Activity, а, к примеру, из BroadcastReceiver. По-крайней мере, моя проблема заключалась в этом.

Как сделать так, чтобы экземпляр конструктора возвращал примитивный тип?

Доброго времени суток.
Есть конструктор. Нужно, чтобы экземпляр от него возвращал инкремент. Как это можно и лучше реализовать?
'use strict'
function Count() {
// Здесь правильный код
}
var newCount = new Count();
alert(newCount); // 1
alert(newCount); // 2
alert(newCount + newCount); // 7


Ответ

Конструктор не может возвращать примитивные типы. Поэтому формально ответ на вопрос: никак.
Но можно воспользоваться возможностью определения для объектов функций toString и valueOf, которые вызываются автоматически при приведениях к различным типам, например:
function Count() { var val = 0; this.valueOf = this.toString = function() { return ++val; }; } var newCount = new Count(); document.write(newCount); // 1 document.write(newCount); // 2 document.write(newCount + newCount); // 7

Как стандартными способами c++11 записать файл в utf-8

А именно использую ofstream и в самом файле записывается русскими буками хорошо, а вот с названием документа проблемы. Что только не пробовал, название файла получается что-то вроде такого �.txt (неверная кодировка)

Может я не совсем правильно задал вопрос, мне нужно чтобы программа сохраняла txt файл с названиями аа.txt аб.txt ав.txt - ... - яя.txt
Кратко расскажу суть программы: Есть словарь слов, расположенный в алфавитном порядке, программа должна разбить этот словарь по 33*33 документам (Минус 3*32, нет слов начинающихся с ь,ы,ъ). Документ аб.txt будет иметь все слова начинающиеся с аб...
Запись в файлы корректная, единственное, что названия файлов неправильные
Вот моя функция main()
int main() { if (rfile.is_open()) { while (getline(rfile, line)) { string first, second; try { first = line[0]; second = line[1]; }catch (...) { continue; } if (first == " " || first == "." || first == "-" || first == "|" || first == "," || second == " " || second == "|" || second == "-" || second == "." || second == ",") continue; string wfilename = first + second + ".txt"; ofstream wfile; wfile.open(wdirectory + wfilename, ios_base::app); if (wfile.is_open()) wfile << line; wfile.close(); } rfile.close(); } else cout << "Unable to open file" << endl;
return 0; }
Система Linux mint x64

Решение найдено! Я брал первые две буквы строки и использовал их для составления названия. Чтобы все корректно работало, нужно было конвертировать исходный файл в utf-8. На linux эта команда выглядит как iconv -f windows-1251 < /home/user/filename.txt > /home/user/newEncodedFilename.txt Знаки < и > обязательны. Далее уже использовать новый файл. Спасибо sercxjo


Ответ

Русские буквы в utf-8 обычно занимают 2 байта. Выбирая первые два байта из строки вы скорее всего получите только одну русскую букву, но возможно если первый из них другой символ или длина utf-8-представления символа более 2 байт, некорректно прерывается последовательность utf-8 кодировки. Для первого байта последовательности (x&192)==192, для остальных (x&192)==128. По этим признакам можно вырезать первую и вторую буквы (точнее в первом байте указывается длина последовательности в единичной системе исчисления, но будем надеяться на правильность исходных данных). Таким образом, найти длину символа поможет функция:
int wlen(const string &x, int start) { if(x[start]==0) return 0; if((x[start]&192)!=192) return 1; int i=1; while((x[start+i]&192)==128) i++; return i; }
Теперь остаётся заменить получение первого и второго символов строки:
first = line.substr(0, wlen(line, 0)); second = line.substr(first.size(), wlen(line, first.size()));
Ну и далее можно добавить анализ, что first.size()==0 || second.size()==0
Из беседы в чате выяснилось, что исходный файл в кодировке windows-1251. Чтобы привести его в кодировку принятую в Linux Mint можно использовать команду iconv
iconv -f windows-1251 < исходный_файл > новый_файл
Если требуется включить перекодировку в саму программу, можно использовать libiconv пример

Подключение к чужому репозиторию GitHub

Не могу внести изменения в репозиторий гитa. Сам репозиторий успешно клонирован. Но после внесения комита и команды git push появляется следующие remote:
Permission to %Полное имя репозитория% denied to %Мой логин на GitHub%.
SSH ключ был успешно создан и также успешно подключен к моему аккаунта GitHub. Такая ошибка возникает как при консольном "пуше", так и при синхронизации в десктопном приложении GiHub. При это владелец репозитория спокойно вносит различные правки.
Как решается беда?
Если дело в отсутствии прав доступа, то как их выдать (со стороны владельца репозитория)


Ответ

Вы пришли в Git с привычками из SVN.
Git — это распределённая система управления версиями. Это означает, что по умолчанию каждый — ПЖ в своём репозитории, но пацак — в чужом. Когда вы клонировали репозиторий, то у вас на компьютере возникла полноценная копия репозитория, в которой вы можете создавать ветки, в которую вы можете вытягивать изменения из чужих репозиториев и так далее. Но вот репозиторий у владельца свой, отдельный, и своими грязными пацакскими ручонками туда лезть не надо. Если владелец решит выдать вам жёлтые штаны и права на доступ к своему репозиторию — тогда уже можете творить что хотите. Но пока КЦ мало.
В целом, картина такая: у владельца есть репозиторий на гитхабе и, скорее всего, как минимум один локальный репозиторий на своём компьютере. С точки зрения Git вам достаточно клонировать его удалённый репозиторий, сделать изменения, пушнуть их свой репозиторий, а потом этими изменениями поделиться с владельцем удобным вам способом. Например, если вы сделаете свой репозиторий публично доступным, то владелец может сделать пулл из вашего репозитория и слить изменения. Или вы можете отправить изменения по почте.
В рамках GitHub всё несколько удобнее, со всякими пулл-реквестами в гуе и прочими фенечками, но чтобы всё работало, нужно соблюдать процедуру. Вы форкаете чужой репозиторий на свой аккаунт, клонируете себе на компьютер, создаёте ветку, делаете изменения, пушаете в локальный репозиторий, пушаете локальную ветку в свой репозиторий на гитхабе, через интерфейс гитхаба создаёте пулл-реквест, владелец видит ваш пулл-реквест, пуляет ваши изменения, а дальше это уже его забота.
Важные моменты:
Вы всегда работаете со своими репозиториями, владельцу вы только сообщаете, что у вас есть что-то полезное. Всегда создавайте отдельные ветки под каждый отдельный набор изменений. Пулл-реквесты работают через ветки. Если владелец попросит что-то исправить, то вы можете добавить изменения в ту же ветку в рамках одного пулл-реквеста. Если вы будете активно работать над проектом, и владелец доверит вам самостоятельно вносить изменения в свой репозиторий, то пулл-реквесты станут ненужными. Но если вы не знаете Git, то на это не рассчитывайте. Мелкие тривиальные изменения можно делать в рамках своего удалённого репозитория на гитхабе без создания локального репозитория. Гитхаб позволяет "отредактировать" файл даже в чужом репозитории, но при этом вы всё равно получите форк с веткой на своём аккаунте.

Перегрузка операторов

Как определить возвращаемое значение при перегрузке операторов ? В каком случае следует вернуть ссылку на объект, а в каком его побитовую копию ?
update:
#include
using namespace std;
class SomeClass { int value; public: SomeClass(int value) { this->value = value; }
SomeClass& operator=(const SomeClass &rhs) { value = rhs.value;
return *this; }
SomeClass operator+(const SomeClass &rhs) { value += rhs.value;
return *this; } };
int main(int argc, char *argv[]) { SomeClass a(1), b(2);
a = a + b;
return 0; }


Ответ

Операторы бывают двух типов: операторы c побочными эффектами, которые модифицируют один из своих операндов (инкремент/декремент, простое присваивание, составные присваивания типа += и т.п.), и операторы без побочных эффектов, которые не модифицируют своих операндов, а возвращают результат в новом объекте.
Вот тут-то обычно и проходит "водораздел" по типу возвращаемого значения.
Первые традиционно возвращают ссылку на свой операнд, а вторые - самостоятельный временный объект. (О какой "побитовой копии" вы говорите - не ясно. Резльтат оператора обычно содержит новое значение, поэтому не ясно, как он может быть "копией" чего-то.)
В вашем примере оператор присвивания реализован как раз правильно, а вот бинарный оператор сложения реализован до ужаса криво.
Ваш бинарный оператор сложения модифицирует свой левый операнд. Где это видано? Это странное и неожиданное поведение для бинарного оператора сложения.
Правильная реализация могла бы выглядеть так
SomeClass operator +(const SomeClass &rhs) const { int new_value = value + rhs.value; return new_value; // <- Используется неявная конверсия `int` к `SomeClass` }
Оба операнда сохраняют свои исходные значения, и возврат результата, разумеется, делается по значению.
А вот если бы вы хотели перегрузить оператор составного присваивания +=, то это бы выглядело так
SomeClass &operator +=(const SomeClass &rhs) { value += rhs.value; return *this; }
т.е. именно так, как вы написали, но уже с возвратом по ссылке.
Отдельно стоит добавить, что, во-первых, такие "симметричные" по отношению к своим аргументам операторы, как бинарные +, -, * и т.д. рекомендуется перегружать самостоятельной функцией, а не функцией-членом (например, friend-функцией). Во-вторых, если вы перегружаете и бинарные операторы, и соответствующие составные присваивания, то распространенной идиомой является реализация первых через вторые
class SomeClass {
SomeClass& operator +=(const SomeClass &rhs) { value += rhs.value; return *this; }
friend SomeClass operator +(SomeClass lhs, const SomeClass &rhs) { // Обратите внимание, что `lhs` передается по значению lhs += rhs; return lhs; } ... };

"Симметричные" операторы лучше задавать самостоятельной функцией, а не функцией-членом для того, чтобы такие операторы вели себя "симметрично" по отношению к неявным приведениям типов аргументов.
Например, если задать бинарный оператор + так, как показано в моем первом примере, т.е. функцией-членом, то будет наблюдаться следующая неприятная асимметрия
SomeClass a(1), b(2);
a = b + 1; // <- OK a = 1 + b; // <- Ошибка: нет такого оператора `+`
т.е. такой оператор не будет рассматриваться в качестве кандидата в выражении 1 + b. Функции-члены берутся на рассмотрение только из левого операнда. А в случае 1 + b левым операндом является 1, у которой никаких функций-членов нет вообще.
Но как только вы сделаете свой бинарный + самостоятельной функцией, он будет симметричным образом применим в обоих вариантах.

Как останавливать функцию на js?

Создал простой Таймер
function timer() { setInterval(function timer() { var label = document.getElementById('label'); label.innerHTML = parseInt(label.innerHTML) + 1; }, 1000); }
Так вот как можно останавливать его внутри другой функции? Без использования Jquery!


Ответ

var i = 0; var timerId = 0; function timer() { timerId = setInterval(function () { //Здесь код в цикле console.log(i++); }, 1000); } function stopTimer(){ clearInterval(timerId); }

setInterval возвращает id, который нужно передать clearInterval(id), для того чтоб остановилось, см. пример

Угловой градиент как?


как подобное правильно реализовать? Делал через картинки (но это не правильно), сама суть, чтобы поле для заливки градиента было динамичным, то есть - захотел выставил 93%, захотел 2% и тд.


Ответ

Угловой градиент можно создать с помощью conic-gradient
.pie { background: conic-gradient(aqua, lime); border-radius: 50% }
Примеры других градиентов - здесь. И там же - инструкция по подключению на сайт. Дело в том, что conic-gradient на данный момент лишь принят W3C как часть CSS4 Images (ссылка). Браузеры его пока не поддерживают. Но использовать его можно уже сейчас с помощью полифила
С динамичным формированием диаграммы - сложнее. В CSS популярное решение - использовать для диаграммы две заготовленные половинки окружности:

И, если нужно больше 50% заполненности - используются обе половинки. Если меньше 50% - одна. Решается это установкой дополнительного класса (например, .big, для .pie).
Скорее всего, нужен будет небольшой js-скрипт, который будет смотреть, сколько %-заполненности установлено у .pie, и будет ставить, или не ставить, дополнительный класс.

Лучший способ сказать о ошибке в Си

Пишу небольшую библиотеку, с функциями, которыми кто-то будет пользоваться. В функциях случаются ошибки, о которых нужно каким-то образом сообщить. Казалось бы — банальная вещь, но везде сделано по-разному. Мне интересны преимущества каждого способа, их для меня пока три:
Возвращать true или false. Пользователь библиотеки сам будет проверять возвращаемое значение и в зависимости от него выводить сообщение об ошибке. Самостоятельно в функциях библиотеки сообщать в подробностях о всех предупреждениях или ошибках, exit'ом убивать приложение, ничего не возвращая. Возвращать true или false, но при этом ещё и записывать ошибку в специальный буфер. Пользователь библиотеки может узнать об ошибке, вызвав функцию GetError(). Так сделано в SDL
По-моему, лучше всего использовать второй способ, но зачем тогда SDL усложняет всё своими GetError/SetError? Зачем тот же EGL возвращает только код ошибки? Прошу сказать о плюсах/минусах того или иного способа, они ведь наверняка есть.


Ответ

При написании библиотечного кода надо иметь в виду, что пользоваться этим кодом могут совершенно разные приложения. Поэтому вывод куда-либо явного сообщения об ошибке может просто не сработать, т.к. этого "куда-либо" может вовсе не существовать в текущем окружении (об этом уже упомянул @AntonShchyrov в своем ответе). Более того, язык сообщения может быть вовсе не подходящим для пользователя.
Наиболее подходящим вариантом будет предоставить дополнительную функцию или переменную, откуда можно получить код/текст последней ошибки. Существующие варианты такого подхода это errno, GetLastError и т.п. В этом случае, пользователь библиотеки может сам решить куда ему следует (и следует ли вообще) выводить сообщение об ошибке.
Отсюда же вытекает и решение о недопустимости вызова exit из библиотечного кода. По крайней мере, если нет соответствующей функции в библиотеке, которая меняет это поведение (по умолчанию никаких активных exit быть не должно). Пользователю может быть вообще хочется наплевать на обработку ошибок и просто работать дальше, а библиотека рушит ему всё приложение из N потоков на корню.
Возвращать из каждой функции признак успешности её выполнения через return может быть не совсем удобно, т.к. в первую очередь функция должна возвращать то, на что она заточена, а не признак ошибки или код возврата. Для примера, представьте, как будет выглядеть функция типа strlen в таком случае и насколько удобно будет ей пользоваться при этом.
В любом случае, способы оповещения пользователя библиотеки об ошибочных ситуациях должны быть чётко прописаны в руководстве.

Множественное наследование и VC++

В ходе дискуссии пришли к такой программе:
#include using namespace std;
class A { protected: int var; public: A(int x) { var = x; // Это обращение к A::var } };
class B: public A { protected: int var; public: B():A(2) { var = 4; // Обращение к B::var } };
class C: public A { protected: int var; public: C():A(3) { var = 6; // Обращение к C::var } };
class D: public B, public C { protected: int var; public:
void method() { var = B::A::var; // Должен выдать 2 cout << var << endl;
var = C::A::var; // Должен выдать 3 cout << var << endl;
var = B::var; // Должен выдать 4 cout << var << endl;
var = C::var; // Должен выдать 6 cout << var << endl; } };
int main() { D obj; obj.method(); }
Программа отлично компилируется и выводит то, что и ожидалось - в Visual C++ 2015. Попытка скомпилировать с помощью GCC на ideone.com дает массу ошибок:
prog.cpp: In member function 'void D::method()': prog.cpp:46:21: error: 'A' is an ambiguous base of 'D' var = B::A::var; // Должен выдать 2 ^ prog.cpp:49:21: error: 'A' is an ambiguous base of 'D' var = C::A::var; // Должен выдать 3 ^
Вопрос к знатокам стандарта - кто тут неправ, а кто прав? Если неправ VC++, то в чем, почему и как надо поступать правильно?
Update 22.10.2016
Пожалуй, наиболее переносимо будет не полагаться на name lookup, а воспользоваться преобразованиями в духе
var = static_cast(static_cast(this))->var; var = ((A*)(C*)this)->var;
Но при этом нужно делать var в A public'ом. (Опять же не понимаю, почему и где на это ссылка в стандарте...) Полный код тут - http://ideone.com/wt9yrz


Ответ

Как правильно указал @Ant, студия здесь неправа и всё дело в том, что подобные обращения A::B::C::D::E::F являются именно обращениями к вложенным(nested) сущностям, т.е. B должен быть сущностью вложенной в A, С в B и так далее. Это можно видеть в не нормативной ссылке в стандарте:
[basic.lookup.qual]p2 [Note: Multiply qualified names, such as N1::N2::N3::n, can be used to refer to members of nested classes (9.7) or members of nested namespaces. — end note]
Т.е. мы можем ссылаться на несколько уровней, но эти ссылки должны идти по нисходящей, никаких восходящих, либо же смешанных уровней.
Тогда почему это вообще компилируется?(оно компилируется пока не встречает неоднозначность, уберём неоднозначность и всё заработает). Потому что есть следующее правило по поиску скрытых имён:
[class.qual]p3 A class member name hidden by a name in a nested declarative region or by the name of a derived class member can still be found if qualified by the name of its class followed by the :: operator.
И тут получается, что C::A::var должно интерпретироваться как A::var, где C:: является избыточным квалификатором, который не несёт никакой смысловой нагрузки. Никакой другой интерпретации тут быть не может, т.к. C не содержит внутреннего класса с именем A.
Суть ошибки, кстати, хорошо видна с Resharper: он сразу показывается, что квалификаторы C:: и B:: избыточны.

Что касается второй части вопроса(обновления): не работает это по простой причине: классы наследники имеют доступ к данным предка только через this, у них нет доступа к данным произвольных объектов этих классов. Это описано в [class.access.base]p5, а конкретно, случай из вопроса, в (5.3):
m as a member of N is protected, and R occurs in a member or friend of class N, or in a member or friend of a class P derived from N, where m as a member of P is public, private, or protected