Курс «Основы программирования»

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

Сразу отмечу, что данный курс не является «идеальным». В нем есть все необходимое для легкого и плавного старта. Жду обратную связь от слушателей, чтобы улучшать наш курс! Итак, поехали!

Проблема

Процесс решения задачи с помощью вычислительной системы состоит из нескольких этапов:

  1. постановка задачи
  2. формализация
  3. алгоритмизация
  4. программирование
  5. тестирование

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

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

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

  • Умение читать и понимать уже существующий код. Современный разработчик чаще всего работает в команде или продолжает работу своих предшественников, поэтому должен уметь вычленить из существующего кода замысел автора.
  • Умение представить как будет работать написанный текст программы. Разработка больших профессиональных приложений может приводить к тому, что скомпилировать код и посмотреть его работоспособность представляется не очень часто, поэтому умение мысленно запустить код на выполнение может сохранить большое число человеко-часов.
  • Умение тестировать программу в мысленном режиме, не используя специализированные системы. Именно это умение позволяет еще на этапе написания программы предотвратить многочисленные ошибки. Также, составление трассировочных таблиц помогает выявить ошибку в программе, когда становится ясно, что выходные данные не совпадают с эталонными.
  • Умение строить гипотезы неработоспособности кода программы и проверять гипотезу. При обнаружении ошибки в выходных данных программы часто учащиеся пытаются методом случайных изменений текста программы, подогнать решение под верный вывод. “А что если так попробовать” — такой подход свойствен начинающим программистам, не умеющим анализировать совокупность входных и выходных данных.

Решение проблемы

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

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

Содержание курса

Курс состоит из следующих модулей:

  1. Типы данных. Переменные. В данном модуле научимся вводить и выводить информацию. Познакомимся с понятием «переменная», с помощью которой будем хранить некоторую информацию. Посмотрим какие типы данных существуют, ведь с типом величины связаны три ее свойства: форма внутреннего представления, множество принимаемых значений и множество допустимых операций.
  2. Условный оператор. В данном модуле научимся пропускать или выполнять некоторый блок кода в зависимости от некоторого условия. Рассмотрим короткую и полную запись условного оператора. Разберем оператор «switch-case«.
  3. Операторы цикла. Самый большой и важный модуль. В данном модуле разберем цикл со счетчиком for, цикл с предусловием while. Также рассмотрим операторы управления циклом: break, continue. Разберем вложенные циклы, задачи про последовательности, минимаксные задачи, задачи на перебор и задачи на анализ цифр числа.
  4. Строки и символы. В данном модуле узнаем подробнее про символы, а именно как они представлены в компьютере, какие операции можно производить. Также поговорим про строки и как они связаны с символами.
  5. Массивы. Большой модуль с большим количеством практических заданий. В данном модуле познакомимся с массивами. Рассмотрим как их объявлять, заполнять, оперировать с элементами массива. Также познакомимся с многомерными массивами, в частности с двумерным массивом.
  6. Функции. В данном модуле поговорим о том, как структурировать программы. Изучим главный «строительный блок» программирования — функции. Рассмотрим примеры, где уместно написание и использование функции.

Для кого предназначен данный курс?

Курс является вводным и больше всего подойдет слушателям, не имеющим опыта программирования.

На каком языке программирования будет проходить курс?

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

Где будет проходить курс?

Данный курс будет проходить на образовательной платформе Stepik. Уже сейчас можно записываться на курс.

Что кроме изучения языка программирования будет на курсе?

Кроме изучения языка программирования, затронем базовые алгоритмы поиска, алгоритмы со строками, теорию чисел.

Сколько стоит курс?

Курс будет проходить абсолютно бесплатно!

Записывайтесь на курс! Жду от Вас обратной связи для улучшения курса!


ссылка на оригинал статьи https://habr.com/post/423385/

Заглядывая внутрь сопроцессора Intel 8087

Немного истории развития линейки восьмиразрядных процессоров, выпускаемых компанией Intel

Линейка восьмиразрядных процессоров начинает свою историю с апреля 1972 года. Intel 8008 вообще изначально планировался для использования в калькуляторах, устройствах ввода-вывода, но производитель хорошенько «поразмыслив», решил найти линейке новое предназначение — быть центральным процессором ПК. В зависимости от модификаций процессоров тактовая частота составляла 500 или 800 КГц, а производительность равнялась 45000-160000 операций в секунду.


Intel C8008

В апреле 1974 года Федерико Фаггини и Масатоши Шима разработали новую линейку процессоров — Intel 8080. 6000 транзисторов были размещены в 40-контактном керамическом корпусе, 16-разрядная шина адреса и 8-разрядная шина данных, адресуемая память в 64 Кб. Тактовая частота составляла 2 МГц, а производительность — до 500 000 операций в секунду. Для того чтобы использование процессора стало «комфортным», был разработан арифметический сопроцессор, тактовый генератор, формирователи шин, таймера, контроллеры периферийных устройств и тд.


Intel 8080A

Через два года в марте 1976 года свет увидела линейка Intel 8085: 6500 транзисторов были размещены в 40-контактном керамическом (или пластмассовом) корпусе. Тактовая частота составляла от 3 до 8 МГц, разрядность шины данных — 8 бит, разрядность шины адреса – 16 бит, адресуемая память – 64 Кб. Данная линейка успешно была «задействована» в ПК или в виде микроконтроллеров.

В июне 1978 года началось производство первой линейки шестнадцатиразрядных процессоров компании — Intel 8086: 29000 транзисторов были размещены на кристалле размером 5,5 х 5,5 мм. Тактовая частота составляла от 5 до 10 МГц, производительность – от 330 до 750 тысяч операций в секунду, разрядность шины данных — 16 бит, а разрядность шины адреса – 20 бит.


Intel 8086

Спустя год, летом 1979 года, Intel выпустила 8088 линейку — переходное звено между 8-ми и 16-ти разрядными процессорами: 29 000 транзисторов, тактовая частота составляла 5-10 МГц. Но линейка 8088 так и не стала популярной из-за своей дороговизны.


Intel P8088

Сопроцессоры 8087

В июне 1980 была выпущена линейка сопроцессоров Intel 8087 для Intel 8086, 8088. Такие сопроцессоры содержали 45000 транзисторов, тактовая частота в различных модификациях составляла от 4 до 10 МГц.


Intel C8087

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

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

Согласно данным компании INTEL, математический сопроцессор может сократить время выполнения математических операций, таких как умножение, деление и возведение в степень, на 80 процентов и более. Скорость выполнения простых математических операций, таких как сложение и вычитание, не изменяется.

Внутри кристалла микропроцессора Intel 8087

Заглянув во внутрь Intel 8087 с плавающей запятой, я заметил интересную особенность на кристалле: схема формирования смещения подложки. В этой статье я объясню, как эта схема реализована, при использовании аналоговых и цифровых схем для создания отрицательного напряжения.

Intel разработала чип 8087 в 1980 году для того, чтобы улучшить производительность ПК с процессорами линеек 8086/8088 (таких, как IBM PC) при выполнении операций с плавающей запятой. Поскольку первые микропроцессоры были предназначены для выполнения операций с целыми числами, выполнение операций с числами с плавающей запятой было медленным, что уже и говорить о выполнение трансцендентных операций, таких как тригонометрические функции или логарифмы. Сопроцессор 8087 значительно повысил скорость выполнения задач с плавающей запятой, все выполнялось почти в 100 раз быстрее. Архитектура 8087 была реализована и в более поздние процессоры Intel, а инструкции 8087 по-прежнему используются в современных x86 ПК.

Для сопроцессора было введено более 60 новых инструкций, название которых начиналось на «F», для того, чтобы отличать их от целочисленных инструкций Intel 8086.

Я вскрыл чип 8087 и при помощи высокопродуктивного микроскопа сделал фотографии, в итоге их компоновки получил такое изображение:

Кристалл 8087 весьма сложный, содержит 40 000 транзисторов (согласно заявлениям Intel) или 45 000 (согласно Википедии). На фотографии — металлический слой чипа, соединения расположены сверху чипа. Самые толстые белые линии обеспечивают питание и заземление всех частей микросхемы. Под слоем металла — поликремний или кремний, из которого сформированы транзисторы чипа.

В нижней половине чипа — расширенная 80-битная арифметическая схема: сумматор, регистры, переключатели, математические константы. Большой прямоугольник в середине чипа — это микрокод, который реализует набор инструкций процессора. В верхней части находятся логические схемы и схема шины, которая сопряжена с процессором 8086.

Черные линии вокруг чипа на фотографии — мелкие термокомпрессионные соединения, соединяющие контактные площадки ИС (металлизированные проводящие участки квадратной или прямоугольной формы, расположенные преимущественно по периферии кристалла или подложки) с 40 контактам на кристалле. Изучая техническое описание 8087, не сложно определить, какая контактная площадка на матрице какому контакту микросхемы соответствует; 40 контактов чипа (пронумерованы против часовой стрелки) подключены к 40 контактным площадкам на чипе.

Ниже приведено увеличенное изображение части матрицы, на ней мы можем лучше рассмотреть контактные площадки. (Обратите внимание, что выводы заземления и +5 В контактные площадки питания имеют несколько подключений одновременно, что увеличивает количество постачаемого тока). Но вот «сюрприз» — существует дополнительная контактная площадка и соединение, расположенные между контактными площадками 40 и 1, и не связанные ни с одним из контактов микросхемы.

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

Я провел инженерный анализ технологии изготовления с целью раскрытия «секретов фирмы» и пришел к выводам, что это часть схемы смещения подложки 8087, в которой это соединение используется, чтобы подавать отрицательное напряжение на подложку. Как же работает эта схема?

Что такое смещение подложки?

В 1970 годах интегральные схемы высокой плотности были построены из n-МОП-транзисторов (полевой транзистор с изолированным затвором и каналом n-типа). Изображение ниже наглядно демонстрирует их структуру. Основание чипа — кремниевая подложка. Транзисторы в свою очередь тоже из кремния. Для того, чтобы изменить тип проводимости и концентрацию носителей в объеме полупроводника для получения заданных свойств, участки кремния легируются примесями, чтобы создать диффузионные области с желаемыми свойствами. Транзистор может быть рассмотрен как резистор, позволяющий току течь между двумя диффузионными областями истока и стока. Транзистор контролируется затвором, выполненным из поликремния. Входное напряжение на затворе управляет протеканием тока от истока к стоку: высокое напряжение сигнала на затворе позволяет току протекать от истока к стоку, в то время как низкое напряжение сигнала блокирует ток. Изолирующий оксидный слой отделяет затвор от кремния под ним; важность этого слоя рассмотрим немного позже. Эти крошечные транзисторы можно комбинировать с целью формирования логических затворов, компонентов микропроцессоров и других кристаллов цифровой ИС.

В высокопроизводительных интегральных схемах было выгодно применять отрицательное «смещение» напряжения на подложке. Чтобы получить это напряжение смещения подложки, многие чипы в 1970-х годах имели внешний контакт, который был подключен к -5В. Однако инженерам не нравились чипы, требующие дополнительного напряжения. Чипы той эпохи часто нуждались в трех источниках питания. Кроме того, количество контактов на ИС было ограничено (как правило, всего 18 контактов для микросхем памяти). Потому использование еще двух контактов для дополнительного напряжения не было удачным решением. Частично решение было найдено в конце 1970-х годов: чипы генерировали отрицательное напряжение смещения внутри. Так появились чипы, в которых использовался один удобный источник питания + 5В, и это однозначно позволило инженерам быть «счастливее».

Внутри схемы смещения подложки 8087

Вы можете задаться вопросом, как чип может превратить положительное напряжение в отрицательное напряжение. Ответ — это схема с накачкой заряда, называемая зарядовый насос. Использует конденсаторы в качестве накопителей заряда, который переносится от одного конденсатора к другому с помощью системы переключателей. «Генератор» смещения в 8087 имеет два зарядовых насоса, работающих по очереди. На приведенных ниже схемах показана работа одного такого зарядового насоса. Зарядовый насос управляется колебательный сигналом (Q) и его инверсией (Q). На первом этапе включается верхний транзистор, в результате чего конденсатор заряжается до 5 вольт относительно земли. Второй этап — это то место, где происходит волшебство. Нижний транзистор включается, соединяя сторону высокого напряжения конденсатора с землей. Поскольку конденсатор все еще заряжается до 5 вольт, нижняя сторона конденсатора должна теперь составлять -5 вольт, создавая желаемое отрицательное напряжение на выходе. Когда осциллятор снова переворачивается, верхний транзистор включается, и цикл повторяется. Зарядовый насос получил такое название, так как он накачивает заряд с выхода на землю. Зарядовый насос аналогичен ручному водяному насосу.

Я осмотрел чип под микроскопом. Металлический слой скрывает транзисторы внизу, а это затрудняет просмотр схемы. Но, сняв слой металла при помощи соляной кислотой, я добрался до слоев поликремния и кремния, «обнаружил» транзисторы и конденсаторы, показано ниже.(Цветные области — это просто помехи, так как некоторые оксиды не были полностью удалены). На фото ниже показано два зарядовых насоса: один слева от контактной площадки, а второй внизу. Каждый зарядовый насос в соответствии схеме, имеет два диода, большой конденсатор и два транзистора.

Конденсаторы являются наиболее заметной «особенностью» схемы смещения подложки. Хотя на самом деле их размеры микроскопические, они огромны по стандартам измерения габаритов чипа. Площадь под конденсаторы составляет примерно как регистровая память в 72 бита, (больше чем 400 транзисторов). Каждый конденсатор состоит из поликремния над кремниевой частью, разделенной изолирующим оксидом; поликремний и кремний образуют пластины конденсатора. На фотографии конденсаторы усеяны квадратами; эти квадраты являются контактами между поликремнием (или кремнием) и металлическим слоем сверху. (Металлический слой не виден, поскольку он был стерт).

Четыре управляющие транзисторы это транзисторы большой мощности. Их размеры превосходят обычные транзисторы. Красные линии — это поликремниевые соединения, образующие затвор. Зеленые линии — контакты к металлическому слою, подключающие транзисторы к +5 В или земле. Диоды рядом с контактной площадкой формируются из транзисторов при соединении затвора и стока.

Зарядовые насосы приводятся в действие круговым осциллятором, как показано на изображении ниже. Этот круговой осциллятор состоит из пяти инверторов в петле короткого замыкания. Поскольку число инверторов нечетное, система нестабильна и будет осциллировать. Например, если вход для первого инвертора равен 0, выход пятого инвертора будет равен 1. Чтобы замедлить скорость колебаний, в кругу — две резистивно-емкостные цепи. Поскольку для зарядки и разрядки конденсатора потребуется некоторое время, колебания будут замедляться, что даст время для работы зарядовому насосу.

Прежде чем разложить информацию о круговом осцилляторе, я продемонстрирую, как реализован стандартный NMOS инвертор в кремнии. Ниже показан — инвертор, его схематическое изображение и то, как он воплощен на чипе. Инвертор использует транзистор и нагрузочный резистор (который в действительности является транзистором). Если входной сигнал низкий, транзистор выключен, то нагрузочный резистор подает на выход до +5 В. Если входной сигнал высок, транзистор включен, выходное напряжение подается на землю. Таким образом, схема инвертирует вход.

Легированный кремний на изображении — это большие участки бежевого цвета. Тонкие желтые участки, рядом с фиолетовыми, — поликремниевые. Вход представляет собой поликремниевый провод. Там, где он пересекается с легированным кремнием, он образует затвор транзистора между землей (ниже входа) и выходом (над входом). Нагрузочный резистор реализован в транзисторе, который имеет затвор и сток, соединенные вместе; указанный контакт образует это соединение между транзисторным поликристаллическим кремниевым затвором и его кремниевым стоком. Поликремний также образует выходной провод. Таким образом, инвертор на чипе реализован с двумя транзисторами.

На фото выше показано, как образуется круговой осциллятор на кристалле. Изображены все пять инверторов. Каждый инвертор имеет разное направление, что оптимизирует структуру.Также обозначены резисторы и конденсаторы R-C цепи. Резисторы — просто транзисторы с большим расстоянием между истоком и стоком, уменьшающие движение тока. Конденсаторы же сконструированы как конденсаторы зарядового насоса, но намного меньше в размерах; кремний на дне и поликремний сверху образуют конденсаторные пластины, разделенные тонким изолирующим оксидным слоем.

Выводы

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

Хотя генератор смещения напряжения может показаться неясным моментом в компьютерной истории 1970-х годов, этот процесс по-прежнему является частью современных интегральных схем, правда все стало намного сложнее.

Несмотря на то, что чип Intel 8087 с плавающей запятой был разработан и введен в эксплуатацию 38 лет назад, его «влияние» ощутимо и сегодня. Благодаря его появлению, был принят стандарт IEEE 754 — «стандарт IEEE, описывающий формат представления чисел с плавающей точкой. Используется в программных (компиляторы с разных языков программирования) и аппаратных (CPU и FPU) реализациях арифметических действий (математических операций)». Инструкции 8087 остаются частью процессоров x86.

Примечания и ссылки

1. Для сопроцессора было введено более 60 новых инструкций, название которых начиналось на «F», для того, чтобы отличать их от целочисленных инструкций Intel 8086. Например, аналоги команд ADD/MUL/CMP, в 8087 выглядели как FADD/FMUL/FCOM. Эти инструкции были реализованы с помощью команды ESC «escape» 8086, которая была разработана, чтобы позволить процессору 8086 взаимодействовать с сопроцессором.

Появление сопроцессора привело к созданию стандарта IEEE 754 в 1985 году для арифметики с плавающей точкой;

2. Наложение отрицательного напряжения смещения на подложку имело несколько преимуществ. Это уменьшило паразитную емкость, что ускорило работу чипа, сделало пороговое напряжение транзистора более предсказуемым и уменьшило ток утечки.

3. Раньше DRAM и микропроцессорные чипы часто требовали наличия трех источников напряжения: + 5 В (Vcc), +12V (Vdd) и -5V (Vbb). В конце 1970-х годов усовершенствованная технология производства чипов позволила использовать один источник питания. Например, MK4116 от Mostek (16-килобайтная DRAM с 1977 года) требовал трех источников напряжения, в то время как улучшенный MK4516 (1981) работал на одном +5 В, упрощая тем самым конструкции аппаратных средств. С чипами Intel происходило то же самое: 2116 DRAM (16K, 1977) с использованием трех напряжений и улучшенный 2118 (1979) — одно напряжение. Известный микропроцессор Intel 8080 (1974 год) использовал транзисторы, работающие в режиме обогащения, потому требовал трех напряжений. Улучшенная версия, 8085 (1976 год), использовала транзисторы с режимом обеднения и питалась от одного источника питания в +5 В.

4. Третий (+12 В) источник питания в старых чипах не имеет отношения к смещению подложки. Этот источник использовался, потому что в ранних MOS-интегральных схемах были транзисторы, работающие в режиме обогащения, повышающие напряжение на затворах. Эти транзисторы не могли вытянуть сигналы вплоть до +5 В, добавили еще более высокий источник питания +12 В. В середине 1970-х годов новая технология (ионная имплантация) позволила создать транзисторы работающие в режиме обеднения, необходимость в +12 В была исчерпана.

5. Я немного упростил материал при обсуждении зарядового насоса. Из-за падения напряжения в транзисторах напряжение подложки, вероятно, будет около -3 В, а не -5 В. Под направлением насоса я имею в виду ток. Если вы думаете об этом как о перекачивании электронов, отрицательные электроны накачиваются в противоположном направлении подложки.

Спасибо, что остаетесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас оформив заказ или порекомендовав знакомым, 30% скидка для пользователей Хабра на уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps от $20 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps до декабря бесплатно при оплате на срок от полугода, заказать можно тут.

Dell R730xd в 2 раза дешевле? Только у нас 2 х Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 ТВ от $249 в Нидерландах и США! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?


ссылка на оригинал статьи https://habr.com/post/424889/

Идентификация мошенничества с использованием Enron dataset. Часть 1-ая, подготовка данных и отбор признков

Корпорация Enron — это одна из наиболее известных фигур в американском бизнесе 2000-ых годов. Этому способствовала не их сфера деятельности (электроэнергия и контракты на ее поставку), а резонанс в связи с мошенничеством в ней. В течении 15 лет доходы корпорации стремительно росли, а работа в ней сулила неплохую заработную плату. Но закончилось всё так же быстротечно: в период 2000-2001гг. цена акций упала с 90$/шт практически до нуля по причине вскрывшегося мошенничества с декларируемыми доходами. С тех пор слово "Enron" стало нарицательным и выступает в качестве ярлыка для компаний, которые действуют по аналогичной схеме.

В ходе судебного разбирательства, 18 человек (в том числе крупнейшие фигуранты данного дела: Эндрю Фастов, Джефф Скиллинг и Кеннет Лей) были осуждены.

image![image](http://https://habrastorage.org/webt/te/rh/1l/terh1lsenbtg26n8nhjbhv3opfi.jpeg)

Вместе с тем были опубликованы архив электронной переписки между сотрудниками компании, более известный как Enron Email Dataset, и инсайдерская информация о доходах сотрудников данной компании.

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

Описание датасета

Enron dataset (датасет) — это сводный набор открытых данных, что содержит записи о людях, работающих в приснопамятной корпорации с соответствующим названием.
В нем можно выделить 3 части:

  • payments_features — группа, характеризующая финансовые движения;
  • stock_features — группа, отражающая признаки связанные с акциями;
  • email_features — группа, отражающая информацию об email-ах конкретного человека в агрегированном виде.

Конечно же, присутствует и целевая переменная, которая указывает, подозревается ли данный человек в мошенничестве (признак ‘poi’).

Загрузим наши данные и начнём с работу с ними:

import pickle with open("final_project/enron_dataset.pkl", "rb") as data_file:     data_dict = pickle.load(data_file)

После чего превратим набор data_dict в Pandas dataframe для более удобной работы с данными:

import pandas as pd import warnings warnings.filterwarnings('ignore') source_df = pd.DataFrame.from_dict(data_dict, orient = 'index') source_df.drop('TOTAL',inplace=True)

Сгруппируем признаки в соответствии с ранее указанными типами. Это должно облегчить работу с данными впоследствии:

payments_features = ['salary', 'bonus', 'long_term_incentive',                      'deferred_income', 'deferral_payments', 'loan_advances',                      'other', 'expenses', 'director_fees', 'total_payments'] stock_features = ['exercised_stock_options', 'restricted_stock', 'restricted_stock_deferred','total_stock_value']  email_features = ['to_messages', 'from_poi_to_this_person',                   'from_messages', 'from_this_person_to_poi',                   'shared_receipt_with_poi'] target_field = 'poi'

Финансовые данные

В данном датасете присутствует известный многим NaN, и выражает он привычный пробел в данных. Иными словами, автору датасета не удалось обнаружить какой-либо информации по тому или иному признаку, связанному с конкретной строкой в датафрейме. Как следствие, мы можем считать, что NaN это 0, поскольку нет информации о конкретном признаке.

payments = source_df[payments_features] payments = payments.replace('NaN', 0)

Проверка данных

При сравнении с исходной PDF, лежащей в основе датасета, оказалось, что данные немного искажены, поскольку не для всех строк в датафрейме payments поле total_payments является суммой всех финансовых операций данного человека. Проверить это можно следующим образом:

errors = payments[payments[payments_features[:-1]].sum(axis='columns') != payments['total_payments']] errors.head()

2 некорректные строки
Мы видим, что BELFER ROBERT и BHATNAGAR SANJAY имеют неверные суммы по платежам.

Исправить данную ошибку можно, сместив данные в ошибочных строках влево или вправо и посчитав сумму всех платежей еще раз:

import numpy as np shifted_values = payments.loc['BELFER ROBERT', payments_features[1:]].values  expected_payments = shifted_values.sum() shifted_values = np.append(shifted_values, expected_payments) payments.loc['BELFER ROBERT', payments_features] = shifted_values  shifted_values = payments.loc['BHATNAGAR SANJAY', payments_features[:-1]].values payments.loc['BHATNAGAR SANJAY', payments_features] = np.insert(shifted_values, 0, 0)

Данные по акциям

stocks = source_df[stock_features] stocks = stocks.replace('NaN', 0)

Выполним проверку корректности и в этом случае:

errors = stocks[stocks[stock_features[:-1]].sum(axis='columns') != stocks['total_stock_value']] errors.head()

image

Исправим аналогично ошибку в акциях:

shifted_values = stocks.loc['BELFER ROBERT', stock_features[1:]].values  expected_payments = shifted_values.sum() shifted_values = np.append(shifted_values, expected_payments) stocks.loc['BELFER ROBERT', stock_features] = shifted_values  shifted_values = stocks.loc['BHATNAGAR SANJAY', stock_features[:-1]].values stocks.loc['BHATNAGAR SANJAY', stock_features] = np.insert(shifted_values, 0, shifted_values[-1])

Сводные данные по электронной переписке

Если для данных финансов или акций NaN был эквивалентен 0, и это вписывалось в итоговый результат по каждой из этих групп, в случае с email NaN разумнее заменить на некое дефолтное значение. Для этого можно воспользоваться Imputer-ом:

from sklearn.impute import SimpleImputer imp = SimpleImputer()

Вместе с тем будем считать дефолтное значение для каждой категории (подозреваем ли человек в мошеничестве) отдельно:

target = source_df[target_field]  email_data = source_df[email_features] email_data = pd.concat([email_data, target], axis=1) email_data_poi = email_data[email_data[target_field]][email_features] email_data_nonpoi = email_data[email_data[target_field] == False][email_features]  email_data_poi[email_features] = imp.fit_transform(email_data_poi) email_data_nonpoi[email_features] = imp.fit_transform(email_data_nonpoi) email_data = email_data_poi.append(email_data_nonpoi)

Итоговый датасет после коррекции:

df = payments.join(stocks) df = df.join(email_data) df = df.astype(float)

Выбросы

На финальном шаге данного этапа удалим все выбросы (outliers), что могут исказить обучение. В то же время всегда стоит вопрос: как много данных мы можем удалить из выборки и при этом не потерять в качестве обучаемой модели? Я придерживался совета одного из лекторов ведущих курс по ML (машинное обучение) на Udacity — ”Удалите 10 штук и проверьте на выбросы еще раз”.

first_quartile = df.quantile(q=0.25) third_quartile = df.quantile(q=0.75) IQR = third_quartile - first_quartile outliers = df[(df > (third_quartile + 1.5 * IQR)) | (df < (first_quartile - 1.5 * IQR))].count(axis=1) outliers.sort_values(axis=0, ascending=False, inplace=True) outliers = outliers.head(10) outliers

Одновременно с этим мы не будем удалять записи, что являются выбросами и относятся к подозреваемым в мошенничестве. Причина в том, что строк с такими данными всего 18, и мы не можем жертвовать ими, поскольку это может привести к недостатку примеров для обучения. Как следствие, мы удаляем только тех, кто не подозревается в мошенничестве, но при этом имеет большое число признаков, по которым наблюдаются выбросы:

target_for_outliers = target.loc[outliers.index] outliers = pd.concat([outliers, target_for_outliers], axis=1) non_poi_outliers = outliers[np.logical_not(outliers.poi)] df.drop(non_poi_outliers.index, inplace=True)

Приведение к итоговом виду

Нормализуем наши данные:

from sklearn.preprocessing import scale df[df.columns] = scale(df)

Приведем целевую переменную target к совместимому виду:

target.drop(non_poi_outliers.index, inplace=True) target = target.map({True: 1, False: 0}) target.value_counts()

image
В итоге 18 подозреваемых и 121 тех, кто не попал под подозрение.

Отбор признаков

Пожалуй один из наиболее ключевых моментов перед обучением любой модели — это отбор наиболее важных признаков.

Проверка на мультиколлинеарность

import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline sns.set(style="whitegrid")  corr = df.corr() * 100  # Select upper triangle of correlation matrix mask = np.zeros_like(corr, dtype=np.bool) mask[np.triu_indices_from(mask)] = True  # Set up the matplotlib figure f, ax = plt.subplots(figsize=(15, 11))  # Generate a custom diverging colormap cmap = sns.diverging_palette(220, 10)  # Draw the heatmap with the mask and correct aspect ratio sns.heatmap(corr, mask=mask, cmap=cmap, center=0,             linewidths=1, cbar_kws={"shrink": .7}, annot=True, fmt=".2f")

image
Как видно из изображения, у нас присутствует выраженная взаимосвязь между ‘loan_advanced’ и ‘total_payments’, а также между ‘total_stock_value’ и ‘restricted_stock’. Как уже было упомянуто ранее, ‘total_payments’ и ‘total_stock_value’ являются всего лишь результатом сложения всех показателей в конкретной группе. Поэтому их можно удалить:

df.drop(columns=['total_payments', 'total_stock_value'], inplace=True)

Создание новых признаков

Также существует предположение, что подозреваемые чаще писали пособникам, нежели сотрудникам, которые были не замешаны в этом. И как следствие — доля таких сообщений должна быть больше, чем доля сообщений рядовым сотрудникам. Исходя из данного утверждения, можно создать новые признаки, отражающие процент входящих/исходящих, связанных с подозреваемыми:

df['ratio_of_poi_mail'] = df['from_poi_to_this_person']/df['to_messages'] df['ratio_of_mail_to_poi'] = df['from_this_person_to_poi']/df['from_messages']

Отсев лишних признаков

В инструментарии людей, связанных с ML, есть множество прекрасных инструментов для отбора наиболее значимых признаков (SelectKBest, SelectPercentile, VarianceThreshold и др.). В данном случае будет использован RFECV, поскольку он включает в себя кросс-валидацию, что позволяет вычислить наиболее важные признаки и проверить их на всех подмножествах выборки:

from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(df, target, test_size=0.2, random_state=42)

from sklearn.feature_selection import RFECV from sklearn.ensemble import RandomForestClassifier forest = RandomForestClassifier(random_state=42) rfecv = RFECV(estimator=forest, cv=5, scoring='accuracy') rfecv = rfecv.fit(X_train, y_train) plt.figure() plt.xlabel("Number of features selected") plt.ylabel("Cross validation score of number of selected features") plt.plot(range(1, len(rfecv.grid_scores_) + 1), rfecv.grid_scores_, '--o') indices = rfecv.get_support() columns = X_train.columns[indices] print('The most important columns are {}'.format(','.join(columns)))

image
Как можно увидеть, RandomForestClassifier посчитал, что только 7 признаков из 18 имеют значение. Использование остальных приводит к снижению точности модели.

The most important columns are bonus, deferred_income, other, exercised_stock_options, shared_receipt_with_poi, ratio_of_poi_mail, ratio_of_mail_to_poi

Эти 7 признаков будут использованы в дальнейшем, дабы упростить модель и уменьшить риск переобучения:

  • bonus
  • deferred_income
  • other
  • exercised_stock_options
  • shared_receipt_with_poi
  • ratio_of_poi_mail
  • ratio_of_mail_to_poi

Изменим структуру обучающей и тестовой выборок для будущего обучения модели:

X_train = X_train[columns] X_test = X_test[columns]

Это конец первой части, описывающей использование Enron Dataset в качестве примера задачи классификации в ML. За основу взяты материалы из курса Introduction to Machine Learning на Udacity. Также есть python notebook, отражающий всю последовательность действий.


ссылка на оригинал статьи https://habr.com/post/424891/

Насколько большим может быть дрон на солнечных батареях?

Идея кажется гениальной: разместить на дроне солнечные батареи, и тогда ему не нужен будет аккумулятор. Без него дроном можно управлять, пока светит солнце. Это прекрасно (предполагая, что ваши намерения чисты). Именно это проделали студенты Сингапурского национального университета.

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

Солнечная энергия

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

Энергетический выход солнечных батарей зависит от следующих величин:

  • Мощности Солнца. Мощность солнечной энергии на поверхности Земли равняется примерно 1000 Вт на квадратный метр. Это значение изменить нельзя, не изменив Солнце (что не рекомендуется делать) (Е)
  • Размер солнечной батареи. Чем больше батарея, тем больше мощность. Начнём с 0,04 м2 (А)
  • Эффективность солнечной батареи. Просто потому, что на панель падает 1000 Вт/м2, не означает, что вся эта энергия превратится в электричество. Мне кажется достоверной цифра в 28% (е)
  • Угол ориентации. Лучше, если солнечный свет падает на панель перпендикулярно. Но Солнце, скорее всего, не будет находиться прямо в зените. Как насчёт угла θ = 45°?

В результате мы получим энергетический выход по следующему уравнению:

$ P = e A E cos \theta $

И это солнечная мощность.

Энергия полёта

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

Начнём с природы сил и движения. Чтобы придать покоящемуся предмету скорость, требуется сила. Размер силы зависит от массы предмета, величины скорости и времени, за которое происходит её изменение. Заменим предмет на воздух – именно его используют наши аппараты для полётов. Реактивную силу можно увеличить, используя большую массу воздуха или большую площадь ротора. Также её можно увеличить, увеличив скорость воздуха.

Моделирование тяги квадрокоптера

Аэродинамику вращающегося несущего винта тривиальной назвать нельзя. Однако такие проблемы не останавливали меня раньше на пути к построению упрощённой модели. В следующей, чрезвычайно упрощённой физической модели, я буду считать, что тяга вертолёта появляется благодаря изменению импульса движущегося вниз воздуха. Чтобы достичь достаточной тяги для полёта вертолёта, у нас есть два способа. Можно взять небольшой винт и очень быстро толкать воздух вниз, или взять большой винт и толкать воздух медленнее.

Если площадь винта А, а плотность воздуха ρ, тогда подъёмная сила выражается через скорость воздуха следующим уравнением:

$ F_{подъём} = {{dp_{воздух}} \over {dt} } = {{\rho A v^2} \over {2}} $

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

$ P = {{\rho A v^3} \over {4}} $

Поскольку мощность пропорциональна кубу скорости воздуха, для вертолёта на мускульной силе она должна быть маленькой, а, значит, вертолёт должен быть большим. Так и есть.

Теперь к моему любимому графику. Я знал, что моя модель может оказаться абсолютно несостоятельной, поэтому я изучил данные по реальным вертолётам. Исходя из массы и размера винта, можно вычислить мощность полёта и сравнить её с указанной мощностью двигателя. Вот график – вычисленная мощность против указанной мощности для некоторых вертолётов.

Я был очень удивлён линейности полученных данных.

Больше данных о вертолётах

Один мой друг, увлёкшийся созданием собственного квадрокоптера, показал мне сайт T-Motor, где перечислено множество электромоторов и данных по их эффективности. Вот, какие характеристики там указаны:

  • Размер.
  • Напряжение.
  • Ток.
  • Тяга в зависимости от дросселя.
  • Скорость вращения.
  • Мощность – произведение тока и напряжения.

Что можно с этим сделать? Поскольку у меня есть размер и тяга винта, я могу подсчитать скорость воздуха. Её можно использовать для подсчёта теоретической мощности и сравнить с указанной. Вот, что я получил.

Ага. Всё ещё линейная зависимость. Здесь я уже немного поволновался – казалось маловероятным, что моя упрощённая модель тяги вертолёта сработает на таких масштабах. Причём у графиков даже наклон похож – 0,656 и 0,411. Что означает этот наклон? Он означает, что моя расчётная мощность примерно в 2 раза меньше. Если записать мощность, как:

$ P = {{\rho A v^3} \over {2}} $

Тогда расчётная мощность совпадёт с указанной. Не уверен, откуда взялась двойка. Возможно, я сделал ошибку, взяв производную при подсчётах средней скорости воздуха.

Если у нас есть данные, можно построить ещё один график, призовой. Зависимость моей расчётной скорости воздуха от скорости вращения винта.

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

Обратно к солнечной энергии

Но ведь нам не нужна тяга, нам нужна мощность. Увеличение скорости воздуха увеличивает его кинетическую энергию. Чем быстрее увеличивается кинетическая энергия, тем больше для этого требуется мощности.

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

Подсчёт мощности полёта

Вместо того, чтобы учитывать все возможные варианты размера квадрокоптера, винтов и солнечных панелей, а также их эффективности, я просто сделал калькулятор – программу на Python, считающую размер винта, необходимого для того, чтобы аппарат летал при заданных параметрах.

С моими первоначальными прикидками я получил диаметр винта равным 5,9 см. Звучит правдоподобно. А все варианты с увеличением массы или изменением размера солнечных панелей теперь можно подсчитать на калькуляторе.


ссылка на оригинал статьи https://habr.com/post/424795/

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

Захотелось мне сделать хитрый код, который бы не давал отладчику remix себя отлаживать.
Идея проста.
Отладчик загружает код, парсит его, получает последовательность команд.
А что если в аргумент команды PUSHnn запихнуть тоже код и на него потом прыгнуть?

Код такой:

00 PUSH4 5b600856
05 PUSH1 01
07 JUMP
08 JUMPDEST

Если его развернуть, то будет:
00 63 PUSH4
01 5b JUMPDEST
02 60 PUSH1
03 08
04 56 JUMP
05 60 PUSH1
06 01
07 56 JUMP
08 5b JUMPDEST

Запустил я транзакцию на создание контракта и получил «Bad jump destination».

Получается, что не только отладчик, но и все клиенты сети парсят код только один единственный раз при загрузке.


ссылка на оригинал статьи https://habr.com/post/424883/