пришел тут ответ от одной компании, что по результатам тестового задания я не подхожу
не могли бы сказать, есть ли какие-то проблемы в коде приведенном ниже
функционал у него именно тот, что нужно — так это может быть либо проблема в коде, которую я не знаю, либо причины иные
вообще задача заключалась в переделке готового кода, чтобы сделать его правильным (на мой взгляд) с сохранением общей структуры, и добавлении нескольких фич
так что смесь PHP и HTML приведенная в одном месте + стиль именования —
это единственное что на самом деле было вообще сохранено из общей структуры, в процессе работы было переписано 95% начального кода
индентация автоматически исправляется моим редактором кода — не обращайте на нее внимания
<?php
// !!!!!!!!!!!!!!!!! See my notes about the written code in the README file !!!!!!!!!!!!!!!!!!!!!!!!!
$developer = 'Test'; // Please replace with your name
abstract class Reader {
const COLOR = "#cc0000";
protected $_file = null;
protected $_initialFilename = null;
public function __construct($file) {
$this->_initialFilename = $file;
}
public function __destruct() {
$this->closeFile();
}
protected function openFile () {
$file = $this->_initialFilename;
$file = trim ($file);
if (!strlen ($file)) {
throw new Exception ("Empty filename was specified.");
}
$http = "http://";
$dataDir = dirname (__FILE__)."/data";
if (substr ($file, 0, strlen($http)) !== $http) {
// we do the following because it is more secure than file_exists()
$d = @opendir ($dataDir);
if (!$d) {
throw new Exception ("Failed to open directory with data files.");
}
$isFound = false;
while (($f = readdir ($d)) !== false) {
if ($f == "." || $f == "..") {
continue;
}
if ($f === $file) {
$isFound = true;
break;
}
}
closedir ($d);
if (!$isFound) {
throw new Exception ("Failed to find the requested data file.");
}
$file = $dataDir."/".$file;
}
if (($this->_file = @fopen($file, 'r')) === false) {
$this->_file = null;
throw new Exception ("Failed to open a file.");
}
}
protected function closeFile () {
if (!is_null ($this->_file)) {
@fclose ($this->_file);
$this->_file = null;
}
}
protected function postprocessData ($data) {
foreach ($data as $i => &$v) {
if (!is_array ($v) || sizeof ($v) != 2 || !is_numeric ($v[0]) || !is_numeric ($v[1])) {
unset ($v);
throw new Exception ("Invalid format of data in row #".$i.".");
}
$v[0] = intval ($v[0]);
$v[1] = intval ($v[1]);
$v[] = self::COLOR;
}
unset ($v);
return $data;
}
abstract public function getData(&$data);
}
class CSVReader extends Reader {
public function getData(&$data) {
$data = array();
$this->openFile ();
while ($arr = fgetcsv($this->_file)) {
$data[] = $arr;
}
$this->closeFile ();
$data = $this->postprocessData ($data);
}
}
class NewReader extends Reader {
protected $_gradients = array ("#ff0000", "#ee0000", "#dd0000", "#cc0000",
"#bb0000", "#aa0000", "#990000", "#880000", "#770000", "#660000");
public function getData(&$data) {
$data = array();
$str = "";
$this->openFile ();
while (!feof($this->_file)) {
$str .= fread($this->_file, 8192);
}
$this->closeFile ();
if (!strlen ($str)) return;
$matches = array ();
preg_match_all ("/(\[\"([0-9]+)\",\"([0-9]+)\"\]([,]?))/", substr ($str, 1, -1), $matches);
if (isset ($matches[2]) && isset ($matches[3]) && sizeof($matches[2]) == sizeof($matches[3])) {
foreach ($matches[2] as $i => $v) {
$data[] = array ($v, $matches[3][$i]);
}
}
if (strlen ($str) && !sizeof ($data)) {
throw new Exception ("Invalid format of input data.");
}
$data = $this->postprocessData ($data);
}
public static function sortByValue ($a, $b) {
if ($a[1] == $b[1]) {
return 0;
}
return $a[1] > $b[1] ? 1 : -1;
}
// we assume here that timestamps are unique
public function setMoreGradients ($data) {
$data2 = $data;
usort ($data2, array ("NewReader", "sortByValue"));
foreach ($data as &$v) {
foreach ($data2 as $i => $v2) {
if ($v2[0] == $v[0]) break;
}
$v[2] = isset ($this->_gradients[$i]) ?
$this->_gradients[$i] : $this->_gradients[sizeof($this->_gradients[$i]) - 1];
}
unset ($v);
return $data;
}
}
$msg = "";
$data = array ();
try {
//$reader = new CSVReader('data.csv');
$reader = new NewReader(isset ($_GET["file"]) ? urldecode($_GET["file"]) : "data");
$reader->getData($data);
if (!sizeof ($data)) {
$msg = "No data was obtained.";
} else {
$data = $reader->setMoreGradients($data);
}
}
catch (Exception $e) {
$msg = $e->getMessage();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<style type="text/css">
html {
margin: 0px;
padding: 0px;
}
body {
margin: 0px;
padding: 20px;
}
#chart {
position: relative;
border-bottom: 1px #000 solid;
border-left: 1px #000 solid;
margin: 0px;
padding: 0px;
}
#chart .bar {
background-color: #f00;
bottom: 0;
position: absolute;
padding: 2px;
margin: 0px;
color: #fff;
}
<?php
if (!strlen ($msg)) {
foreach ($data as $i => $v) {
// W3C validates these styles as errors, but I'm not sure that it should be fixed
echo
'#bar'.$i.' {
background: -webkit-gradient(linear, left top, left bottom, from('.$v[2].'), to(#000));
background: -moz-linear-gradient(top, '.$v[2].', #000);
}';
}
}
?>
#title {
height: 14px;
padding: 0px 0px 20px 0px;
margin: 0px;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.js"></script>
<script type="text/javascript" src="chart.js"></script>
<title>Test</title>
</head>
<body>
<?php
if (strlen ($msg)) {
echo $msg;
} else {
?>
<div id="title">
<?php
echo 'Litres of something consumed per week by '.$developer;
?>
</div>
<div id="chart">
<?php
foreach ($data as $i => &$values) {
$n = (time() - $values[0]) / (7 * 24 * 3600);
$title =
($n !== floor($n) ? "more than " : "").
floor($n)." week".
(floor ($n) == 1 ? "" : "s")." ago";
echo
'<div class="bar" id="bar'.$i.'" title="'.htmlspecialchars($title).'">'.
'<input type="hidden" class="value" value="'.$values[1].'" />'.
strval($values[1]).
'</div>';
}
?>
</div>
<?php
}
?>
</body>
</html>
/* // !!!!!!!!!!!!!!!!! See my notes about the written code in the README file !!!!!!!!!!!!!!!!!!!!!!!!!*/
$(document).ready(function () {
var max_value = 0;
var spacing_between_bars = 10;
var padding_left = parseInt($("body").css("paddingLeft"), 10) + parseInt($("#chart").css("borderLeftWidth"), 10);
var padding_right = parseInt($("body").css("paddingRight"), 10);
var padding_bottom = parseInt($("body").css("paddingBottom"), 10) + parseInt($("#chart").css("borderBottomWidth"), 10);
var padding_top = parseInt($("body").css("paddingTop"), 10);
var chart_height = $(document).height() - ($("#title").outerHeight(true) + padding_top + padding_bottom);
$('#chart').height(chart_height);
var bar_width_with_spacing = Math.floor(
($(document).width() - (padding_left + padding_right + spacing_between_bars)) /
$('#chart .bar .value').length
);
$('#chart .bar .value').each(function (index, value) {
var new_value = parseInt($(this).val(), 10);
if (new_value > max_value) {
max_value = new_value;
}
});
$('#chart .bar').each(function (index, value) {
var value = parseInt($(this).find('.value').first().val(), 10);
$(this).css({
height: parseInt((value / max_value) * chart_height, 10) + 'px',
width: (bar_width_with_spacing - spacing_between_bars) + 'px',
left: (index * bar_width_with_spacing + spacing_between_bars) + 'px'
});
});
});