За последние 24 часа нас посетили 25814 программистов и 1728 роботов. Сейчас ищут 869 программистов ...

Ввод формул пользователем

Тема в разделе "PHP для новичков", создана пользователем anton337, 29 май 2012.

  1. anton337

    anton337 Активный пользователь

    С нами с:
    23 апр 2012
    Сообщения:
    28
    Симпатии:
    0
    Дано:
    Имеем огромную таблицу (неважно как и откуда сформированную) с большим количеством как строк, так и столбцов.

    Хочется строить графики на основании данных из этой таблицы, причем не просто по каким либо столбцам, а чтобы пользователь мог ВВЕСТИ ФОРМУЛУ, по которой будут вычисляться значения каждой конкретной точки.

    Графики уже рисуются, выборка тоже более-менее делается. А вот как вводить формулы у меня только смутные представления. Вроде какая-то функция делает подстановку текстововй строки с переменными, но я что-то не могу найти какая именно.

    Я прошу: на данный момент идею в общем виде. Ни разу не жду готовый скрипт, просто скажите как оно примерно делается.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    путем некоторых извращений пришел к такому коду:
    Код (PHP):
    1. class Equation {
    2.  
    3.   private static
    4.   $functions = array(
    5.       'cos' => '!01!',
    6.       'sin' => '!02!',
    7.       'floor' => '!03!'
    8.   );
    9.  
    10.   /**
    11.    *
    12.    * @param string $formula
    13.    * @param array $vars - Тут ключи это переменные, а значения - значения.
    14.    * @return boolean 
    15.    */
    16.   public static function Parse($formula, $vars) {
    17.     //lets keep original formula for debug and error reports
    18.     $eq = $formula;
    19.     //this is what function will return
    20.     $r = false;
    21.     //Мы заменим функции на такие вот выражения с восклицательным знаком. А потом проверим, и заменим обратно.
    22.     $eq = str_replace(array_keys($vars), $vars, $eq);
    23.     $eq = str_replace(array_keys(self::$functions), self::$functions, $eq);
    24.     if (preg_match('/^[\d!\+\-\*\/\(\)\s\\.]+$/', $eq)) {
    25.       $eq = str_replace(self::$functions, array_keys(self::$functions), $eq);
    26.       eval('$r = ' . $eq . ';');
    27.     }
    28.     return $r;
    29.   }
    30.  
    31. } 
    в формуле
    1) известные функции из $functions подменяются на конструкицю типа !число!
    2) Ключи из $vars заменяются значениями из $vars
    3) и потом проверяется, если в строке есть только разрешенные символы, то конструкции подменяются обратно на функции и строка идет в Eval

    работает так:
    Код (PHP):
    1. $i = Equation::Parse('cos(Писька + пиписька)/2', array('Писька'=>10, 'пиписька'=>100));
    2.  
     
  3. anton337

    anton337 Активный пользователь

    С нами с:
    23 апр 2012
    Сообщения:
    28
    Симпатии:
    0
    Огромное спасибо, Игорь, пробую разобраться.
    ---------
    Так пока и не разобрался, но оно работает. Мне очень стыдно..
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    А чего тут е понятно? Ты спроси
     
  5. anton337

    anton337 Активный пользователь

    С нами с:
    23 апр 2012
    Сообщения:
    28
    Симпатии:
    0
    Вроде все понятно, но я пока еще совсем плохо классы знаю. И надо как-то все это великолепие в общую структуру вживлять (ничего сложного, но требует времени)
    Через пару дней постараюсь выложить мои вариации на тему подготовки данных и рисование по ним графиков.
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    да тут не класс, а так, просто функция считай.
    это я для удобства в статик засунул. можно вытащить.
    Код (PHP):
    1. function Parse($formula, $vars) {
    2.     //lets keep original formula for debug and error reports
    3.     $functions = array(
    4.         'cos' => '!01!',
    5.         'sin' => '!02!',
    6.         'floor' => '!03!'
    7.     );
    8.     $eq = $formula;
    9.     //this is what function will return
    10.     $r = false;
    11.     //Мы заменим функции на такие вот выражения с восклицательным знаком. А потом проверим, и заменим обратно.
    12.     $eq = str_replace(array_keys($vars), $vars, $eq);
    13.     $eq = str_replace(array_keys($functions), $functions, $eq);
    14.     if (preg_match('/^[\d!\+\-\*\/\(\)\s\\.]+$/', $eq)) {
    15.       $eq = str_replace($functions, array_keys($functions), $eq);
    16.       eval('$r = ' . $eq . ';');
    17.     }
    18.     return $r;
    19.   }