Frikadellen, Fliegen = [], []
for x in AllesZusammen:
(Fliegen, Frikadellen)[IstFrikadelle(x)].append(x)
# або
# (Frikadellen if IstFrikadelle(x) else Fliegen).append(x)
Це вже краще, але все одно було б добре якби до списку додали метод partition. Може б то Ґвідо поскаржитись?
Posted by bunyk
on 23.02.2015Коментарі Вимкнено до vagrant up!
Vagrant – це як висловився dmytrish – CLI до VirtualBox. (А також для інших систем віртуалізації. Перекладається слово як бродяга, і далі ви зрозумієте чому. Для чого там інтерфейс командного рядка? Ну, щоб швидше створювати і перемикатись між віртуальними машинами, а вони сьогодні ой як потрібні.)
Для чого? Ну, для початку – щоб ізолювати середовище розробки. Бо, коли я пишу на своїй машині команду python, мені пропонують наступний вибір:
Трохи забагато, чи не так? А от якби я пробував кожен наступний python у своїй віртуалці – все було б набагато акуратніше.
Чи наприклад інший приклад. Я хочу тестувати взаємодію бота з медіавікі. Для цього мені бажано її мати (не тестувати ж на живій, а раптом помилку зроблю?), а їй потрібен LAMP-стек, тобто апач або nginx, php, mysql. І це потрібно мені не завжди, а лише поки я ганяю тести до медіавікі. Було б класно тримати для цього окрему віртуальну машину, щоб можна було її вмикати і вимикати при потребі. Отож, давайте розберемось як Vagrant в такому випадку може допомогти.
Створює в поточній директорії файл з назвою “Vagrant” що містить конфігурацію для запуску віртуальної машини на основі образу 32-х розрядної Ubuntu 12.04.
vagrant up
Запускає віртуальну машину описану в даному файлі.
vagrant ssh
Входить в запущену віртуальну машину.
За замовчуванням Vagrant робить директорію вашого проекту, доступною віртуальній машині за адресою /vagrant. Тому обережно з rm -rf / бо це потре і ваш проект. А окрім цього можете робити з віртуальною машиною що завгодно. Також зручно мати проект і всередині віртуальної машини і на хості, бо можна одночасно редагувати в зручному редакторі з хоста, і деплоїти з віртуалки.
О, щодо розгортання. Ми можемо зайти по SSH і поставити апач, але тоді це доведеться робити всім хто використовуватиме Vagrant з вашим проектом. Замість цього можна скористатись автоматичним деплойментом.
Інструкція пише що Apache ставиться отаким скриптом:
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi
А також директорія яку він хостить перенаправляється на директорію з нашим проектом.
Його можна зберегти в директорії проекту як bootstrap.sh і відредагувати файл Vagrant так, щоб він запускав цей файл при старті машини, якщо цього не було зроблено ним раніше. Тепер наш Vagrant-файл повинен виглядати приблизно так:
Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise32"
config.vm.provision :shell, path: "bootstrap.sh"
end
Якщо машина вже була запущена, їй можна скомандувати перезапуститись і виконати файл провізіонування:
Він каже зробити порт 80 віртуалки доступним на хості як 4567. Щоб зміни мали ефект – перезавантажте машину:
vagrant reload
localhost:4567 повинен показувати вміст файлу index.html, якщо такий наявний в вашому проекті.
Коли ви закінчили роботу з машиною, можна зробити три речі:
vagrant suspend – зберегти стан машини і зупинити її. Плюси – все зберігається як ви й залишили і для старту буде потрібно лише 5-10 секунд. Мінуси – машина займатиме диск, бо потрібно буде записати знімок її пам’яті.
vagrant halt – зупинити всі програми і вимкнути машину. Вміст диску зберігається, вміст оперативки – звісно ні. Старт буде трохи довшим, бо доведеться знову ініціалізувати всі процеси…
vagrant destroy – знищити всі сліди того що ви взагалі працювали з машиною (диск). vagrant up буде працювати ніби вперше. Плюси – нічого не треба зберігати, економиться диск. Мінуси – при старті багато часу піде на провізіонування.
І ще інша перевага Vagrant в тому, що він може керувати не тільки VirtualBox, а й всякими там VMWare, і навіть AWS. Треба просто вказати йому інший провайдер – і ваш сервер в хмарах. Але про це якось іншим разом.
sudo apt-get install nfs-kernel-server # якщо NFS не було встановлено
git clone https://gerrit.wikimedia.org/r/mediawiki/vagrant
cd vagrant
git submodule update --init --recursive
./setup.sh
vagrant up
Тобто так само як ми оголошуємо що змінна myled міститиме рівень напруги на світлодіоді, так само ми оголошуємо що змінна mybutton міститиме рівень напруги на кнопці.
В документації по mbed написано що оголошення DigitalIn можна використовувати на будь-якому виводі, який позначений на схемі синьою міткою. Якщо на вході будь-яка напруга менше 0.8В – міститиме 0, якщо більше 2В – міститиме 1.
Що цікаво, коли я записав вищеподану програму на плату, світлодіод почав світитись, і почав вимикатись лише коли кнопка натиснута. Це пояснюється чудернацькою схемою підключення кнопок – якщо вона розімкнута – на вхід через резистор йде струм. Якщо замкнута – вхід заземляється, і струм йде в землю, тому там нуль.
Інший приклад – з перериванням:
#include "mbed.h"
InterruptIn mybutton(USER_BUTTON);
DigitalOut myled(LED1);
void pressed()
{
myled = !myled;
}
int main()
{
mybutton.fall(&pressed);
while (1) { // без цього - не працює
wait(100);
}
}
Тут з кожним натисканням кнопки світлодіод вмикається або вимикається. Зауважте що тепер ми оголошуємо кнопку не як DigitalIn, а як InterruptIn.
Ок, може пора нарешті попрацювати руками? Хоча страшно, бо кажуть що руками ту плату можна й вбити, якщо створити коротке замикання в неправильному місці. Я от наприклад вирішив спробувати як вона працює окремо від комп’ютера, і замість того аби втикнути USB в комп’ютер, втикнув його в адаптер електричної мережі. Адаптер, як на ньому написано повинен був давати 5.1В 850мА постійного струму. Плата не захотіла моргати до мене світлодіодами, як було запрограмовано, просто LD1 (COM) загорівся загрозливим червоним. Тому напевне спершу піду ще раз інструкцію прочитаю.
Схема виходів. В коді дозволяється використовувати лише ті що написані білим в синіх і зелених прямокутничках.
Шкода що не маю мультиметра, можна було б подивитись яка напруга на яких контактах.
З того що я начитався, виходить що там де написано 5v – є напруга 5В, там де 3V3 – 3.3В. (такий запис – це хитрий спосіб прибрати зайвий символ – десяткову крапку, і зробити підпис компактнішим.) До п’ятивольтового контакту світлодіоди краще приєднувати через резистор. GND – це заземлення (мінус).
В світлодіода довша ніжка – це +, коротша -, або та ніжка що всередині корпусу діода має в собі більше металу – це мінус.
І це можна перевірити, втикаючи світлодіод в 3V3 та GND. Або послідовно з резистором в 5V та GND.
Тепер, давайте зробимо так, щоб наш перемикач з останнього лістингу керував зовнішнім світлодіодом. Для цього втикаємо його мінус в GND, в A5 наприклад втикаємо резистор, і з’єднуємо додатню ніжку діода з резистором.
Замінюємо визначення: DigitalOut myled(LED1); на DigitalOut myled(PC_0);. Перепрошиваємо, і тепер вже зовнішній світлодіод повинен реагувати на нашу кнопку.
Далі я написав програмку яка змушувала б вбудований LED показувати стан піна A5 як входу.
#include "mbed.h"
DigitalIn mycontact(PC_0);
DigitalOut myled(LED1);
int main() {
while (1) {
myled = mycontact;
}
}
І дуже здивувався, бо коли я опускав туди лише одну ніжку резистора – діод засвічувався. Я подумав що струм тече в мене як заземлення і відпустив резистор – діод все одно світився. Дивно. Або я ще чогось не знаю, або в платі якийсь брак. Думаю варто переключитись на вбудовану кнопку до з’ясування обставин.
Що ще хотілось би зробити – так це взаємодію з комп’ютером. Нехай по натисненні кнопки, комп’ютер виконує якусь команду.
Виявляється, що при приєднанні контролера до комп’ютера, він окрім того що розпізнається як диск, ще й додає пристрій який називається /dev/ttyACM* (замість зірочки має бути якесь число). Принаймі так написано в документації.
Ми можемо подивитись що на цьому пристрої, за допомогою команди:
sudo cat /dev/ttyACM0
Якщо треба вийти, то натискаємо Ctrl+A а тоді вводимо команду :quit. Тепер, можемо змусити контролер посилати нашому комп’ютеру всілякі повідомлення по натисненні кнопочки:
InterruptIn mybutton(USER_BUTTON);
Serial pc(USBTX, USBRX);
void pressed()
{
pc.printf("I'm clicked!\r\n");
}
int main()
{
mybutton.fall(&pressed);
while (1) { wait(100); }
}
І тепер, ми можемо змусити якийсь процес читати цей пристрій і виконувати з нього команди. Наприклад такий Python скрипт:
import os
with open('/dev/ttyACM0', 'rb', 0) as f:
while True:
message = f.read(5) # reading 5 byte messages
if message == 'ALARM':
os.system('mplayer -fs /home/bunyk/video/beastie_boys_sabotage.flv')
Замінюємо повідомлення з "I'm clicked!\r\n" на І вийде просто чудова кнопка тривоги наприклад:
Posted by bunyk
on 18.02.2015Коментарі Вимкнено до Привіт “ядерному мікроконтролеру” ;)
Вкотре переконуюсь що якщо чогось дуже хочеш – то отримаєш. Так от я хотів якось спробувати скласти гірлянду якою можна буде керувати з комп’ютера, трохи думав про Arduino, і недавно мені в руки для тестування потрапила плата NUCLEO-F411RE від компанії STMicroelectronics. Все завдяки автору сайту embedded.co.ua, Василю Йосипенку, якому за це величезне дякую.
Почну з того що на платі надруковане посилання: www.st.com/stm32nucleo. І наклеєна наклейка NUCLEO-F411RE. З діаграми на сайті видно що F411 це найшвидша плата, яка має найбільший розмір флеш-пам’яті – 512K. Аж пів метра!
Далі я звісно перейшов на сторінку плати і почав RTFM. Ось інструкція.
Там в розділі Getting Started знайшов таке:
Перевірте наявність на платі джамперів:JP1 знятий, JP5 (PWR) в позиції U5V, JP6 (IDD) вставлений, CN2 вставлені (NUCLEO). Їх довелось довго шукати, бо всіляких конекторів резисторів та інших деталей на платі трохи є, і вони досить дрібненькі. Але коли я приблизно вивчив їх розташування, виявилось що вже все правильно встановлено.
Для коректної ідентифікації пристрою встановіть драйвери з сайту.Для Linux їх я там не знайшов, тому забив. Але виявилось що й без того мій Linux розпізнав цю плату як диск. На ньому виявився невеликий файл mbed.html, що перенаправляв на https://developer.mbed.org/platforms/ST-Nucleo-F411RE/
Приєднайте плату до комп’ютера за допомогою USB-кабеля type A to mini B. Через USB коннектор CN1. Засвітиться червоні світлодіоди LD3 (PWR) та LD1 (COM). LD1 та зелений світлодіод LD2 повинні мигати. Кабель на щастя знайшовся. Добре мати сусіда-фотографа.
Натисніть кнопку B1 (ту що зліва) і спостерігайте як вона змінює частоту мигання LD2. Вона працює!
Дивіться демо програмки, пишіть свої. Яволь! Заради цього я й відкрив інструкцію.
Далі в інструкції я того як залити програмки не знайшов, погуглив, знайшов хабр. Вони хоч і москалі, але написали непогану невелику інструкцію про те як почати бавитись з Nucleo-F401. Тут приведу її скорочений варіант.
Відкривається симпатичне браузерне IDE. В головному меню натискаємо кнопку “New”.
В вікні нового проекту залишаємо платформу ST-Nucleo-F411RE, вибираємо template “Blinky LED test for the ST Nucleo Boards”, виписуємо собі якесь ім’я програми і натискаємо “OK”.
Створюється проект всередині якого є файл main.cpp, що містить наступний код:
#include "mbed.h"
DigitalOut myled(LED1);
int main() {
while(1) {
myled = 1; // LED is ON
wait(0.2); // 200 ms
myled = 0; // LED is OFF
wait(1.0); // 1 sec
}
}
Натискаємо кнопку “Compile”. Через деякий час, якщо не сталось ніяких помилок, браузер пропонує нам завантажити файл Nucleo_blink_led_NUCLEO_F411RE.bin, чи з подібною назвою, залежно від того як ви назвали свою програму.
Зберігаємо цей файл прямо в директорію /media/NUCLEO. Так, не треба писати образ ні на які пристрої за допомогою dd, просто скидуємо файл. Червоний світлодіод LD1 (COM) почне мигати зеленим, що означає що дані пишуться.
Коли COM припинить мигати, частота мигання LD2 зміниться, і він перестане реагувати на натискання кнопки B1, а це означає що прошивка змінилась. Ура! Вперше якась мікросхема мигає світлодіодом так як я їй сказав. В директорії /media/NUCLEO ніякого нашого файлу видно не буде, що означає що це таки емуляція диску. Думаю не варто туди якісь інші файли кидати, а то ще не так перепрошиється.
Хоча ні, мигає вона ще не так як я сказав, а так як в прикладі показано. Якщо в нас як пристрій виводу – лише одна лампочка, то крім коду Морзе варіантів мало.
hello world на морзянці виглядає так:
…. . .-.. .-.. — / .– — .-. .-.. -..
Hello world нам моргає
Прогалик розділяє букви, / – розділяє слова.
Існує такий стандарт:
Довжина крапки – 1
Довжина тире – 3
Відстань між частинами однієї букви – 1
Відстань між окремими буквами – 3
Відстань між словами – 7
Зібравши це все до купи, і так як в прикладі програми було щось схоже на C, і назва файлу main.cpp теж натякає, переклавши все на C, отримаємо таке:
Ну ось, думаю поки що вистачить. Виявилось набагато простіше ніж я думав. Завтра спробую отримати ввід з вбудованої кнопки, і покерувати зовнішнім світлодіодом, а то вбудовані вже спаяні до мене, і ні про який закон Ома думати не треба. На щастя світлодіоди разом з резисторами і метром проводу для них коштують дешевше ніж поїздка в трамваї, тому дістати їх – нема проблеми. Хоча сама плата в Україні коштує більше ніж 600 грн: http://www.kosmodrom.com.ua/prodlist.php?name=nucleo
Posted by bunyk
on 09.02.2015Коментарі Вимкнено до Як видалити платні речі з AWS
За січень привалив рахунок на 4 з копійками долари, через те що якісь тестери настворювали в моєму тестовому аккаунті на AWS волюмів і лоад балансерів. А так як це вже не вперше, і мені надоїло перевіряти кожен регіон на наявність вказаних в білінгу пунктів, вирішив написати для цієї справи скрипта. Правда якщо ним захочете користуватись ви – треба ще розширити його інстансами, бакетами і всім іншим за що амазон може здирати бабло.
Дивуюсь чому вони замість повідомлення про перевищення бюджету не зроблять функцію автоматичного вимикання зайвих послуг.
Ах, скрипт:
from boto.ec2.connection import EC2Connection
import boto.ec2.elb
def main():
ec2 = EC2Connection()
for region in ec2.get_all_regions():
print 'Region:', region.name
process_region(region)
def process_region(r):
c = r.connect()
for volume in c.get_all_volumes():
print '\tVolume:', volume.id
if volume.attachment_state() == u'attached':
volume.detach()
volume.delete()
c = boto.ec2.elb.connect_to_region(r.name)
for lb in c.get_all_load_balancers():
print '\tLoad balancer:', lb
if __name__ == '__main__':
main()