Search in sources :

Example 1 with Operator

use of expression.Operator in project OpenNotebook by jaltekruse.

the class ExUtil method addRandomOp.

public static Node addRandomOp(Node n, String[] ops, String[] vars, int min, int max, double maxAbsVal, boolean excludeZero, boolean subtractNegatives, boolean addNegatives) {
    int opIndex = rand.nextInt(ops.length);
    String opCode = ops[opIndex];
    Node newChild = new Number(randomInt(min, max, excludeZero));
    Operator op = null;
    Number newNum;
    Expression newEx;
    double expressionVal = 0;
    boolean numberTooBig = false;
    try {
        //			System.out.println(n.toStringRepresentation());
        expressionVal = ((Number) n.numericSimplify()).getValue();
    } catch (NodeException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    if (Math.abs(expressionVal) > maxAbsVal) {
        numberTooBig = true;
    }
    if (opCode.equals(DIVISION)) {
        op = new Operator.Division();
        newEx = new Expression(op);
        if (!(newChild instanceof Number)) {
            // to keep the answer clean
            return addNodeOnRandomSide(n, newChild, op);
        } else if (expressionVal == 0) {
            newNum = (Number) newChild;
            do {
                newChild = new Number(randomInt(min, max, excludeZero));
            } while (newNum.getValue() == 0);
            return new Expression(op, n, newChild);
        } else if (isPrime(expressionVal) || (rand.nextBoolean() && !numberTooBig)) {
            // or the expression was randomly selected to be the divisor when it wasn't prime
            return addRandomOp(n, ops, vars, min, max, maxAbsVal, excludeZero, subtractNegatives, addNegatives);
        // had problem with these next two lines, gave up for now and just adding another operation
        //				newChild = new Number( expressionVal * randomInt(min, max, excludeZero));
        //				return new Expression(op, newChild, n);
        } else {
            // need to find a divisor
            if (numberTooBig) {
                return addRandomOp(n, ops, vars, min, max, maxAbsVal, excludeZero, subtractNegatives, addNegatives);
            }
            double[] factors = getFactors(expressionVal);
            int factorIndex = rand.nextInt(factors.length);
            newChild = new Number(factors[factorIndex]);
            return new Expression(op, n, newChild);
        }
    } else if (opCode.equals(ADDITION)) {
        op = new Operator.Addition();
        if (!(newChild instanceof Number)) {
            // to keep the answer clean
            return addNodeOnRandomSide(n, newChild, op);
        }
        if (!addNegatives) {
            if (max < 0) {
            // the settings contradict one another, the user wanted only negative numbers generated
            //do nothing
            } else {
                // the minimum is below zero, so exclude those values between 0 and the minimum while finding a new number
                int tempMin = 0;
                newNum = (Number) newChild;
                if (min > 0)
                    tempMin = min;
                while (newNum.getValue() < 0) {
                    newNum = new Number(randomInt(tempMin, max, excludeZero));
                }
            }
        }
    } else if (opCode.equals(SUBTRACTION)) {
        op = new Operator.Subtraction();
        if (!(newChild instanceof Number)) {
            // to keep the answer clean
            if (n instanceof Expression && ((Expression) n).getOperator() instanceof Operator.Negation) {
                // MIGHT CAUSE INFINITE RECURSION, BE CAREFUL
                return addRandomOp(n, ops, vars, min, max, maxAbsVal, excludeZero, subtractNegatives, addNegatives);
            }
            return addNodeOnRandomSide(n, newChild, op);
        }
        if (!subtractNegatives) {
            // negative numbers are not supposed to be subtracted, generate new positive number
            if (max < 0) {
            // the settings contradict one another, the user wanted only negative numbers generated
            //do nothing, ignore the value of subtractNegatives
            } else {
                // the minimum is below zero, so exclude those values between 0 and the minimum while finding a new number
                int tempMin = 0;
                newNum = (Number) newChild;
                if (min > 0)
                    tempMin = min;
                while (newNum.getValue() < 0) {
                    newNum = new Number(randomInt(tempMin, max, excludeZero));
                }
            }
        }
    } else if (opCode.equals(MULTIPLICATION)) {
        op = new Operator.Multiplication();
        newEx = new Expression(op);
        if (!(newChild instanceof Number)) {
            // to keep the answer clean
            return addNodeOnRandomSide(n, newChild, op);
        }
    } else if (opCode.equals(NEGATION)) {
        if (n instanceof Expression && ((Expression) n).getOperator() instanceof Operator.Negation || (n instanceof Number && ((Number) n).getValue() < 0)) {
            // THIS WILL CAUSE INFINITE RECURSION IF THE ONLY OPERATOR IS NEGATION!!
            return addRandomOp(n, ops, vars, min, max, maxAbsVal, excludeZero, subtractNegatives, addNegatives);
        }
        return new Expression(new Operator.Negation(), true, n);
    } else {
        throw new RuntimeException("unknown op");
    }
    return addNodeOnRandomSide(n, newChild, op);
}
Also used : Operator(expression.Operator) Node(expression.Node) NodeException(expression.NodeException) Number(expression.Number) Expression(expression.Expression)

Example 2 with Operator

use of expression.Operator in project OpenNotebook by jaltekruse.

the class ExpressionObject method performSpecialObjectAction.

public void performSpecialObjectAction(String s) {
    // actions in the future
    if (((StringAttribute) getAttributeWithName(EXPRESSION)).getValue() == null || ((StringAttribute) getAttributeWithName(EXPRESSION)).getValue().equals("")) {
        JOptionPane.showMessageDialog(null, "There is no expression to work with, enter one in the box below.", WARNING, JOptionPane.WARNING_MESSAGE);
        setActionCancelled(true);
        return;
    }
    if (s.equals(SIMPLIFY)) {
        try {
            getListWithName(STEPS).addValueWithString(Expression.parseNode(getLastStep()).smartNumericSimplify().toStringRepresentation());
            return;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Error with expression simplification", ERROR, JOptionPane.WARNING_MESSAGE);
        }
    }
    if (s.equals(COMBINE_LIKE_TERMS)) {
        try {
            getListWithName(STEPS).addValueWithString(Expression.parseNode(getLastStep()).collectLikeTerms().simplify().toStringRepresentation());
            return;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Error with combining like terms", ERROR, JOptionPane.WARNING_MESSAGE);
        }
    }
    if (s.equals(MAKE_INTO_PROBLEM)) {
        VariableValueInsertionProblem newProblem = new VariableValueInsertionProblem(getParentContainer(), getxPos(), getyPos(), getWidth(), getHeight());
        this.getParentContainer().getParentDoc().getDocViewerPanel().setFocusedObject(newProblem);
        newProblem.addObjectFromPage(this);
        getParentContainer().addObject(newProblem);
        getParentContainer().removeObject(this);
        return;
    } else if (s.equals(UNDO_STEP)) {
        int size = getListWithName(STEPS).getValues().size();
        if (size > 0) {
            getListWithName(STEPS).getValues().remove(size - 1);
        } else {
            JOptionPane.showMessageDialog(null, "No steps to undo.", WARNING, JOptionPane.WARNING_MESSAGE);
            setActionCancelled(true);
        }
        return;
    } else if (s.equals(SUB_IN_VALUE)) {
        String variableStr = "";
        Node substitute = null;
        boolean foundVar;
        do {
            variableStr = (String) JOptionPane.showInputDialog(null, "Enter a variable to replace, variables are case sensitive 'a' is not the same as 'A'.", null, JOptionPane.PLAIN_MESSAGE, null, null, null);
            if (variableStr == null) {
                setActionCancelled(true);
                return;
            }
            if (variableStr.length() != 1 || !Character.isLetter(variableStr.charAt(0))) {
                JOptionPane.showMessageDialog(null, "Need to enter a single letter.", WARNING, JOptionPane.WARNING_MESSAGE);
            }
            foundVar = Node.parseNode(getLastStep()).containsIdentifier(variableStr);
            if (!foundVar) {
                JOptionPane.showMessageDialog(null, "Variable not found in expression.", WARNING, JOptionPane.WARNING_MESSAGE);
            }
        } while (variableStr.length() != 1 || !Character.isLetter(variableStr.charAt(0)) && !foundVar);
        substitute = this.getParentPage().getParentDoc().getDocViewerPanel().getNotebook().getNotebookPanel().getExpressionFromUser("Enter value or expression to substitute.");
        if (substitute == null) {
            setActionCancelled(true);
            return;
        }
        substitute.setDisplayParentheses(true);
        try {
            getListWithName(STEPS).addValueWithString(Node.parseNode(getLastStep()).replace(variableStr, substitute).toStringRepresentation());
        } catch (Exception e) {
            // this should not throw an error, as both the expression and the one being
            // Substituted have both been checked for validity
            JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
            setActionCancelled(true);
        }
        return;
    } else if (s.equals(MODIFY_EXPRESSION)) {
        Node newNode = this.getParentPage().getParentDoc().getDocViewerPanel().getNotebook().getNotebookPanel().getExpressionFromUser("Modify the expression.", getLastStep());
        if (newNode == null) {
            setActionCancelled(true);
            return;
        }
        try {
            getListWithName(STEPS).addValueWithString(newNode.toStringRepresentation());
            return;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
        }
    } else if (s.equals(MANUALLY_TYPE_STEP)) {
        Node newNode = this.getParentPage().getParentDoc().getDocViewerPanel().getNotebook().getNotebookPanel().getExpressionFromUser("Type the entire next line.");
        if (newNode == null) {
            setActionCancelled(true);
            return;
        }
        try {
            getListWithName(STEPS).addValueWithString(newNode.toStringRepresentation());
            return;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
        }
    }
    // all of the rest of the operations require an equals sign
    Node n = null;
    try {
        String expression = ((StringAttribute) getAttributeWithName(EXPRESSION)).getValue();
        if (!expression.equals("")) {
            if (getListWithName(STEPS).getValues().isEmpty()) {
                n = Node.parseNode(((StringAttribute) getAttributeWithName(EXPRESSION)).getValue());
            } else {
                n = Node.parseNode(getLastStep());
            }
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, "Previous expression has an error.", ERROR, JOptionPane.ERROR_MESSAGE);
        setActionCancelled(true);
        return;
    }
    if (!(n instanceof Expression && ((Expression) n).getOperator() instanceof Operator.Equals)) {
        //the expression does not have an equals sign
        JOptionPane.showMessageDialog(null, "Expression requires an equal sign for that operation.", ERROR, JOptionPane.ERROR_MESSAGE);
        setActionCancelled(true);
        return;
    }
    Expression ex = (Expression) n;
    Operator o = null;
    if (s.equals(OTHER_OPERATIONS)) {
        Object[] operations = { "sqrt", "sin", "cos", "tan" };
        String op = (String) JOptionPane.showInputDialog(null, "Choose an operation to apply to both sides", "Operation Selection", JOptionPane.PLAIN_MESSAGE, null, operations, "sqrt");
        if (op == null || op.equals("")) {
            setActionCancelled(true);
            return;
        }
        if (op.equals("sqrt"))
            o = new Operator.SquareRoot();
        else if (op.equals("sin"))
            o = new Operator.Sine();
        else if (op.equals("cos"))
            o = new Operator.Cosine();
        else if (op.equals("tan"))
            o = new Operator.Tangent();
        Expression newLeft = new Expression(o);
        Vector<Node> left = new Vector<>();
        Node newChild = ex.getChild(0);
        if (!op.equals("sqrt")) {
            newChild.setDisplayParentheses(true);
        }
        left.add(newChild);
        newLeft.setChildren(left);
        Expression newRight = new Expression(o);
        Vector<Node> right = new Vector<>();
        newChild = ex.getChild(1);
        if (!op.equals("sqrt")) {
            newChild.setDisplayParentheses(true);
        }
        right.add(newChild);
        newRight.setChildren(right);
        Vector<Node> exChildren = new Vector<>();
        exChildren.add(newLeft);
        exChildren.add(newRight);
        ex.setChildren(exChildren);
        try {
            getListWithName(STEPS).addValueWithString(ex.toStringRepresentation());
        } catch (NodeException e) {
            JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
        } catch (AttributeException e) {
            JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
        }
        return;
    }
    try {
        if (s.equals(ADD_TO_BOTH_SIDES) || s.equals(SUBTRACT_FROM_BOTH_SIDES) || s.equals(DIVIDE_BOTH_SIDES) || s.equals(MULTIPLY_BOTH_SIDES)) {
            String message = "";
            if (s.equals(ADD_TO_BOTH_SIDES)) {
                o = new Operator.Addition();
                message = "Add to both sides";
            } else if (s.equals(SUBTRACT_FROM_BOTH_SIDES)) {
                o = new Operator.Subtraction();
                message = "Subtract from both sides";
            } else if (s.equals(DIVIDE_BOTH_SIDES)) {
                o = new Operator.Division();
                message = "Divide both sides by";
            } else if (s.equals(MULTIPLY_BOTH_SIDES)) {
                o = new Operator.Multiplication();
                message = "Multiply both sides by";
            }
            Node newNode = this.getParentPage().getParentDoc().getDocViewerPanel().getNotebook().getNotebookPanel().getExpressionFromUser(message);
            if (newNode == null) {
                setActionCancelled(true);
                return;
            }
            ex = ex.applyOpToBothSides(o, newNode, true);
            try {
                getListWithName(STEPS).addValueWithString(ex.toStringRepresentation());
            } catch (AttributeException e) {
                JOptionPane.showMessageDialog(null, ERROR_WITH_EXPRESSION, WARNING, JOptionPane.WARNING_MESSAGE);
            }
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, "Error with operation.", ERROR, JOptionPane.ERROR_MESSAGE);
    }
}
Also used : Operator(expression.Operator) Multiplication(expression.Operator.Multiplication) Node(expression.Node) StringAttribute(doc.attributes.StringAttribute) NodeException(expression.NodeException) AttributeException(doc.attributes.AttributeException) AttributeException(doc.attributes.AttributeException) NodeException(expression.NodeException) Expression(expression.Expression) Vector(java.util.Vector)

Aggregations

Expression (expression.Expression)2 Node (expression.Node)2 NodeException (expression.NodeException)2 Operator (expression.Operator)2 AttributeException (doc.attributes.AttributeException)1 StringAttribute (doc.attributes.StringAttribute)1 Number (expression.Number)1 Multiplication (expression.Operator.Multiplication)1 Vector (java.util.Vector)1