Страницы

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

вторник, 26 ноября 2019 г.

Как сделать, чтобы (x==1 && x==2 && x==3 && x==4) возвращало true?


Сегодня задали весёлый вопрос по C++ - как добиться, чтобы 

(x==1 && x==2 && x==3 && x==4) 


имело значение true?
    


Ответы

Ответ 1



Навскидку - сразу два варианта: переопределить оператор == или оператор приведения. Оператор && сам по себе - вряд ли, только вкупе с каким-то из перечисленных... Вот, примерно так - https://ideone.com/XM7O1s: struct Cast { int i; operator int() { return i++; } Cast(int i):i(i){} }; struct Equl { bool operator==(int) const { return true; } }; Можно, конечно, извратиться - типа сравнение с конкретно 1,2,3 и 4 дает true, н это уже сути дела не меняет...

Ответ 2



Примерно так class X { public: bool operator==(int other) { return true; } } x = X();

Ответ 3



В рамках возможностей, предоставляемых С++, вопрос в таких условиях тривиален и неинтересен. Что уж там мелочиться template bool operator ==(const L &, const R &) { return true; } Всем, всегда и везде сплошное true... (Не всем, не всегда и не везде, конечно, но идея понятна.) А далее хоть struct {} x; хоть enum { x }; Вариант даже для С может выглядеть как static int i; #define x (++i)

Ответ 4



Еще вариант с перегрузкой operator== для типа, который не может сравниваться с int: #include #include template bool operator==(T&&, int) { return true; } int main() { std::string x; std::cout << (x==1 && x==2 && x==3 && x==4) ; }

Ответ 5



Вот такой вариант работает: int x = 0; #include #define x (++x) using namespace std; int main() { cout<<(x==1&&x==2&&x==3&&x==4)<

Ответ 6



Препроцессор: #define x true || 0 Пример

Ответ 7



Сегодня задал эту задачу своему другу, он, методом научного тыка, нашёл ещё одн странное решение: #include #define x 1,2,3,4 int main() { if (x == 1 && x == 2 && x == 3 && x == 4) puts("cheater!"); }

Для чего нужны классы?


Не понимаю, для чего нужны классы в PHP?

Допустим, есть function.php, в нём много много функций, выполняющих разные действия
функции частично содержат общие переменные и в некоторых случаях части их кодов совпадают.

Если все эти функции превратить в методы и засунуть в один класс, что изменится в лучшую сторону или по другому - для чего нужны классы?
    


Ответы

Ответ 1



Пример работы с БД: $con = db_connect($data); $query = db_query($con, $data); $fetch = db_fetch($query); Опять же, нужна глобальная переменная $con, проверка результата каждый раз и т.п. Или вот класс: /** * @author * * @todo */ class Db { private $con, $query, $fetch; /** * */ function __construct($data) { return $this->con = db_connect($data); } /** * */ function query($data) { if($this->con) { $this->query = db_query($this->con, $data); return $this; } else { throw new Exception('no connection to db'); } } /** * */ function fetch() { if($this->con) { return $this->fetch = db_fetch($this->query); } else { throw new Exception('no connection to db'); } } /** * */ function __destruct() { db_close($this->con); } /** * */ public static function create($data) { return new Db($data); } } $Db = Db::create('host:localhost;login:1234...'); $fetch = $Db->query('SELECT * FROM db')->fetch(); Простенько запускаем, делаем запрос и выводим результат. Красиво, удобно.

Ответ 2



(Резюме: классы нужны, чтобы абстрагироваться от сложности задания.) Вы серьёзно не знаете, для чего нужны классы? Хм. Ну ладно. Давайте подумаем: что такое программирование? Программирование -- это производство Я имею в виду не учебные задания в стиле «введите строку и посчитайте в ней количеств пробелов». Я имею в виду реально большие проекты. В них не так уж часто встречаютс особо умные куски кода, зато функциональности много, она не обязательно логично устроена (особенно часто такое бывает, если вы конструируете интерфейс пользователя), и, что немаловажно, проект поддерживают не гении, вроде всех на этом сайте, а обычные программисты. Это значит, что большая часть времени жизни кода уйдёт на его поддержку, а не начальную разработку. Гении (и начинающие программисты тоже, как ни странно) не любят доводить что-то д совершенства. Они напишут прототип в виде одной офигенно сложной функции, и voila! задание выполнено. В функции есть тысяча хитростей и зависимостей, которые гению просто держать в голове. Но завтра гений заболеет, уйдёт в запой или вообще уволится — и внезапно код должны поддерживать самые обыкновенные обыкновенные программисты, из мяса и костей. А обыкновенному программисту нелегко работать с длинной сложной функцией, при одно взгляде на неё начинает болеть голова. Он не может держать в голове сразу миллионы поняти и зависимостей! И тут внезапно на помощь приходят классы. Классы позволяют уменьшит сложность. Когда программист разрабатывает класс, он, конечно, думает обо всём класс и держит в голове сразу весь класс. Но когда он разрабатывает другие классы, он думае больше не в терминах «я вызову функцию X, и она установит переменную Y», а в термина классов: «я беру возраст пользователя», «я рисую эту картинку». Теперь голова болит гораздо меньше: вместо того, чтобы думать о всех функциях в проекте одновременно, программист думает только о немногих публичных функциях немногих публичных интерфейсов. Таким образом, в его коде меньше зависимостей: он не должен думать (вернее должен не думать!) о конкретной реализации возраста пользователя, или там отрисовки картинки, он может про это забыть. Его код становится проще, этот код легче понимать, тестировать и поддерживать. Кроме того, он больше не должен думать что-то типа «я добавляю пользователя в списо модераторов, для этого мне надо обновить вот этот массив, вот ту хэш-таблицу, поставит флаг для обновления базы данных и не забыть ещё увеличить счётчик версий». Он прост говорит: «таблица модераторов, добавь-ка в себя вот этого пользователя!» То есть тепер можно думать не в терминах внутренних структур данных, а в терминах семантики: программист пишет прямо то, что он хочет выразить. Несмотря на то, что в языке не было раньше конструкций для выражения его мыслей. Мы видим, что программист на самом деле расширяет язык под свою предметную область, и может легко и адекватно выражать своё намерение. Такой код не только легче писать, но и легче поддерживать. При этом эффективность кода может падать по сравнению кодом, учитывающим особенност реализации других классов, но мы сознательно идём на эту жертву: наша цель — чтобы код стал проще, яснее, чтобы он говорил сам за себя! Обратите внимание, что этот подход — развитие процедурного подхода: там мы складывал код в процедуры, чтобы абстрагироваться от кода одной процедуры во время разработк другой (и код, который опирается на конкретику реализации, обычно считается плохим, потому что он не уменьшает количество абстракций, которые нужно держать в голове). Так и при объектном-ориентированном подходе уменьшается, в свою очередь, количество функций, которые надо держать в голове. Кроме того, ООП даёт другие плюшки, в виде наследования и полиморфизма, которые однако, кажутся мне концептуально менее важными. Хотя и очень приятными в использовании. Таким образом, для маленького проекта, для которого вы можете держать все функци в голове, можно отказаться от использования классов. Но для достаточного большого, серьёзного проекта без помощи классов для уменьшения сложности не обойтись. PS: Для разработчиков на C: в самом деле, можно уменьшать сложность и по-другому например, не выносить нерелевантный код в заголовочные файлы. Классы в языках, которые их поддерживают, предоставляют явное средство управления сложностью, в отличие от неявного, осуществляемого в C.

Ответ 3



ООП - вообще, а не только в PHP - это всего лишь навсего другое представление процедурного программирования. Компилятор (интерпретатор) при парсинге классов заменяет все на обычные функции. Было: class ClassA { public $item; public function MethodA() {}; } Стало: ClassA = object { $item; } function MethodA(ClassA $object) {}; И все вызовы, соответственно, заменяются: ClassA->methodA() => methodA(ClassA); Т.е. в интерпретируемых языках обратное преобразование (из класса в функции) постоянно занимает некоторое время (в компилируемых занимает только на этапе компиляции). Зачем тогда же вводят это ООП, в том числе и в PHP? 1) Уже было сказано - достаточно в одно месте сделать необходимые вычисления (проверки тригеры и т.д.) - и не надо будет об этом заботиться дальше. Да и менять потом придется в одном месте - в классе, а не искать и исправлять по всем файлам 2) Сопровождать этот код (с использованием ООП) в больших проектах - намного проще, чем искать по всем функциям по всем файлам. Можно, конечно, разделить функции по смыслу и запихать их в соответствующие файлики но чем тогда этот подход будет отличаться от ООП? Отличаться будет, конечно, т.к. у ООП еще куча своих плюшек, но в этом плане - аналогия почти полная 3) Именование - в различных классах имена переменных могут пересекаться как угодно. Используя глобальные переменные вы этого не добьетесь. 4) Проектируя какой-нибудь объект вы ожидаете от него определенного поведения. Есл использовать обычные функции, то где будет уверенность, что нужную сейчас глобальную переменную вы не поменяете где-нибудь еще в какой-нибудь левой функции без предупреждения? 5) и 6) и 7) и т.д. - все в книгах расписано, всего здесь не напишешь. Главное - почти все, что реализуется с использованием ООП можно реализовать использу функции. И при небольшом количестве строк кода функции будут заметно выигрывать у ООП, а не правильно используя ООП можно вообще завести проект в дебри. Ведь вы же в магазин не на самолете летаете? И в отпуск не пешком ходите? Так и здесь - до тех пор пока что-то замечательно справляется с поставленной задачей то зачем это что-то менять? Но это именно "до тех пор пока что-то замечательно справляется с поставленной задачей".

Ответ 4



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

Ответ 5



Суть не сколько в классах, а конкретно в ООП, и потребности его использования! Допустим есть у меня файл function.php Дело в том что он у всех есть, не зависимо от того используется ли ООП в проект или нет, радовой функционал не выбросишь, как не крути. Ну и конечно как высказались выше "группировка функций по логическим задачам". главное, это очень удобно.

Ответ 6



Если вы пишете простую программу, ООП не нужен. I. Простую программу на пару сотен строчек можно никак не организовывать, и вы н почувствуете необходимости в ООП. Это одна из проблем при обучении ООП: в нём реальн возникает необходимость, только если вы работаете со сложной системой, а примеры почему-то всегда используют бестолковые, на пару строчек. Разумеется, это вызывает неприятие. Для простого смертного прикладного программиста (ака любителя императивного кода обычно самым простым кодом является процедурное программирование. Если вам для ваших задач хватает его — пользуйтесь им. II. Во многих ответах выше описывают не объектно-ориентированное программирование а "недо-объектное" программирование, когда функции просто раскидываются по классам В итоге, вместо $foo = foo_create(); foo_call_baz($foo, 123, $baz) вы пишете $foo = new Foo(); $foo->call_baz(123, $baz). Разница исключительно на уровне синтаксиса: ставить первый аргумент функции в начале или посередине, использовать для работы с объектами функции с префиксом или писать "присоединять" название функции к переменной. Подобное "недо-объектное" программирование — это естественный следующий шаг посл процедурного программирования. Несмотря на весьма небольшие отличия, работать с объектам несколько удобнее: все функции собираются в одном месте, ну нужно использовать префикс для функций, чтобы избежать конфликтов между модулями, среда разработки всегда точно подсказывает, что можно сделать с объектом. И, разумеется, вы можете воспользоваться инкапсуляцией, чтобы скрыть от пользователя поля, в которые он не должен залезать без спроса. III. Следующий шаг возникает, когда сущности начинают выстраиваться в иерархию. Например есть объект (хоть в процедурном, хоть в объектом понимании) "база данных", и вы хотит выполнить запрос. Но база данных не может быть абстрактной, всегда надо использовать конкретную СУБД: MySQL, SQL Server и т.п. Основные методы работы с этими базами данных похожие, и хочется с ними работать по-одинаковому, чтобы можно было при необходимости менять СУБД, не меня код. Для процедурного программирования естественный ход — это добавить в объект свойств "СУБД" и в функции do_sql_query добавить огромный-преогромный switch по всем вариантам. Поддерживать такой код становится невероятно сложно, в каждой функции приходится обрабатывать все возможные варианты для всех возможных СУБД. И вот здесь на помощь приходит объектно-ориентированное программирование. Тепер вы можете использовать наследование, чтобы построить классы в стройные иерархии, и полиморфизм, чтобы организовать вызов "одинаковых" методов в зависимости от положения класса в иерархии. Так как человеку естественно думать в терминах объектов, а не функций, то объектно-ориентированно программирование хорошо подходит для описания сущностей. Разумеется, те же сущности есть в и процедурном, и в объектом программировании, но именно со всеми возможностями объектно-ориентированного программирования приходит свобода реализовать код красиво и лаконично. IV. В определённый момент даже объектно-ориентированного программирования начинае не хватать: оно предоставляет огромную свободу, и код снова превращается в мешанин из иерархий и виртуальных методов, которые вызываются как попало. Тут на спасение приходят шаблоны проектирования, которые описывают, как с помощью объектно-ориентированного программирования можно эффективно организовывать код, как избегать чрезмерной сложности и делать так, чтобы код был понятен остальным. Другое направление — обобщённое программирование, когда с объектами разных типо можно работать одинаковым или похожим способом. При любой парадигме в сложных программах неизбежно возникают модули и другие способы организации кода. Какой язык — объектно-ориентированный или процедурный — значения не имеет. В объектно-ориентированном стиле можно писать на процедурном языке и наоборот. Кроме того, существует множество парадигм программирования: функциональное программирование логическое программирование и другие. Это уже не привычное императивное программирование, но некоторые аспекты того же функционального программирования начинают перебираться в традиционно императивные языки, что позволяет пользоваться многими интересными возможностями.

Ответ 7



Полностью поддерживаю @lampa . В функцию класса можно спокойно засунуть все необходимые проверки. Плюс вспомните что обычно сайт состоит не из одной страницы, а, к примеру, из 10, и на каждой буде эти 3 строчки + 10 строк проверки входящих параметров, подстановки параметров в строк запроса, проверки результата... И при изменении одной из этих строчек придется менять ее на всех 10ти страницах. А если у вас класс - меняем это только в одном месте и все, на всех страницах будет использоваться уже исправленная или дополненная функция. Как раз класс работы с базой данных это очень хороший пример полезности использования ООП. а представьте, что вы написали проект, который работает не только с MySQL, но и ещ может работать с postgresql или sqlite? Что же на каждой странице делать проверку какой бд мы работаем в данном случае? фу-фу-фу-фу! Для этого есть class! В нем делаем одну переменную и в зависимости от ее значения используем тот или иной метод работы с базой. Ведь правда же удобно? ;)

Ответ 8



Чтобы проектировать и писать сложные вещи. Почитайте книгу Мэтт Зандстра "PHP. Объекты шаблоны и методики программирования", если собираетесь использовать ООП подход в полную силу.

Будущие перспективы программирования? [закрыт]


Здравствуйте, уважаемые. 
Дело в том, что находясь на 2 курсе Информационных технологий наступает такая пора
когда надо выбирать дальнейшее направление в мире программирования. А именно между Web-Dev и прикладным программированием, к тому же выбор ЯП как основново инструмента. 
В институте ”проходим” C++, (хотя у меня язык не поворачивается назвать изучаем
скорее просто просматриваем логические и операторы вывода, старый синтаксис и т. д
и так целый семестр, складывается впечатление, что лектор отстает от жизни лет на 10 как минимум, и ничего нам больше не светит кроме нудной писанины математических функций в тетрадке. Тут же состоялось мое первое знакомство  с прикладным программированием, оставило довольно позитивное впечатление. 
На 3 курсе Java, но уже страшно представить что будет с таким отношением к предмет
со стороны лекторов...  Но это не главное,  мой университет считается "лучшим" по Самообразованию)  и на него я не расчитываю, только диплом.)

К тому же,  я полтора года занимаюсь Веб-программированием и знаю (HTML, CSS, PHP(средне)
MySQL), и до этого времени все шло замечательно, думал учиться на веб-программиста
пока я не задумался о будущем, а переспективно ли это, ведь мне придется выбрать одно направление и несколько инструментов для реализации, которые будут сопровождать меня всю жизнь... 
И пошло поехало, стал взвешивать шансы, сравнивать графики ЯП за последние 7 лет
искать те или иные преимущества веб и прикладного программирования, лихорадочно бродить по гуглу выискивая задатки перспектив... 

Условно разделив ЯП на категории для достижения цели получил довольно интересную картину:
Веб-Программирование:

HTML/CSS/XML 
PHP + MySQL
JavaScript
Python + Django
Ruby + RoR

Прикладное программирование:

Java
C#
C++


Поиски документации по ЯП завели меня еще дальше, теперь выбор будущего стал боле
неопределенным. С одной строны Java – всегда вакантные места и кроссплатформенность, к тому же несколько лет он занимает первые места в рейтинге и даже не намерен уступать. 
C# - за последнее время этот язык поддерживаемый Microsoft вырос на глазах, и продолжае
расти, появляються перспективы полностью заменить C++. Язык будущего, но есть один большой минус, он зависим от платформ, а точнее от Windows... 
C++ - постепенно умирающий язык. ИМХО. Но его нельзя списывать со счетов. 

С другой стороны это Web-программирование которое немного ближе ко мне. 

PHP – это первый мой ЯП который я считал довольно хорошим и перспективным, пока н
познакомился с Python, который очень впечатлил меня своей краткостью, гибкостью и конкурентоспособностью. Конечно популярностью PHP  мог бы позавидовать любой язык. В данный момент популярность начинает спадать, но вакансий как и в случае с Java не становиться меньше, а даже увеличивается. 
Python – все началось наверно с него, он перевернул мое представление о программировании
впечатляющий, лаконичный, легкий, строго типизированый, имеет очень много достоинств. В связке в Django может обвести вокруг пальца любого конкурента, но есть существенный минус, это мало вакансий в моей стране. 

Впечетленным всем этим уже несколько неделей страдаю фигней, а точнее определяю свое будущее и переспективы. 
Если я уйду в Web-разработку(а именно в Python, PHP, Ruby, Js) не прогадаю ли я?
Или, возможно сразу переквалифицироваться в Java или C#, я конечно понимаю, все зависит от человека?
Интересно ваше мнение. 

P. S Сорри за столь сумбурный монолог и за грамматические ошибки если такие имеются.     


Ответы

Ответ 1



Молодой человек, не там ищете. Надо заниматься не тем, что вам сейчас кажется перспективным, а тем, к чему у вас лежит сердце или что у вас лучше получается. Простой пример: уже наштамповали в стране миллионы никому ненужных юристов и экономисто и все потому, что лет 10 назад их реально не хватало и все идиёты поперлись туда - ну как же востребованная профессия! То что сейчас (ровно как и 10 лет назад) Java востребована к сожалению ничего н означает. К моменту когда вы станете довольно борзо писать - вполне может случитьс что технология сдохнет (окончательно она конечно не сдохнет ибо она уже сейчас является становой хребтиной) - ну в общем вы поняли. Аналогично может случиться с любой технологией dot Net, PHP. Сейчас все очень текуче и зыбко - быстро меняется. Единственная непреходящая ценность это инвестиции в себя любимого, а инвестиции себя любимого эффективны только когда это вам нравится. Так что смотри что вам нравитс на том и пиши! Так что когда что-то изменится у вас будет очень важное конкурентное преимущество вы будет очень хорошо знать некую технологию (просто потому, что она вам нравится).

Ответ 2



Вопрос некорректен. Переквалификация в Java или C# не означает отказ от веба. Python ... В связке в Django может обвести вокруг пальца любого конкурента, Нет, он не может. Человек может, а сам по себе питон ничего не может. Веб-Программирование: HTML/CSS/XML -PHP + MySQL JavaScript Python + Django Ruby + RoR Прикладное программирование: Java C# C++ Опять неверно. Никто не мешает использовать Python и Ruby для прикладных целей. даже JavaScript. XML тут тоже не в тему.. он имеет отношение ко всему. Языки C++/C#/Jav вообще универсальны. Пожалуй, на C++ делать что-то долго, но дела это не меняет. И, конечно, знание любого пункта из списка не отменяет необходимость знания HTML/CSS/XML и даже JavaScript. В институте ”проходим” C++,(хотя у меня язык не поворачивается назвать изучаем,скорее просто просматриваем логические и операторы вывода,старый синтаксис и т.д) и так целый семестр,складывается впечатление,что лектор отстает от жизни лет на 10 как минимум Ну это вы совсем зря. Изучение C++ учит дисциплине. Кроме того, для изучения алгоритмо новомодные языки плохо подходят. Именно поэтому для обучения преподавать надо начинать с C++ или Pascal. Выучить новомодные фишки вы всегда успеете, а вот научиться правильно думать необходимо. И не важно, устарел лектор на 10 лет или нет.

Ответ 3



Ценятся программисты, а не кодеры. То есть, конечно, кодеры тоже ценятся (иначе на что бы я жил, хех), но... второсортнее. Разделение ложно. И веб и десктоп отличаются только одним - тем, как описываетс внешний вид и поведенческая логика фронтэнда. В верстке веб-страниц или раскладке виджето программирования не больше, чем в пайке радиодеталей - инженерно-радиотехнических работ. Да, нужен опыт (без него все рискует быть кривым, громоздким, ограниченным, сложноподдерживаемым, неудачным), но и там и там работа, по большей части, чисто механическая. Разумеется, в области фронтэндов есть и интересные и нетривиальные задачи по визуализации или обработке сигналов, но они не особо часты, а в большинстве случаев уже решены. Но самое интересное и нетривиальное, пожалуй, всегда находится "под капотом". А та нет никакой особой разницы каким внешним образом поступают данные и как потом буду визуализироваться результаты. К слову, у немалой кучи "десктопных" приложений под капотом браузер, отрисовывающий HTML+CSS. В обратную сторону реже, но, например, тот же GTK3 имеет HTML5-бэкенд. Ну и нет особой разницы в языке, на котором пишется код. Главное, чтобы он был адеквате задаче, а дальнейшее - это уже вопросы экономики и политики, а не программирования Из упомянутых и Python и C# и Java - языки достаточно общего назначения, так что неверн говорить что "вот этот - для веб, а этот - десктопный." Тем более, что большая часть программирования зависит от семантики, а не синтаксиса языка, а перечисленные языки имеют очень много семантически сходных (хотя и не идеально аналогичных) конструкций. А синтаксис учится быстро. Поэтому лучше, я бы сказал, первично учиться, эээ, computer science. Это, если н посвящать жизнь клепанию сайтов-визиток, todo-приложений под айфон и прочих утилит-менеджеро автозапуска, пригодится всегда, в любой области. Изучать стоит все попадающиеся по руку языки - эти знания лишними не бывают. Впрочем, уделяя приоритет более интересны и, среди интересных - более рыночно-практичным. И, конечно же, любые прикладные навыки-технологии (верстка, фреймворки), на вкус и спрос: знания - сила, но платят, как правило, не за знания, а за практические результаты. Так что если у Вас лежит душа к Python+Django - вот, оно. Рынок этого дела есть (со всеми нишами от индусов-за-еду до грамотных специалистов), за него волноваться не стоит.

Ответ 4



Python как и Ruby - универсальные решения. На Python можете легко писать любое прикладное ПО с биндингами к тому же QT, а в случаи необходимости встраивать С-код.

Ответ 5



Нельзя списывать со счетов C# с платформой asp.net. Технология достаточно удобна и гибка. Из минусов она дороговата для клиента и собственно зависимо от операционной системы. Но как не странно работу найти не проблема и американцы хотят свои финансовые сайты именно на asp.net

Ответ 6



Вы забыли про технологии облачных вычислений.

Ответ 7



Как уже было сказано, деление весьма условно. На том же Python'е сейчас встречаютс вакансии и в облачных вычислениях, и в высоконагруженных серверных решениях, хотя из "формального" описания языка это может показаться нонсенсом. А ещё важно понимать, что программирование - это только инструмент. Если вы будет учиться просто программировать, то останетесь и сами только инструментом для других Разберитесь в чём-нибудь по-настоящему и используйте программирование как самый простой на данный момент способ превращения идей и знаний в материю, меняющую жизнь людей в этой области. И вам будет интересней, и людям полезней.

Ответ 8



Все надо изучать самому. Создавать идеальные алгоритмы методом проб и ошибок не получится так как выучить ЯП - 50% проблемы. Другая половина - почувствовать, понять язык. Программирование - это не простое заучивание новых языком, это изучение методик, паттернов программирования и технологий, встраиваемых в язык. Я бы сказал так:"Хотите творить - идите в прикладники, хотите заработать - идите в веб." Вообще, программированием надо начинать заниматься с детства, потом все само стане на свои места. Вот у вас еще в запасе есть 3 года, так попытайтесь что-либо сделать, разверните крупный проект и попробуйте заработать(или сотворить)....

Ответ 9



Уже упоминал своё имхо в одном из вопросов: Появится ( и о чудо - оказывается уже есть: node-inspector ) node.js + WebInspector, и тогда php, python, jsp - будут сильно потеснены с Web'а Что-же относительно прикладных задач - то это больше соревнование оптимизаторов ( как компилируемых, так и JIT ), чем языков, и уж тем-более программистов

Ответ 10



Да вы правы,я зря сравниваю совершенно разные направления.Наверное меня сбил с толку именно Jython который переводит в бит-код Java. Два года назад я как то раз ответил себе на этот вопрос и углубился в веб-разработк которая мне довольно таки нравиться.Ну что ж, не стоит бросать начатое.Буду дальше осваивать ZendFramework и Python+Django,так как есть огромное желание программировать. Всем спасибо.

Ответ 11



Вы по сайтам с работой полазийте, типа ХедХантера, сравните зарплаты, увидите, чт системным платят больше, ну а если еще какой нибудь САП ненароком освоить, то отрыв еще больше. Как сайты делались так и будут делаться, тоже самое и про системный софт. Это два разных рынка, но их нельзя сравнивать, что преспективнее, а что нет.

Ответ 12



Мой совет тебе. Ориентируйся на гигантов Oracle (JSF) Google (GWT,Android и т.д хотя все это JAVA.

Ответ 13



Для начала пройдите курсы программистов с дальнейшим трудоустройством в какой-нибудь крупной фирме. После этого мировоззрение поменяется))) В любом случае без OOP, SQL, XML, слепого набора на клаве и английского в ИТ делать нечего.

Ответ 14



Мде... Сегодня я закажу суши и съем их а завтра сварю макароны и тоже съем) Когда на асу учился тоже стоял выбор = что делать, столько яп, какой изучть полностью а какой нахер не нужен?? Вывод прост, делайте то что вам по душе. хотите на липсе пишите, хотите пхп изучайте все от вас зависит. не надо ломать голову по таким мелочам, жизнь сама все на места расставит) p.s. Заголовок клевый! я думал тут о всемирном масштабе речь идет)

Ответ 15



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

Ответ 16



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

Ответ 17



Будущее за интернетом, будущее за кроссплатформенным C#, будущее за Ruby, Python. Принципы будущего: скорость разработки, логика разработки, лаконичность синтаксис языка, кроссплатформенность, мощность, универсальность, маштабируемость, глобальность, качественность. C# развивается в кроссплатформенный язык, стоит ему поглотить платформы, этот язы буду юзать - "мочат так - успевай вытирать". Очень мощный, лаконичный, (отличная, родная IDE) понтяный, удобный, быстрый в разработке. Это новый Java, только гораздо мощнее, я не хочу обидеть Java'еров - нет, это же для нас лучше, что есть такие технологии! Java по сравнению с C# не шелохнулся в развитии, в то время как в Microsoft придумываю для разработчиков новейшие методы и способы упростить жизнь программистам. Эти методы революционны! Посмотрите динамику развития с С# 3.0 до версии 5.5! С каждой версией добавляется вдохновения, и по правде сказать самой силы в программировании! Как-нибудь напишу статью, дам ссылочку и будем холиварить. ;)

Чем лучше реализовывать частые постоянные вычисления?


Необходимо выполнять определенный код 30-40 раз в секунду. Возможные задержки реализаци
надо учитывать, как и вариант, что код будет слишком тяжелым, чтобы исполнить за указанный участок времени.

Для отрисовки ввели window.requestAnimationFrame, а что ввели для вычислений?

Пользоваться setTimeout с Date.getNow() для определения времени, затраченного н
выполнение кода - идея не очень. Раньше задержка setTimeout была 3-4мс, сейчас уменьшили до 0-2. Но все-равно, все задается в миллисекундах и погрешность довольно высока.

Ввели Promises - для другого, но я видел где-то безумную реализацию таймера на них.

Ввели Web Workers - по идее, то что надо - вычисления в отдельном потоке, без замедлени
основной страницы. У них там, вроде-бы, сложности с взаимодействием со страницей, но, по сути, это не особо то и нужно в большинстве случаев.

Добавили window.performance.now(), да и вообще время с микросекундами, что прекрасно, но реализацию высокоточного таймера на микросекундах я так и не увидел.

В общем, что использовать, для, грубо говоря, игры?
    


Ответы

Ответ 1



Вам могут помочь underscore функции Throttle и Debounce Я пользуюсь ими в проектах с requestAnimationFrame для снижения нагрузок при частом вычислении значений, которые обновляются реже, чем смена кадров. Реализация функций прекрасно описана и прокомментирована в исходниках undersocre

Многопоточное vs асинхронное сетевое программирование на практике


Как-то в комментариях VladD поделился информацией, что один из его коллег, сетево
программист, перешел от многопоточного к асинхронному сетевому программированию. Хотелось бы на примере конкретной задачи разобраться, насколько асинхронность выиграет у многопоточности.

Задача: возьмем один из простых сетевых протоколов - RFB. Нам нужно одновременн
подключиться к 10 000 серверов с RFB на борту, и узнать версию RFB.

Как это реализовать многопоточно - я знаю, но как это реализовать асинхронно? И н
сколько, в данной задаче, асинхронность выиграет? Сама реализация RFB - не нужна, нужен пример выполнения 10 000 одновременных асинхронных запросов.



Протестировал 3 варианта кода:


Многопоточный (поменял разбивку списка на несколько - на потокобезопасную очередь, чтобы уровнять шансы)
Асинхронный
Асинхронный (паттерн Throttling)


Результаты (проверка 300 000 IP адресов):


Многопоточный: 3 минуты 18 секунд
Асинхронный: 1 минута 27 секунд
Асинхронный (паттерн Throttling): когда перевалило за 6 минут - закрыл программ
и не стал измерять дальше. Скорости можно добиться только использовав в уровне параллелизм
- размер всего списка, но тогда теряется смысл самого использования паттерна. Т.е. реализация от andreycha, если использовать уровень параллелизма меньше размера списка - работает дольше чем даже многопоточная версия. Возможно это просто моя ошибка, либо ошибка andreycha. 


Вывод:


Стандартная асинхронная реализация работает более чем в 2 раза быстрее чем многопоточная.

    


Ответы

Ответ 1



Про асинхронность и ее преимущества тут. Вкратце -- в то время, пока запрос уше в сеть и не вернулся обратно, мы не блокируем потоки на нашем компьютере. Т.о. 10000 адресов можно вполне обработать, например, несколькими потоками. Запускать 10000 одновременных запросов это, конечно, перебор. Но запускать, скажем по полсотни-сотне одновременных запросов -- вполне нормально. Такой шаблон называетс троттлингом -- throttling (или в автомобильных терминах -- дросселированием :D). Т.е. пропускаем весь объем заданий по-немногу. Такой подход позволяет несильно загружать канал при отправке запросов и машину при получении и разборе ответов. Примерный код может выглядеть так: public async Task CheckServers() { var servers = new List(10000) { ... }; const int ConcurrencyLevel = 100; // запускаем первые 100 запросов var tasks = servers.Take(ConcurrencyLevel).Select(GetVersion).ToList(); int nextIndex = ConcurrencyLevel; while (tasks.Count > 0) { // дожидаемся завершения любого запроса var completedTask = await Task.WhenAny(tasks); // удаляем его из списка tasks.Remove(completedTask); // добавляем новый запрос, если таковые остались if (nextIndex < servers.Count) { tasks.Add(GetVersion(servers[nextIndex++])); } string rfbVersion = await completedTask; // работаем с версией } } private async Task GetVersion(string server) { // тут асинхронная реализация обращения к серверу по RFB и возвращение версии } Важный вопрос состоит в правильной асинхронной реализации обращения к серверу п протоколу RFB. Если вы используете библиотеку -- она должна поддерживать асинхронность. Если вы реализуете эту функциональность сами (например, на сокетах) -- значит нужно пользоваться асинхронными функциями сокетов. UPD Выяснилось, что запросы/ответы у ТС настолько легковесные, что в данном случае троттлин работает медленнее, чем если отправить сразу все запросы. Однако этот паттерн може быть по-прежнему полезен, когда необходимо ограничить количество исходящих запросов и/или количество обрабатываемых ответов (например, если разбор ответов сильно загружает процессор/требует много памяти).

Как работают события в C#


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

Будет ли обработчик работать асинхронно? Нужно ли использовать lock-и и блокироват
куски кода, чтобы другие обработчики туда не зашли? И вообще, будут ли работать другие обработчики, пока один из них работает?
    


Ответы

Ответ 1



Значит так. Для начала, событие будет послано всем подписчикам, одному за другим. Это происходи синхронно, как часть отправки события. Порядок вызова подписчиков не определён, следующий подписчик будет запущен только когда предыдущий полностью отработал (за исключением async-методов, разумеется!). События доставляются в том потоке, в котором они инициируются. Это значит, что если всё происходит в UI-потоке, то блокировки бессмысленны, многопоточного доступа нет. Это также означает, что код обработчика событий обязан быть быстрым: если ваш обработчи события делает что-то длинное, при этом остальные обработчики будут ждать, пока первы обработчик закончит, и только тогда получат управление. Хуже того, если пока работает обработчик события, этот поток блокируется, и доставка всех других событий приостанавливается. Тем не менее, есть неприятный момент: если вы (не дай бог!) почему-то в обработчик события запускаете модальный диалог, то в нём запускается внутренний цикл обработк событий, и таким образом при ещё бегущем обработчике событий вполне может прийти следующе событие, и обработчик выполнится рекурсивно! Вы не сможете предотвратить это при помощи блокировок, потому что рекурсия происходит в том же потоке. Просто никогда не делайте ничего длинного блокирующего в обработчике события, иначе неприятностей рано или поздно не избежать. Если вы пользуетесь современным C#, имеет смысл сделать async-обработчик события чтобы он «отдавал» выполнение другим обработчикам при первом же await'е. Таким образом пока один из обработчиков «висит» в await'е, начнёт выполняться следующий. Имейте в виду, что при этом обработчик события станет асинхронным, и его точно так же сможет «догнать» следующий обработчик того же или следующего экземпляра события. Или если вы не пользуетесь async/await (например, потому, что работаете с версие языка эпохи палеолита), то длинную обработку лучше выгружать в другой поток (например, BackgroundWorker, если вы пользуетесь каким-нибудь UI-фреймворком, или TPL). Дополнение: Как справедливо замечает в комментариях @Антон Буторин, если один и обработчиков события синхронно выбрасывает исключение, то запуск остальных обработчико также не происходит, а отправление события завершается (с этим же исключением). Для async void-обработчиков, если исключение выбрасывается в асинхронной части, это может и вовсе привести к падению приложения. Отсюда совет, граничащий по силе с правилом: обработчики событий не должны выбрасывать исключения. Обновление: В обычном случае я бы советовал делать так: Подписка на события, отписка от них и посылка самих событий должны происходить UI-потоке. Код посылки сообщения в таком случае стандартный: public class UserLoginEventArgs : EventArgs { public User User { get; private set; } internal UserLoginEventArgs(User user) { this.User = user; } } public event EventHandler UserLogin; void RaiseUserLoginEvent(User user) { if (UserLogin != null) UserLogin(this, new UserLoginEventArgs(user)); } Заметьте, что вам не нужна обычно используемая техника копирования UserLogin в локальную переменную. Асинхронность, если она нужна, достигается на стороне обработчика сообщения: // синхронный обработчик void OnUserLogin(object sender, UserLoginEventArgs args) { activeUsers.Add(args.User); } // асинхронный обработчик async void OnUserLogin(object sender, UserLoginEventArgs args) { var user = args.User; if (!punishedUsers.Contain(user)) return; await SendUserMessage(user, NotAllowedToLogInText); await LogoutUser(user); }

Как убрать ошибки измерений?




Есть вот такой набор точек, каждая точка представляет собой gps координату автобус
(x,y), у каждой точки есть timestamp.  На построенном графике  видны явные ошибки измерения
Как их можно убрать? Решение должно быть простым, так как всего координат около 100 тысяч. Интересует идея, но желательно, чтобы ее можно было без особых проблем реализовать средствами Java

Пример исходных данных:

  1447037729    3054.619968    2409.828279    570d8


Первое поле - UNIX-время, второе и третье - (x,y) соответственно, четвертое - идентификатор автобуса (автобусов около 50ти) . 
Исходные данные : https://drive.google.com/file/d/0B4bA9d5B_O_BcVpPUXpYTmZBUFE/view
    


Ответы

Ответ 1



Приведённый набор точек - это две зависимости: x(t) и y(t), и по каждой идёт импульсны шум. К таким данным идеально подходит алгоритм медианной обработки в скользящем окне на 7-9 элементов, когда i-тый во времени элемент заменяется на медианное значение элементов с номерами (i-h,i+h) при h=3...4. Обработку для x(t) и y(t) следует проводить независимо, после чего подменить ими исходные массивы. Обработка эффективна при высоком уровне импульсной помехи (в тестовом примере искажен третья часть данных). Дополнительный плюс - что сохраняется формат исходных данных. Обработка краёв ведётся на окнах меньшего размера. Минусы обработки в скользящем окне проявляются при разворотах последовательности, поскольку выступы и провалы шириной меньше h выполаживаются. В демо-программе представлена рекуррентная сортировка массива в окне. Для этого точки лежащие между старым (удаляемым) и новым (добавляемым) элементами, сдвигаются в сторону старого элемента, после чего на место крайнего из возникших дубликатов записывается новый элемент. Это резко снижает вычислительные затраты. Демо-программа (PHP): function print_a($a, $name){ print("$name: "); foreach($a as $item){ printf("%2d, ",$item); } } function slide_median($h, $a){ $size = count($a); $result = []; $slide = []; array_push($slide, reset($a)); array_push($result,$slide[0]); print_a($slide, " Сортировка в окне"); print_a($result, "
Массив результата"); for($i=1; $i<=$h; $i++){ array_push($slide, next($a), next($a)); sort($slide); array_push($result, $slide[$i]); print_a($slide, " Сортировка в окне"); print_a($result, "
Массив результата"); } for($i=0; $i < $size-2*$h-1; $i++){ $old = $a[$i]; $new = $a[$i+2*$h+1]; if($old < $new){ for($key = 0; $key <= 2*$h; $key++){ if($new < $slide[$key]){ break; } if(($old <= $slide[$key])&&($slide[$key] < $new)) $slide[$key] $slide[$key+1]; } $slide[$key-1] = $new; } if($old > $new){ for($key = 2*$h; $key >= 0; $key--){ if($new > $slide[$key]){ break; } if(($old >= $slide[$key])&&($slide[$key] > $new)) $slide[$key] $slide[$key-1]; } $slide[$key+1] = $new; } array_push($result, $slide[$h]); print(" old = $old, new =$new"); print_a($slide, " Сортировка в окне"); print_a($result, "
Массив результата"); } for($i = $h-1; $i > 0; $i--){ $slide = array_slice($a, $size-2*$i-1, 2*$i+1); sort($slide); array_push($result, $slide[$i]); print_a($slide, " Сортировка в окне"); print_a($result, "
Массив результата"); } $slide = [$a[$size-1]]; array_push($result, $slide[0]); print_a([end($a)], " Сортировка в окне"); print_a($a, "

Исходный массив: "); print_a($result, "
Массив результата"); return $result; }; $a = range(20, 40); foreach($a as &$item){ $item += 5*mt_rand(-1,1)*(int)(mt_rand(0,199)/100); } print_a($a, "Исходный массив: "); slide_median(3, $a); Результаты (импульсный шум, амплитуда 5): Исходный массив: : 20, 21, 22, 23, 19, 20, 21, 27, 28, 29, 30, 31, 32, 28, 29, 35, 36, 42, 43, 39, 35,  Сортировка в окне: 20, Массив результата: 20,  Сортировка в окне: 20, 21, 22, Массив результата: 20, 21,  Сортировка в окне: 19, 20, 21, 22, 23, Массив результата: 20, 21, 21,  Сортировка в окне: 19, 20, 20, 21, 21, 22, 23, Массив результата: 20, 21, 21, 21,  old = 20, new =27 Сортировка в окне: 19, 20 21, 21, 22, 23, 27, Массив результата: 20, 21, 21, 21, 21,  old = 21, new =28 Сортировка в окне: 19 20, 21, 22, 23, 27, 28, Массив результата: 20, 21, 21, 21, 21, 22,  old = 22, new =29 Сортировка в окне 19, 20, 21, 23, 27, 28, 29, Массив результата: 20, 21, 21, 21, 21, 22, 23,  old = 23, new =30 Сортировка в окне: 19, 20, 21, 27, 28, 29, 30, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27,  old = 19, new =31 Сортировк в окне: 20, 21, 27, 28, 29, 30, 31, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28,  old = 20, new =32 Сортировка в окне: 21, 27, 28, 29, 30, 31, 32, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29,  old = 21, new =28 Сортировка в окне: 27, 28, 28, 29, 30, 31, 32, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29,  old = 27, new =29 Сортировка в окне: 28, 28, 29, 29, 30, 31, 32, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29,  old = 28, new =35 Сортировка в окне: 28, 29, 29, 30, 31, 32, 35, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30,  old = 29, new =36 Сортировка в окне: 28, 29, 30, 31, 32, 35, 36, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31,  old = 30, new =42 Сортировка в окне: 28, 29, 31, 32, 35, 36, 42, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32,  old = 31, new =43 Сортировка в окне: 28, 29, 32, 35, 36, 42, 43, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35,  old = 32, new =39 Сортировка в окне: 28, 29, 35, 36, 39, 42, 43, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35, 36,  old = 28, new =35 Сортировка в окне: 29, 35, 35, 36, 39, 42, 43, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35, 36, 36,  Сортировка в окне: 35, 36, 39, 42, 43, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35, 36, 36, 39,  Сортировка в окне: 35, 39, 43, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35, 36, 36, 39, 39,  Сортировка в окне: 35, Исходный массив: : 20, 21, 22, 23, 19, 20, 21, 27, 28, 29, 30, 31, 32, 28, 29, 35, 36, 42, 43, 39, 35, Массив результата: 20, 21, 21, 21, 21, 22, 23, 27, 28, 29, 29, 29, 30, 31, 32, 35, 36, 36, 39, 39, 35, Сравнение скользящей медианы и скользящего среднего на интенсивной импульсной помехе проведено с помощью следующей программы: function print_a($a, $name){ print("$name: "); foreach($a as $item){ printf("%3d, ",$item); } } function slide_median($h, $a){ $size = count($a); $result = []; $slide = []; array_push($slide, reset($a)); array_push($result,$slide[0]); for($i=1; $i<=$h; $i++){ array_push($slide, next($a), next($a)); sort($slide); array_push($result, $slide[$i]); } for($i=0; $i < $size-2*$h-1; $i++){ $old = $a[$i]; $new = $a[$i+2*$h+1]; if($old < $new){ for($key = 0; $key <= 2*$h; $key++){ if($new < $slide[$key]){ break; } if(($old <= $slide[$key])&&($slide[$key] < $new)) $slide[$key] $slide[$key+1]; } $slide[$key-1] = $new; } if($old > $new){ for($key = 2*$h; $key >= 0; $key--){ if($new > $slide[$key]){ break; } if(($old >= $slide[$key])&&($slide[$key] > $new)) $slide[$key] $slide[$key-1]; } $slide[$key+1] = $new; } array_push($result, $slide[$h]); } for($i = $h-1; $i > 0; $i--){ $slide = array_slice($a, $size-2*$i-1, 2*$i+1); sort($slide); array_push($result, $slide[$i]); } $slide = [$a[$size-1]]; array_push($result, $slide[0]); print_a($a, "

Исходный массив "); print_a($result, "
Массив медиан  "); return $result; }; function slide_average($h, $a){ $size = count($a); $b = array_merge([0], $a); $sum = reset($a); $result = [$sum]; for($i=1; $i<=$h; $i++){ $sum += next($a)+next($a); $average = (int)($sum/(2*$i+1)+.5); array_push($result, $average); } reset($b); for($i=0; $i < $size-2*$h-1; $i++){ $sum += next($a) - next($b); $average = (int)($sum/(2*$h+1)+.5); array_push($result, $average); } for($i = $h-1; $i >=0; $i--){ $sum -= (next($b) + next($b)); $average = (int)($sum/(2*$i+1)+.5); array_push($result, $average); } print_a($a, "

Исходный массив "); print_a($result, "
Массив средних  "); return $result; }; $a = range(200, 240); foreach($a as &$item){ $item += 50*mt_rand(-1,1)*(int)(mt_rand(0,149)/100); } slide_median(3, $a); slide_average(3, $a); Результаты: Исходный массив : 200, 201, 202, 203, 204, 155, 206, 207, 208, 209, 210, 211, 212 213, 264, 265, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 183, 234, 235, 236, 287, 238, 239, 240, Массив медиан  : 200, 201, 202, 202, 203, 204, 206, 207, 208, 209, 210, 211, 212 213, 216, 217, 218, 219, 219, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 234, 235, 236, 238, 239, 239, 240, Исходный массив : 200, 201, 202, 203, 204, 155, 206, 207, 208, 209, 210, 211, 212 213, 264, 265, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 183, 234, 235, 236, 287, 238, 239, 240, Массив средних  : 200, 201, 202, 196, 197, 198, 199, 200, 201, 209, 210, 218, 226 227, 228, 229, 230, 231, 225, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 223, 224, 225, 226, 234, 235, 236, 244, 248, 239, 240, Видно, что скользящая медиана лучше сглаживает интенсивные случайные выбросы данных. Для данных из реального массива (x,y округлялись до целых): Обработка массива x80c48 Исходный массив : 10790, 10728, 10565, 10228, 10148, 9911, 9861, 9880, 9887, 9894 9907, 9910, 9917, 9932, 9937, 9925, 9900, 9684, 9579, 9446, 9040, 8912, 8703, 8457 8350, 8338, 8129, 8040, 7900, 7836, 7731, 7490, 7271, 7250, 7165, 7013, 6912, 6848 6823, 6857, 6868, 6894, 6902, 6903, 6904, 7114, 7067, 7047, 6994, 6883, 6848, 6787, 6722, 6412, 6236, 6136, 6012, 5991, 5659, 5648, 5595, 5327, 5079, 5015, 4678, 4639, 4569, 4294, 4241, 4164, 4137, 3948, 3905, 3771, 3731, 3664, 3577, 3422, 3304, 3086, 3053, 2977, 2967, 3248, 3257, 3202, 2954, 2834, 2594, 2574, 2611, 2730, 2766, 2514, 2387, 2368, 2365, 2344, 2312, 2098, 1905, 1722, 1579, 1233, 1206, 963, 815, 825, Массив медиан  : 10790, 10728, 10565, 10228, 10148, 9911, 9894, 9894, 9894, 9894 9907, 9910, 9917, 9917, 9917, 9917, 9900, 9684, 9579, 9446, 9040, 8912, 8703, 8457 8350, 8338, 8129, 8040, 7900, 7836, 7731, 7490, 7271, 7250, 7165, 7013, 6912, 6868 6868, 6868, 6868, 6894, 6902, 6903, 6904, 6994, 6994, 6994, 6994, 6883, 6848, 6787, 6722, 6412, 6236, 6136, 6012, 5991, 5659, 5648, 5595, 5327, 5079, 5015, 4678, 4639, 4569, 4294, 4241, 4164, 4137, 3948, 3905, 3771, 3731, 3664, 3577, 3422, 3304, 3086, 3086, 3086, 3086, 3053, 2977, 2967, 2954, 2834, 2730, 2730, 2611, 2594, 2574, 2514, 2387, 2368, 2365, 2344, 2312, 2098, 1905, 1722, 1579, 1233, 1206, 963, 825, 825, Исходный массив : 10790, 10728, 10565, 10228, 10148, 9911, 9861, 9880, 9887, 9894 9907, 9910, 9917, 9932, 9937, 9925, 9900, 9684, 9579, 9446, 9040, 8912, 8703, 8457 8350, 8338, 8129, 8040, 7900, 7836, 7731, 7490, 7271, 7250, 7165, 7013, 6912, 6848 6823, 6857, 6868, 6894, 6902, 6903, 6904, 7114, 7067, 7047, 6994, 6883, 6848, 6787, 6722, 6412, 6236, 6136, 6012, 5991, 5659, 5648, 5595, 5327, 5079, 5015, 4678, 4639, 4569, 4294, 4241, 4164, 4137, 3948, 3905, 3771, 3731, 3664, 3577, 3422, 3304, 3086, 3053, 2977, 2967, 3248, 3257, 3202, 2954, 2834, 2594, 2574, 2611, 2730, 2766, 2514, 2387, 2368, 2365, 2344, 2312, 2098, 1905, 1722, 1579, 1233, 1206, 963, 815, 825, Массив средних  : 10790, 10694, 10492, 10319, 10189, 10069, 9973, 9927, 9893, 9894 9904, 9912, 9917, 9918, 9886, 9839, 9772, 9644, 9498, 9323, 9117, 8927, 8749, 8561 8418, 8274, 8150, 8046, 7923, 7771, 7645, 7520, 7394, 7262, 7136, 7040, 6981, 6927 6888, 6872, 6871, 6879, 6920, 6950, 6976, 6990, 6987, 6980, 6963, 6907, 6813, 6697, 6575, 6450, 6328, 6167, 6013, 5897, 5767, 5616, 5473, 5286, 5140, 4986, 4800, 4645, 4514, 4389, 4285, 4180, 4066, 3985, 3903, 3819, 3717, 3625, 3508, 3405, 3298, 3198, 3151, 3127, 3113, 3094, 3063, 3008, 2952, 2861, 2786, 2723, 2660, 2597, 2564, 2534, 2496, 2437, 2341, 2254, 2159, 2046, 1885, 1722, 1529, 1346, 1192, 1008, 868, 825, Обработка массива y80c48 Исходный массив : 7289, 7275, 7243, 7178, 7163, 7119, 7109, 6903, 6785, 6680, 6448 6379, 6264, 5869, 5709, 5448, 5353, 5083, 5081, 5083, 5063, 5062, 5042, 5166, 5186 5172, 4916, 4925, 4982, 5009, 5025, 5007, 4993, 4991, 4986, 4976, 4968, 4964, 4962 4636, 4488, 4148, 4038, 4029, 4010, 3960, 3798, 3709, 3462, 3475, 3480, 3489, 3498, 3542, 3567, 3581, 3598, 3586, 3647, 3649, 3656, 3693, 3727, 3736, 3782, 3788, 3797, 3831, 3837, 3743, 3710, 3550, 3511, 3406, 3379, 3435, 3520, 3455, 3367, 3204, 3179, 3123, 3115, 2534, 2519, 2472, 2351, 2281, 2141, 2129, 2066, 1862, 1801, 1522, 1302, 1218, 1200, 1038, 851, 812, 778, 746, 721, 621, 529, 420, 386, 279, Массив медиан  : 7289, 7275, 7243, 7178, 7163, 7119, 7109, 6903, 6785, 6680, 6448 6379, 6264, 5869, 5709, 5448, 5353, 5083, 5083, 5081, 5081, 5081, 5083, 5063, 5062 5042, 5009, 5009, 5007, 4993, 4993, 4993, 4993, 4991, 4986, 4976, 4968, 4964, 4962 4636, 4488, 4148, 4038, 4029, 4010, 3960, 3798, 3709, 3489, 3489, 3489, 3489, 3498, 3542, 3567, 3581, 3586, 3598, 3647, 3649, 3656, 3693, 3727, 3736, 3782, 3788, 3788, 3788, 3788, 3743, 3710, 3550, 3511, 3511, 3455, 3435, 3406, 3379, 3367, 3204, 3179, 3123, 3115, 2534, 2519, 2472, 2351, 2281, 2141, 2129, 2066, 1862, 1801, 1522, 1302, 1218, 1200, 1038, 851, 812, 778, 746, 721, 621, 529, 420, 386, 279, Исходный массив : 7289, 7275, 7243, 7178, 7163, 7119, 7109, 6903, 6785, 6680, 6448 6379, 6264, 5869, 5709, 5448, 5353, 5083, 5081, 5083, 5063, 5062, 5042, 5166, 5186 5172, 4916, 4925, 4982, 5009, 5025, 5007, 4993, 4991, 4986, 4976, 4968, 4964, 4962 4636, 4488, 4148, 4038, 4029, 4010, 3960, 3798, 3709, 3462, 3475, 3480, 3489, 3498, 3542, 3567, 3581, 3598, 3586, 3647, 3649, 3656, 3693, 3727, 3736, 3782, 3788, 3797, 3831, 3837, 3743, 3710, 3550, 3511, 3406, 3379, 3435, 3520, 3455, 3367, 3204, 3179, 3123, 3115, 2534, 2519, 2472, 2351, 2281, 2141, 2129, 2066, 1862, 1801, 1522, 1302, 1218, 1200, 1038, 851, 812, 778, 746, 721, 621, 529, 420, 386, 279, Массив средних  : 7289, 7269, 7230, 7197, 7141, 7071, 6991, 6887, 6775, 6653, 6475 6305, 6114, 5924, 5729, 5544, 5375, 5260, 5168, 5110, 5083, 5098, 5111, 5087, 5067 5056, 5051, 5031, 5005, 4980, 4990, 4999, 4998, 4992, 4984, 4977, 4926, 4854, 4735 4601, 4466, 4330, 4187, 4067, 3956, 3858, 3778, 3699, 3625, 3559, 3522, 3502, 3519, 3536, 3552, 3574, 3596, 3612, 3630, 3651, 3671, 3699, 3719, 3740, 3765, 3785, 3788, 3784, 3751, 3711, 3655, 3591, 3533, 3502, 3465, 3439, 3395, 3363, 3326, 3280, 3140, 3006, 2878, 2756, 2628, 2488, 2347, 2280, 2186, 2090, 1972, 1832, 1700, 1567, 1420, 1276, 1135, 1028, 949, 878, 795, 723, 661, 600, 529, 447, 362, 279, По сравнению с алгоритмом скользящего среднего, скользящая медиана намного аккуратнее обращается с данными. Есть перевод статьи на английский язык.

Ответ 2



Для обработки зашумленных данных стоит подумать о фильтре Калмана. Так как у вас тут автобус - сразу вопрос - этот автобус движется по заранее известному маршруту?

Ответ 3



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

Ответ 4



На графике видны как явные, так и неявные ошибки. Имеются повороты, плюс на каждо повороте есть сомнительные точки, по которым сразу и не скажешь, ошибка это, или автобус такой загогулиной ехал. То есть простые варианты типа отбрасывания точек для "невероятных" перемещений на участках поворотов вряд ли помогут. Могу предложить использовать сглаживание методом локальной регрессии, затем построит доверительный интервал (вернее, доверительную область), но не для регрессии, а для значений (см. здесь), и отбрасывать точки за его пределами. 95% интервал может оказаться очень широким, возможно, потребуется взять 90%, 80% и т.д. Что касается 100 тыс. наблюдений, то никакой бигдаты тут нет, на вполне заурядном компе можно пробовать самые разные методы.

Ответ 5



Предлагаю два критерия отбрасывания плохих точек. Зигзаги - два поворота в разные стороны больше 90 градусов подряд. Это на самом дел возможно при откате и пробуксовывании, но если это происходит на одной линии, то н повредит внешний вид графика, а если со смещением, то скорее всего это результат ошибки. Однако при редких точках возможно, что автобус действительно так ехал, здесь критерий мне не ясен. Ещё часто наблюдается ошибочный дрейф во время стоянки. При обнаружении зигзага н маленькой скорости вместо удаления можно скопировать соседнюю точку. Возможно так же считать критерием стоянки постоянную очень маленькую скорость длительное время, но это может быть и движение в пробке. Слишком большое нормальное ускорение с чередованием знака (автобус не дрова везёт) - тут предлагаю порог 0,4 м/c^2 относительно предыдущего значения. Программа #include #include #include #define ZZMAXLEN 40 #define MAXDA 0.4 int main(int argn, char **argv) { double x[4], y[4]; // кольцевые буферы данных int t[4]={0,0,0,0}, n=0, h=0; char id[9]; if(argn!=2) { fprintf(stderr, "Usage:\n\t%s bus-ID\n", argv[0]); return 1; } while(scanf("%d %lf %lf %8s", t+h, x+h, y+h, id)==4) { if(strcmp(id, argv[1])) continue; h= h+1 & 3; if(++n < 4) continue; int dt1= t[h+1&3]-t[h]; int dt2= t[h+2&3]-t[h+1&3]; int dt3= t[h+3&3]-t[h+2&3]; double dx1= x[h+1&3]-x[h]; double dy1= y[h+1&3]-y[h]; double dx2= x[h+2&3]-x[h+1&3]; double dy2= y[h+2&3]-y[h+1&3]; double dx3= x[h+3&3]-x[h+2&3]; double dy3= y[h+3&3]-y[h+2&3]; int filter=0; if(dx1*dx2+dy1*dy2 < 0 && dx2*dx3+dy2*dy3 < 0 && dx1*dx3+dy1*dy3 > 0 && dx2*dx2+dy2*dy2 < ZZMAXLEN*ZZMAXLEN) { // разворот на угол более 90 градусов 2 раза подряд if((dx2*dx2+dy2*dy2)>0 && (dx2*dx2+dy2*dy2)/(dt2*dt2)<0.05) { fprintf(stderr, "D %d\n", n-1); // дрейф filter=2; } else { fprintf(stderr, "Z %d\n", n-2); filter=1; } } // скорости dx1/=dt1; dx2/=dt2; dx3/=dt3; dy1/=dt1; dy2/=dt2; dy3/=dt3; double vx12= (dx1+dx2)/(dt1+dt2); double vy12= (dy1+dy2)/(dt1+dt2); double vx23= (dx2+dx3)/(dt2+dt3); double vy23= (dy2+dy3)/(dt2+dt3); double v12= sqrt(vx12*vx12+vy12*vy12); double v23= sqrt(vx23*vx23+vy23*vy23); // ускорения double ax1= (dx2-dx1)*2/(dt1+dt2); double ay1= (dy2-dy1)*2/(dt1+dt2); double ax2= (dx3-dx2)*2/(dt2+dt3); double ay2= (dy3-dy2)*2/(dt2+dt3); // нормальные ускорения double an1= v12? (vx12*ay1-vy12*ax1)/v12 : 0; double an2= v23? (vx23*ay2-vy23*ax2)/v23 : 0; if(fabs(an1-an2) > MAXDA && an1*an2<0) { fprintf(stderr, "N %d %f %f\n", n-2, an1, an2); // два резких поворота filter=1; } if(filter) { // определяем какую точку удалить if(fabs(an1) > fabs(an2)) if(filter==2) { x[h+1&3]=x[h+2&3]; y[h+1&3]=y[h+2&3]; } else { x[h+1&3]=x[h+2&3]; y[h+1&3]=y[h+2&3]; t[h+1&3]=t[h+2&3]; } else if(filter==2) { x[h+2&3]=x[h+1&3]; y[h+2&3]=y[h+1&3]; } else { x[h+2&3]=x[h+1&3]; y[h+2&3]=y[h+1&3]; t[h+2&3]=t[h+1&3]; } } // тут можно пропустить точки с поворяющимся временем, но я оставил для построения графиков printf("%d\t%lf\t%lf\t%s\n", t[h], x[h], y[h], id); } t[h]=0; do { h=h-1&3; } while (t[h-1&3]0); do { printf("%d\t%lf\t%lf\t%s\n", t[h], x[h], y[h], argv[1]); h= h+1&3; } while (t[h-1&3]0); return 0; } Результаты работы получаем на стандартном выводе, а в стандартном выводе ошибок список удалённых точек и причина (N - нормальное ускорение, Z - зигзаг, D - зигзаг в дрейфе): $ ./a.out 80c48 < data.txt > 80c48.txt N 154 -0.163844 0.490944 D 249 D 252 Z 303 Z 444 Z 567 N 631 0.283293 -0.136238 Z 636 N 727 0.321036 -0.103197 N 984 -0.366378 0.309231 Z 991 N 1082 0.414078 -0.203378 N 1199 -0.020139 0.572870 D 1213 Z 1414 D 1507 D 1515 D 1517 D 1538 И иллюстрация удаления точки 154: Видимо исходные данные уже обработаны каким-то фильтром, так как отсчёты времен неравномерны. Данный метод вырезает одиночные ошибки, но данные GPS часто могут накапливать ошибк (и фильтр Калмана тоже) , и для борьбы с этим можно предложить притягивать слишком отклонённые точки к сетке дорог, которую можно получить усредняя много траекторий.