commit b5836f4ae9e6711850a1b5e02c427c8faa0fd142 Author: mace Date: Mon Jul 24 21:00:57 2023 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3dd6d5e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.idea/ +.gitconfig +log.txt +result.csv diff --git a/README.md b/README.md new file mode 100644 index 0000000..209725e --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# Neuffer developers-test + +We have prepared for you simple test task what as we believe, allow us to estimate your experience. +It is a small php-script, which should be started in console like: + +`php console.php --action {action} --file {file}` + +Script will take two required parameters: + +`{file}` - csv-source file with numbers, where each row contains two numbers between -100 and 100, and + +`{action}` - what action should we do with numbers from `{file}`, and can take next values: + +* plus - to count summ of the numbers on each row in the {file} +* minus - to count difference between first number in the row and second +* multiply - to multiply the numbers on each row in the {file} +* division - to divide first number in the row and second + + +As result of the command execution should be csv file with three columns: first number, second number, and result. In CSV-file should be written **ONLY** numbers greater than null. If result less than null - it should be written in logs. + +**Example 1** + +`php console.php --action plus --file {file}`, where in file you can find next numbers: + +10 20
+-30 20
+-3 5
+ +As result in CSV file you should write: + +10 20 30
+-3 5 2 + +And in log file, something like "_numbers are - 30 and 20 are wrong_" + +**Example 2** + +`php console.php --action division --file {file}`, where in file you can find next numbers: + +20 10
+-30 20
+3 0
+ +As result in CSV file you should write: + +20 10 2
+ +And in log file, something like: + +_numbers are -30 and 20 are wrong_
+_numbers are 3 and 0 are wrong, is not allowed_
+ +##Task +You need to refactor code and write it on proper way. Just do your best: update/delete/add code as you wish. + +After finishing - please push your code in your github/bitbucket account, and send me link back. + +###Requirements + +* After refactoring code shoud work +* Code should work on PHP8.0+ +* As file source example please use test.csv + +###Result +Please put result of your work in your Github or Bitbucket account, and send link back. + diff --git a/console.php b/console.php new file mode 100644 index 0000000..6d5c20d --- /dev/null +++ b/console.php @@ -0,0 +1,46 @@ +start(); + } elseif ($action == "multiply") { + include 'files/Classthree.php'; + $classThree = new Classthree(); + $classThree->setFile($file); + $classThree->execute(); + } elseif ($action == "division") { + include 'files/classFour.php'; + $classFouyr = new classFour($file); + } else { + throw new \Exception("Wrong action is selected"); + } +} catch (\Exception $exception) {} \ No newline at end of file diff --git a/files/ClassOne.php b/files/ClassOne.php new file mode 100644 index 0000000..95dcc73 --- /dev/null +++ b/files/ClassOne.php @@ -0,0 +1,59 @@ +start(); + $fp = fopen($file, "r"); + $row = 1; + while (($data = fgetcsv($fp, 1000, ";")) !== FALSE) { + if($this->isGood($data[0], $data[1])) { + $this->result($data[0], $data[1]); + } else { + $this->wrongNumbers($data[0], $data[1]); + } + } + fclose($fp); + $this->stop(); + } + + function isGood($a, $b) + { + if($a < 0 && $b < 0) return false; + if($a < 0 && (abs($a) > $b)) return false; + if($b < 0 && (abs($b) > $a)) return false; + return true; + } + + function wrongNumbers($a, $b) + { + $fp = fopen("log.txt", "a+"); + fwrite($fp, "numbers ".$a . " and ". $b." are wrong \r\n"); + fclose($fp); + } + + function start() { + $fp = fopen("log.txt", "w+"); + fwrite($fp, "Started plus operation \r\n"); + fclose($fp); + } + + function stop() { + $fp = fopen("log.txt", "a+"); + fwrite($fp, "Finished plus operation \r\n"); + fclose($fp); + } + + function result($a, $b) + { + $a = intval($a); + $b = intval($b); + $result = $a + $b; + $fp = fopen("result.csv", "a+"); + $data = $a.";".$b.";".$result."\r\n"; + fwrite($fp, $data); + fclose($fp); + } +} +?> \ No newline at end of file diff --git a/files/ClassTwo.php b/files/ClassTwo.php new file mode 100644 index 0000000..5905fb2 --- /dev/null +++ b/files/ClassTwo.php @@ -0,0 +1,45 @@ +file = $file; + $this->action = $action; + } + + public function start() + { + $fp = fopen("log.txt", "w+"); + fwrite($fp, "Started minus operation \r\n"); + + $data = fopen($this->file, "r"); + if(!$data) throw new \Exception("File cannot be openned"); + + if(file_exists("result.csv")) { + unlink("result.csv"); + } + + while (($line = fgets($data)) !== false) { + $line = explode(";", $line); + $line[0] = intval($line[0]); + $line[1] = intval($line[1]); + $result = $line[0] - $line[1]; + if($result < 0) { + fwrite($fp, "numbers ".$line[0] . " and ". $line[1]." are wrong \r\n"); + } else { + $resultHandle = fopen("result.csv", "a+"); + $result = $line[0].";".$line[1].";".$result."\r\n"; + fwrite($resultHandle, $result); + fclose($resultHandle); + } + } + + fwrite($fp, "Finished minus operation \r\n"); + fclose($fp); + fclose($data); + } +} \ No newline at end of file diff --git a/files/Classthree.php b/files/Classthree.php new file mode 100644 index 0000000..87e39bc --- /dev/null +++ b/files/Classthree.php @@ -0,0 +1,243 @@ +prepareFiles(); + $this->prepareHanders(); + } + + /** + * destructor + */ + public function __destruct() + { + $this->closeHandlers(); + } + + /** + * main function, execute main code + */ + public function execute(): void + { + $this->validateResourceFile(); + + $this->logInfo("Started multiply operation"); + + $handle = fopen($this->getFile(),'r'); + while ( ($line = fgetcsv($handle) ) !== FALSE ) { + list($value1, $value2) = $this->prepareValues($line[0]); + $result = $this->countResult($value1, $value2); + if($this->isResultValid($result)) { + $this->writeSuccessResult($value1, $value2, $result); + } else { + $this->wrongResultLog($value1, $value2); + } + } + + $this->logInfo("Finished multiply operation"); + } + + /** + * write in logs if numbers give wrong result + * @param int $value1 + * @param int $value2 + * @throws Exception + */ + private function wrongResultLog(int $value1, int $value2) : void + { + $message = "numbers ".$value1 . " and ". $value2." are wrong"; + $this->logInfo($message); + } + + /** + * validate if result is valid + * @param int $result + * @return bool + */ + private function isResultValid(int $result) : bool + { + if($result > 0) + return true; + + return false; + } + + /** + * count result + * @param int $value1 + * @param int $value2 + * @return int + */ + private function countResult(int $value1, int $value2) : int + { + return $value2 * $value1; + } + + /** + * prepare numbers before action, explode it from csv string + * @param string $line + * @return array + */ + private function prepareValues(string $line) : array + { + $line = explode(";", $line); + $value1 = $this->prepareNumber($line[0]); + $value2 = $this->prepareNumber($line[1]); + return [$value1, $value2]; + + } + + /** + * prepare number before action + * @param string $value + * @return int + */ + private function prepareNumber(string $value) : int + { + $value = trim($value); + $value = intval($value); + return $value; + } + + /** + * @return bool + * @throws Exception + */ + private function validateResourceFile() : void { + if($this->getFile() === null) { + throw new \Exception("Please define file with data"); + } + + if(!file_exists($this->getFile())) { + throw new \Exception("Please define file with data"); + } + + if(!is_readable($this->getFile())) { + throw new \Exception("We have not rights to read this file"); + } + } + + + /** + * check and delete main files before execution + */ + private function prepareFiles() : void + { + //delete log file if it is already exists + if($this->isLogFileExists()) { + unlink(self::LOG_FILE); + } + + //delete result file if it already exists + if($this->isResultFileExists()) { + unlink(self::RESULT_FILE); + } + } + + /** + * @param string $file + */ + public function setFile(string $file): void + { + $this->file = $file; + } + + /** + * @return string + */ + public function getFile() : string + { + return $this->file; + } + + /** + * check if result file already exists + * @return bool + */ + private function isResultFileExists() : bool + { + return file_exists(self::RESULT_FILE); + } + + /** + * @return bool + */ + private function isLogFileExists() : bool + { + return file_exists(self::LOG_FILE); + } + + /** + * write messages in log file + * @param string $message + * @throws Exception + */ + private function logInfo(string $message) : void + { + $message = $message."\r\n"; + fwrite($this->logHandler, $message); + } + + /** + * write message in result file + * @param string $message + */ + private function successInfo(string $message) : void + { + $message = $message."\r\n"; + fwrite($this->resultHandler, $message); + } + + /** + * prepare info and save it in result file + * @param int $value1 + * @param int $value2 + * @param int $result + */ + private function writeSuccessResult(int $value1, int $value2, int $result) : void + { + $message = implode(";", [$value1, $value2, $result]); + $this->successInfo($message); + } + + /** + * prepare handlers to writing + * @throws Exception + */ + private function prepareHanders() : void + { + $this->logHandler = fopen(self::LOG_FILE, "a+"); + + if($this->logHandler === false) { + throw new \Exception("Log File cannot be open for writing"); + } + + $this->resultHandler = fopen(self::RESULT_FILE, "a+"); + + if($this->resultHandler === false) { + throw new \Exception("Result File cannot be open for writing"); + } + } + + /** + * close opened handlers + */ + private function closeHandlers() : void + { + fclose($this->logHandler); + fclose($this->resultHandler); + } +} +?> \ No newline at end of file diff --git a/files/classFour.php b/files/classFour.php new file mode 100644 index 0000000..15ac5ac --- /dev/null +++ b/files/classFour.php @@ -0,0 +1,43 @@ +