Вы понимаете, что я хочу сам решать, сколько и где мне отступов ставить?
Вы же понимаете, что тогда вам работа в команде противопоказана? Я как то читал код на питоне, где вместо 4 пробелов ставили 1 пробел. Мне было очень тяжело.
И да, у меня именно такие вот экзотические случаи в порядке вещей.
То есть вы в этих случаях без отступов пишете? Самому как потом это читать? Нигде не зудит от чтения своего же кода без отступов?
Кстати, у меня есть подозрения, что эти ваши случаи, которые в порядке вещей, нужно, и я думаю можно, как то исправить. Давайте вы опишите, а я попробую вам помочь?
Ну и вишенкой не ожидаемая ни в одном другом языке, включая whitespace-sensitive, ошибка тута:
if foo == bar or
foo == baz:
continue
Вообще конечно можно вот так, если вам очень хочется:
if (foo == bar or
foo == baz):
continue
Но за всю карьеру питона мне ни разу не требовалось делать многострочные условия. Когда появлялась такая нужда, я старался устранить саму нужду. Это то же самое, что многострочные объявления функций, когда у вас сотня аргументов: может в каких то языках это считается нормальным, но много где это признак плохого кода/архитектуры.
А где вы там многоэтажный if и кучу безымянных выражений увидели, если не секрет?
Два условия — для питона уже куча?
В том то и дело, когда это два простых условия, двухэтажный if не требуется. И я подозреваю, что у вас там либо дофига условий, либо безымянные нечитаемые условия вида if len(str(count(map(max(min(sort(filter(please(sudo(10)))))) >= len(str(count(map(max(min(sort(filter(20))))))
Отступы «адский ад» только первую неделю активного писания, потом наступает прозрение.
Господи, о чем вы говорите? У меня неделю только длилась эйфория от того, что наконец-то интерпретатор по отступам понимает мой код, и не нужно мне впредь ставить эти скобочки и точки с запятой.
Какой еще ад? Вот я аргумент про питонячьи отступы никогда не понимал и до сих пор не понимаю: вы ставите отступы (всегда), скобочки и точки с запятой, и тут вам новый язык предлагает оставить только отступы, значительно облегчая вам написание кода, убирая кучу синтаксического шума, и для вас это ад? Вы что, мазохист?
Причем, пытаются это объяснить какими-то экзотическими случаями, которые на практике вообще сложно встретить. Типа, я пишу код прям на сервере в простом текстовом редакторе, находясь в космосе с завязанными за спиной руками, мне неудобно делать отступы. То есть как это понимать, что был бы другой язык, вы бы оставили этот код без отступов, и пускай люди мучаются, читая его?
Я как бы не только на плюсах-то пишу, и к другим языкам претензий нет
Да, но при этом в другом коменте у вас была тяга сотворить какой-то многоэтажный if. Что уже говорит о том, что вы что-то делаете не так, раз у вас в одно условие лезет куча безымянных выражений, что появляется тяга их раскладывать на строки.
Понимаете, это как с юниттестами — если у вас плохая архитектура, нет SRP, нет DI, то и юниттесты вы не напишите к проекту, а будете ругаться, какой плохой инструмент эти ваши юниттесты.
Сначала набирал ответ по каждому пункту, но закрались подозрения, что вы пытаетесь в питон принести какой-то другой ЯП. Могу ли я попросить посмотреть код? Может я смогу чем-то помочь. И образец лога. И решение на хаскеле.
И вообще, мне кажется логи на хаскеле должно быть проще парсить, чем на питоне, но могу ошибаться.
То есть вам чисто принципиально обидно? Или вы в других языках позволяете себе где-то не писать отступы? Когда я жрал кактус с богомерзкими фигурными скобочками и точками с запятой, я мечтал, чтобы интерпретатор по отступам сам понимал, какие блоки я от него хочу. Спасибо, что мне в свое время показали питон. И как же я обрадовался, когда отступы оказались самым меньшим из благ, которые я познал в питоне.
Но это еще фигня. Я знаю два прекрасных языка, где помимо скобочек и точек с запятой, приходится перед переменными ставить доллар. Чрезвычайно любопытно, как другие языки работают без долларов, магия какая-то.
Только что обнаружил баг при зуме странице с помощью Ctrl + Scroll. Текущий масштаб (в процентах в углу) отображается неверно, запаздывает на одну итерацию. С помощью Ctrl + "+" такого бага не наблюдается.
Эти комбинации в принципе нет смысла хранить, когда есть кэш. Инвалидация кэша пускай случается при перезарядке или активации какого-либо модификатора урона, и никакой проблемы не будет.
И нагрузка все таки смешная, даже без кэширования, даже для тысячи кораблей. Мой домашний процессор такое может рассчитывать без проблем, и у него еще останется, чтоб крипту майнить. А лагает оно, я уверен, из-за IO (сеть, база, и т. д.), но уж точно не из-за CPU.
Ну во-первых, это онлайн игра, и расчеты идут на сервере.
Во-вторых, нагрузка то смешная. На корабле, ну максимум 20 модулей, из которых лишь половина одновременно активных. Посчитать за выстрел произведение из 3-5 множителей для каждого модуля это вообще фигня.
В-третьих, про смену конфигурации вы верно заметили, с одной стороны глупо просчитывать каждый выстрел. Но и держать просчитанные модели всех возможных комбинаций модулей, кораблей и снарядов тоже глупо, особенно учитывая, что даже текущая скорость корабля может влиять на получаемый урон и промахи. Возможно, какие-то коэффициенты кэшируются при смене снарядов, но в целом динамическая иерархия остается, ибо многие множители меняются в ходе боя постоянно.
В целом в eve online все довольно бодренько с быстродействием. В одной битве могут принимать участие тысячи кораблей
Говоря, что я не встречал такой уровень, имелось в виду не то, что я не встречал четырехуровневых механик в игре, а что я не встречал именно учёт и сохранение свойств материалов в создаваемых модулях для слотов.
Вот кстати еще пример игры, где довольно гибкая кастомизация, благодаря сочетанию глубины настоящих слоев, количества возможных объектов в каждом слое, и количеству их комбинаций: EVE Online.
1. Космический корабль.
2. В корабле помимо его собственных характеристик есть слоты под сменные модули (оружия, ускорители, щиты, реакторы и т. д.) — это агрегация.
3. В модулях есть хранилище расходников (боекомплект, батарейки, наниты и т. д.), которых тоже множество видов, и которые обладают своими характеристиками. Например, разные типы ракет могут быть хороши либо против больших целей, либо против маленьких и быстрых, либо вообще против сооружений. Это тоже агрегация.
Итоговые характеристики корабля динамически вычисляются из характеристик каждого слоя. Например мощность взрыва ракеты зависит от самого корабля, его скорости, от оружия, которое установлено в слот, и от типа снарядов, которым это оружие заряжено. Да, на борту может быть пять пушек, и в каждой разные снаряды, и эффект от них будет разный. То есть можно две пушки зарядить снарядами против мелких целей, и четыре пушки — против крупных, и стрелять одновременно в разные цели.
Вот это настоящие слои, а не просто взять корпус, кучу пушек, ракет, смешать это все в тазике и получить готовый корабль с деревянными неизменяемыми характеристиками. Либо вообще не смешивать, и получить просто кучу компонентов в одной плоскости.
Нет, погодите, перестаньте рассматривать эти 4 уровня как постулат. Процитирую статью:
Давайте рассмотрим определение уровня абстракции из возможных вариантов на примере гипотетической игры «трансформеры-онлайн».
Это говорит о том, что это не какой-то эталон, а просто пример одного из вариантов иерархии отдельно взятой механики игры, а не всей игры целиком. Этих вариантов может быть множество, а уровней для каждой механики может быть разное количество. О чем нам говорит следующая цитата из статьи:
Еще важно понимать, что уровень абстракции определяется не для всего проекта в целом, а отдельно для разных компонентов.
То бишь, каждая игровая механика имеет свою иерархию слоев, и они не складываются, а идут параллельно.
Теперь еще раз объясняю, что значит идут параллельно.
Скрафтив какой-то блок, и поставив его в мире в виде блока, этот блок переходит из системы крафта (с одной иерархией слоев) в систему мира (с другой, своей иерархией уровней). Если бы иерархии этих двух механик складывались, то блок в игровом мире имел бы не только ID, но и ссылки на компоненты, из которых его скрафтили. А свойства блока определялись бы свойствами этих самых дочерних объектов.
В системе крафта тоже нет этих слоев, потому что предметы при крафте не сохраняют в себе ссылки на детали, из которых их крафтили. Получая новый предмет, он ложится в эту же самую плоскость в виде нового заранее прописанного предмета, не учитывая свойства деталей, из которых его скрафтили. Это просто новый, независимый предмет этого же уровня. Вот это важно, это ключевой момент.
Но в статье рассматривается вариант иерархии именно с сохранением ссылок и свойств дочерних объектов, и именно для этого и используются композиция и наследование, это тоже важный момент.
Надо было в статье эти ключевые моменты как-то выделить жирным, потому что они почему-то были проигнорированы, отсюда и все недопонимание, я полагаю.
Допустим, блок в майнкрафте имеет наследование, а значит хранит ссылку на родителя. Например, блок «песок» унаследован от блока «сыпучий», а значит это уже два уровня. При этому базовые характеристики хранятся в родительских атрибутах (положение и направление), а кастомные — в дочернем. А блок «рамка» помимо ссылки на родителя хранит ссылку на дочерний объект, который в него поместили (это агрегация). Это дает нам возможность менять предмет внутри рамки, меняя ее внешний вид. Вот это система уровней, а не просто ставить блоки рядышком, выдумывая новые слои.
Без сохранения связи между слоями, назвать это слоями можно только с точки зрения игрока, но не с точки зрения ООП, а статья именно про ООП.
Вы совершенно точно подметили, что важны именно отношения этих слоев, а не просто их положение относительно друг друга в одной плоскости.
Если у нас есть в коде игры на первом уровне сущности A, B и С, и если в самой игре A+B+C == ABC, то это не новый уровень, а просто расширение текущей плоскости.
Новый уровень — это A+B+C == D при тех же условиях, что D не прописан в коде игры, а генерируется действиями игрока на лету.
В статье рассматривается четвертый уровень, где из деталек делаются штуки, которые вставляются в слоты. Процессор в майнкрафте никуда уже вставить нельзя, это просто груда деталек, которые взаимодействуют с соседними. Это богатые, но плоские возможности.
Если вы не видите разницу между этими двумя принципиально разными классификациями, это не значит, что ее нет.
А пример с яваскриптом вы, похоже, даже не попытались понять. Он идеально демонстрирует, как убирание слоев (которое вы как то не так понимаете) делает продукт ригидным и неудобным, но с сохранением богатых возможностей. Что мы и видим с процессором в майнкрафте: отсутствие необходимых слоев в игре не лишает игру возможности построить процессор, но превращает это мероприятие в подвиг. Как и любую программу на яваскрипте без функций.
Давайте немного детализируем ваш пример с яваскриптом, чтобы уловить разницу. Представьте, что из яваскрипта уберут функции (как сам механизм). Можно ли на нем будет написать все программы, которые уже написаны? Несомненно, да, и они даже будут работать. Но код превратится в плоскую систему копипаст, участки кода можно будет подписать комментариями, но невозможно будет вызвать из других участков наравне с остальными инструкциями. Проекты перестанут быть гибкими, масштабируемыми и расширяемыми.
Не напоминает процессор из майнкрафта? Автор этого сооружения настолько горд собой, что снял видео и написал статью на хабр. И ему действительно есть, чем гордиться, ведь это реальное достижение, без достаточного количества абстракций реализовать такую махину.
Возможность в игре соорудить какие-то сложные механизмы еще не говорит о гибкости архитектуры. Богатые возможности могут быть обусловлены банально большим количеством строго регламентированных возможностей с разделением на 2-3 уровня абстракции. Но богатые != гибкие.
Тот же Spore меня разочаровал, когда игра только вышла. Я ожидал увидеть песочницу, а увидел лишь имитацию с заранее регламентированными цепочками развития. Тот же майнкрафт в этом плане свободнее.
Причём ему, как и авторам многих самостоятельных артефактов, пришлось крафтить одни блоки из других
Вы не путайте, эти уровни абстракции идут не поверх друг друга, а параллельно. Система крафта никакого отношения к окружающему миру и блокам не имеет. Как только игрок устанавливает блок, тот переходит из одной системы в другую уже со своими слоями, в которых нет информации, из чего этот блок скрафтили, есть только ID блока и его состояние. Об этом говорит полная независимость этих механик: если убрать из игры систему крафта, база данных блоков и их механика никуда не денется.
это если навесить два ограничения
Нет, смотрите. Дело то не в ограничениях. Мы же рассматриваем архитектуру не с какой-то абстрактной точки зрения игрока, а с вполне себе конкретной точки зрения описания программистом слоев с помощью композиции или наследования. Создавая процессор, игрок не добавляет в программный код игры новые абстракции, все работает поверх заложенных программистом.
Чтобы понять мою мысль, попробуйте описать архитектуру окружающего мира, в котором собрали процессор, с точки зрения разработчика программных сущностей и их ООП-отношений.
Вы же понимаете, что тогда вам работа в команде противопоказана? Я как то читал код на питоне, где вместо 4 пробелов ставили 1 пробел. Мне было очень тяжело.
То есть вы в этих случаях без отступов пишете? Самому как потом это читать? Нигде не зудит от чтения своего же кода без отступов?
Кстати, у меня есть подозрения, что эти ваши случаи, которые в порядке вещей, нужно, и я думаю можно, как то исправить. Давайте вы опишите, а я попробую вам помочь?
Представляете, из-за моей привычки не допускать жирных сигнатур пришлось попробовать, чтоб убедиться, что не ругается))
Вообще конечно можно вот так, если вам очень хочется:
Но за всю карьеру питона мне ни разу не требовалось делать многострочные условия. Когда появлялась такая нужда, я старался устранить саму нужду. Это то же самое, что многострочные объявления функций, когда у вас сотня аргументов: может в каких то языках это считается нормальным, но много где это признак плохого кода/архитектуры.
В том то и дело, когда это два простых условия, двухэтажный if не требуется. И я подозреваю, что у вас там либо дофига условий, либо безымянные нечитаемые условия вида
if len(str(count(map(max(min(sort(filter(please(sudo(10)))))) >= len(str(count(map(max(min(sort(filter(20))))))
Господи, о чем вы говорите? У меня неделю только длилась эйфория от того, что наконец-то интерпретатор по отступам понимает мой код, и не нужно мне впредь ставить эти скобочки и точки с запятой.
Какой еще ад? Вот я аргумент про питонячьи отступы никогда не понимал и до сих пор не понимаю: вы ставите отступы (всегда), скобочки и точки с запятой, и тут вам новый язык предлагает оставить только отступы, значительно облегчая вам написание кода, убирая кучу синтаксического шума, и для вас это ад? Вы что, мазохист?
Причем, пытаются это объяснить какими-то экзотическими случаями, которые на практике вообще сложно встретить. Типа, я пишу код прям на сервере в простом текстовом редакторе, находясь в космосе с завязанными за спиной руками, мне неудобно делать отступы. То есть как это понимать, что был бы другой язык, вы бы оставили этот код без отступов, и пускай люди мучаются, читая его?
Да, но при этом в другом коменте у вас была тяга сотворить какой-то многоэтажный if. Что уже говорит о том, что вы что-то делаете не так, раз у вас в одно условие лезет куча безымянных выражений, что появляется тяга их раскладывать на строки.
Понимаете, это как с юниттестами — если у вас плохая архитектура, нет SRP, нет DI, то и юниттесты вы не напишите к проекту, а будете ругаться, какой плохой инструмент эти ваши юниттесты.
И вообще, мне кажется логи на хаскеле должно быть проще парсить, чем на питоне, но могу ошибаться.
хеллоу ворлд написали? что там натыкать за день можно
Неоднократно видел случаи, когда программисты Це/ППХ садятся за питон и продолжают писать на питоне в сишном стиле.
«Девушка может уехать из деревни, а вот деревня из девушки — никогда» (с)
Да после питона, что-то почти любой язык мне кажется неудобным. В браузерах вообще кроме JS и трансляторов в JS ничего нет.
Семантика и синтаксис.
То есть вам чисто принципиально обидно? Или вы в других языках позволяете себе где-то не писать отступы? Когда я жрал кактус с богомерзкими фигурными скобочками и точками с запятой, я мечтал, чтобы интерпретатор по отступам сам понимал, какие блоки я от него хочу. Спасибо, что мне в свое время показали питон. И как же я обрадовался, когда отступы оказались самым меньшим из благ, которые я познал в питоне.
Но это еще фигня. Я знаю два прекрасных языка, где помимо скобочек и точек с запятой, приходится перед переменными ставить доллар. Чрезвычайно любопытно, как другие языки работают без долларов, магия какая-то.
Это мощный язык с простотой бейсика. Об этом пишется в статье.
В смысле, нет? Поясните.
Вы хвалите или осуждаете?
И нагрузка все таки смешная, даже без кэширования, даже для тысячи кораблей. Мой домашний процессор такое может рассчитывать без проблем, и у него еще останется, чтоб крипту майнить. А лагает оно, я уверен, из-за IO (сеть, база, и т. д.), но уж точно не из-за CPU.
Во-вторых, нагрузка то смешная. На корабле, ну максимум 20 модулей, из которых лишь половина одновременно активных. Посчитать за выстрел произведение из 3-5 множителей для каждого модуля это вообще фигня.
В-третьих, про смену конфигурации вы верно заметили, с одной стороны глупо просчитывать каждый выстрел. Но и держать просчитанные модели всех возможных комбинаций модулей, кораблей и снарядов тоже глупо, особенно учитывая, что даже текущая скорость корабля может влиять на получаемый урон и промахи. Возможно, какие-то коэффициенты кэшируются при смене снарядов, но в целом динамическая иерархия остается, ибо многие множители меняются в ходе боя постоянно.
В целом в eve online все довольно бодренько с быстродействием. В одной битве могут принимать участие тысячи кораблей
Вот кстати еще пример игры, где довольно гибкая кастомизация, благодаря сочетанию глубины настоящих слоев, количества возможных объектов в каждом слое, и количеству их комбинаций: EVE Online.
1. Космический корабль.
2. В корабле помимо его собственных характеристик есть слоты под сменные модули (оружия, ускорители, щиты, реакторы и т. д.) — это агрегация.
3. В модулях есть хранилище расходников (боекомплект, батарейки, наниты и т. д.), которых тоже множество видов, и которые обладают своими характеристиками. Например, разные типы ракет могут быть хороши либо против больших целей, либо против маленьких и быстрых, либо вообще против сооружений. Это тоже агрегация.
Итоговые характеристики корабля динамически вычисляются из характеристик каждого слоя. Например мощность взрыва ракеты зависит от самого корабля, его скорости, от оружия, которое установлено в слот, и от типа снарядов, которым это оружие заряжено. Да, на борту может быть пять пушек, и в каждой разные снаряды, и эффект от них будет разный. То есть можно две пушки зарядить снарядами против мелких целей, и четыре пушки — против крупных, и стрелять одновременно в разные цели.
Вот это настоящие слои, а не просто взять корпус, кучу пушек, ракет, смешать это все в тазике и получить готовый корабль с деревянными неизменяемыми характеристиками. Либо вообще не смешивать, и получить просто кучу компонентов в одной плоскости.
Это говорит о том, что это не какой-то эталон, а просто пример одного из вариантов иерархии отдельно взятой механики игры, а не всей игры целиком. Этих вариантов может быть множество, а уровней для каждой механики может быть разное количество. О чем нам говорит следующая цитата из статьи:
То бишь, каждая игровая механика имеет свою иерархию слоев, и они не складываются, а идут параллельно.
Теперь еще раз объясняю, что значит идут параллельно.
Скрафтив какой-то блок, и поставив его в мире в виде блока, этот блок переходит из системы крафта (с одной иерархией слоев) в систему мира (с другой, своей иерархией уровней). Если бы иерархии этих двух механик складывались, то блок в игровом мире имел бы не только ID, но и ссылки на компоненты, из которых его скрафтили. А свойства блока определялись бы свойствами этих самых дочерних объектов.
В системе крафта тоже нет этих слоев, потому что предметы при крафте не сохраняют в себе ссылки на детали, из которых их крафтили. Получая новый предмет, он ложится в эту же самую плоскость в виде нового заранее прописанного предмета, не учитывая свойства деталей, из которых его скрафтили. Это просто новый, независимый предмет этого же уровня. Вот это важно, это ключевой момент.
Но в статье рассматривается вариант иерархии именно с сохранением ссылок и свойств дочерних объектов, и именно для этого и используются композиция и наследование, это тоже важный момент.
Надо было в статье эти ключевые моменты как-то выделить жирным, потому что они почему-то были проигнорированы, отсюда и все недопонимание, я полагаю.
Допустим, блок в майнкрафте имеет наследование, а значит хранит ссылку на родителя. Например, блок «песок» унаследован от блока «сыпучий», а значит это уже два уровня. При этому базовые характеристики хранятся в родительских атрибутах (положение и направление), а кастомные — в дочернем. А блок «рамка» помимо ссылки на родителя хранит ссылку на дочерний объект, который в него поместили (это агрегация). Это дает нам возможность менять предмет внутри рамки, меняя ее внешний вид. Вот это система уровней, а не просто ставить блоки рядышком, выдумывая новые слои.
Без сохранения связи между слоями, назвать это слоями можно только с точки зрения игрока, но не с точки зрения ООП, а статья именно про ООП.
Вы совершенно точно подметили, что важны именно отношения этих слоев, а не просто их положение относительно друг друга в одной плоскости.
Новый уровень — это A+B+C == D при тех же условиях, что D не прописан в коде игры, а генерируется действиями игрока на лету.
В статье рассматривается четвертый уровень, где из деталек делаются штуки, которые вставляются в слоты. Процессор в майнкрафте никуда уже вставить нельзя, это просто груда деталек, которые взаимодействуют с соседними. Это богатые, но плоские возможности.
Если вы не видите разницу между этими двумя принципиально разными классификациями, это не значит, что ее нет.
А пример с яваскриптом вы, похоже, даже не попытались понять. Он идеально демонстрирует, как убирание слоев (которое вы как то не так понимаете) делает продукт ригидным и неудобным, но с сохранением богатых возможностей. Что мы и видим с процессором в майнкрафте: отсутствие необходимых слоев в игре не лишает игру возможности построить процессор, но превращает это мероприятие в подвиг. Как и любую программу на яваскрипте без функций.
Вот я товарищу именно это пытаюсь донести уже сколько комментов подряд.
Не напоминает процессор из майнкрафта? Автор этого сооружения настолько горд собой, что снял видео и написал статью на хабр. И ему действительно есть, чем гордиться, ведь это реальное достижение, без достаточного количества абстракций реализовать такую махину.
Возможность в игре соорудить какие-то сложные механизмы еще не говорит о гибкости архитектуры. Богатые возможности могут быть обусловлены банально большим количеством строго регламентированных возможностей с разделением на 2-3 уровня абстракции. Но богатые != гибкие.
Тот же Spore меня разочаровал, когда игра только вышла. Я ожидал увидеть песочницу, а увидел лишь имитацию с заранее регламентированными цепочками развития. Тот же майнкрафт в этом плане свободнее.
Вы не путайте, эти уровни абстракции идут не поверх друг друга, а параллельно. Система крафта никакого отношения к окружающему миру и блокам не имеет. Как только игрок устанавливает блок, тот переходит из одной системы в другую уже со своими слоями, в которых нет информации, из чего этот блок скрафтили, есть только ID блока и его состояние. Об этом говорит полная независимость этих механик: если убрать из игры систему крафта, база данных блоков и их механика никуда не денется.
Нет, смотрите. Дело то не в ограничениях. Мы же рассматриваем архитектуру не с какой-то абстрактной точки зрения игрока, а с вполне себе конкретной точки зрения описания программистом слоев с помощью композиции или наследования. Создавая процессор, игрок не добавляет в программный код игры новые абстракции, все работает поверх заложенных программистом.
Чтобы понять мою мысль, попробуйте описать архитектуру окружающего мира, в котором собрали процессор, с точки зрения разработчика программных сущностей и их ООП-отношений.