views:

70

answers:

3

I need to validate measurements entered into a form generated by PHP.

I intend to compare them to upper and lower control limits and decide if they fail or pass.

As a first step, I imagine a PHP function which accepts strings representing engineering measurements and converts them to pure numbers before the comparison.

At the moment I'm only expecting measurements of small voltages and currents, so strings like

'1.234uA', '2.34 nA', '39.9mV'. or '-1.003e-12'

will be converted to

1.234e-6, 2.34e-9, 3.99e-2 and -1.003e-12, respectively.

But the method should be generalisable to any measured quantity.

A: 

In your function
first you need to initialize values for units like -6 for u, -3 for m...etc
divide the string in Number and Unit(i.e micro(u),mili(m),etc).
and then say the entered no is NUM; and unit is UNIT..(char like u,m etc);

while(NUM>10)
{
NUM=NUM/10;
x++; //x is keeping track of the DOT.
}
UNIT=UNIT+x;    //i.e UNIT is increased(for M,K,etc) or decreased(for u,m,etc)
echo NUM.e.UNIT;

May be it will do!

Webbisshh
Thanks, Pradyumna, it just goes to show that two people will never solve a problem in the same way.
pavium
A: 

My own possibly simple-minded approach has been to use an array of patterns in preg_replace

function convert($value) {
    $result = preg_replace($patterns, $replacements, $value);
    return $result;
}

Where

$patterns = array('/p[av]/i', '/n[av]/i', '/u[av]/i', '/m[av]/i');
$replacements = array('e-12', 'e-9', 'e-6', 'e-3');

And it could be extended to higher prefixes, but it seems heavy-handed to keep adding increasingly complex regexes to the $patterns array.

Edit: The comparison, later, should interpret the return value as a real number.

I'm hoping someone can suggest something more elegant.

pavium
+1  A: 
function convert($value) {
   $units = array('p' => 'e-12', 
                  'n' => 'e-9', 
                  'u' => 'e-6', 
                  'm' => 'e-3');
   $unitstring = implode("", array_keys($units));
   $matches = array();
   $pattern = "/^(-?(?:\\d*\.\\d+)|(?:\\d+))\s*([$unitstring])([a-z])$/i";
   $result = preg_match($pattern, $value, $matches);
   if ($result) 
      $retval = $matches[1].$units[$matches[2]].$matches[3];
   else
      $retval = $value;
   return $retval;
}

So to explain what the above does:

  • $units is an array to map unit-prefix to the exponent.
  • $unitstring conglomerates the units into a single string (in the example it would be 'pnum')
  • The regular expression will match an optional -, followed by either 0 or more digits, a period and 1 or more digits OR 1 or more digits, followed by one of the unit prefixes (only one) and then a single alphabetical character. There can be any amount of whitespace between the number and the units.
  • Because of the parethesis and the use of preg_match, the number section, the unit prefix, and the unit are all separately captured in the array $matches as elements 1, 2, and 3. (0 will contain the entire string)
  • $result will be 1 if it matched the regex, 0 otherwise.
  • $retval is constructed by just connecting the number, the exponent (based on the unit prefix from the array) and the units provided, or it will just be the passed in string (such as if you're given the -1.003e-12, it will be returned)

Of course you can tweak some things, but in general this is a good start. Hope it helps.

Zeroshade
Yes, thanks Zeroshade. The associative array certainly makes clear the relationship between unit-prefix and exponent, but there might be a cost in the increased complexity of the following code. I think my actual implementation included an additional preg_replace which removed spaces so that strings like 1.23 uA became 1.23e-6 It seemed to work well, but I really like the readability of your associative array.
pavium
Thanks. The only big increased complexity here is the regular expression itself. preg_replace is going to be more expensive than just preg_match. Then again, if you're going for speed and performance why are you using php? =P Unless you're converting large numbers of these at a time (which if you're getting input from a form I doubt) the cost for the complexity will probably be negligible.
Zeroshade
No great worries about speed and performance: I'm just validating 10 measurements entered into a form by an operator who doesn't necessarily know the difference between a picoamp and a microvolt. The cost I referred to is the increased mental activity I had to endure while I got my head around your regex. But I like to learn new things. Thanks for your suggestions.
pavium