• [Вопрос] Вы видели людей, которые пользуются мобильными контент-подписками?
    +1
    А что за юридический термин такой «Никчемный договор». Это какой-то перевод с английского? А законов ты не знаешь. Есть такое понятие «конклюдентное действие», заключение договоров нажатием кнопок, подмигиванием, молчанием и т.п. это имменно конклюдентные действия. Достаточно составить оферту и написать там маленькими буквами, нажимая кнопку вы принимаете предложение о заключения договора. Именно так это и работает.
    ГК РФ Статья 438. Акцепт
    1. Акцептом признается ответ лица, которому адресована оферта, о ее принятии.
    Акцепт должен быть полным и безоговорочным.
    2. Молчание не является акцептом, если иное не вытекает из закона, соглашения сторон, обычая или из прежних деловых отношений сторон.


  • [Вопрос] Вы видели людей, которые пользуются мобильными контент-подписками?
    0
    take it easy. Уже все придумано.
    habr.com/ru/post/221539
    Коллективный иск это только в кино. В России суд сейчас это просто пародия. Добиваться защиты там можно только, если уже совсем негде.
  • [Вопрос] Вы видели людей, которые пользуются мобильными контент-подписками?
    +2
    Я в последнее время в случае проблем сразу пишу матерный твит и в тот же миг служба SMM Билайна приходит на помощь и решает все мои вопросы. Я даже не звоню никуда и не разговариваю с роботом. Последний раз культурно наебали меня на Дальнем Востоке. Я был в командировке в Благовещенске с безлимитным тарифом Мегафона. За ночь мой баланс около 5к рублей обнулился, а утром я узнал, что Благовещенск не относится к зоне «Вся Россия» и тариф там, сколько-то рублей за килобайт. Обругал их и проклял. Вернулся в Мск и переключил номер на Билайн. Который всегда в случае спора со мной уступает. А я сохраняю лояльность и с ними уже который год.
  • [Вопрос] Вы видели людей, которые пользуются мобильными контент-подписками?
    0
    Такие подписки у ОПСОСОВ это способ дополнительного заработка. Правовое государство, которое ты упомянул уже прикрыло кислород немного. Называется эта защита от лохотрона — отдельный счет для услуг контент-провайдеров. Включаешь его и случайный переход на лохотрон-сайт перестанет быть проблемой.
  • Docker + Laravel + RoadRunner = ❤
    +1
    Статья очень занимательная. Пиши еще.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    0
    за 27 секунда человек не сможет. Скриптом даже сложно такое время сделать.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    0
    Проблема со спидометром. Время беру точное, а вот реальная скорость движения с учетом рендеринга меняется в результате скорость выдает иногда с большим отклонением. Надо подумать как еще повысить точность.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    0
    Добавил автопилоту «человечности», передача управляющих команд происходит с интервалом 1мс, без интервала автопилот может парковаться на сумашедших скоростях.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    0
    Код получился сложнее, но работает гораздо лучше.
    m = {

    sleep: function (ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    },

    round: function (f, digits = 0) {
    if (digits) {
    let multiplier = Math.pow(10, digits);
    return Math.round((f + Number.EPSILON) * multiplier) / multiplier;
    } else {
    return Math.round(f);
    }
    },

    press: async function (code, cnt = 1) {
    let lookup_tbl = {
    'e': 69, 'q': 81, 'a': 65, 'd': 68, 'w': 87, 's': 83,
    'left': 37, 'up': 38, 'right': 39, 'down': 40,
    '<': 103, '>': 105
    };

    let e1 = new Event('keydown');
    let e2 = new Event('keyup');
    e1.keyCode = lookup_tbl[code];
    e2.keyCode = lookup_tbl[code];
    //кол-во повторений
    while (cnt--) {
    document.dispatchEvent(e1);
    document.dispatchEvent(e2);
    await this.sleep(1);
    }
    },

    get_state: function (s) {
    let o = window.document.getElementById(s);
    let v1 = o.children[0].innerHTML;
    let v2 = o.children[1].innerHTML.split(' ')[0];
    v1 = parseFloat(v1);
    v2 = parseFloat(v2);
    return {'offset': v1, 'speed': v2, 'offset_abs': Math.abs(v1), 'speed_abs': Math.abs(v2)}
    },

    get_xyz: function () {
    let x = window.document.getElementById('x-range');
    let y = window.document.getElementById('y-range');
    let z = window.document.getElementById('z-range');
    x = x.children[0].innerHTML.split(' ')[0];
    x = parseFloat(x);

    y = y.children[0].innerHTML.split(' ')[0];
    y = parseFloat(y);

    z = z.children[0].innerHTML.split(' ')[0];
    z = parseFloat(z);

    return {'x': x, 'y': y, 'z': z, 'x_abs': Math.abs(x), 'y_abs': Math.abs(y), 'z_abs': Math.abs(z)}
    },
    /*
    логика такая: включаем наблюдателя, ловим изменение значение и замеряем скорость,
    ловим 2 раз и определяем скорость, отключаем наблюдателя и возвращаем результат
    в промис.
    */
    calc_pos: async function (axis) {
    let el = window.document.getElementById(axis + '-range').children[0];
    let t1, t2, tt1, tt2, v1, v2, ms, speed, counter = 0;

    //отслеживать изменения значений будем через наблюдателя
    //callback функция для наблюдателя
    return new Promise(resolve => {

    let callback = (mutationsList, observer) => {
    let m = mutationsList[0];
    let ischanged;
    //если у нас уже есть t1
    //отловим изменение скорости на 2 единицы, чтобы
    //вычисления были точнее
    //ловить будем только, если что-то поменялось
    try {
    ischanged = m.addedNodes[0].nodeValue !== m.removedNodes[0].nodeValue;
    } catch (e) {
    //pass
    }

    if (ischanged) {
    let islowspeed = t1 && (performance.now() - t1) >= 1300;
    if (counter == 40 || islowspeed){
    t2 = performance.now();
    v2 = m.addedNodes[0].nodeValue;
    v2 = parseFloat(v2.split(' ')[0]);
    ms = t2 - t1;
    speed = (v1 - v2) * 1000 / ms;
    //вырубаем наблюдателя
    observer.disconnect();
    resolve(this.round(speed, 2));
    } else {
    //замер делаем только на первом цикле
    if (!counter) {
    t1 = performance.now();
    v1 = m.addedNodes[0].nodeValue;
    v1 = parseFloat(v1.split(' ')[0]);
    }
    //увеличиваем счетчик циклов
    ++counter;
    }
    }
    //на случай, если скорость не изменяется в течение 5 секунд
    if (!tt1) {
    tt1 = performance.now();
    //если не было ни одного изменения
    } else if (!counter) {
    tt2 = performance.now() - tt1;
    if (tt2 > 5000) {
    //вырубаем наблюдателя и возвращаем 0
    observer.disconnect();
    resolve(0);
    }
    }
    };

    let observer = new MutationObserver(callback);

    observer.observe(el, {
    characterData: false,
    childList: true,
    attributes: false
    });
    });

    },

    //возвращает нужный ключ массива и его порядковый номер
    get_idx: function (a, val, column = 0) {
    if (isNaN(val)) {
    return null;
    }
    for (let i = 0; i < a.length; ++i) {
    //если значение меньше ключа, значит мы у цели
    if (a[i][column] > val) {
    //предыдущий индекс(если есть) и есть искомый ключ
    i = i > 0 ? i - 1 : i;
    return i;
    }
    }
    //если ничего лучше нет, отдаем последний индекс
    return a.length - 1;
    },

    flip_obj: function (table) {
    res = {}
    let keys = Object.keys(table);
    for (let i = 0, len = keys.length; i < len; ++i) {
    let key = keys[i];
    res[table[key]] = key;
    }
    return res;
    },

    //таблица скоростей и соответствующих им расстояний до точки начала координат
    lookup_table: [
    [0, 0],
    [0.01, 0.2],
    [0.02, 0.5],
    [0.05, 1.5],
    [0.1, 2],
    [0.15, 2.5],
    [0.2, 3],
    [0.3, 3.5],
    [0.35, 5],
    [0.4, 5.5],
    [0.5, 6],
    [0.55, 10],
    [0.6, 20],
    [0.65, 30],
    [2.2, 80],
    [3, 120],
    [4, 150],
    ],

    adjust_pos: async function (axis, speed = null) {
    //соответствие осей и кнопок управления по осям
    let ss = {'x': ['q', 'e'], 'y': ['d', 'a'], 'z': ['w', 's']}
    if (this.abort) {
    return null;
    }

    //получаем данные о положении
    let pos = this.get_xyz();
    //таблица подстановки вектора скорости движения и положения на оси относительно 0
    let lookup_table = this.lookup_table;

    //рабочий цикл будет включаться только при наличии данных о векторе скорости
    if (speed !== null) {
    //console.log('axis:', axis, 'speed:', speed, 'pos:', pos[axis]);

    //получаем индекс положения корабля на оси
    //расстояния в таблице подстановок только положительные, поэтому берем
    //расстояние по модулю. расстояния в колонке 1 таблицы
    let pos_idx = this.get_idx(lookup_table, pos[axis + '_abs'], 1);

    //теперь получаем индекс из таблицы векторов скорости
    //если положение корабля отрицательное к нулю,
    //перевернем вектор скорости, чтобы отрицательные значения движения к нулю
    //были положительными
    if (pos[axis] < 0) {
    speed = -speed;
    }

    //берем значение скорости и смотрим по таблице
    //скорости в нулевой колонке
    let speed_idx = this.get_idx(lookup_table, Math.abs(speed), 0);
    //если хотя бы одного индекса нет, выходим
    if (pos_idx === null || speed_idx === null) {
    console.log('error! pos_idx or speed_idx not found.');
    return false;
    }
    //console.log('speed:', speed, 'speed_idx:', speed_idx, 'pos_idx:', pos_idx);
    //теперь мы можем определить направление и число импульсов
    //для каждого расстояния есть желаемая скорость.
    //для расстояния 0 скорость 0, для расстояния 0.5, скорость 0.02
    //кол-во импульсов вычисляется исходя из того, что импульс = 0.02м/с
    //формула: impulse = Math.floor(speed - lookup_table[pos_idx][0]) / 0.02)
    //т.е. вычитая из текущей скорости желаемую скорость, мы определяем
    //скорость которую надо прибавить или отнять, чтобы получить нужную
    //делим на 0.03 (скорость 1 импульса) и получаем кол-во импульсов

    //если отклонение от нужной скорости до 5%, ничего не делаем
    let diff = speed - lookup_table[pos_idx][0];
    let diff_percent = Math.abs(diff / lookup_table[pos_idx][0]);
    if( diff_percent > 0.05) {

    let impulse = Math.floor(diff / 0.03);

    //направление импульса зависит от 2 вещей: направления вектора скорости,
    // положение корабля относительно 0 осевой точки
    //это индексы направлений импульса
    let directions = {'1': 0, '-1': 1, '0': 0};

    //определяем направление импульса
    let direction = Math.sign(impulse) * Math.sign(pos[axis]);
    //определяем кнопку
    direction = directions[direction.toString()];
    let key = ss[axis][direction]

    //передаем импульс, если отклонение от нужной скорости более 5%
    console.log('axis:', axis, 'speed:', speed, 'key:', key, impulse);
    if(Math.abs(impulse) >= 200){
    console.log('impulse >= 200, skip.', impulse);
    }else {
    await this.press(key, Math.abs(impulse));
    }
    }
    }

    //запускаем себя заново с данными о скорости
    return this.calc_pos(axis).then(speed => this.adjust_pos(axis, speed))
    },
    //этим методом и производится автоматическая стыковка корабля
    autodock: async function (abort = false) {
    this.abort = abort;
    this.adjust_pos('x');
    this.adjust_pos('y');
    this.adjust_pos('z');
    this.adjust_axis();
    },

    adjust_axis: async function () {
    let yaw = m.get_state('yaw');
    let roll = m.get_state('roll');
    let pitch = m.get_state('pitch');
    let run = true;
    while (run) {
    if (this.abort) {
    return null;
    }
    //console.log(yaw['offset'], pitch['offset'], roll['offset']);
    if (yaw['offset'] > 0) {
    m.set_axis('yaw', Math.sqrt(yaw['offset_abs'] / 10));
    } else {
    m.set_axis('yaw', -Math.sqrt(yaw['offset_abs'] / 10));
    }
    if (pitch['offset'] > 0) {
    m.set_axis('pitch', Math.sqrt(pitch['offset_abs'] / 10));
    } else {
    m.set_axis('pitch', -Math.sqrt(pitch['offset_abs'] / 10));
    }
    if (roll['offset'] > 0) {
    m.set_axis('roll', Math.sqrt(roll['offset_abs'] / 10));
    } else {
    m.set_axis('roll', -Math.sqrt(roll['offset_abs'] / 10));
    }

    await m.sleep(50);
    yaw = m.get_state('yaw');
    roll = m.get_state('roll');
    pitch = m.get_state('pitch');
    }

    },

    set_axis: async function (s, speed) {
    speed = Math.round((speed + Number.EPSILON) * 10) / 10;
    let ss = {'yaw': ['left', 'right'], 'roll': ['<', '>'], 'pitch': ['up', 'down']}
    if (!(s in ss)) {
    console.log(s + ' not in ', ss);
    return;
    }

    let o = m.get_state(s);
    speed *= 10
    let cur_speed = o['speed'] * 10;
    let distance = 0;

    distance = speed - cur_speed;

    if (distance > 0) {
    while (distance--) {
    m.press(ss[s][1]);
    }
    } else {
    distance = Math.abs(distance);
    while (distance--) {
    m.press(ss[s][0]);
    }
    }
    },

    abort: false,

    }

    m.autodock();
    //m.autodock(1); чтобы остановить автопилот
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    +1
    Выложи код сюда.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    +1
    Пилот «принял на грудь». Идея классная, но реализация — дрянь. Код примитивный и работает очень плохо. Особенно убило, что умудряется провалить стыковку, даже когда уже полтора метра до шлюза осталось и можно просто откинуться в кресле.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    0
    Идея хорошая. Только там нет длительности импульсов. Можно будет считать только количество.
  • Стыкуемся с МКС с помощью JavaScript и циркуля
    –2
    Прикольная штука.
  • Кому на бюджете жить хорошо?
    0
    Опухоль исполнительной власти внутри судебной системы.
  • Кому на бюджете жить хорошо?
    0
    Да, это гонка на дистанции с 2002 по 2019
  • Кому на бюджете жить хорошо?
    0
    Была у меня мысль отметить как-то знаковые события на временной шкале. Не знаю как реаилизовать. Пример бы рабочий на d3.js
  • Кому на бюджете жить хорошо?
    0
    Не уверен, что понял вопрос. О каких именно цифрах речь?
  • Настройка GUI в линуксе для мониторов с High DPI
    0

    Спасибо. Вообще линукс этим бесит. Распихано по углам. Тут подпилил, тут подрезал, но все равно криво выглядит. И это спустя годы после выхода highdpi матриц на рынок.

  • Визуализация результатов выборов в Москве на карте в Jupyter Notebook
    0
    Очень впечатляюще. Огромное спасибо за материал.
    Вопрос:
    Реально ли folium заменить чем-то офлайновым?
  • О переменных в программировании
    0
    Бро, бросай эту идею, гарантированно не проходная.
  • О переменных в программировании
    0
    Вообще все сущности так или иначе являются областями памяти. Ты вот предложил что-то, но зачем ты это предлагаешь сделать так и не сказал. Предложение ради предложения никому не требуется. Если ты решаешь какую-то свою задачу по проталкиванию RFC, лучше найди что-то очень понятное простое и нужное. Ты предложил фундаменталььные изменения в три строчки ни о чем.
  • О переменных в программировании
    +5
    Плохая идея. Аргументация хромает, вернее ее вообще нет.
  • Хитрое префиксное дерево Си реализация
    0
    Большое спасибо. Почитаю. Вместо описанного в этой статье префиксного дерева я как раз сейчас пытаюсь реализовать структуру направленного графа.
  • Хитрое префиксное дерево Си реализация
    0
    Пролистал, но не нашел ничего похожего. Может книга другая? Я смотрел:
    Ахо А.В., Сети Р. Ульман Дж.Д. Компиляторы: Принципы, технологии и инструменты
  • Массивы в РНР 7: хэш-таблицы
    0

    Скажи, пожалуйста, как можно запустить куски кода из статьи в качестве отдельного си приложения?

  • Как сделать расширение на PHP7 сложнее, чем «hello, world», и не стать красноглазиком. Часть 2
    0
    За пару копеек спасибо. Копейка рубль бережет :-)
    Насчет CPP ничего не скажу — вообще ничего не понял. Знакомо только (void *).
  • Как сделать расширение на PHP7 сложнее, чем «hello, world», и не стать красноглазиком. Часть 2
    0

    это еще уметь надо. Где бы посмотреть как на зефире с ресурсами сделать расширение?

  • Как сделать расширение на PHP7 сложнее, чем «hello, world», и не стать красноглазиком. Часть 1
    0
    Ни разу ничего не делал с помощью этого расширения. Посмотрел сейчас пример на ffi на github.com/dstogov/php-ffi Кажется, что такую одноразовую функцию как array_fill() можно. Но эта статья только пролог к написанию расширения, использующему ресурсы. Сделать с ресурсом через ffi мне кажется не выйдет.
  • Как сделать расширение на PHP7 сложнее, чем «hello, world», и не стать красноглазиком. Часть 1
    0

    Не понял. А чем плохи расширения? С какого на какой язык стоит сменить?

  • Загрузка ядра Linux. Часть 1
    0

    Вот уж точно, что все относительно. Я делаю на Си структуру данных trie и считал это низким уровнем. :-)

  • Хитрое префиксное дерево Си реализация
    +1
    Выравнивание сожрет 1 байт на узле, но польза все равно останется за счет уменьшения ссылок. Узел 16 байт, 1 ссылка 3 байта. На большом словаре примерна одинаковое кол-во узлов и ссылок, получается экономия 1 байт из 19, что чуть больше 5%.
    Жаль читать по 3 байта одним махом невозможно, придется копировать 3 байта на число uint32_t.
    typedef struct _ref_s {
    uint8_t data[3];
    } ref_s;
    
    typedef struct _node_s {
    uint32_t mask[3];
    ref_s ref_id;
    } node_s;
    
    typedef struct _refs_s {
        uint32_t increment;
        uint32_t size;
        ref_s data[];
    } refs_s;
    
    


    www.jdoodle.com/c-online-compiler#&togetherjs=e0PePScmmQ
  • Хитрое префиксное дерево Си реализация
    0
    Еще вот думаю как-то сделать, чтобы алфавит и размер маски можно было бы выбирать. Сейчас используется около 80 бит, но там англ. + русский + символы, обычно сразу оба алфавита не нужны.
    В итоге можно сделать дерево более компактным, чем делает продвинутая, но более медленная либа libdatrie.
  • Хитрое префиксное дерево Си реализация
    0
    С авторами знаком, а вот про книгу не слышал. Спасибо.
  • Хитрое префиксное дерево Си реализация
    0
    Спасибо. Приятно, что кто-то полез под капот.
    1. А если в процентах измерить, это сколько даст роста?
    2. Там список я взял, который делал для ассоц. массива. Поэтому там так все. Предок там вообще не нужен ни разу, да и сам список нужен только при создании дерева. При чтении уже не используется.
    Сейчас хочу попробовать самые потенциально сильные изменения, скорость повыше, а размер еще меньше.
    Там сейчас битовая маска 96 бит 12 раз по 1 байту. Поэтому счет битов идет 12 раз. Хочу сделать не char, а int32 3 раза.
    Id хранятся в полях int32, что сильно больше самого большого словаря. По моим замерам, весь русский язык умещается в 5 млн. узлов. А значит можно взять 3 байта на id, а не 4.
  • Приложение Burger King: насмешка над защитой персональных данных. Исправляем?
    +6
    Нет, не считаю, что кого-то оскорбил. В моих словах даже негативной оценки не содержится. А если считать это негативной оценкой властей, то я выразился в рамках приличий. А Вы что белорусский силовик, что оскорбились?
  • Приложение Burger King: насмешка над защитой персональных данных. Исправляем?
    +2
    Это называется белорусский метод. Если возникает скандал власти в Белоруссии предпочитают устранить не причину скандала, а устранить «источник шума».
  • Burger King: тайная слежка, ложь, хищение банковских карт. Продолжение
    –3

    Автор, ты молодец. Закрепляй успех, а не размазывай по страницам праведный гнев про наглую ложь. Насчёт пруфов ты зря возмущаешься. Ты выдвинул серьёзные обвинения, по закону ты обязан доказать их, иначе ты становишься клеветником.

  • Приложение Burger King: насмешка над защитой персональных данных. Исправляем?
    +15
    Хорошая статья. Слежу за историей последние пару дней. По некоторым статьям и комментариям ощущение, что в БК не только юр. отдел есть, но еще большой PR отдел, который сейчас пытается исправить ситуацию. :-) Однако тактика защиты довольно странная. Нам пытаются продать идею, что повышение пенсионного возраста полезно для здоровья запись экрана пользователя — нормально. Замазывает софтина поля для ввода критических данных или не замазывает — дело десятое. Сам факт, что приложение пишет видео, лично для меня стал неприятным сюрпризом. Если бы я был заказчиком и узнал об этом, я бы начал свою версию истории с того, что мы сменили разработчика, который нас так подставил, а уже потом, про то, что там на самом деле ничего не видно и вообще нас там нет.
  • Разбираемся, что записывает, а что не записывает приложение Burger King
    0
    Какой-то анализ PR отдела burgerking. Сравнить с вебвизором можно, но с таким же успехом, как сравнить спортивную машину с обыкновенной. Вебвизор не изображения сохраняет, а перемещения курсора по экрану и скролл. А тут видюха пишется. :-)
  • Низкоуровневая реализация префиксного дерева trie на PHP
    0
    попробую теперь переписать. Закончил версию 0.1.0. Теперь узлы отделены от ссылок. Каждый узел 6 байт маска + 3 байта ссылка на блок ссылок. Сами ссылки на детей этого узла занимают места столько, сколько этих детей существует, по 3 байта каждый ребенок.
    Но скорость снизилась слишком сильно. 42.5 тыс. слов в секунду при поиске. Надо теперь точно сделать на Си. Что посоветуешь посмотреть по части Си расширений для PHP?