• Wake-on-LAN в серой сети? SSH?

    saboteur_kiev
    @saboteur_kiev Куратор тега SSH
    software engineer
    Ну как минимум к роутеру в вашей квартире у вас должен быть админский доступ. Если это роутер провайдера, то печально, а так - настроить раздачу статического адреса привязанного к МАК не должна быть проблемой. Ну и да, перейти на кабель.

    С серым IP проблематичнее. Варианта два - у провайдера должна быть услуга "статический IP", которая обычно подразумевает и статический IP и белый IP сразу. Уточните, не должно быть слишком дорого - во всяком случае дешевле, чем VDS.

    Ну и если выбрать решение с VDS - если есть админский доступ к роутеру, то на среднестатистических роутерах сейчас есть возможность настроить VPN туннель.

    Итого, все упирается в два вопроса:
    1. Какой у вас доступ к роутеру, можно ли его получить, можно ли договориться с админом провайдера выполнить нужные вам настройки. Либо просто купить себе свой нормальный роутер и его админить.
    2. Купить услугу статический/белый IP у вашего провайдера
    Ответ написан
    3 комментария
  • Wake-on-LAN в серой сети? SSH?

    Energoblock
    @Energoblock
    Geek
    У меня подобная задача решена таким образом:
    1) Куплен VDS с белым IP, там установлен сервер openvpn.
    2) Домашний роутер с Openwrt. На нём настроен клиент openvpn, который подключается к VDS. Так же установлен wakeonlan для пробуждения компьютеров по локальной сети. На роутер всегда есть доступ через openvpn. На компьютеры за роутером - через ssh-туннель.
    3) Есть один ПК, у которого wakeonlan работает кривовато, а менять железо желания нет. Для него изобрёл костыль на базе esp6288 и реле. Реле подключено параллельно кнопке Power на системном блоке. На esp6288 залита прошивка ESP-easy, настроено подключение к моей wifi-сети и статический IP (в моём примере 192.168.1.105). Реле подключено на GPIO pin 12 и по-умолчанию отключено.
    На роутере есть скрипт power_on.sh
    wget -qO /dev/null http://192.168.1.105/control?cmd=GPIO,12,1
    sleep 1
    wget -qO /dev/null http://192.168.1.105/control?cmd=GPIO,12,0

    Как вы можете понять, скрипт включает реле, ждёт секунду, а потом отключает реле. Этим действием эмулирует нажатие кнопки Power. Системный блок прекрасно включается и работает. Выключаю ПК его уже через консоль с помощью shutdown -h now.
    Ответ написан
    7 комментариев
  • Как и что вы используете в zsh (oh-my-zsh)?

    Тема: robbyrussell
    Плагины oh-my-zsh: git, colored-man, zsh-syntax-highlighting
    Поиск по истории стрелками:
    typeset -A key
    if [[ "$TERM" != emacs ]]; then
    [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" up-line-or-search
    [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" down-line-or-search
    fi
    function zle-line-init () { echoti smkx }
    function zle-line-finish () { echoti rmkx }
    zle -N zle-line-init
    zle -N zle-line-finish


    Aliases:
    DOT=~/.dotfiles
    
    alias -g g='| grep'
    alias -g l='| less -r'
    alias -g m='| more -r'
    alias -g copy='| pbcopy'
    alias rm='rm -i'
    
    alias vimrc='vim ~/.vimrc'
    alias ff='rm -rf'
    alias reload='source ~/.zshrc'
    
    alias please='sudo'
    alias su='sudo su -'
    alias py='python3 '
    alias ls='ls -G'
    alias la='ls -A'
    alias ll='la -l'
    alias al="ls -ap | grep '^\.' | grep -v './$'"
    alias a='ls -d .*'
    alias jsc='/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Resources/jsc'
    alias gh="cat $DOT/oh-my-zsh/plugins/git/git.plugin.zsh | grep -i '^alias' | grep -i "
    alias gw="cat $DOT/.git_wizardry | grep -i "
    alias pl="mkdir playground/; cd playground/"
    Ответ написан
    2 комментария
  • Как и что вы используете в zsh (oh-my-zsh)?

    RicoX
    @RicoX
    Ушел на http://ru.stackoverflow.com/
    oh-my-zsh не пользуюсь, на zsh мой конфиг ниже:

    ~/.zshrc
    
    bindkey '^[[A' up-line-or-search                # up arrow for back-history-search
    bindkey '^[[B' down-line-or-search              # down arrow for fwd-history-search
    bindkey ';5D' backward-word                    # ctrl+left
    bindkey ';5C' forward-word                      # ctrl+right
    bindkey '\e[1~' beginning-of-line              # home
    bindkey '\e[2~' overwrite-mode                  # insert
    bindkey '\e[3~' delete-char                    # del
    bindkey '\e[4~' end-of-line                    # end
    bindkey '\e[5~' up-line-or-history              # page-up
    bindkey '\e[6~' down-line-or-history            # page-down
    
    zstyle ':completion:*' insert-tab false        # Автокомплит для первого символа
    
    HISTFILE=~/.zhistory
    ## Число команд, сохраняемых в HISTFILE
    SAVEHIST=5000
    ## Чucлo команд, coxpaняeмыx в сеансе
    HISTSIZE=5000
    DIRSTACKSIZE=20
    # Опции истории команд
    #Добавляет в историю время выполнения команды.
    setopt extended_history
    alias history='fc -il 1'
    
    #История становится общей между всеми сессиями / терминалами.
    setopt share_history
    
    # Дополнение файла истрии
    setopt  APPEND_HISTORY
    
    #Добавить команду в историю не после выполнения а перед
    setopt INC_APPEND_HISTORY
    
    # Игнopupoвaть вce пoвтopeнuя команд
    setopt  HIST_IGNORE_ALL_DUPS
    
    # Удалять из файл истории пустые строки
    setopt  HIST_REDUCE_BLANKS
    
    # команды «history» и «fc» в историю заноситься не будут
    setopt HIST_NO_STORE 
    
    # если набрали путь к директории без комманды CD, то перейти
    setopt AUTO_CD
    
    #Сообщать при изменении статуса фонового задания
    setopt NOTIFY
    
    #Перемещение стрелочками по выбору
    #setopt menucomplete
    #zstyle ':completion:*' menu select=1 _complete _ignored _approximate
    
    #Вести себя как в BASH
    setopt AUTO_MENU BASH_AUTO_LIST
    
    # исправлять неверно набранные комманды
    setopt CORRECT_ALL
    # вопрос на автокоррекцию
    SPROMPT='zsh: Заменить '\''%R'\'' на '\''%r'\'' ? [Yes/No/Abort/Edit] '
    
    # загружаем список цветов
    autoload colors && colors
    
    #Можно вводить комментарии начинающиеся с #.
    setopt interactive_comments
    
    autoload -U compinit promptinit
    compinit
    promptinit;
    #Дополняем спрятанные .файлы:
    _comp_options+=(globdots)
    
    # экранируем спецсимволы в url, например &, ?, ~ и так далее
    autoload -U url-quote-magic
    zle -N self-insert url-quote-magic
    
    # Включение поддержки выражений вроде «{1-3}» или «{a-d}» — они будут разворачиваться
    # в «1 2 3» и «a b c d» соответственно
    setopt BRACECCL 
    
    # куда же мы без калькулятора
    autoload -U zcalc
    
    if [[ $EUID == 0 ]]
    then
    #Закорючки %2` означают две директории в пути.
    PROMPT=$'%{\e[1;31m%}%n %{\e[1;34m%}%2~%{\e[1;31m%} %#%{\e[0m%} '
    else
    #PROMPT=$'%{\e[1;32m%}%n %{\e[1;34m%}%~ %#%{\e[0m%} ' # root dir #
    PROMPT=$'%{\e[1;31m%}%n %{\e[1;34m%}%2~%{\e[1;31m%} %#%{\e[0m%} '
    fi
    RPROMPT=$'%{\e[1;30m%}%T% %{\e[1;36m%} %M%{\e[0m%}' # right prompt with time
    
    alias ls='ls --color=auto'
    alias grep='grep --colour=auto'
    alias df='df -k --print-type --human-readable' 
    alias du='du -k --total --human-readable' 
    alias -g  HE='2>>( sed -ue "s/.*/$fg_bold[red]&$reset_color/" 1>&2 )' # Highlight Errors
    
    # разукрашиваем команды с помощью grc
    if [ -f /usr/bin/grc ]; then
    alias ping='grc --colour=auto ping'
    alias traceroute='grc --colour=auto traceroute'
    alias make='grc --colour=auto make'
    alias diff='grc --colour=auto diff»'
    alias cvs='grc --colour=auto cvs'
    alias netstat='grc --colour=auto netstat'
    # разукрашиваем логи с помощью grc
    alias logc="grc cat"
    alias tail='grc --colour=auto tail -n 200 -f'
    alias logh="grc head"
    fi
    
    # После перехода в директорию вызываем ls. 
    function lcd() {cd "$1" && ls} 
    
    ##подключаем всякую фигню
    
    #Красивый вывод mysql
    export MYSQL_PS1="mysql: \d|> "
    # Необходимо добавить в конфиг Mysql
    # [mysql]
    # pager  = grcat ~/.grcat 
    
    #Раскраска строки ввода 
    source ~/.zsh/zsh-syntax-highlighting.zsh
    Ответ написан
    4 комментария
  • Какой алгоритм текстового калькулятора лучше?

    tsarevfs
    @tsarevfs
    C++ developer
    Польская запись -- простой и незатейлевый алгоритм. Работает с выражениями содержащими бинарные операции и скобки. Вероятно ваш выбор.
    Низходящий разбор это то что вы пытались описать под первым пунктом. Он более универсален. Позволяет разбирать более сложные грамматики c унарными операциями и контекстной завичимостью (один знак может иметь разные значения в зависимости от контекста). В этом методе больше подводных камней. Нужно изучить много теории чтобы понять как обойти некоторые сложности, например левую рекурсию. При некоторой настойчивости можно разобраться.
    Восходящий разбор. SLR, LALR парсеры. Активно применяются на практике. Они сложные, их нет практического смысла писать самостоятельно. Если вы будете использовать генератор парсеров Bison, то это оно.

    То что вы описали вторым пунктом разбивается на выборе операции с максимальным приоритетом. В сложных случаях для этого придется разобрать выражение одним из описанных мной способов.
    Ответ написан
    2 комментария
  • Какой алгоритм текстового калькулятора лучше?

    @dsadso
    Посмотрите на обратную польскую запись. Самое простое что может быть.
    https://habr.com/ru/post/100869/
    Ответ написан
    Комментировать
  • Какой алгоритм текстового калькулятора лучше?

    tumbler
    @tumbler
    бекенд-разработчик на python
    Добро пожаловать в мир конструирования компиляторов :)
    Если кратко и просто, то основные стадии работы компилятора такие:
    1. Лексический анализ (разделение строки на лексемы - числа и операции)
    2. Синтаксический анализ (скобки, приоритет операций - в общем, перевод потока лексем во внутреннее представление
    3. Дальше уже не компилятор а интерпретатор начинается: вычисление значений выражений.

    Так вот, первый вариант - это в минимальном приближении "грамотный" интерпретатор, второй вариант - строковый "костыль", который тяжело отлаживать, поддерживать и расширять.
    Есть и другие подходящие альтернативы: воспользоваться существующими библиотеками для DSL (примером которых является задача вычисления математических выражений), либо написать свою грамматику и воспользоваться готовыми решениями лексического и синтаксического анализа.
    Ответ написан
    Комментировать
  • Почему нет IDE для функциональных языков программирования?

    @abroabr
    Есть, но хреновые.
    Недостаточно популярны ибо сами языки.

    Нет критической массы разработчиков, чтобы сделать для них специализированную IDE имело смысл.
    Есть текстовые редакторы программистские со специализированными под язык плагинами.
    Ответ написан
    2 комментария
  • Как декомпилировать exe файл скрипта на Python?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    1. Скачиваешь PyInstaller Extractor
    2. Устанавливаешь uncompyle6
    3. Распаковываешь extractor'ом exe'шник
    4. Декомпилируешь интересующие pyc-файлы с помощью uncompyle6
    Ответ написан
    Комментировать
  • Как удалить сниппет из сообщения в телеграмм боте?

    @unfunk
    Используйте параметр disable_web_page_preview в send_message

    bot.send_message(message.chat.id, answer, parse_mode='Markdown', disable_web_page_preview=True)
    Ответ написан
    1 комментарий
  • Радость дизайнера - боль верстальщика. Межбуквенные отступы - кернинг и трекинг. Как рассчитать их значения для css?

    HamSter007
    @HamSter007
    HTML/CSS верстальщик
    body {
    font-family: 'PT Sans Caption', sans-serif;
    font-size: 11px;
    line-height: 120%;
    font-weight: normal;
    text-decoration: underline;
    letter-spacing: 0px;
    font-style:normal;
    }


    Все остальное дизайнер пусть оставит себе.

    Если же это какая-то единичная каллиграфия (1-2 слова), то возможен вариант вставки картинкой (пожалуй отдельная история).
    Ответ написан
  • Как передать значения из C# в Python?

    flapflapjack
    @flapflapjack
    на треть я прав
    Питон умеет нажимать клавиши как программно, так и эмулировать аппаратно с помощью драйвера interception.

    Вот статья: https://habr.com/ru/post/346258/

    Насчет обмена данных между приложениями - вот тут qaru.site/questions/2069124/streaming-data-between...

    пишут, что для этого идеально подходят файлы с отображением памяти
    https://docs.microsoft.com/en-us/dotnet/standard/i...

    Можно еще использовать например сокеты, но это больше подходит для сетевых приложений чем для двух процессов на одном ПК.
    Ответ написан
    6 комментариев
  • Как сделать отступы в морской бой?

    longclaps
    @longclaps
    Многобукв, и кто даёт такие имена переменным - тот **дак.
    from random import randint, choice
    
    
    def neighbours(cells):
        return {(i, j) for y, x in cells
                for i in range(y - 1, y + 2) for j in range(x - 1, x + 2)}
    
    
    N = 10  # а вот менять не надо
    abc, digits = 'abcdefghij', '0123456789'
    field, sea_map = {}, [[' '] * N for _ in range(N)]
    for size in 4, 3, 3, 2, 2, 2, 1, 1, 1, 1:
        while True:
            ship = [(randint(0, N - 1), randint(0, N - 1))]
            for _ in range(1, size):
                ship.append(choice([(i, j) for y, x in ship for i, j in (
                    (y - 1, x), (y, x - 1), (y, x + 1), (y + 1, x)
                ) if 0 <= i < N > j >= 0 and (i, j) not in ship]))
            if not neighbours(ship) & field.keys():
                break
        field.update(dict.fromkeys(ship, ship))
    fleet = set(field)
    
    for step in range(1, 51):  # ограничимся 50ю ходами
        print('    0 1 2 3 4 5 6 7 8 9 \n  ┌─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┐')
        for ch, row in zip(abc, sea_map):
            print(ch, '┤', *row, '├', ch)
        print('  └─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┘\n    0 1 2 3 4 5 6 7 8 9')
        s = input(f'{step:>2}  Ваш ход: ')
        try:
            y, x = abc.index(s[0]), digits.index(s[1])
            ship, row = field.get((y, x), ), sea_map[y]
            if ship:
                del field[y, x]
                row[x] = '*'
                print(s, 'Попал\n' if ship & field.keys() else 'Убил\n')
                if not field:
                    print('Победа!')
                    break
            else:
                if row[x] == ' ':
                    row[x] = str(len(fleet & neighbours([(y, x)])))
                print(s, 'Мимо\n')
        except:
            print('Ожидался ход в формате \'a0\', но что-то пошло не так...\n')
    else:
        print(f'В этот раз не вышло, в строю осталось {len(field)} палуб '
              f'на {len({id(ship) for ship in field.values()})} кораблях.')
    Ответ написан
    Комментировать
  • Как преобразовать строку в функцию?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Если функция next определена в том же модуле, где callback_inline, то

    globals()[callback_data.data](user_last_message)

    Если в импортированном модуле, например с именем example, то

    getattr(example, callback_data.data)(user_last_message)
    Ответ написан
    Комментировать
  • Уведомление о том, что пользователь не зашел ВК?

    iiiBird
    @iiiBird
    Пока ты спишь - твой конкурент совершенствуется
    в https://vk.com/dev/users.get есть fields "online"
    ну а дальше уже любым удобным способом - к примеру через бота в лс вк получать уведомления.
    Ответ написан
    Комментировать
  • Уведомление о том, что пользователь не зашел ВК?

    Wolfnsex
    @Wolfnsex
    Если не хочешь быть первым - не вставай в очередь!
    В общем, мне нужен способ отправить мне уведомление, если боты не авторизовались в ВК до 7 утра.
    Я думаю выглядеть это будет примерно так:
    0. Открываем вот эту страницу, находим там поле "online", оно отвечает за то, онлайн пользователь или нет
    1. Запускаем по крону скрипт, в 7:00 утра, который проверяет, онлайн пользователь или нет
    2. Если нет - скрипт отправляет SMS/Email/etc куда следует

    Или Вы не об этом?
    Ответ написан
    3 комментария
  • Как найти частичное совпадение строк?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Без дополнительных библиотек и с использованием расстояния Дамерау-Левенштейна можно примерно так:
    import re
    
    
    def get_substrings(string):
        """Функция разбивки на слова"""
        return re.split('\W+', string)
    
    
    def get_distance(s1, s2):
        """Расстояние Дамерау-Левенштейна"""
        d, len_s1, len_s2 = {}, len(s1), len(s2)
        for i in range(-1, len_s1 + 1):
            d[(i, -1)] = i + 1
        for j in range(-1, len_s2 + 1):
            d[(-1, j)] = j + 1
        for i in range(len_s1):
            for j in range(len_s2):
                if s1[i] == s2[j]:
                    cost = 0
                else:
                    cost = 1
                d[(i, j)] = min(
                    d[(i - 1, j)] + 1,
                    d[(i, j - 1)] + 1,
                    d[(i - 1, j - 1)] + cost)
                if i and j and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]:
                    d[(i, j)] = min(d[(i, j)], d[i - 2, j - 2] + cost)
        return(d[len_s1 - 1, len_s2 - 1])
    
    
    def check_substring(search_request, original_text, max_distance):
        """Проверка нечёткого вхождения одного набора слов в другой"""
        substring_list_1 = get_substrings(search_request)
        substring_list_2 = get_substrings(original_text)
    
        not_found_count = len(substring_list_1)
    
        for substring_1 in substring_list_1:
            for substring_2 in substring_list_2:
                if get_distance(substring_1, substring_2) <= max_distance:
                    not_found_count -= 1
    
        if not not_found_count:
            return True
    
    
    search_request = 'трубок использовали для прожигания'
    original_text = 'трубок использовали для прожигания стальковша.Замена воронки 18м 8сл. Разлита полностью'
    
    result = check_substring(search_request, original_text, max_distance=2)
    
    print(result)  # True если найдено, иначе None


    Можете доработать под свои задачи. Но учтите, нахождение расстояния Дамерау-Левенштейна в принципе ресурсоёмкая операция, тем более с реализацией на чистом Python. Например, искать вхождение подстроки в нескольких мегабайтах текста -- может быть довольно долго.

    Чтобы ускорить нахождение расстояния ДЛ, можно использовать реализацию для Python на языке Си: https://github.com/gfairchild/pyxDamerauLevenshtein

    Так же существуют менее точные, но более быстрые алгоритмы сравнения двух строк:
    https://habr.com/ru/post/114997/
    В PyPI и на GitHub должны быть библиотеки с готовыми реализациями наиболее востребованных из них.
    Ответ написан
    7 комментариев
  • Почему выдаёт Runtime ошибку?

    half-life
    @half-life
    Как то так
    import math
    import os
    
    INPUT_FILE = 'input.txt'
    OUTPUT_FILE = 'output.txt'
    NUMBER_THRESHOLD = 1000
    
    if __name__ == '__main__':
        if not os.path.exists(INPUT_FILE) or not os.path.isfile(INPUT_FILE):
            raise FileNotFoundError
        with open('input.txt') as file:
            text = file.read()
        if not text:
            raise ValueError('File is empty')
        try:
            a, b, c, *_ = [int(n) for n in text.strip().split(" ") if n.isdigit() and int(n) < NUMBER_THRESHOLD]
        except ValueError:
            raise ValueError('Wrong input data')
    
        out = ""
        if not (a < b + c and b < a + c and c < a + b):
            out = "-1"
        else:
            p = 0.5 * (a + b + c)
            h = 2 * math.sqrt(p * (p - a) * (p - b) * (p - c)) / a
            out = f'{str(a + b + c)} {("%.5f" % (a * h / 2))}'
    
        with open(OUTPUT_FILE, 'w') as file:
            file.write(out)

    Ответ написан
    2 комментария
  • Можно совмещать написать GUI на PyQt4 и оттуда вызывать функции написанные на C/C++?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    У Python и C высокий уровень интероперабельности. Из кода на Python можно использовать Сишный код, а из кода на C можно выполнять скрипты Python. Для начала почитать можно здесь и здесь.
    Ответ написан
    Комментировать
  • Как совмещать библиотеку pytelegrambot api и другие библиотеки?

    @id2669099
    я думаю, Вам не хватает понимания и знаний работы с языком, не зацикливайтесь на телеграме, попробуйте что-то новое, практика ответит на все Ваши вопросы как кому что кормить, да и есть документации к библиотекам, а тут Вам скорее всего на такой вопрос не ответят, т.к. никакой конкретики в вопросе нет, да и за Вас никто код не напишет скорее всего, приведите пример того что Вы пытаетесь сделать и на каком этапе происходит недопонимание, думаю, в этом случае всё будет намного приветливее со стороны тех, кто отвечает здесь на вопросы

    P.S.: и да, не забывайте форматировать код, который вставляете сюда, а если сомневаетесь как это будет выглядеть - есть предпросмотр :)
    Ответ написан
    Комментировать