«Имеет место быть»

Имеет место (7.14КиБ)

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

В данной фразе «факты» — главное действующее лицо, они — подлежащее. Факты делают что? Имеют. «Имеют» — сказуемое. «Место» — очевидное дополнение, это объект действия «иметь», которое выполняют «факты». «Факты имеют место», то есть у фактов есть место, то есть факты наличествуют.

Что тут такое «быть»? Откуда оно взялось и что значит в этом предложении? Какой смысл в него вкладывают люди, которые его употребляют в такой форме? Расскажите?

42 комментария

Тибла

Когда я написал про «шевалье», «шваль» и французов, вспомнил про слово «тибла».

«Тибла» — так пренебрежительно называют русских в Эстонии. Догадайтесь от каких русских слов произошла это прозвище. Вот жирный намёк: там есть мат.

21 комментарий

Шевалье → шваль? Нет!

До того, как наткнулся в ЖЖ на довольно убедительное расследование, был уверен, что слово «шваль» произошло от «шевалье». Самая известная теория гласит (с разными вариациями), что дело в войне 1812 года и отступлении армии Наполеона, тогда крестьяне стали звать французов, находящихся в жалком состоянии, «шваль», от «шевалье» как те друг друга называли.

Более убедительная теория, с которой я только что ознакомился, выглядит так: жил-был в 1611 году Иван Прокофьев, по прозвищу «Шваль» (это слово обозначало тогда «портной»), эта самая шваль в обмен на освобождение из плена (был захвачен шведами), открыл в назначенное время ворота Новгорода, позволив шведам завоевать город.

Утверждается, что народ таким образом сохранил память об этом событии.

6 комментариев

Необычные заборы в Лениногорском районе

Синяя металлическая ограда с круглыми вырезами на бетонном парапете в парке, на заднем плане видны деревья и декоративная стена с круглыми элементами.

Мне тут напомнили про необычные заборы, которые, встречаются в Лениногорском районе. Это такие толстые металлические листы с отверстиями (как на фото). Им нет сносу и стоят они в Лениногорске сколько я себя помню (оказывается, в Симферополе тоже такие же попадались, по словам одного из читателей).

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

13 комментариев

Предсказания из прошлого, 1991-й год

Родители оцифровали видео, записанное в 1991-м году на юбилее моего папы, я его сейчас выборочно смотрю (какие все молодые!). Там папа затеял интересное: попытаться на камеру предсказать что произойдёт через пять лет, в 1996-м году, на следующий юбилей.

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

Из того, что сбылось: 1992 году татарский язык становится вторым государственным языком в республике Татарстан (в соответствии с законом Республики Татарстан «О языках народов Республики Татарстан»), в 1992-93 гг талоны исчезли.

С остальным хуже — в 1992 году скорость роста цен на продукты питания снизилась, но сильно повысились цены на ЖКХ, сильно снизились пенсии, выросла смертность и люди вряд ли стали добрее.

Но всё-таки все конкретные прогнозы сбылись.

3 комментария

У МВД какие-то другие данные о численности населения?

Со страницы МВД в сервисе «Вконтакте»:

Общая численность граждан РФ, занятых на службе в МВД, превышает 1 миллион человек — это почти полтора процента населения страны.

Миллион — это полтора процента населения? Я чуть чаем не подавился, выходит, что население России в два раза меньше, чем я привык думать?

Ничего подобного. Согласно данным Росстата, в России проживает 142 914 136 человек. Делим миллион на эту цифру, умножаем на 100, получаем:

(1 000 000 / 142 914 136) × 100% ≈ 0,7%

Всё в порядке.

15 комментариев

Советская остановка буквой «У»

Заброшенный металлический павильон с полом и скамьей, покрытый граффити, стоит на обочине среди травы и берёз; на заднем плане виден забор и здание.

С детства не видел таких остановок, они уже мало где сохранились, эта, заброшенная, находится около деревни Камышла Лениногорского района республики Татарстан. Остались ещё где-нибудь такие?

Добавлено позже: вот что ответил Артемий Лебедев (а он очень много путешествует) на мой вопрос не встречал ли он такие остановки где-то ещё:

На вид что-то из 60-х, тогда стало модным экспериментировать с подобными конструкциями, особенно при дизайне стел на въездах в населённые пункты.

Я такие остановки никогда не встречал.

22 комментария

JS Linux

JS/Linux (27.15КиБ)

Все уже видели Linux на JavaScript, который работает в браузере (нужен Google Chrome 11 или FireFox 4)?

В отличие от моего JUnix, который являлся эмулятором, написанным на JavaScript, это эмулятор процессора x86 с кое-какой периферией, на котором запущен Linux, в котором есть компилятор (tcc, Tiny C Compiler v 0.9.25), в котором можно скомпилировать программу на Си в полноценный ELF и запустить!

Можно сравнить насколько быстрее стали браузеры за прошедшие годы, JUnix я писал в 1999-2001 гг, тогда он еле ворочался, а тут — реализуется железо и это всё быстро работает. Фантастика!

Добавлено позднее: есть более ранний эмулятор Unix V6 на PDP-11, другого автора Шмидта, внутри есть ассемблер (команда as) и Фортран (fc).

Добавлено ещё позднее: 20 мая в JS/Linux была добавлена поддержка «Оперы» 11.11 и IE9.

3 комментария

StackBlur в go-gd

Портировал алгоритм Stack Blur с языка Processing на Google Go, теперь в моей библиотеке go-gd появился метод StackBlur.

Методы Smooth и GaussianBlur, которые я портировал из форка PHP-GD мне не нравились, не давали удобоваримого размытия, StackBlur куда лучше.

Вот небольшое описание этого алгоритма от автора, Марио Клингемана:

This is a compromise between Gaussian Blur and Box blur. It creates much better looking blurs than Box Blur, but is 7x faster than my Gaussian Blur implementation.

I called it Stack Blur because this describes best how this filter works internally: it creates a kind of moving stack of colors whilst scanning through the image. Thereby it just has to add one new block of color to the right side of the stack and remove the leftmost color. The remaining colors on the topmost layer of the stack are either added on or reduced by one, depending on if they are on the right or on the left side of the stack.

Оставить комментарий

Дима…

С 18 мая по 21 мая в Лениногорске. Разбился на машине двоюродный братишка, завтра ему должно было исполниться 22. Не могу представить что чувствуют его родители. Комментарии отключаю. Не пишите, пожалуйста, мне ничего по этому поводу, очень прошу.

Возможно самое старое фото Москвы

Старая Москва (47.23КиБ)

Хочу порекомендовать интересный проект — «Фотографии старой Москвы», на нём собраны фотографии старой Москвы, начиная с 1842 года с привязкой к карте. Если вы живёте или были в Москве, можете посмотреть как выглядели знакомые места в разные годы.

Выше — возможно самая старая фотография Москвы (кстати, я спросил разрешения у владельцев проекта на использования фотографий с сайта):

Старейшее известное фото Москвы. Представляет собой раскрашенный и отретушированный дагерротип Леребура, сделанный в 1842 г. На фотографии виден начальный этап строительства Большого кремлевского дворца.

2 комментария

«Go»: количество го-программ

«Го-программы» (goroutines) — это термин языка «Go», это функции, которые выполняются параллельно, что-то вроде местных потоков. Я пока ещё почти не умею с ними работать, только учусь. Одна из особенностей, на которую я сразу наткнулся, то что в языке есть специальный вызов «GOMAXPROCS» (модуль runtime), который указывает сколько процессоров будет задействованно, чтобы запускать го-программы.

По-умолчанию, «Go» использует только один процессор, вот цитата:

It should be smarter and one day it will be smarter, but until it is if you want CPU parallelism you must tell the run-time how many goroutines you want executing code simultaneously. There are two related ways to do this. Either run your job with environment variable GOMAXPROCS set to the number of cores to use (default 1); or import the runtime package and call runtime.GOMAXPROCS(NCPU).

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

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

package main

import ("syscall"; "runtime")

func main() {
    if n, _ := syscall.SysctlUint32("hw.ncpu"); n > 0 {
        runtime.GOMAXPROCS(int(n))
    }
}

20 комментариев

Незаконная ссылка на блог?

Незаконная ссылка на блог (9.26КиБ)

С сайта студии Артемия Лебедева, раздел юридического отдела студии. Что такое «незаконное использование фотографии Артемия Лебедева и ссылки на его блог»? Про фотографию я понимаю, а как может быть ссылка на блог незаконной?

Добавлено позднее: всё стало ясно, когда я посмотрел на сайт, к которому относилась претензия (спасибо читателю, обратившему моё внимание на это). Судя по всему, кто-то создал анкету на сайте и использовал в ней фото Лебедева и ссылку на его блог. Но я по-прежнему не вижу как ссылку можно назвать незаконной.

9 комментариев

МТС Глонасс 945

МТС Глонасс 945 (13.46КиБ)

Взял посмотреть в агентстве Марины Рожковой телефон МТС Глонасс 945, посмотрю, расскажу о выводах. На фотографии запущена программа «GNSS Test», которая показывает количество и расположение обнаруженных спутников GPS (зелёные точки) и ГЛОНАСС (очень тёмные красные точки).

6 комментариев

Развитие биндинга графической библиотеки «GD» для «Go»

Несколько лет назад авторы языка PHP форкнули библиотеку GD, биндинг к которой для языка Go я вчера написал, и стали развивать собственную версию. В язык PHP входит именно форк.

Исходная библиотека беднее, например, там нет вызова ImageConvolution и всего того, что с ним можно делать (размытие, выделение краёв и так далее), а мне хочется, чтобы в моём биндинге они были. Можно, конечно, выдрать GD из РHP, но я хочу написать более-менее универсальное решение, а во все пакеты на всех платформах входит именно оригинальная библиотека.

Почесав репу, я потратил пару часов, переписал часть PHP-библиотеки GD на «Go» и воткнул её в свой биндинг. Теперь в go-gd есть вызовы GrayScale, Negate, Brightness, Contrast, Color, Convolution, GaussianBlur, EdgeDetectQuick и Emboss.

Оставить комментарий

Биндинг графической библиотеки «GD» для «Go»

Написал за часть ночи и часть утра биндинг к графической библиотеке «GD»: go-gd.

Дело в том, что несмотря на существование модуля «image», в «Go» нет почти ничего для работы с графикой, всё что умеет язык — читать и писать JPEG и PNG (скоро появится поддержка GIF и TIFF), копировать области, получать значение цвета в заданных координатах, рисовать прямоугольники и точки. Это всё.

А мне, по условиям программисткой игры, в которую я ввязался, нужно уметь работать с графикой куда более разнообразно, например, изменять размеры изображения (resize image). Единственная сторонняя библиотека для этого, которая существует — «scale», сильно портит картинку.

Биндинги писать на «Гоу» чрезвычайно просто, единственное — язык запрещает читать переменную сишную errno и я не нашёл никакого способа получить её значение.

Покрытие «GD» у меня не 100%, есть функции, которые я просто поленился реализовывать. Руководства к пользованию нет, есть небольшой пример использования, makefile для его сборки и к модулю «GD» для PHP, там почти всё совпадает (только у меня функций намного меньше, GD в PHP не тот, что использую я, а форк).

Оставить комментарий

Сколько занимает программа на «Go»

Хочу немного развеять тот миф, который я невольно создал — что скомпилированные программы, написанные на языке «Go» занимают очень много. Мой скомпилированный пример с веб-сервером (программа «httphere») занимает почти шесть мегабайт и это не выглядит много для такой программы.

На самом деле, всё не так просто. Простенькая программа на «Go», например, классический «Hello, world!» займёт около 230КБ:

bolk-osx:Hello bolk$ cat <<GO > hello.go
> package main; func main() { println("Hello, world!") }
> GO

bolk-osx:Hello bolk$ 6g hello.go && 6l -o hello hello.6 && du -h hello 
232K	hello

При увеличении исходного кода размер вырастает незначительно, в моей шестимегабайтной программе большую часть занимает веб-сервер (модуль «http»), если его убрать, то скомпилированная программа «похудеет» примерно на 5,5МБ.

Сейчас я пишу программу где уже 414 строк (в httphere — 132) и подключено 11 стандартных модулей, включая модуль для работы с изображениями («image»), скомпилированная версия занимает 1,5 мегабайта. Хотел бы попробовать сжать файл архиватором UPX, но, к сожалению, он не понимает тип запускаемых файлов моей системы (Mach-O 64 бита).

9 комментариев

«Go»: чтение ini-файлов

Мне тут для программы на языке «Go» понадобился простой парсер ini-файлов, который я и написал. Делюсь.

Кстати говоря, я сильно облегчил себе жизнь, когда написал небольшой bash-скрипт, компилирующий и запускающий программы на «Go», вот он:

#!/bin/bash
NAME=$1

if [ -f "$NAME" ]; then
    TMPNAME=`mktemp -t go.XXXXXXX`

    shift
    6g -I. -o $TMPNAME.6 $NAME && 6l -L. -o $TMPNAME $TMPNAME.6 && $TMPNAME $*
    rm -f $TMPNAME.6 $TMPNAME >/dev/null 2>&1
else
    echo "Error: '$NAME' is not found."
fi

Сам модуль выглядит вот так (и называется «ini»):

package ini

import (
    "os"
    "bufio"
    "strings"
)

type inisection map[string]string
type inifile map[string]inisection

func ParseFile(name string) inifile {
    f, err := os.OpenFile(name, os.O_RDONLY, 0666)
    if err != nil {
        return nil
    }

    defer f.Close()

    r := bufio.NewReader(f)

    one := inisection{}             // одна, текущая секция
    ini := inifile   {}             // все секции
    section := ""                   // текущее название секции

    for {
        line, err := r.ReadString('\n')

        if err != nil {
            break
        }

        chunks := strings.Split(strings.TrimRight(line, "\r\n"), "=", 3)
        if len(chunks) == 2 {
            key, value := strings.Trim(chunks[0], "\t "), strings.Trim(chunks[1], "\t ")

            last := len(value) - 1
            if last > 0 && value[0] == '"' && value[last] == '"' {
                value = string(value[1:last])
            }

            one[key] = string(value)
        } else {
            last := len(chunks[0]) - 1

            if chunks[0][0] == '[' && chunks[0][last] == ']' {
                ini[section] = one
                one = inisection{}
                section = string(chunks[0][1:last])
            }
        }
    }

    // «поджимаем хвост», поскольку предыдущая секция попадает в map
    // только когда появляется следующая, последнюю нужно перекладывать «руками»

    if len(one) > 0 {
        ini[section] = one
    }

    return ini
}

Модули пишутся очень просто — достаточно объявить как он будет называться (в директиве «package») и можно его подключать через «import». В «Go» модуль экспортирует всё, что начинается с большой буквы.

Мой модуль экспортирует единственную функцию — ParseFile, принимающую на вход имя файла, на выходе будет ассоциативный массив ассоциативных массивов (map of maps), ключами верхнего уровня является имя секции (если отсутствует, то имя пустое), ключами второго уровня — ключи ini-файла.

12 комментариев

Деревня Верхние Девлизери. Троицкий приход

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

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

Эта каменная церковь была построена на средства мещанина г. Алатыря Василия Львовича Симбирина, по образцу церкви в селе Анатьли Рыбнослобоцкого района. В 1905 году церковь освятили, а в 1908 получила статус церковно-приходского совета, при церкви была открыта земская школа.

Оставить комментарий

«Go»: обработка ошибок

После первого прочтения документации по языку «Гоу» у меня сложилось неправильное впечатление о конструкции «panic», отчасти из-за её названия. Мне показалось, что «panic» используется для генерирования фатальной, для программы, ошибки, которую лучше не обрабатывать, а прекратить выполнение, во избежание серьёзных проблем.

Моё небольшое исследование показало, что это не так, «panic» — это стандартное средство генерации ошибки (аналог исключений), тогда как «defer» плюс «recover» — стандартный способ сгенерированную ошибку отловить и обработать.

Напомню как это делается. Генерация ошибки осуществляется вызовом «panic», перехват — defer-вызовом функции, в которой при помощи функции recover проверяется был ли defer-вызов произведён из-за вызова «panic» (defer вызывается, когда управление, по любой причине, покидает текущую зону видимости).

Например:

package main

func test() int {
    defer func() {
        if e := recover(); e != nil {
            print("Error\n")
        }

        panic(true)
}

func main() {
   print(test())
}

Ошибки могут быть типизированными: можно вызвать «panic(42)», «panic(„Hello“)», «panic(struct{h, k int}{0, 0})» или, к примеру, «panic(os.NewError(„Cannot open file“))», тип ошибки можно узнать, так же как и её содержимое. Это уже больше похоже на исключения.

Если внимательно посмотреть на мой пример выше, то не совсем ясно следующее: «паника» привёла к выполнению анонимной defer-функции и, фактически, прервала выполнение функции «test». Эта функция была описана, как возвращающая результат типа «int». Что нужно сделать, чтобы в случае вызова «panic», мы смогли вернуть какой-нибудь результат?

Способ есть, давайте разберём его в другом примере. В нём же я покажу как именно определить тип «паники».

package main

import . "os" // содержимое модуля будет доступно без префикса

func poisson(n int) (result string) {
    defer func() {
        switch r := recover(); r.(type) {
            case string:
                result = "Result: " + r.(string) + "\n"
            case Error:
                result = "Error: " + r.(Error).String() + "\n"
        }
    }()

    if n < 0 {
        // NewError и Error используется из модуля «os»
        panic(NewError("Poisson distributions have no value over negative numbers"))
    }

    panic("I dunno")
}

func main() {
    print(poisson(-1)) // Poisson distributions have no value over negative numbers
    print(poisson(+1)) // I dunno
}

У функции «poisson», которая притворяется, что считает распределение Пуассона, возвращаемый параметр имеет имя, он как бы связан с переменной «result». Если мы что-то поместим в эту переменную, то это и будет возвращаемым функцией значением. Поскольку в «Go» есть замыкания, мы можем использовать переменную «result» и внутри анонимной функции в defer-вызове. Всё просто.

Что происодит дальше. Вызов «panic» принимает на вход «interface{}», то есть, фактически, параметр любого типа. Чтобы определить тип этого параметра, используется специальнуя конструкция «переменная.(type)» (которая, к слову, может использоваться только в операторе «switch»).

Упомянутая конструкция может определить какой тип ошибки нам вернулся. Похожая конструкция «переменная.(имя-типа)» („r.(string)“ и „r.(Error)“) называется «type assertion». Она позволяет, в общих чертах, проверить, что в переменной сохранено значение указанного типа и получить это значение.

Полученные значения обрабатываются и сохраняются в переменной «result», которая связана со значением возвращаемым функцией «test», оно и попадает в print функции «main».

Я уже настолько проникся языком, что это решение уже мне не кажется таким странным, как поначалу.

4 комментария