Стиль ИИ
От: B0FEE664  
Дата: 25.12.24 20:33
Оценка: :)
По мотивам Агенты заменят ВСЕ
Автор: TheBeginner
Дата: 23.12 17:36


В своей жизни я много кода написал и много кода прочитал. Разного уровня, стиля, качества. Сейчас, глядя на авторский код я даже часто могу угадать примерную область деятельности, уровень образования и стаж.
А сейчас такая картина:
набрали по объявлению на острове в индийском океане;
по слухам пятеро там стОят как один тут, в ЕС;
иногда делаю код-ревью их пуллреквестов.

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

Короче, глядя на код вы можете сказать, его писал человек или ИИ?
И каждый день — без права на ошибку...
Re: Стиль ИИ
От: Alekzander  
Дата: 25.12.24 21:34
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Короче, глядя на код вы можете сказать, его писал человек или ИИ?


ИИ не пишет код. ИИ подставляет код, написанный кем-то где-то на Гитхабе или форуме ProgrammingNoobs, и оттуда попавший в датасет, с метаданными, описывающими задачу.

Читать это гамно я принципиально не собираюсь. Я не против кода с Гитхаба или форума ProgrammingNoobs, но при одном условии: что его оттуда скопировали здравомыслящие люди, и взяли только правильные куски, а не лошадиные жопы и обрезанные сосиски. А какое может быть понимание, если этот код прошёл через рандомизатор?

Но так или иначе, а периодически приходится видеть. В частности, я видел, как "написанным ИИ" кодом хвастался один чел, которому железный дурак сгенерировал работу с окнами через WinAPI. Архитектор винды старался, предусматривал userdata для колбеков — а там передача шла через глобальную переменную. Потому что та дичь, чей код попал в датасет, концепцию userdata не осилила. Имена колбеков совпадали с dummy-именами из MSDN — ясен пень, их надо было переименовать в соответствии с задачей. Но та дичь, чей код попал в датасет, скопировала код примера из MSDN, и ничего там не переименовала.

И видя этот код, якобы написанный ИИ, я мысленным взором видел наших загорелых друзей, которые его на самом деле когда-то и написали. Так что, всё довольно аутентичненько, я б сказал.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Отредактировано 25.12.2024 21:37 Alekzander . Предыдущая версия .
Re: Стиль ИИ
От: vsb Казахстан  
Дата: 25.12.24 22:13
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Короче, глядя на код вы можете сказать, его писал человек или ИИ?


Не могу. Если очень плохой код — могу предположить, что писал человек, ИИ обычно пишет код условно говоря среднего и выше качества. Это единственный критерий, который я могу применить.
Отредактировано 25.12.2024 22:15 vsb . Предыдущая версия .
Re: Стиль ИИ
От: vsb Казахстан  
Дата: 25.12.24 22:26
Оценка:
Вот если кому интересно — два листинга. Один вариант писал я, второй код ChatGPT. Можете попробовать предположить — где какой.

  вариант один
package com.example;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import java.util.*;

/**
 * Minimal implementation of {@link NamespaceContext}.
 */
public class NamespaceContextImpl implements NamespaceContext {
    private final Map<String, String> prefixToUri = new HashMap<>();
    private final Map<String, Set<String>> uriToPrefixes = new HashMap<>();

    public NamespaceContextImpl(String... prefixNamespaceUriPairs) {
        if (prefixNamespaceUriPairs == null || prefixNamespaceUriPairs.length % 2 != 0) {
            throw new IllegalArgumentException("Must provide prefix/URI pairs.");
        }
        for (int i = 0; i < prefixNamespaceUriPairs.length; i += 2) {
            String prefix = prefixNamespaceUriPairs[i];
            String uri = prefixNamespaceUriPairs[i + 1];
            prefixToUri.put(prefix, uri);
            uriToPrefixes.computeIfAbsent(uri, k -> new HashSet<>()).add(prefix);
        }
    }

    @Override
    public String getNamespaceURI(String prefix) {
        if (prefix == null) throw new IllegalArgumentException("Prefix cannot be null.");
        if (prefix.equals(XMLConstants.XML_NS_PREFIX)) return XMLConstants.XML_NS_URI;
        if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
        return prefixToUri.getOrDefault(prefix, XMLConstants.NULL_NS_URI);
    }

    @Override
    public String getPrefix(String namespaceURI) {
        if (namespaceURI == null) throw new IllegalArgumentException("NamespaceURI cannot be null.");
        if (namespaceURI.equals(XMLConstants.XML_NS_URI)) return XMLConstants.XML_NS_PREFIX;
        if (namespaceURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) return XMLConstants.XMLNS_ATTRIBUTE;
        Set<String> prefixes = uriToPrefixes.get(namespaceURI);
        return (prefixes == null || prefixes.isEmpty()) ? null : prefixes.iterator().next();
    }

    @Override
    public Iterator<String> getPrefixes(String namespaceURI) {
        if (namespaceURI == null) throw new IllegalArgumentException("NamespaceURI cannot be null.");
        if (namespaceURI.equals(XMLConstants.XML_NS_URI)) {
            return Collections.singleton(XMLConstants.XML_NS_PREFIX).iterator();
        }
        if (namespaceURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
            return Collections.singleton(XMLConstants.XMLNS_ATTRIBUTE).iterator();
        }
        Set<String> prefixes = uriToPrefixes.get(namespaceURI);
        return prefixes == null ? Collections.emptyIterator() : Collections.unmodifiableSet(prefixes).iterator();
    }
}


  вариант два
package com.example;

import static java.util.Collections.unmodifiableCollection;
import static java.util.Objects.requireNonNull;
import static javax.xml.XMLConstants.NULL_NS_URI;
import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
import static javax.xml.XMLConstants.XML_NS_PREFIX;
import static javax.xml.XMLConstants.XML_NS_URI;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.NamespaceContext;

public class NamespaceContextImpl implements NamespaceContext {

  private final List<String> prefixes;
  private final Map<String, String> prefixToNamespaceUri;
  private final Map<String, String> namespaceUriToPrefix;

  public NamespaceContextImpl(String... prefixNamespaceUriPairs) {
    if (prefixNamespaceUriPairs.length % 2 != 0) {
      throw new IllegalArgumentException("prefixNamespaceUriPairs must be even");
    }

    var capacity = prefixNamespaceUriPairs.length / 2;

    prefixes = new ArrayList<>(capacity);
    prefixToNamespaceUri = HashMap.newHashMap(capacity);
    namespaceUriToPrefix = HashMap.newHashMap(capacity);

    for (int i = 0; i < prefixNamespaceUriPairs.length; i += 2) {
      var prefix = prefixNamespaceUriPairs[i];
      var namespaceUri = prefixNamespaceUriPairs[i + 1];

      requireNonNull(prefix, "prefix");
      requireNonNull(namespaceUri, "namespaceUri");

      prefixes.add(prefix);

      if (prefixToNamespaceUri.put(prefix, namespaceUri) != null) {
        throw new IllegalArgumentException("duplicate prefix: " + prefix);
      }

      var oldPrefix = namespaceUriToPrefix.put(namespaceUri, prefix);
      if (oldPrefix != null && oldPrefix.isEmpty()) {
        namespaceUriToPrefix.put(namespaceUri, oldPrefix);
      }
    }
  }

  @Override
  public String getNamespaceURI(String prefix) {
    return switch (prefix) {
      case null -> throw new IllegalArgumentException("prefix is null");
      case XML_NS_PREFIX -> XML_NS_URI;
      case XMLNS_ATTRIBUTE -> XMLNS_ATTRIBUTE_NS_URI;
      default -> prefixToNamespaceUri.getOrDefault(prefix, NULL_NS_URI);
    };
  }

  @Override
  public String getPrefix(String namespaceUri) {
    return switch (namespaceUri) {
      case null -> throw new IllegalArgumentException("namespaceUri is null");
      case XML_NS_URI -> XML_NS_PREFIX;
      case XMLNS_ATTRIBUTE_NS_URI -> XMLNS_ATTRIBUTE;
      default -> namespaceUriToPrefix.getOrDefault(namespaceUri, null);
    };
  }

  @Override
  public Iterator<String> getPrefixes(String namespaceUri) {
    return unmodifiableCollection(prefixes).iterator();
  }

}


  правильный ответ
Первый вариант писал ChatGPT, второй вариант писал я.
Отредактировано 25.12.2024 22:27 vsb . Предыдущая версия .
Re[2]: Стиль ИИ
От: Michael7 Россия  
Дата: 26.12.24 05:10
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>
  правильный ответ
vsb>Первый вариант писал ChatGPT, второй вариант писал я.


Я угадал. У ИИ код обычно лучше оформлен. В том числе со знанием английского. Но он запросто может сгаллюцинировать несуществующий метод или даже целиком несуществующую библиотеку, причем выглядеть это будет очень правдоподобно.
Re: Стиль ИИ
От: Нomunculus Россия  
Дата: 26.12.24 05:17
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

Один единственный раз я попросил написать код ИИ. Скрипт для Блендера. Так как не знал ни Блендер, ни Питон. ИИ написал. И не работало НИЧЕГО от слова «совсем». Так что код от ИИ идет лесом. Пока
Re[2]: Стиль ИИ
От: so5team https://stiffstream.com
Дата: 26.12.24 05:42
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Вот если кому интересно — два листинга. Один вариант писал я, второй код ChatGPT. Можете попробовать предположить — где какой.


vsb>
vsb>    @Override
vsb>    public String getNamespaceURI(String prefix) {
vsb>        if (prefix == null) throw new IllegalArgumentException("Prefix cannot be null.");
vsb>


А что, в Java все еще принято проверять аргументы ссылочных типов на null?
Re[3]: Стиль ИИ
От: vsb Казахстан  
Дата: 26.12.24 08:52
Оценка:
Здравствуйте, so5team, Вы писали:

S>А что, в Java все еще принято проверять аргументы ссылочных типов на null?


Конкретно в этом случае это требование контракта NamespaceContext:

When requesting a Namespace URI by prefix, the following table describes the returned Namespace URI value for all possible prefix values: ... null: IllegalArgumentException is thrown

В общем случае — для публичных методов — да, желательно проверять, чтобы ошибочное значение отловилось как можно быстрей. Правда принято кидать NullPointerException, а не IllegalArgumentException, но это вопрос непринципиальный. Иногда используют аннотации @NotNull и препроцессоры для кода, которые такие проверки вставляют автоматически, иногда — вручную. В целом в Java как языке в этом отношении ничего не поменялось, поэтому и принятые практики не поменялись, я полагаю.

Обещают добавить в язык not null типы, как в других языках, но когда это будет и будет ли вообще — неизвестно.
Отредактировано 26.12.2024 8:59 vsb . Предыдущая версия .
Re: Стиль ИИ
От: Privalov  
Дата: 26.12.24 09:34
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Короче, глядя на код вы можете сказать, его писал человек или ИИ?


Просто глядя на код — наверное, не всегда. Потому что этот код подозрительно похож на примеры со StackOverflow или MSDN.
А вот если попытаться запустить, тогда можно. Код от ИИ не работает примерно никогда.
Отредактировано 26.12.2024 9:38 Privalov . Предыдущая версия .
Re[4]: Стиль ИИ
От: so5team https://stiffstream.com
Дата: 26.12.24 09:53
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В общем случае — для публичных методов — да, желательно проверять, чтобы ошибочное значение отловилось как можно быстрей.


Тогда мне кажется, что код от chatGPT более скрупулезно подходит к этому вопросу. Например, вы просто написали:
if (prefixNamespaceUriPairs.length % 2 != 0)

без предварительной проверки prefixNamespaceUriPairs на null. Нет такой проверки и в вашем getPrefixes (хотя может такую проверку делает unmodifiableCollection).

vsb>В целом в Java как языке в этом отношении ничего не поменялось, поэтому и принятые практики не поменялись, я полагаю.


vsb>Обещают добавить в язык not null типы, как в других языках, но когда это будет и будет ли вообще — неизвестно.


Как печально.
Отредактировано 26.12.2024 9:56 so5team . Предыдущая версия .
Re[5]: Стиль ИИ
От: vsb Казахстан  
Дата: 26.12.24 12:12
Оценка:
Здравствуйте, so5team, Вы писали:

S>Тогда мне кажется, что код от chatGPT более скрупулезно подходит к этому вопросу. Например, вы просто написали:

S>
if (prefixNamespaceUriPairs.length % 2 != 0)

S>без предварительной проверки prefixNamespaceUriPairs на null.

Ну проверять всё на свете это уже особая форма паранойи... В данном случае это varargs метод, который будет конструироваться кодом вида new NamespaceContextImpl("p1", "url1", "p2", "url2") и null при таком использовании туда не попадёт. Если сильно захотеть, тот null передать можно. Но и при этом большой беды не будет, т.к. exception вылетит практически сразу же, так что лишняя проверка может хуже и не сделает, но особо не нужна в данном случае.

> Нет такой проверки и в вашем getPrefixes (хотя может такую проверку делает unmodifiableCollection).


Это уже можно считать багом, спасибо. exception там вылетит, но NullPointerException вместо IllegalArgumentException, как того требует контракт. Проглядел.

vsb>>В целом в Java как языке в этом отношении ничего не поменялось, поэтому и принятые практики не поменялись, я полагаю.


vsb>>Обещают добавить в язык not null типы, как в других языках, но когда это будет и будет ли вообще — неизвестно.


S>Как печально.


Ещё добавлю, что современная IDE обычно поддерживает Nullable/NonNull аннотации на уровне линтера. Поэтому систему типов этими аннотациями таки дополнить можно и в целом большинство очевидных багов это устранит, если не игнорировать предупреждения. Это уже безопасность наподобие TypeScript, когда в рантайме проверок нет, но на этапе сборки — есть. Возможно этот подход будет для многих оптимальным, на мой взгляд он похож на правило 80/20 — минимальными усилиями убираются большинство багов. А испещрять код всевозможными ручными проверками — у этого уже есть своя когнитивная нагрузка, и не факт, что польза от поимки редчайшего бага превысит вред от повышения избыточности кода.
Отредактировано 26.12.2024 12:14 vsb . Предыдущая версия .
Re[2]: Стиль ИИ
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.12.24 14:49
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>Один единственный раз я попросил написать код ИИ. Скрипт для Блендера. Так как не знал ни Блендер, ни Питон. ИИ написал. И не работало НИЧЕГО от слова «совсем». Так что код от ИИ идет лесом. Пока


Какое то особенное везение у вас. Брльшинство вещей что я просил, работает сразу, для вставки только доработать нужно — имена, типы, структуру
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.