Re[4]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 07.08.12 17:25
Оценка:
Здравствуйте, sumson, Вы писали:

S>Здравствуйте, мыщъх, Вы писали:


М>>Здравствуйте, sumson, Вы писали:


S>можно менять значение 4 на любое другое которое предполагается в качестве замены на табуляцию

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

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

вот такая логика обработки в предельно упрощенном виде. где она у вас? причем, правило формирование отступов изложено в исходном посте.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[4]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 07.08.12 17:37
Оценка:
Здравствуйте, MTD, Вы писали:

М>>смущает, что подчеркнутый комментарий сместился на один символ вправо (хотя на работу скрипта это и не влияет), а так зачот, да.

MTD>Это потому, что до левых кавычек табуляция, а потом пошел текст и пробелы в нем я решил, что менять на табуляцию неправильно.
да, замена пробелов внутри комментариев это болезненная тема. там может порушиться форматирование, предназначенное для человека, а не для машины. но это мелочи. главное, что ваш вариант воспринимается питоном на ура, т.е. скрипт после переформатирование сохраняет работоспособность, а "косметику" уже можно и руками навести.

MTD>По времени у меня ушло минут 40, код на питоне около 50 строчек так, что как тестовое задание — вполне

самое интересное, что можно давать пользоваться гуглом, т.к. в нем решения не находится. ну вот я искал и ничего рабочего не нашел, после чего плюнул и написал сам.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[4]: # оригинальное тестовое задание
От: Sharowarsheg  
Дата: 07.08.12 18:59
Оценка:
Здравствуйте, kaa.python, Вы писали:

М>>эээ.... а какую грамматику поддерживать-то? там совсем немного подводных камней.


KP>Да любую, например ту, которую ты только что привел. Основная мысль в том, что если надо еще изучать спеки по питону и допустимым вариантам форматирования, за пределами примера, это потребует больше времени.


Еще основнЕе, кажется, мысль о том, что кандидат должен знать питон, прежде, чем понять, в чем смысл задачи.
Re[5]: # оригинальное тестовое задание
От: sumson Россия  
Дата: 07.08.12 19:03
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>вот такая логика обработки в предельно упрощенном виде. где она у вас? причем, правило формирование отступов изложено в исходном посте.


ок, теперь понял, единственное осталось непонятно как делать замену пробелов на символы табуляции?
навскидку я думаю можно делать вместо пробелов первого уровня вложенности один символ табуляции, пробелы для второго уровня — два символа табуляции и т д.
ну и программа должна ещё проводить верификацию скрипта на корректность уровней вложенности.
по поводу стека всё понятно.
Я знаю, как управлять Вселенной. И скажите, зачем же мне бежать за миллионом?!(c)
Re[6]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 07.08.12 19:28
Оценка:
Здравствуйте, sumson, Вы писали:

S>Здравствуйте, мыщъх, Вы писали:


М>>вот такая логика обработки в предельно упрощенном виде. где она у вас? причем, правило формирование отступов изложено в исходном посте.


S>ок, теперь понял, единственное осталось непонятно как делать замену пробелов на символы табуляции?

вариантов много. логично использовать один символ табуляции в качестве одного уровня вложенности, которому может в рамках одного и того же скрипта соответствовать разное кол-во пробелов (как и показано в исходном примере). именно поэтому задача номер один -- определить текущий уровень вложенности. задача номер два (тривиальная) -- indent_str = '\t'*indent_level;

S>навскидку я думаю можно делать вместо пробелов первого уровня вложенности один символ табуляции,

S>пробелы для второго уровня — два символа табуляции и т д.
первый уровень вложенности это вроде нуль? но в целом да -- все верно.

S> ну и программа должна ещё проводить верификацию скрипта на корректность уровней вложенности.

да, конечно, потому что в противном случае в поисках идентичного уровня вложенности она исчерпает стек и корабль врежется в берег "море кончилось" (с). но это уже клинический случай. мы же не верификатор пишем

сложнее всего обрабатывать конструкции в стиле:

def foo():
    a = [1, # hello
2]


для корректной обработки которых нужно писать довольно продвинутый парсер, но в тестовое задание это уже не входит, хотя если кандидат обратит на это внимание -- это плюс в карму.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: # оригинальное тестовое задание
От: vsb Казахстан  
Дата: 08.08.12 03:00
Оценка:
Для тестовой задачи слишком сложная, имхо.
Re[2]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 08.08.12 04:20
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Для тестовой задачи слишком сложная, имхо.

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

а что сложного? даже если писать на чем-то низкоуровневом типа си. псевдокод выражается в двух словах.


1. кладем в стек ноль;
2. считаем пробелы;
3. если пробелов больше, чем на вершите стека — кладем на стек;
4. если пробелов меньше, чем на вершине стека — снимаем со стека, пока не найдем равенство (или не кончиться стек);
5. убиваем пробелы до первого символа и ставим N знаков табуляции, где N — кол-во элементов стека минус единица;
6. комментарии обрабатываем отдельно, учитывая символ \";

все просто. непонятно почему народ стремится заменять пробелы табуляцией простой заменой. ведь оно же не работает...
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[3]: # оригинальное тестовое задание
От: vsb Казахстан  
Дата: 08.08.12 04:31
Оценка:
Здравствуйте, мыщъх, Вы писали:

vsb>>Для тестовой задачи слишком сложная, имхо.

М>интервью предусматривает в том числе и интерактивный режим, где собеседуемого плавно подводят к мысли.

М>а что сложного? даже если писать на чем-то низкоуровневом типа си. псевдокод выражается в двух словах.



М>1. кладем в стек ноль;

М>2. считаем пробелы;
М>3. если пробелов больше, чем на вершите стека — кладем на стек;
М>4. если пробелов меньше, чем на вершине стека — снимаем со стека, пока не найдем равенство (или не кончиться стек);
М>5. убиваем пробелы до первого символа и ставим N знаков табуляции, где N — кол-во элементов стека минус единица;
М>6. комментарии обрабатываем отдельно, учитывая символ \";

М>все просто. непонятно почему народ стремится заменять пробелы табуляцией простой заменой. ведь оно же не работает...


Сложность в переносах строк — парсинге всяких скобок, открывающих-закрывающих кавычек, комментариев, если я правильно понимаю python. Если требуется сформулировать алгоритм решения задачи, это одно, если требуеся его реализовать, то это посложнее, часа четыре, а то и больше. Хотя, конечно, зависит от того, насколько человек хочет получить работу. Я на свою первую работу студентом дня три реализовывал тестовую задачу, сейчас бы вряд ли стал без уверенности в результате.
Re[4]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 08.08.12 04:47
Оценка:
Здравствуйте, vsb, Вы писали:

vsb> Сложность в переносах строк — парсинге всяких скобок, открывающих-закрывающих

vsb> кавычек, комментариев, если я правильно понимаю python.
да, подводные камни есть. и они показывают наличие инженерных навыков. в частности, о том, что комментарии используются для выключения кода и если их убрать, то... опс! сюрприз. а мы забыли переформатировать код за ними...

как говорится, умный от мудрого отличается тем, что умный справляется с проблемами в которые мудрый не попадает. мудрый инженер заранее предусмотрит такой сценарий, потому что это у него в крови (или в генах).

> Если требуется сформулировать алгоритм решения задачи, это одно,

> если требуеся его реализовать, то это посложнее, часа четыре, а то и больше.
четыре часа это на ассемблере что ли? по моим прикидкам -- 30 минут с учетом стресса на интервью. один из форумчан решил за 40 минут, что очень близко.

> Хотя, конечно, зависит от того, насколько человек хочет получить работу.

> Я на свою первую работу студентом дня три реализовывал тестовую задачу,
> сейчас бы вряд ли стал без уверенности в результате.
гм, тут меня гугл приглашал как _пассивного_ кандидата после успешного завершения телефонных интервью слетать к ним на недельку, чтобы порешать математические задачки for fun. и это при том, что у меня есть работа, котору я менять не собираюсь (о чем их заранее уведомил) и у них базовый оклад на 20% меньше моего базового оклада. с бонусами у них выходит больше, но бонусы это такая химия... но дело не в бонусах. мне отпуск брать и проводить у них на камбузе? они что ли думают, что они новый ватикан и каждый программист считает за честь там побывать? а вы говорите четыре часа...
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[7]: # оригинальное тестовое задание
От: sumson Россия  
Дата: 08.08.12 12:13
Оценка:
Здравствуйте, мыщъх, Вы писали:

новая версия:

%{
#include <stack>

// tabulation width in spaces count
#define TAB_WIDTH 8

int tabs = 0;
int spaces = 0;
bool newLine = false;

typedef struct SIndentData
{
    int indentLevel;
    int tabsLevel;
    SIndentData(const int level,int spaces, int tabs)
    :indentLevel(0),tabsLevel(level)
    {
        for(;tabs > 0;tabs--)
        {
            indentLevel += TAB_WIDTH;
        }
        
        for(;spaces > 0;spaces--)
        {
            indentLevel++;
        }
    }
};

typedef std::stack<SIndentData> SIndentStack;
SIndentStack gbIndentStack;
%}

%option c++
%option yywrap

newline [\n]+
space   [ ]
tab     [\t]
grid    [#]
%%

{grid}   {
    // need to skip comments that starts with #
    if(newLine)
    {
        for(;tabs > 0;tabs--)
        {
            std::cout << "\t";
        }

        for(;spaces > 0;spaces--)
        {
            std::cout << " ";
        }

        newLine = false;
    }

    ECHO;
}


{tab}   {
    if(newLine)
        tabs++;
    else
        ECHO;
}

{space}   { 
    if(newLine)
        spaces++;
    else
        ECHO;
}

{newline}   {
    newLine = true;tabs = 0;spaces = 0;
    ECHO;
}

. {
    if( newLine && 
       (tabs > 0 || spaces > 0))
    {
        int tabsCount = 1;
        if(gbIndentStack.empty())
        {
            // add to stack first indent level
            gbIndentStack.push(SIndentStack::value_type(SIndentData(tabsCount, spaces, tabs)));
        }
        else
        {
            SIndentData newIndentData(tabsCount, spaces, tabs);

            // get top indent level to check indent level
            if(newIndentData.indentLevel > gbIndentStack.top().indentLevel)
            {
                // new indent level, add it to stack
                gbIndentStack.push(SIndentStack::value_type(SIndentData(gbIndentStack.top().tabsLevel + 1, spaces, tabs)));
                tabsCount = gbIndentStack.top().tabsLevel;
            }
            else if(newIndentData.indentLevel < gbIndentStack.top().indentLevel)
            {
                // try to find our indent level on the stack
                while(!gbIndentStack.empty())
                {
                    if(newIndentData.indentLevel == gbIndentStack.top().indentLevel)
                    {
                        // if found - all ok
                        break;
                    }

                    // remove from the stack top data
                    gbIndentStack.pop();
                }

                if(gbIndentStack.empty())
                {
                    // don't find our pair indent level
                    std::cout << "error!";
                    yyterminate();
                }
                else
                {
                    tabsCount = gbIndentStack.top().tabsLevel;
                    
                    // remove from the stack top level
                    // becose we have found its pair
                    gbIndentStack.pop();
                }
            }
            else
            {
                // don't add to stack equal indent level
                tabsCount = gbIndentStack.top().tabsLevel;
            }
        }

        // cout tabulation symbols
        for(;tabsCount > 0;tabsCount--)
        {
            std::cout << "\t";
        }

        tabs = 0;spaces = 0;
    }

    ECHO;
    newLine = false;
}

%%

int main( int /* argc */, char** /* argv */ )
{
    FlexLexer* lexer = new yyFlexLexer;
    while(lexer->yylex() != 0)
     ;
    return 0;
}

int yyFlexLexer::yywrap()
{
    return 1;
}


1) есть поддержка смешанных отступов, состоящих из пробелов и табуляций, но нужно правильно указывать размер табуляции в пробелах(в моём случае 8)
2) комментарии, начинающиеся с # не участвуют в общей логике, пропускаются как есть

на вход даю сл текст:

# http://docs.python.org/reference/lexical_analysis.html
def perm(l):
        # Compute the list of all permutations of l
    if len(l) <= 1:
                  return [l]
    r = []
    for i in range(len(l)):
             s = l[:i] + l[i + 1:]
             p = perm(s)
             """ hello, world !
                     of rasta/ \"""
             """
             for x in p:
              r.append(l[i : i + 1] + x)
              if 1 == 1:
                       if  6  == 999:
                         if 9 == 666: pass
    return r

на выходе получаю:
# http://docs.python.org/reference/lexical_analysis.html
def perm(l):
        # Compute the list of all permutations of l
    if len(l) <= 1:
        return [l]
    r = []
    for i in range(len(l)):
        s = l[:i] + l[i + 1:]
        p = perm(s)
        """ hello, world !
            of rasta/ \"""
        """
        for x in p:
            r.append(l[i : i + 1] + x)
            if 1 == 1:
                if  6  == 999:
                    if 9 == 666: pass
    return r
Я знаю, как управлять Вселенной. И скажите, зачем же мне бежать за миллионом?!(c)
Re: # оригинальное тестовое задание
От: Centaur Россия  
Дата: 08.08.12 17:22
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>вот тут жизнь подкинула интересную тему, сносящую крышу и отсутствующую в гугле. захотелось найти средство для замены пробелов в скриптах на питоне на символы табуляции.


М>короче, предлагаю кандидату (особенно на роль сеньора) написать скрипт, заменяющий пробелы символами табуляции


Правильный питонист должен сказать, что табуляции не одобряются действующим стандартом кодирования PEP 8.

М>(и, в качестве бонуса, обрабатывающий скрипты где есть и то, и другое)


Re: # оригинальное тестовое задание
От: McSeem2 США http://www.antigrain.com
Дата: 08.08.12 17:46
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>вот тут жизнь подкинула интересную тему, сносящую крышу и отсутствующую в гугле. захотелось найти средство для замены пробелов в скриптах на питоне на символы табуляции. вопрос задавался 100500 раз, но каждый раз на него давались ответы в стиле "emacs это не только ценный мех" или "в vim'е это делается одним жестом руки" и предлагалось заменять четыре (!) пробела одним символом табуляции.


Не важно, сколько пробелов, но табуляция — очень коварная штука бывает. Помню проблему на Фортране и PDP-11. Какой-то редактор заменял пробелы табуляциями везде где это возможно. Ну и вот, заменил где-то в коде пробел на табуляцию внутри апострофов. Просто место так удачно совпало, что можно было заменить один пробел одной табуляцией на 8 позиций. Нифига не работало конечно же, поскольку предполагалось сравнение с пробелом, а компилятор честно втыкал в код то, что написано, то есть tab. Потратили много времени и когда обнаружили — ох мы ругались. А из за таких вот неявных подводных камней и спутники бывает улетают не туда.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[2]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 08.08.12 18:03
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Здравствуйте, мыщъх, Вы писали:


MS>Не важно, сколько пробелов, но табуляция — очень коварная штука бывает.

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


def foo():
  a = """
  *
  """
  return a

for c in foo():
    print "%02X" % (ord(c)),
print


он печатает:
0A 20 20 2A 0A 20 20

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

> Нифига не работало конечно же, поскольку предполагалось сравнение с пробелом,

> а компилятор честно втыкал в код то, что написано, то есть tab.
по схожей причине я предпочитаю пробелы обозначать как \x20, ибо уже наступил на эти грабли.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: # оригинальное тестовое задание
От: D. Petrov США  
Дата: 08.08.12 18:27
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>просьба ногами не бить, а если и бить, то не больно. и не всем сразу, а по очереди.


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



Нормальная задачка (хотя табы в коде — полный отстой). Была похожая лаба на первом курсе института только про переформатирование программы на Паскалье. Залогом успеха было использование стека.
Re[3]: # оригинальное тестовое задание
От: McSeem2 США http://www.antigrain.com
Дата: 08.08.12 18:30
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>по схожей причине я предпочитаю пробелы обозначать как \x20, ибо уже наступил на эти грабли.


А я застал времена IBM-360 c кодировкой с матерным названием EBCDIC, где пробел был 0x40, при этом исходники должны были быть совместимы. Конечно, при копировании все перекодировалось, но 0x20 в коде не катило. Вот такой я динозавр. Вообще, это была самая идиотская кодировка.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[5]: # оригинальное тестовое задание
От: Michael7 Россия  
Дата: 08.08.12 22:30
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>Здравствуйте, vsb, Вы писали:


vsb>> Сложность в переносах строк — парсинге всяких скобок, открывающих-закрывающих

vsb>> кавычек, комментариев, если я правильно понимаю python.
М>да, подводные камни есть. и они показывают наличие инженерных навыков. в частности, о том, что комментарии используются для выключения кода и если их убрать, то... опс! сюрприз. а мы забыли переформатировать код за ними...

Наличие таких комментариев делает задачу некорректной. То есть задача написания абсолютно корректного для любых примеров форматера становится трудно достижимой. Например, что если после комментария, код не на питоне, а допустим на другом языке программирования и приведен для справки. Конечно, код на другом языке не подвергнется раскомментированию, но все равно нехорошо как-то.
Re[6]: # оригинальное тестовое задание
От: мыщъх США http://nezumi-lab.org
Дата: 08.08.12 23:49
Оценка:
Здравствуйте, Michael7, Вы писали:

M>Здравствуйте, мыщъх, Вы писали:


М>>Здравствуйте, vsb, Вы писали:


>> сюрприз. а мы забыли переформатировать код за ними...

M> Наличие таких комментариев делает задачу некорректной.
если мы переформатируем код за комментариями (и если эта фича конфигурабельна), то лучше поддержать такую возможность, чем бояться, что за комментами будет ASCII art, который мы порушим.

кстати, есть легенда о том как давным-давно рухнул мост по которому шла рота солдат (резонанс). или не легенда? судя по книжкам коммандиры отдавали приказ сбить ногу перед входом на мост. архитектор моста на то и архитектор, чтобы обладать эрудицией и выходить за рамки ТЗ.

> То есть задача написания абсолютно корректного для любых примеров форматера

> становится трудно достижимой. Например, что если после комментария
> код не на питоне, а допустим на другом языке программирования и приведен
> для справки. Конечно, код на другом языке не подвергнется раскомментированию,
> но все равно нехорошо как-то.
согласен с вами. в комментах может быть и таблица, например. переформатирование ее угробит. кстати, это хорошая тема для собеседования.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: # оригинальное тестовое задание
От: ResidentR6  
Дата: 11.08.12 21:16
Оценка:
В сад такой подход! Это не на должность сеньора, а на должность ПСИХА.
Диагностирует ПОМЕШАТЕЛЬСТВО. Возможно он когда-нибудь напишет свою
операционку. Но скорее всего просто просадит бюджет.

Реальное программирование — ремесло. Задачи должны быть не на камасутру,
а на масштабы и на скорость.

А ещё это командная работа. И ценный человек именно те качества имеет,
которых в команде ЕЩЁ НЕТ! Потому такими тестами самых ценных и
отшвырнёшь. Ибо по себе судишь...
Posted via RSDN NNTP Server 2.1 beta
Re[2]: # оригинальное тестовое задание
От: ResidentR6  
Дата: 11.08.12 21:18
Оценка:
Да, я помню что просил ногами не бить. Потому я лопатой, легонечко.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: # оригинальное тестовое задание
От: ResidentR6  
Дата: 11.08.12 21:20
Оценка:
Лучше сразу дай задачу: Изобрести что-то супер-инновационное на двух
колёсах с педалями.
Posted via RSDN NNTP Server 2.1 beta
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.