Posts Tagged: JavaScript

Шифрование с помощью аффинной системы подстановок Цезаря (JavaScript)

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

Это была первая лаба по достаточно интересному предмету про шифрование. Я бы с радостью сделал и другие лабы на жс, но переделывать арифметику из оригинальных найденных кодов было тяжело. Вся проблема была в различии арифметики Java и JS, которое давало о себе знать, когда дело касалось больших целых чисел.

Но поскольку в элементарном шифровании Цезаря больших целых чисел нет, а алгоритм предельно прост, было очень нетрудно, и даже интересно сделать всё на скрипте.

Я постарался оформить страничку аккуратно, а также решил, что будет красиво и просто, если лаба будет занимать один единственный html-файл, поэтому впервые за долгое время я закодил всё на ванили.

Думаю, что студентам также, возможно, окажется полезным задание и отчёт.

Working with quarters in JavaScript

Today my friend was working on a tool and a part of his task was to define a quarter of a given date and also to define its borders. I had spare time and tried to join this job.

The first thing we did was googling for it, and the result was this helpful topic: Math.floor((date.getMonth() + 3) / 3), but after that the task of finding start and end dates of a quarter still remained.

While I was busy with monkey coding this function:

function getQuarterBounds(date) {
    date = date || new Date();

    var q = Math.floor((date.getMonth() + 3) / 3);
    var year = date.getFullYear();
    var quarters = {
        1: {
            start: '01-01',
            end: '03-31'
        }, 2: {
            start: '04-01',
            end: '06-30'
        }, 3: {
            start: '07-01',
            end: '09-30'
        }, 4: {
            start: '10-01',
            end: '12-31'
        }
    };

    return [
        new Date(year + '-' + quarters[q].start),
        new Date(year + '-' + quarters[q].end)
    ];
}

My friend noticed that setMonth() function has a second argument which is a day, and when it is equal to 0 then the result date will be the last day of a previous month, -1 sets one more day before that day and so on.

This functionality was very helpful in our case:

function getQuarterBounds(date) {
    date = date || new Date();

    return [
        new Date(new Date().setMonth(
            date.getMonth() - date.getMonth() % 3, 1)),
        new Date(new Date().setMonth(
            date.getMonth() + 3 - date.getMonth() % 3, 0))
    ];
}

Year, sometimes you have to recall sad “RTFM” expression

Работа с кварталами (время) в JavaScript

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

Тут же нагуглили этот полезный ответ Math.floor((date.getMonth() + 3) / 3), однако оставалось находить границы квартала.

В то время, как я тут же принялся быдлокодить такую функцию:

function getQuarterBounds(date) {
    date = date || new Date();

    var q = Math.floor((date.getMonth() + 3) / 3);
    var year = date.getFullYear();
    var quarters = {
        1: {
            start: '01-01',
            end: '03-31'
        }, 2: {
            start: '04-01',
            end: '06-30'
        }, 3: {
            start: '07-01',
            end: '09-30'
        }, 4: {
            start: '10-01',
            end: '12-31'
        }
    };

    return [
        new Date(year + '-' + quarters[q].start),
        new Date(year + '-' + quarters[q].end)
    ];
}

Мой приятель обратил внимание, что функция setMonth() вторым аргументом имеет день, который в случае, если равен 0, ставит последний день предыдущего месяца, а при -1 и меньших значений начинает мотать дальше.

В нашем случае этот функционал оказался как раз очень удобен:

function getQuarterBounds(date) {
    date = date || new Date();

    return [
        new Date(new Date().setMonth(
            date.getMonth() - date.getMonth() % 3, 1)),
        new Date(new Date().setMonth(
            date.getMonth() + 3 - date.getMonth() % 3, 0))
    ];
}

Да уж, иногда бывает, что вспоминаешь неутешительное «RTFM»

Тестовое задание Яндекса (Trip Sorter)

При приёме программистов на работу, кандидатам любят давать тестовые задания. Чаще всего их можно получить от убогих кадровых агентств, тогда к ним лучше не приступать, либо от нормальных компаний после собеседования, тогда стоит подумать, нужно ли тратить на них время или не стоит, в зависимости от того, какое впечатление произвела компания. А можно получить задание на проверку скилов и от очень брендовых с точки зрения HR компаний, коей в области ИТ у нас в стране и является Yandex, занимая, возможно, самое первое место.

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

Как показано в одном комиксе из серии “What I really do”, суть работы программиста заключается в наборе в строке поиска слов “how to Java”. В каждой шутке есть доля правды, и едва приступив к заданию, я решил посмотреть, не делал ли его кто-нибудь до меня. Сначала я пробил слова из задания и ничего не обнаружил, а затем попробовал вбить само название файла, которое было на английском. Тогда я наткнулся на блог какого-то разработчика, кажется он был из Испании. Человек писал в своём блоге о том, что в компании ему предложили следующее тестовое, и что ему обидно, что его не взяли на работу туда.

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

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

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

Буду рад, если кто-нибудь скажет, что в решении есть ошибки.

Simple Combobox — jQuery плагин

Этой весной впервые поработал немного фрилансером, мне нужно было сделать форму, в которой было несколько элементов с автокомплитом. Элементы зависели друг от друга (речь шла о заполнении формы адреса по КЛАДР). Я решил, что будет проще набросать собственный механизм для автокомплита и поначалу оформил это как набор лисенеров, управляя этими компонентами и меняя их данные вручную. Но затем, доделав работу до конца, подумал, что было бы здорово сделать такой компонент jQuery плагином. В итоге поулчилась вот такая штука.

Simple Combobox jQuery plugin

This spring it was the first time I worked as a freelancer. My main task was scripting a form with autocomplete elements. These elements were connected with each other. I decided it would be easier to work around own mechanism of autocomplete combobox component. The first thing I did was a simple html markup and several listeners. I managed comboboxes (primarily refilling and setting as disabled) manually. After I finished the job I thought about making a jQuery plugin from the stuff. Finally I ended up with this.

Led Marqee with JavaScript

Sometimes you have spare time on your job. It’s very cool especially when there are only few days before the New Year left. These days are usually not loaded with job at all what is opposite to mid December, time with a peak activity. Code something personal is almost always much more interesting than code somebody’s task. Probably this is just because of when you code something for yourself you pick out something what is really very interesting for you to code.

One day I was wondering how led marquee is working in the subway car, that is how its messages are encoded and then animating on the screen.

I tried to google for it and got the idea, but then I started to google it for JavaScript examples. I took one algorithm as a core (I’m so sorry I didn’t succeeded to find its URL now, hope I’ll add it sometime) and then tried to code something more stylish and functional based on it.

A year has passed since that time, my code structure probably would be a bit more clear if I start it now, but anyhow the page seems quite nice to me and I would like to share it.

I think you can get everything from the page, because it’s so simple.

Of course I would like to change the pixel state not immediately. But if I try to use animation for changing pixels’ opacity, the page become very slow. Probably Flash would work just fine here or maybe HTML5 canvas would solve this problem great also.

After the job was finished by December 31, I went to my friend to celebrate the New Year. It was great. I enjoyed the company and atmosphere, and right the next day I sent the link with “Happy New Year, %username%!” to close friends of mine.

That is funny, but sometimes you’re in a rush even when coding something completely yours

See the page, download a zip, GitHub.

Бегущая строка (табло) на JavaScript

Бывает, что на работе выдаётся свободное время. Особенно приятно это, когда под самый Новый Год, в последние деньки, работа, после самого активного в году времени вдруг резко заканчивается. Не перестаю не замечать за собой, что кодить для себя практически всегда интересней, чем что-то по работе. Наверно потому что по своей инициативе выбираешь как раз то, что интересно больше всего.

Как-то раз, сидя в вагоне «Русича» и глядя на табло, я подумал, а как интересно кодят его сообщения и как вообще оно работает в плане отображения текста в виде точек и, самое главное, его анимации.

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

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

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

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

Доведя работу до точки, а случилось это только днём 31 декабря, я отправился на празднование Нового Года к другу. Новый Год мы встретили чудесно в замечательной компании, а на следующий день я отправил ссылку на страничку близким друзьям.

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

Страничка, zip, GitHub.

About table with `display: block` and `overflow-y: auto`

Few days ago my college and I had a page with an extra wide table on it which breaked the page body that is the horizontal scroll appeared on the whole page. We solved the problem with adding the following style on the table: { display: block; overflow-y: auto; max-width: 10px /* any low value here */ }.

But as you may know the tables are not supposed to wear display: block CSS declaration and that was why we failed trying to create something universal for all the tables.

We decided we have to check if the table is extra wide or not and found a quite simple solution, this small: jquery plugin from the answer:

$.fn.hasOverflow = function() { 
    var $this = $(this); 
    var $children = $this.find('*'); 
    var len = $children.length; 
 
    if (len) { 
        var maxWidth = 0; 
        var maxHeight = 0 
        $children.map(function() { 
            maxWidth = Math.max(maxWidth, $(this).outerWidth(true)); 
            maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); 
        }); 
 
        return maxWidth > $this.width() || maxHeight > $this.height(); 
    } 
 
    return false; 
};

We edited it first to make it taking only width in account and then used it in the following way: $('body').hasOverflow().

But it did not work somethimes (probably something more has been changed on the page) and what is also bad thing is that it selects so huge amount of elements on a big pages that it really impacts the performance. But the next day we started to solve it again and in a few minutes we came with a very simple solution:

$(window).width() < $('body')[0].scrollWidth

It works fine by now! We needed just to sleep on it

Про table с `display: block` и `overflow-y: auto`

Недавно была у нас страничка, там появлалась очень широкая таблица, которая разрывала страницу, т.е. заставляла появиться горизонтальный скролл на body. Мы решили эту проблему добавлением стиля на таблицу, а именно { display: block; overflow-y: auto; max-width: 10px /* любая маленькая величина */ }.

Но как известно, таблицы не предназначены для того, чтобы на них вешался display: block, поэтому несмотря на многочисленные попытки сделать что-то универсальное, у других, более узких таблиц, возникли проблемы.

Мы решили, что надо определять, рвёт ли таблица страницу, или не рвёт.

Тут же нашли решение – вот такой компактный jquery-плагин здесь:

$.fn.hasOverflow = function() { 
    var $this = $(this); 
    var $children = $this.find('*'); 
    var len = $children.length; 
 
    if (len) { 
        var maxWidth = 0; 
        var maxHeight = 0 
        $children.map(function() { 
            maxWidth = Math.max(maxWidth, $(this).outerWidth(true)); 
            maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); 
        }); 
 
        return maxWidth > $this.width() || maxHeight > $this.height(); 
    } 
 
    return false; 
};

Мы подправили его так, чтобы рассматривалась только ширина и использовали его следующим образом: $('body').hasOverflow().

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

$(window).width() < $('body')[0].scrollWidth

Пока исправно работает! Утро вечера мудренее