I’ve been looking for things I could do for a code sample and I came across a suggestion. The project is:

A calculator function that takes a single string of input that includes numbers and operators and returns the numeric result of the equation. Donâ€™t forget input validation, error handling (divide by zero), and operator precedence concerns!

So I created something that does this. If the function can’t process the equation it will throw an error. The function is recursive to help take care of parentheses.

# PHP

/** processOperator function to take care of operations. @param &$numbers array of numbers in string @param &$operators array of operators in string @param $operator the operator worked on */ function processOperator( &$numbers, &$operators, $operator ) { $search = array_search( $operator, $operators ); while ( $search !== false ) { switch ( $operator ) { case "^": $numbers[ $search ] = ( pow( $numbers[ $search ], $numbers[ $search + 1 ] ) ); break; case "*": $numbers[ $search ] = $numbers[ $search ] * $numbers[ $search + 1 ]; break; case "/": if ( $numbers[$search + 1] != 0 ) { $numbers[$search] = $numbers[$search] / $numbers[$search + 1]; } else { throw new Exception('Division by zero.'); } break; case "+": $numbers[ $search ] = $numbers[ $search ] + $numbers[ $search + 1 ]; break; case "-": $numbers[ $search ] = $numbers[ $search ] - $numbers[ $search + 1 ]; break; } unset( $operators[ $search ] ); unset( $numbers[ $search + 1 ] ); $operators = array_values( $operators ); $numbers = array_values( $numbers ); $search = array_search( $operator, $operators ); } } /** * function to take in a equation in the form of a text string and solve * doesn't currently account for Parentheses. * All values should be seperated by a space * @param equation a string of an equation we run to run. * @return float of the number of the solved equation */ function solveTextString( $equation ) { $equation = trim( $equation ); $numbers = array( ); $operators = array( ); $total = 0; $openBraces = 0; $pemdas = array('^', '*', '/', '+', '-'); $openParentheses = substr_count( $equation, "(" ); $closedParentheses = substr_count( $equation, ")" ); if ( $openParentheses != $closedParentheses ) { throw new Exception('Uneven Parentheses.'); } // Process inner equations while ( $openParentheses > 0 ) { $open = strpos( $equation, '('); $close = null; for ( $i = $open + 1; $i 0) && ($character == ')') ) { $openBraces--; } } $innerEquation = substr($equation, $open + 1, ($close - $open ) - 1); $innerEquationSolved = solveTextString( $innerEquation ); $equation = trim( str_replace( "($innerEquation)", trim($innerEquationSolved), $equation ) ); --$openParentheses; } $parts = explode( ' ', trim( $equation ) ); if ( (count ( $parts ) % 2) == 0 ) { throw new Exception('Invalid Equation'); } foreach ( $parts as $key => $part ) { if ( !is_numeric( $part ) && ( $key % 2 != 0 ) ) { switch( $part ) { case "^": case "*": case "/": case "+": case "-": $operators[] = $part; break; default: throw new Exception('Invalid Equation'); } } elseif ( is_numeric( $part ) && ( $key % 2 == 0 ) ) { $numbers[] = ( float )$part; } else { throw new Exception('Invalid Equation.'); } } if ( count ($operators ) >= count ($numbers ) ) { throw new Exception('Invalid Equation.'); } for ($i = 0; $i < count( $pemdas ); $i++ ) { processOperator( $numbers, $operators, $pemdas[$i] ); } return( $numbers[0] ); }