josielold 0 Denunciar post Postado Julho 14, 2011 Olá pessoal. Tenho um código aqui bastante antigo, guardei para usar, caso precisasse algum dia. Cehgou o dia em que eu precisei desse código, por uma causa muito nobre, breve todos saberão :) e eu preciso mehorá-lo, pois ele é meio feinho... É um código que gera cálculos matemáticos aleatoriamente. ~Vocês poderiam dar-me um help por favor? agradecido desde já. Código: $operators=array('+', '-', '*', '/'); $a=mt_rand(0, 10); $operator=$operators[array_rand($operators)]; $b=mt_rand(0, 10); eval("\$result=$a$operator $b;"); Valeu! Compartilhar este post Link para o post Compartilhar em outros sites
Bruno Augusto 417 Denunciar post Postado Julho 14, 2011 Existem duas coisas que podem ser melhoradas. A primeira é cuidar para que você não receba um "Division by zero". A segunda é fazer o eval funcionar, já que da forma como está, não funciona, nem mesmo se colocar um print antes da função. Para rrumarisso, veja como eval() funciona. Compartilhar este post Link para o post Compartilhar em outros sites
João Batista Neto 448 Denunciar post Postado Julho 14, 2011 Um padrão muito legal para esse fim é o Interpreter: Interpreter :seta: Comportamental Motivação: O padrão Interpreter descreve como definir uma gramática simples, representando as sentenças dessa gramática e interpretando essas sentenças. Estrutura: Participantes: AbstractExpression: Define a operação abstrata interpret que é comum para todos os nós da árvore abstrata. TerminalExpression: Implementa a operação interpret associada com os símbolos terminais da árvore. NonterminalExpression: Implementa a operação interpret associada com os símbolos não terminais da árvore. Mantém instâncias para cada um dos símbolos relacionados com a operação. Context: Mantém informações que são globais para todo o Interpreter. Client: Constroi (ou recebe) a árvore abstrata que representa a sintaxe da gramática, que é construída utilizando os nós terminais e não terminais. Chama a operação interpret. O padrão Interpret não define um parser, apenas como representar os nós da árvore. Como o problema também não envolve a análise de expressão, uma implementação simples de Interpreter resolve muito bem, vejamos: AbstractExpression.php <?php /** * Define a operação abstrata interpret que é comum para todos os nós da árvore abstrata. */ abstract class AbstractExpression { public abstract function interpret( Context $context ); } Context.php <?php /** * Mantém informações que são globais para todo o Interpreter. */ class Context { } Nesse caso, o Context não é utilizado, precisaríamos dele caso estivéssemos trabalhando com expressões mais complexas, variáveis, loops, etc... Agora, uma expressão terminal: NumericExpression.php <?php /** * Implementa a operação interpret associada com os símbolos terminais da árvore. */ class NumericExpression extends AbstractExpression { /** * @var float */ private $value; public function __construct( $value ) { $this->value = (float) $value; } /** * @param Context $context * @see AbstractExpression::interpret() */ public function interpret( Context $context ) { return $this->value; } } E algumas expressões não terminais, primeiro a definição dela: BinaryOperationExpression.php <?php /** * Mantém instâncias para cada um dos símbolos relacionados com a operação. */ abstract class BinaryOperationExpression extends AbstractExpression { /** * @var AbstractExpression */ protected $a; /** * @var AbstractExpression */ protected $b; final public function __construct( AbstractExpression $a , AbstractExpression $b ) { $this->a = $a; $this->b = $b; } } AdditionOperationExpression.php <?php /** * Implementa a operação interpret associada com os símbolos não terminais da árvore. */ class AdditionOperationExpression extends BinaryOperationExpression { /** * @param Context $context * @see AbstractExpression::interpret() */ public function interpret( Context $context ) { return $this->a->interpret( $context ) + $this->b->interpret( $context ); } } SubtractionOperationExpression.php <?php /** * Implementa a operação interpret associada com os símbolos não terminais da árvore. */ class SubtractionOperationExpression extends BinaryOperationExpression { /** * @param Context $context * @see AbstractExpression::interpret() */ public function interpret( Context $context ) { return $this->a->interpret( $context ) - $this->b->interpret( $context ); } } DivisionOperationExpression.php <?php /** * Implementa a operação interpret associada com os símbolos não terminais da árvore. */ class DivisionOperationExpression extends BinaryOperationExpression { /** * @param Context $context * @see AbstractExpression::interpret() */ public function interpret( Context $context ) { $b = $this->b->interpret( $context ); if ( $b != 0 ) { return $this->a->interpret( $context ) / $b; } else { throw new LogicException( 'Divisão por zero' ); } } } MultiplicationOperationExpression.php <?php /** * Implementa a operação interpret associada com os símbolos não terminais da árvore. */ class MultiplicationOperationExpression extends BinaryOperationExpression { /** * @param Context $context * @see AbstractExpression::interpret() */ public function interpret( Context $context ) { return $this->a->interpret( $context ) * $this->b->interpret( $context ); } } Vejamos: <?php $a = new NumericExpression( 10 ); $b = new NumericExpression( 20 ); $operation = new MultiplicationOperationExpression( $a , $b ); echo $operation->interpret( new Context() ); Saída: 200 Trocando de operação: <?php $a = new NumericExpression( 10 ); $b = new NumericExpression( 20 ); $operation = new DivisionOperationExpression( $a , $b ); echo $operation->interpret( new Context() ); Saída: 0.5 Uma expressão mais complexa: 5 * ( 3 + ( 10 / 2 ) ) <?php $a = new NumericExpression( 5 ); $b = new NumericExpression( 3 ); $c = new NumericExpression( 10 ); $d = new NumericExpression( 2 ); $operation = new MultiplicationOperationExpression( $a, new AdditionOperationExpression( $b, new DivisionOperationExpression( $c , $d ) ) ); echo $operation->interpret( new Context() ); Saída: 40 Compartilhar este post Link para o post Compartilhar em outros sites
Bruno Augusto 417 Denunciar post Postado Julho 15, 2011 Poutz! Olha pra que nível que uma continha aleatória elevada. :o Mas pelo menos agora temos algo mais palpável sobre como utilizar o Interpreter :grin: Compartilhar este post Link para o post Compartilhar em outros sites
Alisson Reinaldo Silva 0 Denunciar post Postado Março 20, 2013 João, primeiramente gostaria de parabenizar seu excelente trabalho! Gostaria de saber se é possível você explicar qual o problema que gera a necessidade de uso deste padrão? Neste caso apresentado, aparentemente criamos uma estrutura imensa para resolver um problema simples, acredito que isto foi só para demonstrar o uso, na prática não valeria a pena neste caso específico montar toda esta estrutura para efetuar estas operações. Me corrija se eu estiver errado por favor. Também gostaria de saber se é possível apresentar um exemplo com uso do Context, pois não consegui entender ele. Um último ponto (abusando da sua boa vontade), não entendi também o uso do método interpret() usado na NumericExpression, pois passamos como parâmetro um objeto Context que não é utilizado dentro do próprio método. No caso, em: echo $operation->interpret( new Context() ); Este new Context() é passado como parâmetro para o método interpret, que é um método implementado na classe MultiplicationOperationExpression() por exemplo, que por sua vez, passa este mesmo objeto Context como parâmetro para o método interpret implementado na NumericExpression, neste caso seria o $a ou o $b. Mas é aí que não entendo, o método interpret() desta classe retorna $this->value e não faz uso do objeto Context() passado no início. Poderia me dar uma luz? rsrs Seria o caso de neste método Interpret() da NumerixExpression, eu retornar algo como: public function interpret( Context $context ) { return $context->doSomethingWith($this->value); } ?? Agradeço muito por tudo, tenho lido muito sobre patterns aqui no forum!!! Parabéns! Compartilhar este post Link para o post Compartilhar em outros sites