Video
youtube
Год назад, когда я в первый раз посмотрел это интервью, то восхитился логикой мышления интервьюируемого и в целом объяснение мне было понятно. Однако код, который он писал, тогда был для меня скорее похож на китайскую грамоту. Сейчас я посмотрел интервью еще раз, и уже попытался интерпретировать его решение для Python. Оказалось, при желании все возможно. И код выглядит не так устрашающе, как на C++. И кажется, что не так уж это и сложно. Однако насколько здор��во уметь не замыкаться в себе при встрече с заковыристым вопросом, а продолжать размышлять вслух и в результате найти ответ. Думаю. не каждый способен на такое в состоянии стресса.
первый подход
test1 = [1,2,3,4,4,6,9] def has_sum(data, target): low = 0 high = len(data)-1 for _i in range(high): s = data[low] + data[high] if s == target: return True low += 1 return False has_sum(test1, 9)
второй подход
test2 = [1,2,1,1,1,3,1,3,9] def has_sum_unordered(data, target): cache = set() for value in data: if value in cache: print(f'found {value}') return True cache.add(target - value) return False has_sum_unordered(test2,10)
1 note
·
View note
Text
Занимательные функции в Bash profile на macOS
Без лишних предисловий просто расскажу о функциях bash profile, которыми сам пользуюсь.
Изменение громкости
Для того, чтобы изменить громкость звука в macOS с помощью терминала, добавьте в ~/.profile (или ~/.bash_profile, в зависимости от того, что у вас там есть) такую функцию:
function vl() { osascript -e "set Volume $1" }
Теперь можно изменять громкость системного звука с помощью команды vl и параметра от 0 до 7. Причем можно задавать промежуточные значения, например 3.5 (50% громкости)
Включение-выключение VPN (IPSec)
Если вы пользуетесь VPN по протоколу IPSec, то с помощью этой функции вы сможете включать и выключать настроенный профиль (предполагается, что профиль VPN уже есть у вас в системе), а также узнать статус подключения.
function uvpn() { INFO=`scutil --nc list` status=$(echo "${INFO}" | awk '{if (NR!=1) print$2}' | sed -e 's/[()]//g') vpnName=$(echo "${INFO}" | awk 'BEGIN {ORS=" "}; {if (NR!=1) for(i = 5;i <= NF-1; i++) print$i}' | sed -e 's/"//g') vpnID=$(echo "${INFO}" | awk '{if (NR!=1) print$3}') case "$1" in start) echo "started $vpnName" scutil --nc $1 $vpnID;; stop) echo "stopping $vpnName" scutil --nc $1 $vpnID status=$(scutil --nc list | awk '{if (NR!=1) print$2}' | sed -e 's/[()]//g') sleep .5 echo VPN is $status;; *) echo VPN is $status;; esac }
Запуск uvpn без параметров покажет состояние подключения. Соответственно uvpn start и uvpn stop довольно self-explanatory. К сожалению, если у вас IKEv2 VPN, этот скрипт не поможет. В интернете есть для этого решение с помощью Apple Script, но я его не тестировал.
Управление охлаждением процессора
Для работы этого скрипта вам понадобится установить программу SMCFanControl. Несмотря на то, что данная улитита старая и проверенная, разработчик напоминает, что программу стоит запускать на свой страх и риск, и что манипуляции с вентиляторами процессора могут привести к выходу компьютера из строя. Короче, я предупредил.
alias smc="/Applications/smcFanControl.app/Contents/Resources/smc" function fan() { RPM=$2 FANSTOTAL=$(smc -f | awk 'BEGIN { FS=": " } ; {print $2}' | head -1) case "$1" in auto|-a|reset|-r) smc -k "FS! " -w 0000 echo Fan speed is set to auto mode ;; set|-s) echo Total fans amount: $FANSTOTAL for i in $(seq 1 $FANSTOTAL); do smc -k "FS! " -w 0003 smc -k F`expr $i - 1`Tg -w `printf '%x\n' $(expr $RPM \* 4)` done echo Fan speed is set to $RPM ;; *) smc -f;; esac }
Описание:
fan set 3500 установит скорость 3500 RPM для каждого вентилятора в системе.
fan auto вернет режим работы вентиляторов по умолчанию
fan с любыми другими параметрами или с пустым аргументом просто покажет информацию о текущем состоянии вентиляторов.
Кстати, вместо функции в bash profile, можно добавить скрипт в /usr/local/bin.
vim /usr/local/bin/fanfun
#!/bin/bash set -e FANSTOTAL=$(smc -f | awk 'BEGIN { FS=": " } ; {print $2}' | head -1) RPM=$2 case "$1" in auto|-a|reset|-r) smc -k "FS! " -w 0000 echo Fan speed is set to auto mode;; set|-s) echo Total fans amount: $FANSTOTAL for i in $(seq 1 $FANSTOTAL); do smc -k "FS! " -w 0003 smc -k F`expr $i - 1`Tg -w `printf '%x\n' $(expr $RPM \* 4)` done echo Fan speed is set to $RPM ;; help|-h) echo "----------------------" echo "'fan set <number>' or 'fan -s <number>' to force fan speed" echo "'fan reset' or 'fan -r' to reset fan status to default" echo "----------------------" smc -f;; *) smc -f;; esac
В этом случае надо будет сделать симлинк на программу smc.
ln -s /Applications/smcFanControl.app/Contents/Resources/smc /usr/local/bin/smc
А также сделать скрипт исполняемым:
chmod +x /usr/local/bin/fanfun
1 note
·
View note
Text
Can't stop
1 note
·
View note
Text
Roundtrip from Edius to Davinci Resolve
To make proper roundtrip from editing in EDIUS to colorgrade in Davinci Resolve, you would probably use oficial AAF roundtrip workflow. This workflow will suffice if you work with files locally on your machine. In case you have network located files on your timeline, you will get a 'Files not found' error when you put AAF with colorgraded files back to EDIUS. Thats why I use AAF-to-XML roundtrip which is undocumented but still possible.
For some reason the UNC paths to network-located media written by Davinci will not be located by EDIUS. This is not a Davinci Resolve issue, because this workflow works correctly in Adobe Premiere. Thats why we need to fix the XML with some magic!
Our roundtrip consists of two simple steps:
Edit in Edius and export AAF to Davinci Resolve for color correction
Put back color corrected clips back to Edius Timeline with XML
from EDIUS to Davinci
When you complete your editing, choose File >> Export Project >> AAF... You will be prompted to select a preset. Choose Type 4:
You can customize export settings according to your needs. I use Copy Option with margin of 1 sec:
Don't forget to check Export between in and out and click Save.
To use Quicktime HQX codec you have to install Quicktime and Edius codecs on your Davinci Resolve Windows machine. To eliminate possible security flaws, uncheck all Quicktime components except the first and necessary one upon installation. Once you have Qucktime installed, Davinci Resolve will recognize any Canopus HQX MOV file on the timeline. If you don't like the idea of QT installation, which is understandable since Apple discontinued Windows version support, you need to export your edit with DNxHD codec. It is available as a part of Edius 8/9 Workgroup version.
Prior to importing AAF file to Resolve, place rendered clips into the Media Pool on the [MEDIA] page.
from Davinci to EDIUS
There you go, when you have colorgraded your edit, now you would like to put it back to Edius to do the final touches. On a deliver page choose Custom >> Render Individual Clips >> Choose Format and Codec. I use MXF OP1a with XDCAM MPEG2, which is nicely supported by EDIUS. Then choose File >> Filename uses -- Source Name >> Add a uniquie name (Prefix/Suffix). Choose render location to your desired network folder. Add to render queue and start render. After all files are done, go to Davinci Resolve EDIT page and choose File >> Export AAF/XML. Export XML to the same network folder where your renders are (this is important).
Well, to get things done we need to import our XML to Edius. I wrote some kind of XML resolver, which will make our rondtrip possible. Here is it:
import os, sys import subprocess from tkinter import filedialog, Tk import xml.etree.ElementTree as ET from urllib.request import urlparse tk_root = Tk() tk_root.withdraw() INIT_DIR = r"\\your\network\located\folder\with\xml\file\and\rendered\files" def open_file(): """put your .xml file in the same network folder where your rendered files are""" xml_in = filedialog.askopenfilename(initialdir=INIT_DIR, filetypes=(("XML", "*.xml"), ("All Files", "*.*"))) try: tree = ET.parse(xml_in) except FileNotFoundError: sys.exit() root_folder = get_root_folder(xml_in) return xml_in, tree, root_folder def get_root_folder(file): ss = urlparse(os.path.split(file)[0]) return ss.netloc def parse_path(fpath, folder): parsed = urlparse(fpath) parsed = parsed._replace(netloc=folder) #set correct hostname return parsed.geturl() def main(): xml_in, tree, folder = open_file() root = tree.getroot() output_file = '{}_to-EDIUS.xml'.format(os.path.splitext(xml_in)[0]) output_folder = os.path.split(xml_in)[0] for tag in root.iter('pathurl'): new_tag = parse_path(tag.text, folder) tag.text = new_tag # field_dom = ET.Element('fielddominance') # field_dom.text = 'upper' # ''' can use `for tag in root.iter('samplecharacteristics'):` for entire text''' # for tag in tree.findall('./sequence/media/video/format/samplecharacteristics'): # tag.append(field_dom) with open(output_file, 'wb') as out: out.write(b'<?xml version="1.0" encoding="UTF-8"?>\n\n') tree.write(out, encoding='utf-8') if os.name == 'nt': subprocess.Popen('explorer /open, {}'.format(os.path.normpath(output_folder))) if __name__ == '__main__': main()
For xml parsing I use standard Python library xml.etree.ElementTree. When the script is launched you will be prompted to choose XML file you exported on previous step. Basically all what we need is to get rid of wrong part of each filepath in XML. These network paths start with file://localhost/, but instead EDIUS looks for proper net location, so localhost has to be replaced with server name. Script will take server name from the location of your XML file, that's why you had to put XML file in the render folder. The result is a new XML file which will work flawlessly in EDIUS. The folder with new file will open automatically.
I know what you're thinking right now. If the problem was simply with wrong file path, why won't we just search and replace? The answer is: YES, you are right. Basically it is what we do, but with XML parser instead of text editor. But look at these commented lines in main() function. You can use the script to modify and change any tag or field in your XML file. For example, you can add field dominance or any other paramerer according to FCP XML 1.0 specifications.
And besides it was fun.
Take care and thanks for reading this!
0 notes
Text
Доступ к Jupyter notebook через Docker и Nginx.
Зачем (мне) это нужно
Для меня Jupyter — это удобная система ввода и просмотра кода, работающая через браузер. Иногда надо протестировать простой Python код, ну не делать же это в терминале! Не всегда есть возможность запустить IDE, не всегда есть физический доступ к машине со всеми установленными пакетами, и так далее. Когда работаешь в Jupyter, достаточно запустить браузер, подключиться по сети к компьютеру с запущенным сервером, ввести код, нажать CTRL+Enter и тут же увидеть результат. Не говоря уже о том, что с помощью Jupyter можно строить графики, изучать языки (в пакете, который использую я, кроме Python есть поддержка языков R и Julia), а также делать заметки или даже писать статьи на Markdown (кстати, эту статью я так и пишу). К тому же, возможность предварительно комментировать код помогает, когда, например, надо пояснить условие задачи с Hackerrank. Вот так, например, выглядит моя страничка, посвященная алгоритмам. Красота же!
Казалось бы, что проще, сделал pip install jupyter, запустил сервер и дело с концом. Но мы же легких путей не ищем. Нам нужны такие условия, которые позволяют иметь под рукой неизменный и полный набор инструментов в каждый момент времени, а это проще всего сделать с помощью Docker образа. Я давно хотел попытаться разобраться с этим способом работы с виртуальной операционной системой, и данный юзкейс подвернулся как раз вовремя. Я решил, что Jupyter у меня будет работать из-под Docker, так что мне не придется настраивать вручную все языки и нужные пакеты, просто скачаю готовый образ, запущу и все будет работать. А если домашний сервер подведет, я могу легко воссоздать те же условия работы, запустив тот же образ на новой машине и перенеся рабочие файлы. Звучит заманчиво, однако если бы и это было так просто, то было бы неинтересно.
Да, действительно, сегодня установить Docker на современный Mac компьютер так же просто, как, скажем, налить чаю или установить игру из App Store. Скачал установщик, запустил, все работает. Файлы виртуальной машины будут автоматически доступны как снаружи сети, так и из вашей машины. Но, как оказалось, мой старый Mac Mini 2010 года не совместим с Docker for Mac. Поэтому вот ниже решение, как все вышеописанное чудо запустить вручную. Для этого, кстати, потребуется еще и nginx, но об этом позже.
Настройка Docker
Итак, сначала мы устанавливаем Docker Toolbox. Напомню, что это legaсy-путь, только для старых компьютеров Apple, которые не поддерживают стандартный Docker.app. Проверить, поддерживает ли ваш компьютер виртуализацию менеджера памяти (MMU) можно с помощью команды
sysctl kern.hv_support
Если ответ отличается от единицы, то добро пожаловать читать дальше. Сейчас пробежимся кратко по шагам установки Docker. Подробные инструкции по установке можно прочитать здесь.
Итак, сначала запускаем Docker Quickstart Terminal. Kitematic не понадобится, зачем нам интерфейс, мы же любим, когда всё по хардкору, так что настраивать все будем из терминала. В целом, на этом шаге уже все должно работать. Просто напишите
docker run --rm hello-world
чтобы убедиться, что тестовый образ скачался и запустился. Теперь можно скачать и установить любой подходящий образ Jupyter. Их довольно много, все зависит от предустановленных пакетов. Список всех доступных вариантов здесь. Для начала можно выбрать base-image.
docker pull jupyter/base-notebook
Затем запустим тестовый образ (используем порт 8888 как на хостовом компьютере, так и в виртуалке):
docker run -it --rm -p 8888:8888 jupyter/base-notebook
Теперь самое время добавить больше параметров. Например, чтобы файлы, сгеренированные в Jupyter, были доступны локально без запуска Docker, нужно создать рабочую папку и связать ее с папкой внутри виртуальной машины. Для этого используем опцию --volume. По умолчанию наша виртуальная машина работает под управлением непривилегированного пользователя jovyan. Укажем докеру, что нам нужно смонтировать папку work домашней директории пользователя jovyan в домашней папке вашего хоста:
docker run -it --rm -d --name jplab --workdir /home/jovyan/work \ -v /Users/barney/docker/work:/home/jovyan/work \ -p 8888:8888 jupyter/base-notebook
Поскольку jupyter notebook должен быть доступен извне сети, хорошо озаботиться тем, чтобы в него можно было залогиниться только по паролю. Для этого можно воспользоваться запущенным на предыдущем этапе приложением. Создайте новый Python Jupyter notebook, откройте браузер на странице localhost:8888, чтобы сгенерировать пароль для Jupyter.
from IPython.lib import passwd passwd()
Пролученный sha1:...-код нужно вставить при создании финального контейнера, с которым уже можно работать. Возможно, вам захочется сделать так, чтобы время внутри виртуальной машины было синзронизировано с временем вашего компьютера. Это будет не так просто, поскольку, напомню, это туториал для пользователей устаревших моделей mac. На новых компьютерах вся эта пляска с бубнами не нужна, достаточно поставить Docker for Mac, скачать образ и время будет синхронизироваться автоматически. На Linux это тоже просто: для синхронизации времени в Docker-образе используют команду -v /etc/localtime:/etc/localtime:ro. На нашем старом mac это не сработает, поэтому придется скопировать содержимое /etc/localtime в локальную папку, например в ~/etc/timezone и использовать следующую команду.
docker run -it -d --name jplab -e JUPYTER_ENABLE_LAB=1 \ --workdir /home/jovyan/work -v /Users/barney/docker/work:/home/jovyan/work \ -v ~/etc/timezone:/etc/localtime:ro -p 8888:8888 jupyter/datascience-notebook:latest \ start-notebook.sh --NotebookApp.password=sha1:*** --NotebookApp.allow_origin=* --NotebookApp.base_url=/jp
Обратите внимание, что мы запустили образ jupyter/datascience-notebook, использовали кастомный скрипт start-notebook.sh, идущий в комплекте с этим образом, для того, чтобы задать параметр base_url, добавить пароль и использовать опцию allow_origin. Также с помощью -e JUPYTER_ENABLE_LAB=1 активируется JupyterLab — новый интерфейс работы с Jupyter notebook. Очень рекомендую его попробовать, в нем множество преимуществ по сравнению с классическим интерфейсом. Для запуска JupyterLab в конце адреса в веб-браузере замените tree на lab.
Теперь Jupyter должен работать локально на вашей машине по адресу localhost:8888/jp. Теперь осталось настроить веб-сервер так, чтобы наша Docker-виртуалка была видна извне сети. Сначала поставим Homebrew (если, конечно, вы этого по какой-то причине до сих пор не сделали). Вставьте в терминале:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Требования к установке Homebrew можно найти тут.
Теперь настроим прокси-сервер nginx:
Установка простая:
brew install nginx
Немного изменим настройки nginx, чтобы наша docker машина была доступна извне. Для этого Nginx должен работать как прокси протокола Websocket. Подробнее об этом можно почитать тут. Еще понадобится локальный ip-адрес, на котором работает докер-машина, его можно узнать командой:
docker-machine ip default
Обычно это 192.168.99.100.
Итак, добавим в /usr/local/etc/nginx/nginx.conf:
upstream websocket { server 192.168.99.100:8888; } server { listen 8888; server_name localhost; location /jp { proxy_pass http://websocket/jp; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; client_max_body_size 10M; }
Теперь запустим nginx:
nginx
и Jupyter должен стать доступен удаленно (при условии, что вы правильно настроили переадресацию портов на 8888).
Рекомендую также настроить логи для nginx. Я, например, столкнулся с тем, что при удаленном доступе вместо интерфейса jupyter была просто пустая страница. Без логов разобраться с этим было непросто. Однако посмотрев в файл juypter_error.log, оказалось, что ошибка связана с неправильными правами доступа к папке /usr/local/var/run/nginx/proxy_temp. Настроить логи можно, добавив в nginx.conf в раздел http, например, такое:
log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"' ; map $status $loggable { ~^[23] 0; default 1; } access_log /usr/local/etc/nginx/log/juypter_access.log main if=$loggable; error_log /usr/local/etc/nginx/log/juypter_error.log;
В этом случае access-log не будет заспамлен сообщениями об удачных операциях. Подробнее почитать про логи в Nginx можно тут.
Вот и все, друзья!
P.S. Тем, кто хочет посмотреть на Docker повнимательнее, можно начать с этой статьи.
P.P.S. Конечно, простого пароля доступа для настоящей секретности недостаточно. По хорошему, нужно настраивать доступ к Jupyter ноутбуку через SSL, а также включить авторизацию пользователей через JupyterHub. Но я с этим пока не разобрался. Думаю начать с регистрации на LetsEncrypt. Подробнее почитать о настройке доступа к Jupyter через https можно тут: https://github.com/jupyterhub/...
0 notes
Text
Так-то лучше
Чей дом в ананасе в пучине морской? Who lives in a pineapple under the sea? Он порист, он жёлт и пропитан водой! Absorbent and yellow and porous is he. Ты вздора морского ждёшь, телик включив? If nautical nonsense be somethin’ ya wish. Сигай к нам на палубу, рыбой скачи! Then drop on the deck and flop like a fish.
0 notes
Photo

—Штурман, приборы! —Пять! —Что «пять»? —А что «приборы»?
1 note
·
View note
Photo

Сын сказал, надо брать квартиру на 13 этаже.
1 note
·
View note