Created
September 10, 2018 04:22
-
-
Save Zulcom/4e66480ddc5cf2b13097822ed06a238e to your computer and use it in GitHub Desktop.
PHPUnit test demo related to presentation https://goo.gl/yw3U1y
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SfuKruto\model; | |
/** | |
* Класс-обработчик дробей | |
*/ | |
class Fraction | |
{ | |
/** @var int|Radical числитель */ | |
private $numerator; | |
/** @var integer знаменатель */ | |
private $denominator; | |
/** @var bool является радикалом */ | |
private $isRadical; | |
/** | |
* Fraction constructor. | |
* @param int|Radical числитель | |
* @param int знаменатель | |
*/ | |
public function __construct($numerator, $denominator) | |
{ | |
$this->isRadical = is_a($numerator, 'SfuKruto\model\Radical'); | |
$this->numerator = $numerator; | |
$this->denominator = $denominator; | |
$this->reduce(); | |
} | |
/** | |
* Сокращает дробь | |
*/ | |
private function reduce() | |
{ | |
if (!$this->isRadical) { | |
$a = abs($this->numerator); | |
$b = abs($this->denominator); | |
} else { | |
$a = abs($this->numerator->getPerfectSquare()); | |
$b = abs($this->denominator); | |
} | |
if ($a < $b) { | |
$a ^= $b; | |
$b ^= $a; | |
$a ^= $b; | |
} | |
while ($a * $b != 0) { | |
$tmp = $b; | |
try { | |
$b = $a % $b; | |
} catch (\Throwable $e) { | |
$b = 0; | |
break; | |
} | |
$a = $tmp; | |
} | |
/** @var int|float Наибольший общий делитель */ | |
$gcd = $a + $b; | |
if ($this->denominator < 0) { | |
$gcd *= -1; | |
} | |
if (!$this->isRadical) { | |
$this->numerator /= $gcd; | |
} else { | |
$this->numerator->setRadicand($this->numerator->getRadicand() / ($gcd * $gcd)); | |
} | |
$this->denominator /= $gcd; | |
} | |
public function __toString() | |
{ | |
if ($this->denominator == 0) { | |
throw new \InvalidArgumentException('Не является числом!'); | |
} else { | |
if (!$this->isRadical) { | |
$toReturn = $this->numerator; | |
} else { | |
$toReturn = $this->numerator->__toString(); | |
} | |
if ($this->denominator > 1) { | |
$toReturn .= "/{$this->denominator}"; | |
} | |
} | |
return $toReturn; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SfuKruto\model; | |
/** | |
* Класс для обработки корней | |
*/ | |
class Radical | |
{ | |
/** @var int|float подкоренное выражение */ | |
private $radicand; | |
/** @const string знак корня */ | |
private $ROOT_SIGN = '√'; | |
private $IMAGINARY_UNIT_SIGN = 'i'; | |
/** | |
* Radical constructor. | |
* @param int|float подкоренное выражение | |
*/ | |
public function __construct($radicand) | |
{ | |
$this->radicand = $radicand; | |
} | |
/** | |
* @param int|float $radicand | |
*/ | |
public function setRadicand($radicand) | |
{ | |
$this->radicand = $radicand; | |
} | |
/** | |
* @return float|int | |
*/ | |
public function getRadicand() | |
{ | |
return $this->radicand; | |
} | |
public function __toString() | |
{ | |
$toReturn = ""; | |
if ($this->radicand <= 0) { | |
$toReturn = "{$this->IMAGINARY_UNIT_SIGN}*"; | |
$this->radicand *= -1; | |
} | |
if ($this->radicand == 0) { | |
$toReturn .= "0"; | |
} else { | |
$perfectSquare = $this->getPerfectSquare(); | |
if ($perfectSquare != 1) { | |
$toReturn .= $perfectSquare; | |
} | |
$perfectSquare *= $perfectSquare; | |
if ($this->radicand != $perfectSquare) { | |
$toReturn .= $this->ROOT_SIGN.$this->radicand / $perfectSquare; | |
} | |
} | |
return $toReturn; | |
} | |
/** Получить полный квадрат числа | |
* @return int | |
*/ | |
public function getPerfectSquare() | |
{ | |
$a = abs($this->radicand); | |
$square = 1; | |
$maxDiv = floor(sqrt($a)); | |
for ($i = 2; $i <= $maxDiv; ++$i) { | |
while ($a % ($i * $i) == 0) { | |
$a /= $i * $i; | |
$square *= $i; | |
} | |
$maxDiv = floor(sqrt($a)); | |
} | |
return $square; | |
} | |
/** Является ли числом | |
* @return bool | |
*/ | |
public function isInteger() | |
{ | |
$s = $this->getPerfectSquare(); | |
return ($this->radicand == $s * $s); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SfuKruto\controller; | |
use SfuKruto\model\Radical; | |
use SfuKruto\model\Fraction; | |
class Solver | |
{ | |
private $a; | |
private $b; | |
private $c; | |
private $note; | |
private $solution = []; | |
/** | |
* Solver constructor. | |
* @param $a | |
* @param $b | |
* @param $c | |
*/ | |
public function __construct($a, $b, $c) | |
{ | |
$this->a = $a; | |
$this->b = $b; | |
$this->c = $c; | |
$this->solve(); | |
} | |
public function getFirstRoot() | |
{ | |
return $this->solution['x']; | |
} | |
public function getSecondRoot() | |
{ | |
return $this->solution['y']; | |
} | |
/** | |
* @return mixed | |
*/ | |
public function getNote() | |
{ | |
return $this->note; | |
} | |
/** | |
* @return array | |
*/ | |
public function getSolution(): array | |
{ | |
return $this->solution; | |
} | |
public function solve() | |
{ | |
if ($this->a == 0) { | |
if ($this->b != 0) { | |
$this->note = "a = 0; уравнение вырождается в линейное:"; | |
$this->solution['x'] = (new Fraction(-$this->c, $this->b))->__toString(); | |
} elseif ($this->c == 0) { | |
$this->note = 'Все коэффициенты равны нулю'; | |
$this->solution['x'] = 'Любое число'; | |
} else { | |
$this->note = 'Нет решений'; | |
} | |
} else { | |
$discriminant = $this->b * $this->b - 4 * $this->a * $this->c; | |
if ($discriminant != 0) { | |
$this->note = 'Два корня'; | |
$dRoot = new Radical($discriminant); | |
if ($dRoot->isInteger()) { | |
$this->solution['x'] = (new Fraction( | |
-$this->b + sqrt($discriminant), 2 * $this->a | |
))->__toString(); | |
$this->solution['y'] = (new Fraction( | |
-$this->b - sqrt($discriminant), 2 * $this->a | |
))->__toString(); | |
} else { | |
$rational = (new Fraction(-$this->b, 2 * $this->a))->__toString(); | |
$irrational = (new Fraction(new Radical($discriminant), 2 * $this->a))->__toString(); | |
if ($rational == '0') { | |
$this->solution['x'] = $irrational; | |
$this->solution['y'] = "-{$irrational}"; | |
} else { | |
$this->solution['x'] = "{$rational}+$irrational"; | |
$this->solution['y'] = "{$rational}-$irrational"; | |
} | |
} | |
} else { | |
$this->note = 'Дискриминант равен 0, корень один'; | |
$this->solution['x'] = (new Fraction(-$this->b,2*$this->a))->__toString(); | |
} | |
} | |
} | |
public function __toString() | |
{ | |
return "{$this->note}\n x1 = {$this->solution['x']}, x2 = {$this->solution['y']}"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SfuKruto\tests\controller; | |
use SfuKruto\controller\Solver; | |
use PHPUnit\Framework\TestCase; | |
class SolverTest extends TestCase | |
{ | |
private $ROOT_SIGN = '√'; | |
private $IMAGINARY_UNIT_SIGN = 'i'; | |
public function testLinearEquation() | |
{ | |
$solver = new Solver(0, -1, -1); | |
$this->assertEquals(-1, $solver->getFirstRoot()); | |
$this->assertEquals(null, $solver->getSecondRoot()); | |
} | |
public function testPerfectSquare() | |
{ | |
$solver = new Solver(1, 0, -2); | |
$this->assertEquals("{$this->ROOT_SIGN}2", $solver->getFirstRoot()); | |
$this->assertEquals("-{$this->ROOT_SIGN}2", $solver->getSecondRoot()); | |
} | |
public function testComplexResult() | |
{ | |
$solver = new Solver(1, 0, 25); | |
$this->assertEquals("{$this->IMAGINARY_UNIT_SIGN}*5", $solver->getFirstRoot()); | |
$this->assertEquals("-{$this->IMAGINARY_UNIT_SIGN}*5", $solver->getSecondRoot()); | |
} | |
public function testFractionResult() | |
{ | |
$solver = new Solver(1, 5, -1); | |
$this->assertEquals("-5/2+{$this->ROOT_SIGN}29/2", $solver->getFirstRoot()); | |
$this->assertEquals("-5/2-{$this->ROOT_SIGN}29/2", $solver->getSecondRoot()); | |
} | |
public function testZero() | |
{ | |
$solver = new Solver(0, 4, 0); | |
$this->assertEquals("0", $solver->getFirstRoot()); | |
$this->assertEquals(null, $solver->getSecondRoot()); | |
} | |
public function Small(){ | |
$solver = new Solver(0.00001,2,1); | |
$this->assertEquals('-199999',$solver->getFirstRoot()); | |
$this->assertEquals('-0.5',$solver->getSecondRoot()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment