Как стать автором
Обновить
148.3

Ненормальное программирование *

Извращения с кодом

Сначала показывать
Порог рейтинга

Мониторинг в терминале?

Буквально за 15 минут собрал демку для просмотра алертов tenis'а с помощью bashui.
Я использовал "быструю" функцию для создания меню (таблиц). Подробней про эту функцию можно почитать тут. Кнопки бутафорские просто для иллюстрации)

Творите, выдумывайте, пробуйте!)

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии2

Программист из Индонезии разработал небольшой шуточный проект GitHub Profile Roast. Как следует из употреблённого в разговорном оттенке слова «roast» в названии, целью сервиса является творчески и с шутками оскорбить пользователя, максимально используя для этого личные детали. Делать это сервис пытается на основе аккаунта GitHub.

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

Сервис работает на английском и французском языках, а также на нескольких неевропейских, популярных в Юго-Восточной Азии (хинди, индонезийский, корейский, японский, китайский). Русского в этом списке нет.

Работает это всё через доступ к API компании OpenAI. Какой-либо умной защиты промпта нет. Как продемонстрировали в микроблогах, провести инъекции в промпт было относительно легко.

Из других любопытных наблюдений: сервис отказывается работать с некоторыми профилями. Среди замеченных в подобном Линус Торвальдс (имя пользователя torvalds) и часть аккаунтов компаний, к примеру, Microsoft и Google. Вместо череды колкостей сайт выдаёт вежливый отказ оскорблять этого пользователя. Возможно, это некий чёрный список, который автор сервиса заложил, чтобы сохранить механическую целостность фронтальной части своей головы.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии6

Почему бы не сделать runtime языка С++ проще и легче? почему бы не сделать его перенос в том числе проще? Когда я задался этим вопросом, я решил, что во чтобы то ни стало, я напишу свой RT, для тех, кто пишет под слабые машины, или тех, кто пишет под bare metal среду. результат вы можете посмотреть на гитхабе: вотъ

Когда я работал, я старался максимально всё упростить, при этом сохранив юзабельность. не знаю как для других, но лично мне было важно сохранить исключения, для меня это удобно. но в С++ они жутко дорогие из-за RTTI (RunTime Type Information), и на bare metal реализуется с большим напрягом. выход прост - использовать статусы вместо типов. но чтобы оставить всем знакомый и удобный синтаксис исключений и позволить функциям возвращать что-то вместо статуса, где это везде лепят, я переделал всё на тупо макросах :>

так же я понял, что сложность моей работы и сложность переносимости этой вещицы усложнится, если прям всё с нуля пилить, поэтому просто воспользовался libc, выпилив libc++. Пришлось сделать обёртки над new и delete, но это не так уж и сложно, просто вызывать malloc/free.

Так же я невероятно сильно намучился в попытках сделать всё используя стандартный синтаксис С++. Потратил несколько часов в попытках разобраться как оторвать исключения от использования rtti, возился в флагах, писать cxa, gxx и unwind с нуля, даже лез в ассемблерный код в попытках вырезать надоеду, но по итогу сдался и просто слепил всё из макросов.

Всем добра <3

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии2

В продолжение публикации «Загрузка es‑модулей в браузерные приложения» cделал более‑менее практичное веб‑приложение с загрузкой кода из публичных ресурсов (GitHub Pages & jsDelivr).

Пример диалога
Пример диалога

Приложение позволяет использовать OpenAI API напрямую из браузера. В приложении задействованы следующие библиотеки:

Код приложения - здесь, описание - здесь (на англ.).

Отдельное спасибо @SuperCat911 за комменты про importmap - без них бы не получилось юзать OpenAI-библиотеку :)

Кстати, до 4-версии у OpenAI не было браузерной версии API-клиента (только для nodejs). И несмотря на то, что библиотека написана на TS, для браузера они сделали ES-модули, а не UMD-бандл.

Теги:
Всего голосов 3: ↑3 и ↓0+5
Комментарии1

Просто шутка.
Я уже 20 лет плохо сплю (ПТСР), и люблю засыпать под музыку/фильмы/лайв стримы/аудиокниги и пр. Но иногда оно меня будит по ночам. Решил исправить ситуацию. Написал коротенький скрипт, который постепенно сводит звук на ноль:

import re
import subprocess
from time import sleep


LOOK_FOR = re.compile(r'\[(\d+\%)\]')


def decrease_volume(percent) -> int:
    info = subprocess.check_output(
        ['amixer', '-D', 'pulse', 'set', 'Master', f'{percent}%-'],
    ).decode('utf-8')
    return int(LOOK_FOR.findall(info)[0][:-1])


def main() -> None:
    while True:
        print(f'Volume = {decrease_volume(1)}')
        sleep(10.0)


if __name__ == '__main__':
    main()

Ну, забавно, что постепенное затихание даже немного помогает заснуть. Я - на боковую. Всем спокойной ночи

Теги:
Всего голосов 10: ↑10 и ↓0+10
Комментарии6

Энтузиаст с помощью отладчика Telink RP2040 запустил Micropython на невероятно дешёвых умных часах LT716 за $3.

Устройство работает на процессоре Telink TC32 с тактовой частотой 24 МГц, имеет 512 КБ флэш-памяти и 16 КБ ОЗУ, оснащено экраном разрешением 80x160, поддерживает BLE.

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Разработчики обновили плагин vscode-pets (VS Code Pets) для Visual Studio Code. Проект добавляет в редактор кода котиков, собак, уток, скрепыша и змейку (специально для программистов на Python). Миловидные зверьки бегают по окну приложения, ищут баги и создают хорошее настроение во время написания кода. Цифровые помощники могут взаимодействовать с пользователем с помощью мыши, а с помощью команды vscode-pets.throw-ball с ними можно поиграть.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии0

В США разработчикам в экспериментальных целях платят, чтобы они программировали в режиме изменённого сознания (фактически накуренными). В Университете Мичигана проводят исследование «Накуренный во время программирования».

В рамках этого мероприятия планируется изучить влияние определенных веществ на продуктивность. За это платят $80. Для участия надо быть старше 21 года и знать Python.

Ранее исследование показало, что 59% респондентов уже кодили на работе под кайфом или в состоянии алкогольного опьянения.

Теги:
Всего голосов 2: ↑2 и ↓0+6
Комментарии1

Друзья! Вышел новый видос, своеобразная экранизация рубрики "сам себе экосистема", где я сам разрабатываю клиенты нужных мне приложений. Пожалуйста, оцените :)

Теги:
Всего голосов 4: ↑4 и ↓0+7
Комментарии0

31 июля 2020 года влогер MattKC опубликовал видеоролик, в котором попытался уместить игру в QR-коде. В результате он написал вариант «Змейки», которая занимает 2953 байта. Исполняемый файл такого размера возможно уместить в QR-коде, поскольку этот формат кодирует до 3 КиБ данных.

Эксперимент влогера не остался без внимания. Уже 3 августа свой вариант показал Брайан Каллахан. Эта «Змейка» требует всего 2024 байта. Впрочем, вариант MattKC ужимается с помощью Crinkler до 1,4 КиБ.

Дальнейшие эксперименты ушли ниже тысячи, а потом и сотни байтов. В последние месяцы развернулась борьба за каждый байт. В ноябре 2023 года удалось заменить ассемблерную инструкцию и выиграть целый байт. Ещё два байта сэкономили две недели назад за счёт замены jae и xor на adc.

Итоговый вариант — это «Змейка» на 58 байт для Microsoft DOS. Для сравнения: ничего не выполняющая программа на C gcc -Os -w -xc - <<< "main;"на 64-битном Linux займёт 15 776 Б. 58 байт — это немного даже для текстовых данных: хватит на небольшое предложение или последовательность эмодзи по типу «??‍❤️‍?‍????‍♀️??‍❤️‍?‍??».

58-байтная «Змейка»
58-байтная «Змейка»

Конечно, в QR-коде эта игра тоже уместится. Также автор выложил онлайн-демку (управление по стрелкам клавиатуры на ПК или свайпу на мобильных устройствах).

github.com/donno2048/snake

Теги:
Всего голосов 5: ↑5 и ↓0+6
Комментарии3

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

Для того, чтобы сделать Ctrl+C на одном компе, а Ctrl+V — на другом. А аппаратный буфер обмена — в мышке. Сунуть старую бучную планку «сколько не жалко» и развлекаться :)

Может, можно даже как-то сделать там секьюрный Air Gap, чтобы можно было обменяться только той информацией, которой пользователь открытым текстом приказывает обменяться. Ну, чтобы это не было шизой ради шизы. Но как именно — ХЗ.

Хотя это не обязательно — суперпятница же! Сделайте хаб «Клиника дяди Финика» для ненормального, но не только программирования :)

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии9

1 мая стартует новый формат соревнований на HighLoad.Fun, который напомнит вам о первых HighLoad CUP от Mail.Ru в 2017 и 2018 годах.Смысл соревнования написать HTTP сервер на любом языке программирования который реализует API описанный с помощью Swagger'а, запаковать в Docker контейнер и загрузить в registry платформы, где произойдёт тестирование. Чьё решение быстрее и без ошибок обработает входящий поток запросов — победит.

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

Ссылка на соревнование: https://highload.fun/timed_competitions/authserver

Теги:
Всего голосов 4: ↑4 и ↓0+5
Комментарии0

Система автоматической унификации назначений данных (САУНД) разрабатывается для повышения внятности программирования. Идея обсуждалась ранее. Приведем эксперименты по созданию спецификации языка программирования.

def c = add(a, b, carry=0):
  not a and not b =>
    carry => c = [carry]  else => c = []
  else =>
    not a => @a = [0]
    not b => @b = [0]
    a = [a' x]
    b = [b' y]
    last = (x + y + carry) % base
    new_carry = (x + y + carry) // base
    c = [add(a', b', new_carry), last]


def m = findmin(a):
  m = nil
  a =>
    run enumerate(i=a.begin):
      i < a.end =>
        *i < *m => m = i
        enumerate(i.next)
      

def sort(@a):
  a =>
    a = [x a']
    i = findmin(a')
    swap(@x, *i)
    sort(@a')


def s = sum(a):
  a =>
    a = [x a']
    s = x + sum(a')
  else =>
    s = 0


def pythagorean_table(n):
  run rows(i=1):  i <= n  =>
    run cols(j=1):  j <= n  =>
      print(i * j)
      cols(j + 1)
    print("\n")
    rows(i + 1)    

Условные конструкции обозначаются символом =>, вместо циклов - рекурсивный вызов функции-блока.

Квадратные скобки обозначают операцию создания списка либо добавления элемента к списку, аналогично MATLAB.

Символ @ используется при вызове функций, чтобы указать на возможность модификации переменной.

Символ * перед переменной обозначает операцию разыменования итератора.

Ключевое слово run используется для запуска функции-блока.

В языке отсутствуют операторы, прерывающие ход выполнения программы, такие как return, break, continue.

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии0

Ближайшие события

Некоторые могут помнить, как в комментариях под одной из своих статей на тему Unsafe в Android я писал, что занимаюсь портированием FFM API на эту платформу. Не так давно API окончательно вышло из предварительного доступа и стало полноправной частью JDK 22. Я поймал за хвост вдохновение и с утроенными силами начал писать код и придумывать как перенести непереносимое. Так начались поиски способа рантайм генерации нативного кода под любую из поддерживаемых андроидом архитектур, и он был найден! Выходом стала системная библиотека libLLVM.so, которая умеет делать всё, что мне нужно. Осталось лишь подключить её к java коду без готового линкера. После серии экспериментов и кучи кода родилось это:

На данном скриншоте видно тестовый запуск генерации простенькой функции с выводом полученного машинного кода (он парсится из выходного ELF файла). Я планирую использовать что-то подобное как часть линкера для FFM API.

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

Если вас заинтересовала тема, за процессом можно следить на github`е проекта

Теги:
Всего голосов 8: ↑8 и ↓0+8
Комментарии0

Будет ли полнофункциональный текстовый браузер жрать больше ресурсов, чем обычный, или же меньше?

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

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

Короче, задача тянет уже на неплохой AI, не находите? О_о

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии5

В scala 3 есть свои context receivers и они не похожи на то что есть в Kotlin!

object PostConditions:
  opaque type WrappedResult[T] = T

  def result[T](using r: WrappedResult[T]): T = r

  extension [T](x: T)
    def ensuring(condition: WrappedResult[T] ?=> Boolean): T =
      assert(condition(using x))
      x
end PostConditions
import PostConditions.{ensuring, result}

val s = List(1, 2, 3).sum.ensuring(result == 6)

Разберу по строчкам:

opaque type WrappedResult[T] = T: непрозрачный тип. Внутри объекта PostConditions компилятор "знает" что это один и тот же тип, снаружи смотрит на них как на два разных типа. Это не даст перепутать тип с типом обёртки, и, например, случайно присвоить одно в другое.

def result[T](using r: WrappedResult[T]): T = r: функция, которая принимает неявный параметр откуда-то из контекста и возвращает его как нормальное значение.

extension [T](x: T):
def ensuring(condition: WrappedResult[T] ?=> Boolean): T = ....
extension метод, который принимает лямбду. Лямбда принимает неявный параметр, а метод ensuring его предоставляет.

val s = List(1, 2, 3).sum.ensuring(result == 6)Метод списка sum возвращает Int, для него вызывается вышенаписанный метод ensuring, в который передаётся лямба. внутри лямбды есть неявный параметр и потому там (и только там, больше нигде) можно вызвать функцию result, которая вернёт этот самый T.

В коде где-либо снаружи PostConditions объект типа WrappedResult[T] не получится создать.

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии0

Инженеры и разработчики Аапо Леметтинен, Владимир Осмехин и Георгий Марков смогли собрать и запустить самый большой в мире сумматор из домино. Авторы проекта также дали в ролике краткое объяснение о компьютерах из домино. Фактически это сумматор, который способен считать сумму двух 6-битных двоичных чисел.

На видео ниже компьютер из домино правильно посчитал сумму 59 и 19. В двоичном виде это 111011+10011.

Теги:
Всего голосов 6: ↑6 и ↓0+6
Комментарии0

На прошлой неделе в подреддите /r/gamedev появилась просьба порекомендовать движок для игры. Просящий создал игру в жанре хоррор, но разочаровался в своём текущем техническом решении и пытался найти движок получше.

Это мог быть рядовой пост на форуме по геймдеву — мало ли энтузиастов каждый день обсуждают свои процессы? Особенность случая в том, что хоррор автор проекта создал в виде презентации PowerPoint.

Это не шутка: в комментариях разработчик выложил трейлер своей игры. Геймплей Restless Evil сильно напоминает Five Nights at Freddy's. Отсутствие настоящего движения в 3Д-пространстве допускает реализацию в приложении для просмотра слайдов.

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

Остряки в комментах посоветовали попробовать Google Slides, чтобы получился облачный мультиплеер. Более серьёзные ответы из треда — это известный свободный движок визуальных романов RenPy и открытый инструмент для интерактивных историй Twine.

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии0

Реализация дружественных классов на Kotlin

Класс A объявлен в библиотечном модуле, свойства с модификатором internal доступны только внутри одного модуля:

class A {
    internal val foo: String = "bar"
}

interface AFriend {
    val A.foo get() = foo
}

Класс B объявлен в другом модуле, но получает доступ к свойству foo через расширение в интерфейсе AFriend.

class B : AFriend {
    fun printFoo() {
        println(A().foo)
    }
}

fun main() {
    B().printFoo() // print bar
}

Всего голосов 4: ↑4 и ↓0+4
Комментарии3
2