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

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

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

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

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

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

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

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

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

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

Теги:
+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
Комментарии6

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

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

Теги:
+4
Комментарии0

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

Теги:
+4
Комментарии0

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

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

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

Теги:
+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

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

12 – 13 июля
Геймтон DatsDefense
Онлайн
19 сентября
CDI Conf 2024
Москва

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

Вклад авторов