math_word_problems.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. /*
  3. * To change this license header, choose License Headers in Project Properties.
  4. * To change this template file, choose Tools | Templates
  5. * and open the template in the editor.
  6. */
  7. /**
  8. * Description of Math_word_Problems
  9. *
  10. * @author gregory
  11. */
  12. class math_word_problems {
  13. public $state = "error";
  14. private $debug = false;
  15. private $sql;
  16. private $user;
  17. private $difficultyValue;
  18. private $returnData;
  19. /**
  20. * Setup new numbers engine
  21. *
  22. * @param bool $test Enable debug mode.
  23. */
  24. public function __construct($test = false) {
  25. if ($test) {
  26. $this->debug = true;
  27. }
  28. $this->sql = e107::getDB();
  29. $this->user = e107::getUser()->getLoginName();
  30. $this->state = "ready";
  31. }
  32. public function getProblem() {
  33. $this->difficultyValue = $this->difficulty();
  34. if($this->debug) {
  35. $this->returnData['difficulty'] = $this->difficultyValue;
  36. }
  37. $this->questionAssembler();
  38. return $this->returnData;
  39. }
  40. private function questionAssembler() { //return [ 'answer1'=>$solution['/'], 'question'=>$TempQuestion, 'type'=>__CLASS__];
  41. $questionIndexSelected = array_rand($this->questionData());
  42. $question = $this->questionData()[$questionIndexSelected];
  43. $this->returnData['question'] = $this->substitutor($question);
  44. //print_a([__CLASS__.' '.__FUNCTION__=>['rawQuestion'=>$question,'processedQuestion'=>$this->returnData['question']]]);
  45. }
  46. private function questionData() {
  47. $wordedMath = [
  48. ['{name1} used {int,1,1,diff} meters of cloth to sew {int,2,1,diff} pillow cases. How much cloth would be used to sew {int,3,2,diff} pillow cases?','(({int,1,1,diff}/{int,2,1,diff})*{int,3,2,diff})'],
  49. //['A mother makes {int,1,1,diff} sandwiches for a party. Each child received {int,2,1,diff} sandwiches. How many children were at the party?','({int,1,1,diff}/{int,2,1,diff})'],
  50. ['The mass of a sponge is {int,1,1,diff} g. When put in water it expanded and gained a mass of {int,2,1,diff} g. Find the mass difference if {int,3,1,diff} similar sponges were used in the experiment?','({int,2,1,diff}*{int,3,1,diff})'],
  51. //['{name1} is {int,1,1,diff} years old. His brother is {int,2,1,diff} months older than him. How old is {name1}’s brother?','({int,1,1,diff}+({int,1,1,diff}/12))'],
  52. ['An elephant eats {int,1,1,diff} kg of food a week. How much will it eat in {int,2,1,10} years?','(({int,1,1,diff}*52)*{int,2,1,10})'],
  53. // ['A cake recipe uses 60 g of flour. How many cakes can I bake with 4.2 kg of flour?'],
  54. // ['On a scale there is 88 grams on side A and 1.3 kg on side B. How much more weight do I need to put on side A to balance the scale?','()'],
  55. // ['{name1} baked 400 cupcakes and she sold 2 fifths at the market. How many cupcakes does she have left?'],
  56. // ['A baker baked 720 slices of pizza. He sold 5 nineths of the pizzas and threw away 45 slices. How many slices were left?'],
  57. // ['A cake recipe uses 1 quarter kilogram of sugar. How many cakes can I bake with 750 grams of sugar?'],
  58. // ['There were 280 marbles in a jar. {name1} dropped the jar and lost 3 quarters of the marbles. How many marbles were left?'],
  59. // ['At the beach there were 675 people. One fifth were children and the rest were adults. How many adults were at the beach?'],
  60. // ['{name1} is 56 years old and has a brother who is 84 months younger. How old is his brother?'],
  61. // ['{name1} has to pack 28.35 kg of sugar into 10 bags equally. How much sugar would each bag contain?'],
  62. // ['There was 310.4 kg of sand. It has to be divided into 100 tubs equally. How much sand would each tub contain?'],
  63. // ['A packet contains 2.39 kg of flour. {name1} bought 1000 packets for her cake shop. How much flour does she have in total?'],
  64. ];
  65. return $wordedMath;
  66. }
  67. /**
  68. * Return the difficulty based on previously answered questions.
  69. *
  70. * @return int Difficulty as percent.
  71. */
  72. private function difficulty() {
  73. $query = "SELECT (SUM(correct)/COUNT(correct)*100) as percent
  74. FROM e107.`e107_tkReport` WHERE
  75. answereddatestamp >= unix_timestamp((NOW()) - INTERVAL 1 MONTH)
  76. AND username = '$this->user' AND subject = '".__CLASS__."';";
  77. if($this->debug) {
  78. $this->returnData['difficultySQL'] = $query;
  79. }
  80. $this->sql->gen($query);
  81. while ($row = $this->sql->fetch()) {
  82. if (is_numeric($row["percent"])) {
  83. return (int)$row["percent"];
  84. } else {
  85. return 1;
  86. }
  87. }
  88. }
  89. private function substitutor($question) {
  90. $questionStr = $this->names($question[0]);
  91. $solutionStr = $this->names($question[1]);
  92. $questionArray = preg_split("/{|}/",$questionStr);
  93. foreach ($questionArray as $questionPart) {
  94. if($this->contains('int', $questionPart)) {
  95. $substituteString = $this->ints(explode(',',$questionPart));
  96. $questionStr = str_replace('{'.$questionPart.'}', $substituteString, $questionStr);
  97. $solutionStr = str_replace('{'.$questionPart.'}', $substituteString, $solutionStr);
  98. }
  99. }
  100. // eval needed
  101. return [ 'answer1'=>(int)eval("return ".$solutionStr.";"), 'question'=>$questionStr, 'type'=>__CLASS__];
  102. }
  103. private function names($questionString) {
  104. $freeNames = ['Anna','George','Marie','Elliot','Paul','Stacey','Maureen'];
  105. for ($int = 1; $int <= 10; $int++) {
  106. $randomName = array_rand($freeNames);
  107. if($this->contains('{name'.$int.'}', $questionString)) {
  108. $name = $freeNames[$randomName];
  109. $questionString = str_replace('{name'.$int.'}', $name, $questionString);
  110. unset($freeNames[$randomName]);
  111. }else{
  112. break;
  113. }
  114. }
  115. return $questionString;
  116. }
  117. private function ints($dataBlock) {
  118. foreach ($dataBlock as $key=>&$data) {
  119. if($this->contains('diff', $data)) {
  120. $data = (int)$this->difficultyValue;
  121. if($data<$dataBlock[($key-1)]) {
  122. $data = $dataBlock[($key-1)];
  123. }
  124. }
  125. }
  126. return mt_rand($dataBlock[2],$dataBlock[3]);
  127. }
  128. /**
  129. * contains($needle, $haystack)
  130. *
  131. * <code>
  132. * Example;<br/>
  133. * $haystack = 'Hello how are you';<br/>
  134. * $needle = 'are';<br/>
  135. * contains($needle, $haystack); // == true<br/>
  136. * </code>
  137. * @param string $needle
  138. * @param string $haystack
  139. * @return bool
  140. */
  141. function contains($needle, $haystack)
  142. {
  143. return strpos($haystack, $needle) !== false;
  144. }
  145. }