-
Notifications
You must be signed in to change notification settings - Fork 30
Update All SI Units #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -52,12 +52,19 @@ class answer_unit_conversion { | |||||
| private $default_last_id; // Dimension class id counter. | ||||||
| private $default_id; // Id of the default rule. | ||||||
| private $default_rules; // String of the default rule in a particular format. | ||||||
| private $part_unit; // String of the unit of a part, given. | ||||||
| // @codingStandardsIgnoreLine | ||||||
| public static $unit_exclude_symbols = '][)(}{><0-9.,:;`~!@#^&*\/?|_=+ -'; | ||||||
| public static $rule_exclude_symbols = '][}{><,:;`~!@#&*?|_='; | ||||||
| public static $prefix_scale_factors = array('d' => 1e-1, 'c' => 1e-2, 'da' => 1e1, 'h' => 1e2, | ||||||
| 'm' => 1e-3, 'u' => 1e-6, 'n' => 1e-9, 'p' => 1e-12, 'f' => 1e-15, 'a' => 1e-18, 'z' => 1e-21, 'y' => 1e-24, | ||||||
| 'k' => 1e3, 'M' => 1e6, 'G' => 1e9, 'T' => 1e12, 'P' => 1e15, 'E' => 1e18, 'Z' => 1e21, 'Y' => 1e24); | ||||||
| // For convenience, u is used for micro-, rather than "mu", which has multiple similar UTF representations. | ||||||
| 'm' => 1e-3, 'u' => 1e-6, 'µ' => 1e-6, 'μ' => 1e-6, 'n' => 1e-9, 'p' => 1e-12, | ||||||
| 'k' => 1e3, 'M' => 1e6, 'G' => 1e9, 'T' => 1e12, 'P' => 1e15, | ||||||
| 'E' => 1e18, 'Z' => 1e21, 'Y' => 1e24, 'f' => 1e-15, 'a' => 1e-18, 'z' => 1e-21, 'y' => 1e-24, | ||||||
| 'R' => 1e27, 'Q' => 1e30, 'r' => 1e-27, 'q' => 1e-30 ); | ||||||
| // For convenience, u can be used for micro-, rather than "mu", which has multiple similar UTF representations. | ||||||
| // Note: All UTF representations of µ can be used too. | ||||||
| public static $units_special = array('mol','min','cd'); /* all units >= 2 characters starting with prefix */ | ||||||
| public static $prefix_all = 'k M G T P E Z Y m u µ μ n p f a z y R Q r q d c da h'; | ||||||
|
|
||||||
| // Initialize the internal conversion rule to empty. No exception raised. | ||||||
| public function __construct() { | ||||||
|
|
@@ -66,20 +73,61 @@ public function __construct() { | |||||
| $this->default_mapping = null; | ||||||
| $this->mapping = null; | ||||||
| $this->additional_rules = ''; | ||||||
| $this->part_unit = ''; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Parse a unit into prefix and SI unit | ||||||
| * | ||||||
| * @param string $unit get the unit with prefix and SI unit, must be trimmed before | ||||||
| * @return string SI unit only | ||||||
| */ | ||||||
| public function parse_prefix_unit($unit) { | ||||||
| if (is_array($unit)) { | ||||||
| throw new Exception('parse_prefix_unit does not handle arrays!'); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The string should be in |
||||||
| return ''; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Unreachable code. |
||||||
| } | ||||||
| $pattern = '/^([\wµμ]*).*/'; /* get only first word, accept also µ μ */ | ||||||
| $replacement = '${1}'; | ||||||
| $shu = preg_replace($pattern, $replacement, $unit); | ||||||
| if ( (strlen($shu) < 2) || | ||||||
| (in_array($shu, static::$units_special) )) { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| return $unit; | ||||||
| } | ||||||
| foreach (static::$prefix_scale_factors as $i => $prefix) { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| if (str_starts_with($unit,$i)) { | ||||||
| $unit = substr($unit, strlen($i)); | ||||||
| break; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||
| } | ||||||
| } | ||||||
| return $unit; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * It assign default rules to this class. It will also reset the mapping. No exception raised. | ||||||
| * | ||||||
| * @param string $default_id id of the default rule. Use to avoid reinitialization same rule set | ||||||
| * @param string $default_rules default rules | ||||||
| */ | ||||||
| public function assign_default_rules($default_id, $default_rules) { | ||||||
| if ($this->default_id == $default_id) { | ||||||
| public function assign_default_rules($default_id, $default_rules, $part_unit = '') { | ||||||
| if (($default_id == 2) && ($part_unit != $this->part_unit)) { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would probably be better to have a class constant |
||||||
| var_dump("part_unit:", $part_unit); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| $default_rules = ''; | ||||||
| // $_units = $this->parse_targets($part_unit); // does not work as expected | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| $_units = array_map('trim', explode('=', $part_unit)); | ||||||
| var_dump("_units after array_map/trim:", $_units); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| foreach ($_units as $_unit) { | ||||||
| //$_key = array_key_first($_unit); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| $unit = $this->parse_prefix_unit($_unit); | ||||||
| if ($unit != '') { | ||||||
| $default_rules .= $unit . ':' . static::$prefix_all . ';'; | ||||||
| } | ||||||
| } | ||||||
| } elseif ($this->default_id == $default_id) { | ||||||
| return; // Do nothing if the rules are unchanged. | ||||||
| } | ||||||
| $this->default_id = $default_id; | ||||||
| $this->part_unit = $part_unit; | ||||||
| $this->default_rules = $default_rules; | ||||||
| $this->default_mapping = null; | ||||||
| $this->mapping = null; | ||||||
|
|
@@ -118,23 +166,6 @@ public function reparse_all_rules() { | |||||
| } | ||||||
|
|
||||||
|
|
||||||
| // Return the current unit mapping in this class. | ||||||
| public function get_unit_mapping() { | ||||||
| return $this->mapping; | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| // Return a dimension classes list for current mapping. Each class is an array of $unit to $scale mapping. | ||||||
| public function get_dimension_list() { | ||||||
| $dimension_list = array(); | ||||||
| foreach ($this->mapping as $unit => $class_scale) { | ||||||
| list($class, $scale) = $class_scale; | ||||||
| $dimension_list[$class][$unit] = $scale; | ||||||
| } | ||||||
| return $dimension_list; | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| /** | ||||||
| * Check whether an input unit is equivalent, under conversion rules, to target units. May throw | ||||||
| * | ||||||
|
|
@@ -247,7 +278,7 @@ private function check_convertibility_parsed($a, $targets_list) { | |||||
| * @return array(conversion factor, unit exponent) if it can be converted, otherwise null. | ||||||
| */ | ||||||
| private function attempt_conversion($test_unit_name, $base_unit_array) { | ||||||
| $oclass = $this->mapping[$test_unit_name]; | ||||||
| $oclass = $this->mapping[$test_unit_name] ?? null; | ||||||
| if (!isset($oclass)) { | ||||||
| return null; // It does not exist in the mapping implies it is not convertible. | ||||||
| } | ||||||
|
|
@@ -381,8 +412,8 @@ private function parse_rules(&$mapping, &$dim_id_count, $rules_string) { | |||||
| throw new Exception('Syntax error of SI prefix'); | ||||||
| } else if (count($e) == 2) { | ||||||
| $unit_name = trim($e[0]); | ||||||
| if (preg_match('/['.self::$unit_exclude_symbols.']+/', $unit_name)) { | ||||||
| throw new Exception('"'.$unit_name.'" unit contains unaccepted character.'); | ||||||
| if (preg_match('/['.self::$rule_exclude_symbols.']+/', $unit_name)) { | ||||||
| throw new Exception('"'.$unit_name.'" rule contains unaccepted character.'); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The string should be in |
||||||
| } | ||||||
| $unit_scales[$unit_name] = 1.0; // The original unit. | ||||||
| $si_prefixes = explode(' ', $e[1]); | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,26 +29,29 @@ class unit_conversion_rules { | |
| public function __construct() { | ||
| $this->basicunitconversionrule[0] = array(get_string('none', 'qtype_formulas'), ''); | ||
| $this->basicunitconversionrule[1] = array(get_string('commonsiunit', 'qtype_formulas'), ' | ||
| m: k c d m u n p f; | ||
| s: m u n p f; | ||
| g: k m u n p f; | ||
| mol: m u n p; | ||
| N: k m u n p f; | ||
| A: m u n p f; | ||
| J: k M G T P m u n p f; | ||
| m: k c d m u µ μ n p f; | ||
| s: m u µ μ n p f; | ||
| g: k m u µ μ n p f; | ||
| mol: m u µ μ n p; | ||
| N: k m u µ μ n p f; | ||
| A: k m u µ μ n p f; | ||
| J: k M G T P m u µ μ n p f; | ||
| J = 6.24150947e+18 eV; | ||
| eV: k M G T P m u; | ||
| W: k M G T P m u n p f; | ||
| eV: k M G T P m u µ μ; | ||
| W: k M G T P m u µ μ n p f; | ||
| Pa: k M G T P; | ||
| Hz: k M G T P E; | ||
| C: k m u n p f; | ||
| V: k M G m u n p f; | ||
| C: k m u µ μ n p f; | ||
| V: k M G m u µ μ n p f; | ||
| ohm: m k M G T P; | ||
| F: m u n p f; | ||
| T: k m u n p; | ||
| H: k m u n p; | ||
| Ω: u µ μ m k M G T P; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is (U+03A9 / GREEK CAPITAL LETTER OMEGA). I suggest adding Ω (U+2126 / OHM SIGN) as well. |
||
| F: m u µ μ n p f; | ||
| T: k m u µ μ n p; | ||
| H: k m u µ μ n p; | ||
| '); | ||
|
|
||
| $this->basicunitconversionrule[2] = array(get_string('allsiunits', 'qtype_formulas'), ''); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure I am getting this right: You changed the conversion rules for |
||
|
|
||
| /* You can define your own rules here, for instance: | ||
| * $this->basicunitconversionrule[100] = array( | ||
| * $this->basicunitconversionrule[1][0] + ' and your own conversion rules', | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.