table)){ $this->table[$student] = [ "intelligence" => rand(70,100), "endurance" => rand(70,100), "skills" => [], ]; } } public function addskill(string $student, string $skill){ $this->addstudent($student); if(!array_key_exists($skill,$this->table[$student]["skills"])){ $int = $this->table[$student]["intelligence"]; $end = $this->table[$student]["endurance"]; $this->table[$student]["skills"][$skill] = [ "intelligence" => min(100, $int + rand(-30,30)), "endurance" => min(100, $end + rand(-10,10)), ]; } } // Below is mostly just for reference in the json file public function addUserNameInfo(string $student, $firstname,$lastname){ $this->addstudent($student); $this->table[$student]["firstname"] = $firstname; $this->table[$student]["lastname"] = $lastname; } public function generateraw($student,$skill, $count ) { $this->addskill($student,$skill); $int = $this->table[$student]["skills"][$skill]["intelligence"]; $end = $this->table[$student]["skills"][$skill]["endurance"]; $results = []; $gaveup = false; for($i=0; $i < $count; $i++){ $r = new \stdClass; if($gaveup) { $r->done = !$gaveup; } else { $r->done = (rand(0, $end) > 20); // Determine if the assignment was done } if($r->done){ $score = rand(0,$int) ; $r->result = ($score > 20); // determine if the assignment was successful if(!$r->result){ $r->failed = !($score > 10); } } else { $r->result = false; // make sure a result property is always there $r->failed = true; } // Aways generate a little feedback $r->fb = $this->generatedfeedback(); $results[] = $r; if(!$gaveup && $i >= 3) { // There is a slight chance the students with low endurance for this course will stop with this course's work entirely $gaveup = (rand(0,$end) < 15); } } return $results; } public function generate($student,$skill, array $gradeinfos ){ global $DB; $table ="local_treestudyplan_gradecfg"; $rlist = []; $gen = $this->generateraw($student,$skill, count($gradeinfos)); for($i=0; $i < count($gradeinfos); $i++){ $g = $gradeinfos[$i]; $gi = $g->getGradeitem(); $gr = $gen[$i]; // First get the configured interpretation for this scale or grade $scale = $gi->load_scale(); if( isset($scale)){ $gradecfg = $DB->get_record($table,["scale_id"=>$scale->id]); } else if($gi->grademin == 0) { $gradecfg = $DB->get_record($table,["grade_points"=>$gi->grademax]); } else { $gradecfg = null; } // next generate the grade if($gradecfg) { if(!$gr->done){ // INCOMPLETE // fair chance of teacher forgetting to set incomplete to "no evidence" $grade = 0;// $grade = (rand(0,100) > 15)?max(1, $gradecfg->min_progress-1):"0"; $r = (object)["gi" => $g, "grade" => $grade, "fb" =>"" ]; } else if(!$gr->result){ $grade = rand($gradecfg->min_progress, $gradecfg->min_completed -1 ); $r = (object)["gi" => $g, "grade" => $grade, "fb" =>$gr->fb ]; } else{ // COMPLETED $r = (object)["gi" => $g, "grade" => rand( $gradecfg->min_completed, $gi->grademax ), "fb" =>$gr->fb ]; } $r->gradetext = $r->grade; if( isset($scale)){ $scaleitems = $scale->load_items(); if($r->grade > 0){ $r->gradetext = trim($scale->get_nearest_item($r->grade)); } else { $r->gradetext = "-"; } } } else if($gi->gradepass > 0) { if(!$gr->done){ // INCOMPLETe or FAILED $grade = rand(0, $gi->gradepass/2); $r = (object)["gi" => $g, "grade" => $grade, "fb" =>($grade > 0)?$gr->fb:"" ]; } else if(!$gr->result){ //PROGRESS $r = (object)["gi" => $g, "grade" => rand( round($gi->gradepass/2), $gi->gradepass -1 ), "fb" =>$gr->fb ]; } else{ // COMPLETED $r = (object)["gi" => $g, "grade" => rand( $gi->gradepass, $gi->grademax ), "fb" =>$gr->fb ]; } $r->gradetext = $r->grade; } else { // Blind assumptions if nothing is provided // over 55% of range is completed // under 35% is not done $range = floatval($gi->grademax - $gi->grademin); if(!$gr->done){ // INCOMPLETe or FAILED $grade = rand(0, round($range * 0.35) - 1); $r = (object)["gi" => $g, "grade" => $gi->grademin+$grade, "fb" =>($grade > 0)?$gr->fb:"" ]; } else if(!$gr->result){ //PROGRESS $r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.35),round($range * 0.55) - 1 ), "fb" =>$gr->fb ]; } else{ // COMPLETED $r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.55) , $range ), "fb" =>$gr->fb ]; } $r->gradetext = $r->grade; } $rlist[] = $r; } return $rlist; } public function getstats($student){ return $this->table[$student]; } public function serialize(): ?string{ return json_encode([ "table" => $this->table],JSON_PRETTY_PRINT); } public function unserialize(string $data): void { $o = json_decode($data,true); $this->table = $o["table"]; } public function toFile(string $filename){ file_put_contents($filename,$this->serialize()); } public function fromFile(string $filename){ if(file_exists($filename)){ try{ $json = file_get_contents($filename); $this->unserialize($json); } catch(Exception $x){ cli_problem("ERROR loading from file"); throw $x; // Throw X up again to show the output } } } }