Задать вопрос
  • VK.COM: как составить запрос, чтобы получить СТАТЬЮ?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Пока методов для работы со Статьями ВК нет.

    Задавал такой вопрос Поддержке

    spoiler
    5d7fc95f367b0022984376.jpeg
    Ответ написан
    Комментировать
  • Как узнать короткое имя пользователя?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    users.get()

    Или просто /id12345
    Где 12345 это id пользователя
    Ответ написан
    Комментировать
  • Как исправить ошибку при отправки фото, ботом в беседу вк?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    В сообщении об ошибке же всё сказано:
    get() missing 2 required positional arguments: 'id_group' and 'vk'


    Речь про эту строку:
    attachment = get_pictures.get('photo' + str(186540911) + '_' + str([457239017]))


    Надо передать ещё два параметра: id группы и vk
    Ответ написан
  • Каким способом можно обойти ограничение count в vk_api?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Листать по страницам. См. документацию метода photos.getAll() – параметр offset

    Глубже в кроличью нору – посмотрите на метод execute() – он позволяет за один запрос выполнить до 25 вызовов методов API ВКонтакте.
    Ответ написан
    Комментировать
  • Как объединить несколько функций JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Исходный код можно примерно так отрефакторить. Вынести в аргументы то, что меняется:
    function addBehavior(idFrom, idTo, isChangingHeight) {
      const elFrom = document.getElementById(idFrom);
      const elTo = document.getElementById(idTo);
      
      const onOut = () => {
        elTo.style.width = "";
        isChangingHeight  &&  elTo.style.height = "";
    //    elFrom.removeEventListener(onOut);
      }
      
      const onOver = () => {
        elTo.style.width = "50%";
        isChangingHeight  &&  elTo.style.height = "50%";
    //     elFrom.removeEventListener(onOver);
      }
      
      elFrom.addEventListener("mouseover", onOver);  
      elFrom.addEventListener("mouseout", onOut);
    }
    
    addBehavior('gg', 'bg', true);
    addBehavior('zz', 'qq');

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

    ВК сам предлагает простое key-value хранилище: storage.set
    Ответ написан
    Комментировать
  • Как создать приложение VK Mini Apps на хостинге без Node.js?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Нельзя просто взять, и ...


    «Стили ВК, анимации от ВК» и пр. пряники для VK Apps находятся в их библиотеке компонентов VKUI под React. В виде, требующем дополнительной, скажем так, обработки, прежде, чем можно отдать браузеру.
    Ответ написан
  • Как получить все элементы с определенным id и применить к ним какую либо функцию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    id обязательно должны быть уникальными. Нельзя использовать один id для нескольких элементов.

    Зато className может присутствовать у многих элементов. Назначьте всем слайдам класс slide-item

    Upd. примерно так можно, коротко и просто:
    Ответ написан
  • Как отсортировать массив за цифрами?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Disclaimer: неоптимальный вариант для популяризации функций PHP

    Можно использовать sscanf(), чтобы вынимать число из каждой строки (если они одинаково начинаются) и сортировать массив своей функцией, переданной в usort():

    $arr = [
      'image_name_1.jpg',
      'image_name_11.jpg',
      'image_name_2.jpg',
      'image_name_100.jpg',
      'image_name_001.jpg',
    ];
    
    usort($arr, function($a, $b) {
      $format = 'image_name_%d.jpg';
      list($aVal) = sscanf($a, $format);
      list($bVal) = sscanf($b, $format);
      return $aVal - $bVal;
    });
    
    echo json_encode($arr);
    /*
    ["image_name_1.jpg","image_name_001.jpg","image_name_2.jpg","image_name_11.jpg","image_name_100.jpg"]
    */
    Ответ написан
    Комментировать
  • Как управлять запросами к API на клиенте?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Писать свой или искать готовый механизм очереди с контролем времени.

    В очередь (массив) класть запрос (метод, параметры) и callback. Либо промисы.

    Держать массив с временем ответов последних 100 (30) вызовов. Если самый древний более 10 (5) секунд назад, можно выполнить очередной.

    Как-то написал вот такую
    кривую реализацию


    Модуль очереди:
    /**
     * Hold Your Horses!
     * Promise-based dispatcher that respects frequency limits.
     * It queues requests so that no more than N are processed within 1 second.
     * Those can go in parallel.
     *
     * Instantiate the new HH with options, specifying time limit.
     * Method .add(function) adds a new job to the queue.
     * Argument function should return Promise object that starts to process only after the function is called.
     * @return Object Promise.
     */
    
    function HorsesHolder(options) {
      options         = options || {};
      this.rps        = options.rps || 3; // requests per second
      this.parallel   = options.parallel || this.rps; // max parallel running jobs
    
      this.times      = []; // -1: slot is busy, 0: slot is free, positive timestamp - time slot's job has finished
      for (let i=0; i<this.rps; i++) this.times.push(0); // [0, 0, 0] initially
    
      this.queue      = [];
      this.inprogress = [];
      this.debug      = !!options.debug;
      
      this.debug  &&  console.log("%s ms: [HH] initialized", this.ts());
    }
    
    
    HorsesHolder.prototype.add = function(promiseMaker) {
      var self = this;
      
      return new Promise(function(resolve, reject) {
        self.queue.push({
          resolve: resolve,
          reject: reject,
          promiseMaker: promiseMaker,
        });
        
        self._ping();
      });
    };
    
    
    // Decide: work or wait
    HorsesHolder.prototype._ping = function() {
    
      if (this.queue.length === 0) {
        this.debug  &&  console.log("%s ms: [ping] queue is empty", this.ts());
        return;
      }
      
      const best = this._bestTime();
      
      if (best === -1) {
        this.debug  &&  console.log("%s ms: [ping] cannot go: %s", this.ts(), JSON.stringify(this.times));
        return;
      }
      
      const index = this.times.indexOf(best);
      
      this.debug  &&  console.info("%s ms: [ping] exec now at index %d", this.ts(), index);
    
      this._execute(index);
    }
    
    
    /**
     * Out of current times[] finds the best to occupy, if possible;
     * otherwise -1
     */
    HorsesHolder.prototype._bestTime = function() {
      let best = -1;
    
      for (let i=0; i<this.rps; i++) {
        const time = this.times[i];
        if (time === 0) return 0;        // can go now - nothing better!
        if (time < 0) continue;          // previous not finished yet
        if (this.ts() < time + 1000) continue; // not yet
    
        if (best === -1) best = time;
        else best = Math.min(best, time);
      }
      
      return best;
    }
    
    
    HorsesHolder.prototype.ts = function() {
      return (new Date()).getTime();
    }
    
    
    HorsesHolder.prototype._execute = function(index) {
      this.times[index] = -1; // mark busy
      const job = this.queue.shift();
      this.inprogress.push(job);
    
      const self = this;
      
      job.promiseMaker()
      .then(function(r) {
        self.debug  &&  console.info("%s ms: [HH] Job done at index %d", self.ts(), index);
        job.resolve(r);
      })
      .catch(function(err){
        self.debug  &&  console.error("%s ms: [HH err] Error at index %d: %s", self.ts(), index, err.toString());
        job.reject(err);
      })
      .finally(function(){
        self.inprogress.splice( self.inprogress.indexOf(job), 1);
        self.times[index] = self.ts();
        setTimeout(() => self._ping(), 1000);
      });
    }
    
    export default HorsesHolder;


    Модуль работы с VK API:
    /*global VK*/
    /**
     * Function returns Promise for each VK API call.
     * Respects the 3 call per second limit.
     *
     * by Sergei Sokolov <hello@sergeisokolov.com> 2019.
     */
     
    import HorsesHolder from '@/utils/horsesholder';
    
    const debug = true;
    
    const HH = new HorsesHolder({ debug });
    
    
    export default function asyncVK(methodName, data) {
    
    	return HH.add(() => {
    
    		data = data || {};
    		if (!data.v) data.v = 5.92; // VK API version https://vk.com/dev/versions
    		
    		return new Promise((res, rej) => {
    			VK.Api.call(
    				methodName,
    				data,
    				r => {
    					if (r.error) {
    						debug && console.error("[asyncvk] VK API call error:", r.error);
    					}
    					
    					
    					if (r.response) {
    						
    						res(r.response);
    						
    					} else if (r.error) {
    						
    						rej(r.error);
    						
    					} else {
    						
    						debug && console.error("[asyncvk] VK API bad response:", r);
    						
    						rej(r);
    						
    					}
    				}
    			)
    		});
    	});
    }


    Ответ написан
    1 комментарий
  • Почему не выводятся на экран числа массива с помощью цикла for?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    первый вариант:

    var mass = [1,2,3,4,5,6,7,8,9,10];
    for(i=0;i<mass.length;i++){
        document.getElementById('root').innerHTML += mass[i];
    }


    второй вариант:

    var r = document.getElementById('root');
    var mass = [1,2,3,4,5,6,7,8,9,10];
    for(i=0;i<mass.length;i++){
        r.innerHTML += mass[i];
    }


    Но разумеется можно короче
    var mass = [1,2,3,4,5,6,7,8,9,10];
    for (document.getElementById("root").innerHTML = mass.join(","); 0;)
    Ответ написан
    Комментировать
  • Возможно ли при клике сэмулировать двойнок клик?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ваниль:
    document.getElementById("tot-block")
      .addEventListener("click", e => e.target.dispatchEvent(
        new MouseEvent('dblclick', {
          'view': window,
          'bubbles': true,
          'cancelable': true
        })
      )
    );


    ⚠️ Любое событие, сгенерированное скриптом, отличается от «честного» действия пользователя свойством события isTrusted.
    Ответ написан
    Комментировать
  • Какие есть способы округлить число на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const roundigit = digit => {
      if (1!==digit.toString().length||!Number.isFinite(digit))throw "Не цифра!";return digit;}

    spoiler
    Цифра - это 0, 1,2,3,4,5,6,7,8 или 9 - каждая их них целая. Можно не округлять. Расходимся.


    если серьёзно
    Чтобы в сторону нуля округлять, вариант:
    const floor = x => x | 0;
    Ответ написан
    2 комментария
  • VK api. Как получить json всех Олегов из города Кукуева?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вероятная причина ошибки

    Метод users.get() можно вызывать с ключом одного из трёх типов:
    • сервисный ключ (приложения)
    • ключ сообщества
    • ключ пользователя
    в то время, как users.search() можно вызывать только с ключом пользователя.

    Раз users.get() срабатывает , а на users.search() возвращается ошибка токена, вероятнее всего используется токен Сообщества или Сервисный ключ приложения.

    Что делать

    Получите ключ Пользователя. Для этого понадобится создать своё приложение ВК или использовать уже готовое. Специальных прав запрашивать не нужно, просто получить токен.

    В запросе к users.search() для поиска только в городе N, понадобится найти сначала id этого города N в Справочнике городов ВК. Для этого есть метод database.getCities() - клик по ссылке (внизу страницы) выполнит поиск и вернет несколько населенных пунктов, похожих на «Кукуево», у каждого свой id.

    Итого, в метод users.search() вы передадите следующие параметры:
    1. v=5.101 — версия API, обязательный
    2. access_token=XXXXX — токен Пользователя в любом приложении ВК
    3. count=1000 — без этого параметра вернёт только 20 результатов
    4. q=Олег — поисковая строка
    5. city=123 — id города Кукуево, полученный ранее в database.getCities()
    6. sex=2 — мужской пол (необязательно)
    7. age_from=18 — искомый Олег закончил школу
    8. age_to=24 — наверное, искомый Олег ещё не получает пенсию
    Ответ написан
    3 комментария
  • Какую программу использовать для имитации рисования маркёром на доске?

    Есть онлайн-сервисы для изготовления этих doodle videos

    Из софта предложу только Adobe After Effects, но он дорогой и потребуется некоторое обучение инструменту. Есть уроки на YouTube (тыц).

    Возможно, есть и какой-то специализированный софт попроще, но я не в курсе.
    Ответ написан
    1 комментарий
  • Как отправить POST запрос на VK API?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Метод markSeen() есть только у закладок: fave.markSeen()

    Получаемое сообщение об ошибке именно об этой причине и говорит:
    "error_msg":"Unknown method passed"

    «Передан неизвестный метод»

    Попробуйте вызывать существующие методы ВК API.

    Например, users.get()
    import requests
    
    payload = {
      'access_token': 'XXXXXXX',
      'v': '5.101'
    }
    
    r = requests.post('https://api.vk.com/method/users.get', data=payload)
    
    print(r.text)
    Ответ написан
    Комментировать
  • Как использовать строковые методы и выведите "tetsetesesesesteest"?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Строку собирайте по частям. Пригодятся эти семь методов объекта String:
    Примените каждый из них, чтобы получить часть результата.

    Например, так
    const x = "test";
    const result = ''
      + x.substr(0, 2) // te
      + x.split('').reverse().join('') // tset
      + x.substring(1,3).repeat(4) // eseseses
      + x.substring(0,2) // te
      + x.substring(1)   // est
    ; // tetsetesesesesteest

    Но здесь «незаконно» используется преобразование к Array для отзеркаливания строки "test" -> "tset".

    Задача творческая и довольно забавная. Проявите себя и найдите какой-то оригинальный способ.
    Ответ написан
    Комментировать
  • Как передать индекс цикла внутрь него другому массиву?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    К изучению: замыкания в JS.

    С минимальными изменениями можно примерно так сделать функцию, создающую функции, каждая запоминает переданный i:
    плохой код
    const slides = document.querySelectorAll('.reviews__item');
    var radioButtons = document.getElementsByName('review-toggle');
    var makeListener = function(i) {
      return function (evt) {
        evt.preventDefault;
        for (var j = 0; slides.length > j; j++) {
          slides[j].classList.add('slider__item--hidden');
        };
        slides[i].classList.remove('slider__item--hidden');
      };
    }
    
    for (var i = 0; i < radioButtons.length; i++) {
      radioButtons[i].addEventListener ('click', makeListener(i));
    };


    Лучше так:
    Ответ написан
    Комментировать
  • Удалить лишние знаки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const f = n => parseFloat(n.toFixed(5));
    
    // Tests:
    f(1) // 1
    f(1.12) // 1.12
    f(1.1234567890) // 1.12346
    f(000001) // 1
    f(100000) // 100000
    f(-1e5) // -100000


    Upd. Если обязательно именно отбросить без округления, то надо работать как со строками:
    (()=>{
      
    const f = x => {
      const n = parseFloat(+x);
      const sign = Math.sign(n);
      // отсечь экпоненциальную запись (0.0000001).toString() === "1e-7"
      if (Math.abs(n) < 1e-5) return 0; 
      return sign * parseFloat(x)
        .toString()
        .split('.')
        .map((n,i) => i ? n.substring(0,5) : parseInt(n))
        .join('.');
    }
    
    // Tests:
    ['0000001', '0.0000101', 1.000000001,  -1e-4, -1e-5, -1e-6, 1e5, Math.E, 1, -1, 0, false, ]
      .map(n => `${n} // ${f(n)}`)
      .join('\n');
    /*
    0000001 // 1
    0.0000101 // 0.00001
    1.000000001 // 1
    -0.0001 // -0.0001
    -0.00001 // -0.00001
    -0.000001 // 0
    100000 // 100000
    2.718281828459045 // 2.71828
    1 // 1
    -1 // 1
    0 // 0
    false // 0
    */
    Ответ написан