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

Вы должны сгруппировать оба объекта, которые хотите сохранить, а затем сосчитать тот, в котором вы хотите найти вхождения. Вот пример входного файла:

Brand   Model
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Acura   RDX
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
Beach   Baby
BMW     320i
BMW     320i
BMW     320i
BMW     320i
BMW     320i
BMW     320i
BMW     320i
BMW     550i
BMW     550i
BMW     550i
BMW     550i
BMW     550i
BMW     550i
BMW     550i
Cadillac        Escalade
Cadillac        Escalade
Cadillac        Escalade
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo
Chana   Cargo

Простые панды один вкладыш:

df = pd.read_table('fun.txt', header=0)
print(df.groupby(['Brand','Model'])['Model'].agg(['count']))

И вывод:

                   count
Brand    Model
Acura    RDX          10
BMW      320i          7
         550i          7
Beach    Baby         10
Cadillac Escalade      3
Chana    Cargo        12

Если вы хотите отсортировать значения по частоте (от наибольшего к наименьшему) и оставьте только самое большое, измените однострочник на:

groupby_df = (df.groupby(['Brand','Model'])['Model'].agg(['count']).sort_values(by='count', ascending=False).reset_index().drop_duplicates('Brand', keep='first'))

, чтобы получить:

      Brand     Model  count
0     Chana     Cargo     12
1     Acura       RDX     10
2     Beach      Baby     10
3       BMW      320i      7
5  Cadillac  Escalade      3
28
задан Jonas 16 August 2010 в 19:55
поделиться

15 ответов

По крайней мере, вы сформулировали вопрос с правильной точки зрения =)

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

Классическим примером этого является доступ к данным; вы можете сгенерировать 250 классов (по 1 для каждой таблицы в схеме), эффективно создав решение для шлюза таблиц, или вы можете создать что-то более похожее на модель предметной области и использовать NHibernate / ActiveRecord / LightSpeed ​​/ [выберите свой orm] для отображения богатой модели предметной области в базу данных.

Хотя и ручное решение, и ORM являются эффективными генераторами кода, основное различие заключается в том, когда код генерируется. В ORM это неявный шаг, который происходит во время выполнения и, следовательно, является односторонним по своей природе. Решение, созданное вручную, требует явного шага для генерации кода во время разработки и вероятности того, что сгенерированные классы потребуют настройки в какой-то момент, что создаст проблемы при повторной генерации кода. Явный шаг, который должен произойти во время разработки, вносит трение в процесс разработки и часто приводит к коду, который нарушает DRY (хотя некоторые утверждают, что сгенерированный код никогда не может нарушать DRY).

Другая причина рекламирования генерации кода связана с миром MDA / MDE (Model Driven Architecture / Engineering).Я не придаю этому большого значения, но вместо того, чтобы приводить ряд плохо выраженных аргументов, я просто собираюсь привлечь кого-нибудь еще - http://www.infoq.com/articles/8-reasons -why-MDE-fails .

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

Одним из типов генерации кода, действительно повышающим продуктивность, является «генерация микрокода», когда использование макросов и шаблонов позволяет разработчику генерировать новый код непосредственно в среде IDE и вводить / вводить свой путь через заполнители (например, пространство имен / имя класса и т. д.). Такая генерация кода - это функция resharper, и я интенсивно использую ее каждый день. Причина того, что микрогенерация выигрывает там, где большинство крупномасштабных генераций кода терпит неудачу, заключается в том, что сгенерированный код не привязан к какому-либо другому ресурсу, который должен быть синхронизирован, и поэтому, как только код сгенерирован, он такой же, как и весь другой код в решение.

@John
Перенос создания "базовых классов" из среды IDE в xml / dsl часто наблюдается при большой разработке. Классическим примером может быть попытка разработчиков преобразовать базу данных в модель предметной области.Если генератор кода не очень хорошо написан, он просто создает дополнительную нагрузку на разработчика, поскольку каждый раз, когда им нужно обновить модель предметной области, им придется либо переключать контекст и обновлять xml / dsl, либо расширять модель предметной области. а затем перенесите эти изменения обратно в xml / dsl (эффективно выполняя работу дважды).

Есть некоторые генераторы кода, которые очень хорошо работают в этой области (дизайнер LightSpeed ​​- единственный, о котором я могу думать), выступая в качестве движка для поверхности дизайна, но часто эти генераторы кода генерируют ужасные код, который невозможно поддерживать (например, поверхности проектирования winforms / webforms, поверхность проектирования EF1) и, следовательно, быстро сводит на нет любые преимущества производительности, полученные от использования генератора кода в первую очередь.

20
ответ дан 28 November 2019 в 02:49
поделиться

Я на самом деле добавляю последние штрихи к генератору кода, который я использую для проекта, на который меня наняли. У нас есть огромные XML-файлы определений, и за несколько дней работы я смог создать более 500 классов C #. Если я хочу добавить функциональность ко всем классам, скажем, я хочу добавить атрибут ко всем свойствам. Я просто добавляю его в мой код-генератор, нажимаю go и бам! Я сделал.

Это действительно хорошо, правда.

1
ответ дан Joel 28 November 2019 в 02:49
поделиться

Все говорят здесь о простой генерации кода, но как насчет генерации кода на основе моделей (например, MDSD или DSM)? Это поможет вам выйти за пределы простых ORM / участников-участников / генераторов шаблонов и перейти к генерации кода высокоуровневых концепций для вашей проблемной области.

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

Подобно тому, как 3GL и ООП обеспечили увеличение абстракции за счет генерации большого количества кода сборки на основе спецификации более высокого уровня, разработка на основе моделей позволяет нам снова повысить уровень абстракции с еще одним повышением производительности.

MetaEdit + от MetaCase (для взрослых) и ABSE от Isomeris (мой проект, в альфа-версии, информация на http://www.abse.info ) - две технологии, находящиеся на переднем крае генерации кода на основе моделей. .

Что действительно нужно, так это изменение мышления (как ООП, необходимого в 90-х годах) ...

2
ответ дан Rui Curado 28 November 2019 в 02:49
поделиться

Как насчет примера хорошего использования генератора кода?

При этом используются шаблоны t4 (генератор кода, встроенный в Visual Studio) для генерации сжатых CSS из файлов .less: http://haacked.com/archive/2009/12/02/t4- template-for-less-css.aspx

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

2
ответ дан Joel Coehoorn 28 November 2019 в 02:49
поделиться

Генератор кода полезен, если:

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

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

  3. Дополнительная проблема отладки сгенерированного кода не сделает отладку недостаточно эффективной, чтобы перевесить преимущества от 1 и 2.

3
ответ дан Larry Watanabe 28 November 2019 в 02:49
поделиться

Каноническим примером этого является доступ к данным, но у меня есть другой пример. Я работал над системой обмена сообщениями, которая связывается через последовательный порт, сокеты и т. Д., И я обнаружил, что мне постоянно приходится писать такие классы снова и снова:

public class FooMessage
{
    public FooMessage()
    {
    }

    public FooMessage(int bar, string baz, DateTime blah)
    {
        this.Bar = bar;
        this.Baz = baz;
        this.Blah = blah;
    }

    public void Read(BinaryReader reader)
    {
        this.Bar = reader.ReadInt32();
        this.Baz = Encoding.ASCII.GetString(reader.ReadBytes(30));
        this.Blah = new DateTime(reader.ReadInt16(), reader.ReadByte(),
            reader.ReadByte());
    }

    public void Write(BinaryWriter writer)
    {
        writer.Write(this.Bar);
        writer.Write(Encoding.ASCII.GetBytes(
            this.Baz.PadRight(30).Substring(0, 30)));
        writer.Write((Int16)this.Blah.Year);
        writer.Write((byte)this.Blah.Month);
        writer.Write((byte)this.Blah.Day);
    }

    public int Bar { get; set; }
    public string Baz { get; set; }
    public DateTime Blah { get; set; }
}

Попробуйте представить, если вы будет, написав этот код для не менее 300 различных типов сообщений. Один и тот же скучный, утомительный, подверженный ошибкам код пишется снова и снова. Мне удалось написать примерно 3 из них, прежде чем я решил, что мне будет проще написать генератор кода, и я сделал это.

Я не буду публиковать код code-gen, это много загадочных вещей в CodeDom, но суть в том, что мне удалось сжать всю систему до одного XML-файла:

<Messages>
    <Message ID="12345" Name="Foo">
        <ByteField Name="Bar"/>
        <TextField Name="Baz" Length="30"/>
        <DateTimeField Name="Blah" Precision="Day"/>
    </Message>
    (More messages)
</Messages>

Насколько это проще? (Риторический вопрос.) Я мог наконец дышать. Я даже добавил несколько наворотов, чтобы он мог генерировать «прокси», и я мог написать такой код:

var p = new MyMessagingProtocol(...);
SetFooResult result = p.SetFoo(3, "Hello", DateTime.Today);

В конце я бы сказал, что это спасло меня от написания хороших 7500 строк. кода и превратил 3-недельное задание в 3-дневное задание (ну, плюс пара дней, необходимых для написания кода).

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

4
ответ дан Aaronaught 28 November 2019 в 02:49
поделиться

Действительно, когда вы используете практически любой язык программирования, вы используете «генератор кода» (за исключением ассемблера или машинного кода). Я часто пишу маленькие 200-строчные сценарии, которые запускают несколько тысяч строк C. это также программное обеспечение, которое вы можете получить, которое помогает генерировать определенные типы кода (например, yacc и lex используются для генерации синтаксических анализаторов для создания языков программирования.)

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

Например, вот очень длинный и утомительный файл, который я (не) написал как часть моей работы по модификации игрового движка CRX на базе Quake2. Он берет целочисленные значения всех # определенных констант из двух заголовков и превращает их в «cvars» (переменные для игровой консоли.)
http: //meliaserlow.dyndns. tv: 8000 / alienarena / lua_source / game / cvar_constants.c

Вот короткий сценарий Bash, сгенерировавший этот код во время компиляции:
http: // meliaserlow.dyndns.tv:8000/alienarena/lua_source/autogen/constant_cvars.sh

Теперь, что бы вы предпочли сохранить? Они оба эквивалентны с точки зрения того, что они описывают, но один из них гораздо длиннее и раздражает в обращении.

4
ответ дан Max E. 28 November 2019 в 02:49
поделиться

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

  • Это было быстрее (было большое количество кода для генерации)
  • Я мог перегенерировать код по прихоти в случае обнаружения ошибки (в ранних версиях кода иногда могут быть ошибки)
  • Меньше ошибок; когда у нас была ошибка в сгенерированном коде, она была везде , что означает, что ее с большей вероятностью можно было найти (и, как отмечалось в предыдущем пункте, ее было легко исправить и восстановить код).
6
ответ дан Fredrik Mörk 28 November 2019 в 02:49
поделиться

Ну, это либо:

  • вы пишете 250 классов, все почти одинаковые, но немного другие, например. делать доступ к данным; занимает неделю, и это скучно, подвержено ошибкам и раздражает грубая работа через 30 минут
    • Итак, генератор кода дает вам:

      • скорость
      • воспроизводимость
      • намного меньше ошибок
      • намного больше свободного времени! : -)

      Прекрасные примеры:

      • Шаблоны Linq-to-SQL T4 от Damien Guard для создания одного отдельного файла на класс в вашей модели базы данных, используя самый лучший секрет Visual Studio 2008 - шаблоны T4

      • PLINQO - то же самое, но для генератора Кодесмита

      и бесчисленное множество .....

17
ответ дан marc_s 28 November 2019 в 02:49
поделиться

Для доменных или многоуровневых приложений генерация кода является отличным способом создания исходной модели или уровня доступа к данным. Он может произвести 250 классов сущностей за 30 секунд (или в моем случае 750 классов за 5 минут). Это оставляет программисту возможность сосредоточиться на улучшении модели с помощью отношений, бизнес-правил или получения представлений в MVC.

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

Если вы просто хотите, чтобы слой данных был «автоматически создан», чтобы вы могли «заставить графический интерфейс работать за 2 дня», то я бы предложил использовать продукт / набор инструментов, ориентированный на управляемый или двухуровневый сценарий приложения.

И, наконец, имейте в виду, что «garbage in = garbage out». Если весь ваш уровень данных однороден и не абстрагируется от базы данных, пожалуйста, спросите себя, зачем вам вообще нужен уровень данных. (Если вам не нужно выглядеть продуктивно :))

2
ответ дан Jennifer Zouak 28 November 2019 в 02:49
поделиться

Если с генератором кода вы также намереваетесь использовать фрагменты, попробуйте разницу между вводом ctor + TAB и написанием конструктора каждый раз в ваших классах. Или проверьте, сколько времени вы зарабатываете, используя фрагмент для создания оператора switch, связанного с перечислением со многими значениями.

0
ответ дан 28 November 2019 в 02:49
поделиться

Использование построителей графического интерфейса, которые генерируют для вас код, является обычной практикой. Благодаря этому вам не нужно вручную создавать все виджеты. Вы просто перетаскиваете их и используете сгенерированный код. Для простых виджетов это действительно экономит время (я часто использовал это для wxWidgets).

4
ответ дан 28 November 2019 в 02:49
поделиться

Если вам платят LOC и вы работаете на людей, которые не понимают, что такое генерация кода, это имеет большой смысл. Это не шутка, кстати - я работал с несколькими программистами, которые использовали эту технику именно для этой цели. Формально LOC больше никому не платят (во всяком случае, мне об этом известно), но от программистов обычно ожидают продуктивности, а выдача больших объемов кода может заставить кого-то выглядеть продуктивным.

В качестве лишь слегка касательного момента, я думаю, это также объясняет тенденцию некоторых программистов разбивать единую логическую единицу кода на как можно большее количество различных классов (вы когда-нибудь получали в наследство проект с классами LastName, FirstName и MiddleInitial?).

0
ответ дан 28 November 2019 в 02:49
поделиться

Вот некоторая ересь:

Если задача настолько глупая, что ее можно автоматизировать во время написания программы (т.е. исходный код может быть сгенерирован скриптом из, скажем, XML ), то то же самое можно сделать во время выполнения (т.е. некоторое представление этого XML может быть интерпретировано во время выполнения) или с помощью некоторого метапрограммирования. Таким образом, по сути, программист был ленив, не пытался решить настоящую проблему, но выбрал простой выход и написал генератор кода. В Java / C # посмотрите на отражение, а в C ++ посмотрите на шаблоны

0
ответ дан 28 November 2019 в 02:49
поделиться

Существует множество вариантов использования генерации кода.

Написание кода на знакомом языке и генерация кода для другого целевого языка.

  • GWT - Java -> Javascript
  • MonoTouch - C# -> Objective-C

Написание кода на более высоком уровне абстракции.

  • Компиляторы
  • Доменно-специфические языки

Автоматизация повторяющихся задач.

  • Слои доступа к данным
  • Начальные модели данных

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

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

1
ответ дан 28 November 2019 в 02:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: