Под влиянием замечательного поста решил попробовать автоматизировать часть рутинных задач при помощи python и его продвинутой оболочки iPython. Учитывая, что с Python’ом я до этого дел никаких не имел, для упрощения старта решил воспользоваться «всё-в-одном» паком под Windows Python(x,y).
Пак встал без проблем – без каких либо сообщений об ошибках или предупреждений. Однако попытка запуска ipython notebook сопровождалась вот такой гроздью сообщений об ошибках и чем-то странным в браузере:
ERROR:root:Uncaught exception GET /static/jquery/css/themes/base/jquery-ui.min.css?v=d1a93 (127.0.0.1)
HTTPRequest(protocol='http', host='127.0.0.1:8888', method='GET', uri='/static/jquery/css/themes/base/jquery-ui.min.css?v=d1a93', version='HTTP/1.1', remote_ip='127.0.0.1', body='', headers={'Accept-Language': 'ru-RU', 'Accept-Encoding': 'gzip, deflate', 'Host': '127.0.0.1:8888', 'Accept': '*/*', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)', 'Dnt': '1', 'Connection': 'Keep-Alive', 'Referer': 'http://127.0.0.1:8888/'})
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\tornado\web.py", line 1042, in _execute
getattr(self, self.request.method.lower())(*args, **kwargs)
File "C:\Python27\lib\site-packages\tornado\web.py", line 1568, in get
mime_type, encoding = mimetypes.guess_type(abspath)
File "C:\Python27\lib\mimetypes.py", line 294, in guess_type
init()
File "C:\Python27\lib\mimetypes.py", line 355, in init
db.read_windows_registry()
File "C:\Python27\lib\mimetypes.py", line 259, in read_windows_registry
for ctype in enum_types(mimedb):
File "C:\Python27\lib\mimetypes.py", line 249, in enum_types
ctype = ctype.encode(default_encoding) # omit in 3.x!
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0: ordinal not in range(128)
...
Как оказалось, к самому iPython эти ошибки не имеют никакого отношения. Проблема возникает при загрузке web-сервера Tornado - при попытке получить из реестра mime-типы. В ветке реестра [HKEY_CLASSES_ROOT\CLSID{4063BE15-3B08-470D-A0D5-B37161CFFD69}\EnableFullPage\MIME] почему-то оказались mime-записи, содержащие кириллицу.
Лечение было проведено методом «на авось» - элементы типа «видео/mpeg» были переименованы в «video/mpeg», а то, что переименовать не удалось, было просто удалено. После этого iPyton прекрасно запустился. Понятно, что какие вылезут в результате такого лечения косяки – не понятно. Пока, правда, всё прекрасно обходится без них :)
Baga-Blog
четверг, 11 апреля 2013 г.
пятница, 5 апреля 2013 г.
Чтобы Backspace в Explorer стал "вверх"
Продолжаю обостраивать систему под себя. Цель: заставить Explorer переходить по клавише Backspace на один уровень иерархии вверх.
Когда-то именно так и было, но в Win7 (говорят, что это началось ещё в Vista, но с ней мне не довелось работать) в Explorer значение клавиши Backspace кардинально поменялось - она стала отправлять вас в "предыдущее место находжения", а не в родительский каталог. Это, то ли в силу мой привычки, то ли приёмов работы, меня стало откровенно раздражать. Довольно долгое гугление позволило обнаружить ответ. Собственно, там два ответа, но уменя без проблем запустился толь один - скачать и поместить в автозагрузку
Download HTGBack XP-Style Backspace Key
После этого привычный Backspace в Explorer наконец-то начинает вести себя привычным способом. К сожалению, при большом аптайме и после интенсивного использования виртуальной машины, Explorer перестаёт реагировать на нажатие этой магической клавиши. Правда, кто тут виноват (виртуалка vs программа), установить вряд ли удастся да и не нужно - раз в месяц можно и перезагрузить, благо, по-настоящему долгих задач нет.
Когда-то именно так и было, но в Win7 (говорят, что это началось ещё в Vista, но с ней мне не довелось работать) в Explorer значение клавиши Backspace кардинально поменялось - она стала отправлять вас в "предыдущее место находжения", а не в родительский каталог. Это, то ли в силу мой привычки, то ли приёмов работы, меня стало откровенно раздражать. Довольно долгое гугление позволило обнаружить ответ. Собственно, там два ответа, но уменя без проблем запустился толь один - скачать и поместить в автозагрузку
Download HTGBack XP-Style Backspace Key
После этого привычный Backspace в Explorer наконец-то начинает вести себя привычным способом. К сожалению, при большом аптайме и после интенсивного использования виртуальной машины, Explorer перестаёт реагировать на нажатие этой магической клавиши. Правда, кто тут виноват (виртуалка vs программа), установить вряд ли удастся да и не нужно - раз в месяц можно и перезагрузить, благо, по-настоящему долгих задач нет.
пятница, 29 марта 2013 г.
Переключение по Left Shift + Right Shift
Сочетание клавиш для переключения языка ввода (пусть будет "раскладки", хотя это и не совсем точно) - дело сугубо индивидуальное... Лично мне куда удобнее "два шифта" (правильно звучит вроде как по сочетанию L.Shift + R.Shift) - они больше, попадать по ним проще и быстрее, да и не нужно складывать всякие фигуры из множества пальцев.
Стандартным образом заставить Win работать таким образом не получится. В всяком случае, мне этого не удалось. Большинство форумчан настоятельно предлагают популярные же Arum Switcher или Punto... Но! Они предлагают массу вариантов, вот только искомого категорически не умеют. После довольно долгих поисков была обнаружена софтнина, которая делает почти то, что нужно:
keyla
К сожалению, в стандартном приветствии для ввода пароля придётся пользоваться одним из стандартных сочетаний - т.к. на этом этапе keyla ещё не загружена.
Стандартным образом заставить Win работать таким образом не получится. В всяком случае, мне этого не удалось. Большинство форумчан настоятельно предлагают популярные же Arum Switcher или Punto... Но! Они предлагают массу вариантов, вот только искомого категорически не умеют. После довольно долгих поисков была обнаружена софтнина, которая делает почти то, что нужно:
keyla
К сожалению, в стандартном приветствии для ввода пароля придётся пользоваться одним из стандартных сочетаний - т.к. на этом этапе keyla ещё не загружена.
воскресенье, 14 октября 2012 г.
Двумерный динамический массив в C++ (из 1D): перегрузка оператора ()
В предыдущей статье было показано, как можно использовать одномерный массив в качестве двумерного. Одновременно был отмечен ряд недостатков такой реализации. Повторим их кратко:
В C++ существует возможность перегрузки операторов, которая позволяет задать собственное поведение операторов пользовательских типов. Т.к. переопределить операторы стандартных типов нельзя, то повлиять на поведение '[]' одномерного массива мы никак не можем. Поэтому, чтобу "подружить" одномерный массив с его интерпритацией в качестве двумерного, нам потребуется сделать специальный класс-обёртку, которая и будет реализовывать необходимое поведение.
Зададим для "обёртки" следующие ограничения:
Напомним, что проектируемый класс просто обёртка над уже существующим 1D массивом:
Создадим к показанному выше 1D-массиву класс-обёртку:
Здесь
-arr_ptr - ссылка на указатель (ссылка на массив). Именно этим приёмом (ссылкой) гарантируется, что класс-обёртка отреагирует на изменение исходного указателя (одномерного массива). Пример: память исходного массива была освобождена, а указатель установлен в NULL. Тогда, если по ошибке будет использована обёртка, произойдёт исключение по разыменованию NULL-указателя. Второй эффект такой реализации: если исходный указатель будет указывать на новый участок памяти (допустим, другой массив и т.п.), то и "обёртка" будет указывать туда же. При этом она будет считать, что размерность нового массива полностью соответствует старому!
-n - размерность массива [n,n]. Объявлена константой, т.к. изменение размерности у исходного массива произойти не может - для этого нужно выделить новую область памяти, скопировать туда данные, а затем освободить "старую" область.
arr_ptr и n размещены с секции private, чтобы избежать случайной порчи этих членов класса - вся работа с ними скрыта от пользователя. Более того, само это сокрытие, т.е. предоставление прозрачного интерфейса для обращения по индексам (и сокрытие механизма пересчёта индексом) и является целью создания класса-обёртки.
-arrWrapper(CT *const &ptr, const long N) - конструктор, принимающий в качестве параметров указатель (ссылку на указатель) на выделенную область памяти и соответствующий ей размер двумерного массива. Т.к. изменять значения этих параметров в процессе инициализации не требуется, они имеют квалификатор const.
- CT& operator()(const int i, const int j)const - определённая нами версия оператора (), которая и осуществляет пересчёт "двумерного" индекса в "одномерный". По реализации полностью совпадает с функцией пересчета из предыдущего поста. Обращение к элементу будет осуществляться как wrp(i,j), где wrp - "связанная" с некоторым одномерным массивом "обёртка".
- при "ручном пересчёте" есть вероятность "глупой ошибки" вроде опечатки и т.п.;
- использование функции "удлиняет" форму записи и делает менее прозрачным для понимания код;
- и "ручной пересчёт", и вызов функции выглядят непривычно по сравнению с традиционной адресацией двумерного массива "[][]".
В C++ существует возможность перегрузки операторов, которая позволяет задать собственное поведение операторов пользовательских типов. Т.к. переопределить операторы стандартных типов нельзя, то повлиять на поведение '[]' одномерного массива мы никак не можем. Поэтому, чтобу "подружить" одномерный массив с его интерпритацией в качестве двумерного, нам потребуется сделать специальный класс-обёртку, которая и будет реализовывать необходимое поведение.
Зададим для "обёртки" следующие ограничения:
- не занимается управлением памятью, в т.ч. не выделяет память под массив, не освобождает её;
- при инициализации (на этапе декларации) получает в качестве входных параметров-констант А) адрес начала памяти (одномерного массива), Б) размерность массива (предполагаем матрицу квадратной);
- должна отражать поведение, как если бы использовался исходный указатель;
- должна позволять производить чтение и модификацию элемента массива.
Напомним, что проектируемый класс просто обёртка над уже существующим 1D массивом:
typedef long CT; // Cell Type of the array /* ... */ CT *arr = new(nothrow) CT[n*n]; //pointer to 1D-array of n*n elements if(!arr){ // no memory allocated cout << "The array was not allocated" << endl; return 1; }
Создадим к показанному выше 1D-массиву класс-обёртку:
class arrWrapper{ private: CT *const &arr_ptr; //pointer to 1D array of n*n size const long n; // dimension of the square matrix [n,n] public: arrWrapper(CT *const &ptr, const long N):arr_ptr(ptr), n(N) {}; inline CT& operator()(const int i, const int j)const { return arr_ptr[i*n+j]; }; };
Здесь
-arr_ptr - ссылка на указатель (ссылка на массив). Именно этим приёмом (ссылкой) гарантируется, что класс-обёртка отреагирует на изменение исходного указателя (одномерного массива). Пример: память исходного массива была освобождена, а указатель установлен в NULL. Тогда, если по ошибке будет использована обёртка, произойдёт исключение по разыменованию NULL-указателя. Второй эффект такой реализации: если исходный указатель будет указывать на новый участок памяти (допустим, другой массив и т.п.), то и "обёртка" будет указывать туда же. При этом она будет считать, что размерность нового массива полностью соответствует старому!
-n - размерность массива [n,n]. Объявлена константой, т.к. изменение размерности у исходного массива произойти не может - для этого нужно выделить новую область памяти, скопировать туда данные, а затем освободить "старую" область.
arr_ptr и n размещены с секции private, чтобы избежать случайной порчи этих членов класса - вся работа с ними скрыта от пользователя. Более того, само это сокрытие, т.е. предоставление прозрачного интерфейса для обращения по индексам (и сокрытие механизма пересчёта индексом) и является целью создания класса-обёртки.
-arrWrapper(CT *const &ptr, const long N) - конструктор, принимающий в качестве параметров указатель (ссылку на указатель) на выделенную область памяти и соответствующий ей размер двумерного массива. Т.к. изменять значения этих параметров в процессе инициализации не требуется, они имеют квалификатор const.
- CT& operator()(const int i, const int j)const - определённая нами версия оператора (), которая и осуществляет пересчёт "двумерного" индекса в "одномерный". По реализации полностью совпадает с функцией пересчета из предыдущего поста. Обращение к элементу будет осуществляться как wrp(i,j), где wrp - "связанная" с некоторым одномерным массивом "обёртка".
Полный пример создания и использования двумерного динамического массива (на основе 1D-массива и перегрузки оператора ())
#include<stdio.h> //to use memset #include<iostream> //to use cin, cout typedef long CT; // Cell Type of the array class arrWrapper{//Wrapper for 1D array private: CT *const &arr_ptr; //pointer to 1D array of n*n size const long n; // dimension of the square matrix [n,n] arrWrapper& operator=(arrWrapper &)const{}; //to prevent //default '=" operator, not needed to show the () public: arrWrapper(CT *const &ptr, const long N): arr_ptr(ptr), n(N) {}; inline CT& operator()(const int i, const int j)const { return arr_ptr[i*n+j]; }; }; int main (int argc, char** argv) { long n = 0; //variable to obtaint 2D-array size using namespace std; // to be able to use cin & cout cout << "Please, inter the matrix size n = "; //GET ARRAY SIZE cin >> n; // read size n from keyboard //GET MEMORY FOR 1D ARRAY OF n*n SIZE CT *arr = new(nothrow) CT[n*n]; //pointer to 1D-array //of n*n elements if(!arr){ // no memory allocated cout << "The array was not allocated" << endl; return 1; } //Fill array with char(0) values for sizeof(int)*n*n bytes memset(arr, static_cast<char>(0), (sizeof(long)/sizeof(char))*n*n); //************************************************ //INIT ('link') WRAPPER WITH THE 1D ARRAY and SIZE //************************************************ //DECLARE WRAPPER arrWrapper wrp(arr, n);//derlare & init with array //USE WRAPPER for (int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ //ACCESS ELEMENT [i,j] USING the WRAPPER wrp(i,j) = 10000*i+j; } } //FREE MEM delete [] arr; arr = NULL;
среда, 26 сентября 2012 г.
Двумерный динамический массив в C++: эмулирование одномерным массивом
Этот пост - первый в коллекции "велосипедов" по работе с двумерными массивами в С++. Оказалось, что удобно иметь место, куда можно послать и где держать краткое описание с пояснениями. Гугление же как правило выдаёт не очень хороший результат: нужное в нём найти можно, но много мусора, а велосипед чаще всего оказывается "не той системы".
Известно, что в С++ поддерживаются команды динамического выделения непрерывной области памяти - под одномерные массивы, для чего сущестует расширенный "квадратными скобками" синтаксис операторов new и delete.
Ожидания многих новичков не оправдываются - оператор для двумерного массива в языке отсутсвует, т.е.
Иногда после этого начинающий в С/С++ пытается создать одномерный динамический массив и присвоить указатель на него переменной типа двумерного массива (или указателя на указатели)
Если m и n - размерность требуемого двумерного массива (т.е. число строк и столбцов), то пересчет индексов (обращение к [i,j]-тому элементу) можно осуществлять как
С другой стороны, приходится постоянно вручную писать пересчёт индексов [i*n+j], что черевато опечатками и как следствие плохо диагностируемымы ошибками. Поэтому иногда предпочитают определить функцию пересчёта индексов для иключения таких ошибок, например
Тогда цикл обращения будет выглядеть как
Обратим внимание, что функция возвращает ссылку (CT&) на элемент массива, и именно это обеспечивает возможность присваивания element(i,j,arr,n) = 1. Если же возвращать не ссылку на значение, а значение типа CT, то изменять значения элемента массива не получится (хотя чтение так же как и в верхнем случае будет выполняться нормально). Передаваемые же в функцию параметры объявлены константными (const) "для порядку", т.к. внутри функции мы их не меняем.
Известно, что в С++ поддерживаются команды динамического выделения непрерывной области памяти - под одномерные массивы, для чего сущестует расширенный "квадратными скобками" синтаксис операторов new и delete.
int *iptr = new int[100];//get memory for 100 elements delete [] iptr; //free memory
Ожидания многих новичков не оправдываются - оператор для двумерного массива в языке отсутсвует, т.е.
new int[100][100];//!errorпросто ошибка. С другой стороны, он особенно и не требуется, поскольку динамические массивы любой размерности прекрасно создаются при помощи одномерного массива. Для этого достаточно помнить, что в С/С++ массивы хранятся по строкам (в отличие от, например, фортрана). Это значит, что двумерная матрица
1 2 3 4 5 6хранится как одномерный массив
1 2 3 4 5 6
Иногда после этого начинающий в С/С++ пытается создать одномерный динамический массив и присвоить указатель на него переменной типа двумерного массива (или указателя на указатели)
int **ptr = NULL; int *iptr = new int[100*100]; ptr = iptr; //!errorТакое присваивание не позволит сделать компилятор, кроме случая явного приведения int** к int*. Но в последнем случае хотя и не будет происходить ошибки на стадии компиляции, при выполнении (как минимум на операциях записи в массив) программа будет остановлена по нарушению доступа к памяти. Это произойдёт потому, что в ptr[i][j] значение из ptr[i] будет рассматриваться как адрес одномерного массива длиной [j]. Поэтому мы не можем использовать нотацию [][] и должны самостоятельно пересчитивать индекс элемента внутри одномерного массива.
Если m и n - размерность требуемого двумерного массива (т.е. число строк и столбцов), то пересчет индексов (обращение к [i,j]-тому элементу) можно осуществлять как
iptr[i*n+j]
Полный пример создания и использования двумерного динамического массива (на основе 1D-массива)
#include<stdio.h> //to use memset typedef long CT; // Cell Type of the array /////////////////////////////////////////// // Main function demonstrate 2D array // /////////////////////////////////////////// int main (int argc, char** argv) { long n = 10; //variable to obtain //2D [n,n]-array size. //Input is better, //but for example purposes //we don't use io routines. //HERE WE GET ARRAY //Pointer to and memory allocation for //1D-array of n*n elements CT *arr = new(nothrow) CT[n*n]; if(!arr){ // no memory allocated return 1; //STOP. Put here your code //for no-memory case. } //Fill array with char(0) values //for sizeof(int)*n*n bytes, //i.e. init memory with zeroes. memset(arr, static_cast<char>(0), (sizeof(long)/sizeof(char))*n*n); //and HERE WE USE ARRAY for( int i = 0; i < n; ++i){ for( int j = 0; j < n; ++j){ //set arr[x][y] => arr[x*n+y] arr[i*n+j]=i*100+j; //write some } } //Free memory when you don't need it delete [] arr; //Set pointer to the de-allocated chunk //of memory to NULL to prevent //misuse of already freed memory. arr = NULL; return 0; }
С другой стороны, приходится постоянно вручную писать пересчёт индексов [i*n+j], что черевато опечатками и как следствие плохо диагностируемымы ошибками. Поэтому иногда предпочитают определить функцию пересчёта индексов для иключения таких ошибок, например
inline CT& element(const int i, const int j, CT*const arr, const int size) { return arr[i*size+j]; }
Тогда цикл обращения будет выглядеть как
//and HERE WE USE ARRAY for( int i = 0; i < n; ++i) for( int j = 0; j < n; ++j) element(i,j,arr,n) = i*100+j;
Обратим внимание, что функция возвращает ссылку (CT&) на элемент массива, и именно это обеспечивает возможность присваивания element(i,j,arr,n) = 1. Если же возвращать не ссылку на значение, а значение типа CT, то изменять значения элемента массива не получится (хотя чтение так же как и в верхнем случае будет выполняться нормально). Передаваемые же в функцию параметры объявлены константными (const) "для порядку", т.к. внутри функции мы их не меняем.
понедельник, 23 мая 2011 г.
Как спрятать текст под кат
Обнаружил, что периодически забываю, как делать простые и нужные вещи. Поэтому решил собрать некоторые простые и незамысловатые действия, дабы не гуглить их потом заново.
Собственно, прилично описание subj последний раз нашел здесь.
А потом обнаружил, что блоггер это уже давно сам умеет...
Собственно, прилично описание subj последний раз нашел здесь.
А потом обнаружил, что блоггер это уже давно сам умеет...
четверг, 18 ноября 2010 г.
GMT: установка
В этой статье мы обойдем вниманием стандартную процедуру установки GMT, которая вполне хорошо документирована как на оригинальном сайте, так и на сайтах многих пользователей (например). Типичные проблемы связаны с зачастую неспособностью нового пользователя указать (т.е. ответить на вопросы инсталлятора) правильные расположения библиотек и отследить зависимости. Это вполне объяснимо: новичку просто надо курить маны. Опытному же исследователю жаль тратить свое время на выполнение рутинных задач (для автоматизации которых требуется некоторый навык и умения, ни как не связанные с процессом исследования). Специально для этого случая существует rpm.
Все, что вам остается:
добавить репозиторий в список repo менеджера пактов вашего дистрибутива.
Запустить установку. При этом будут скачаны не только последние доступные версии, но и отслежены все зависимости.
Итак,
заходим на http://software.opensuse.org/
вводим в поисковую строку GMT
выбирает свой дистрибутив
Производим поиск — и установку нужной версии.
PS
Надеюсь, теперь вы не будете верить, что установка GMT - это сложно, непонятно и неприятно. Ведь все так просто
Все, что вам остается:
добавить репозиторий в список repo менеджера пактов вашего дистрибутива.
Запустить установку. При этом будут скачаны не только последние доступные версии, но и отслежены все зависимости.
Итак,
заходим на http://software.opensuse.org/
вводим в поисковую строку GMT
выбирает свой дистрибутив
Производим поиск — и установку нужной версии.
PS
Надеюсь, теперь вы не будете верить, что установка GMT - это сложно, непонятно и неприятно. Ведь все так просто
Подписаться на:
Сообщения (Atom)