Search in sources :

Example 1 with NodeException

use of expression.NodeException in project OpenNotebook by jaltekruse.

the class ExUtil method generateRandomExpressions.

public static String[] generateRandomExpressions() {
    String[] ops = { ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION };
    String[] vars = { "x", "y", "z", "a", "b", "c", "d", "s", "t", "w", "v", "m", "n", "j", "k", "l" };
    int numTrials = 10;
    String[] expressions = new String[numTrials];
    int numZeros = 0;
    int numNegatives = 0;
    int minNumOps = 2;
    int maxNumOps = 5;
    int maxAbsVal = 20;
    int minGeneratedVal = 1;
    int maxGeneratedVal = 10;
    int numOps;
    for (int j = 0; j < numTrials; j++) {
        numOps = randomInt(minNumOps, maxNumOps, false);
        Node n = randomExpression(ops, vars, numOps, maxAbsVal, minGeneratedVal, maxGeneratedVal, true, false, false, true);
        try {
            expressions[j] = n.toStringRepresentation();
            if (((Number) n.numericSimplify()).getValue() == 0) {
                numZeros++;
            }
            if (((Number) n.numericSimplify()).getValue() < 0) {
                numNegatives++;
            }
        } catch (NodeException e) {
            e.printStackTrace();
        }
    }
    //		System.out.println(numNegatives + " out of " + numTrials + " trials evaluated to a negative.");
    return expressions;
}
Also used : Node(expression.Node) NodeException(expression.NodeException)

Example 2 with NodeException

use of expression.NodeException 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 3 with NodeException

use of expression.NodeException in project OpenNotebook by jaltekruse.

the class ExpressionGenerator method generateProblem.

public GeneratedProblem generateProblem(int difficulty) {
    GeneratedProblem newProblem = new GeneratedProblem();
    ExpressionObject expressionObj = new ExpressionObject();
    try {
        newProblem.setDifficulty(difficulty);
        newProblem.getListWithName(GeneratedProblem.GEN_LIST).getValues().clear();
        ((ListAttribute<UUIDAttribute>) newProblem.getListWithName(GeneratedProblem.GEN_LIST)).addValueWithString(getProblemID().toString());
        Node[] n = generateExpression(difficulty);
        expressionObj.setExpression(n[0].toStringRepresentation());
        expressionObj.addCorrectAnswer(n[1].toStringRepresentation());
    } catch (AttributeException e) {
        e.printStackTrace();
    } catch (NodeException e) {
        e.printStackTrace();
    }
    getProblemHoldingDocument().getDocViewerPanel().drawObjectInBackground(expressionObj);
    expressionObj.setParentContainer(newProblem.getParentContainer());
    newProblem.addObjectFromPage(expressionObj);
    return newProblem;
}
Also used : ExpressionObject(doc.mathobjects.ExpressionObject) Node(expression.Node) GeneratedProblem(doc.mathobjects.GeneratedProblem) NodeException(expression.NodeException) AttributeException(doc.attributes.AttributeException) ListAttribute(doc.attributes.ListAttribute)

Example 4 with NodeException

use of expression.NodeException in project OpenNotebook by jaltekruse.

the class VariableValueInsertionProblem method generateProblem.

public GeneratedProblem generateProblem(int difficulty) {
    Grouping newProblem = new Grouping(getParentContainer(), getxPos(), getyPos() + getHeight() + bufferSpace, getWidth(), getHeight());
    String s;
    Node n = null;
    Vector<String> varNames = new Vector<>();
    Vector<Number> varVals = new Vector<>();
    for (StringAttribute strAtt : (Vector<StringAttribute>) getScripts().getValues()) {
        s = strAtt.getValue();
        if (s == null || s.equals("")) {
            continue;
        }
        try {
            n = Node.parseNode(s);
            //sub in variables already assigned in previous scripts
            for (int i = 0; i < varNames.size(); i++) {
                n = n.replace(varNames.get(i), varVals.get(i));
            }
            n = n.numericSimplify();
            if (n instanceof Expression) {
                Expression ex = (Expression) n;
                if (ex.getOperator() instanceof Operator.Equals) {
                    if (ex.getChild(0) instanceof Identifier) {
                        Identifier var = (Identifier) ex.getChild(0);
                        if (ex.getChild(1) instanceof Number) {
                            varNames.add(var.getIdentifier());
                            // this causes a lot of unneeded parenthesis
                            // but without it, you cannot sub in a value
                            // where there is an implied parenthesis
                            // ex.getChild(1).setDisplayParentheses(true);
                            varVals.add((Number) ex.getChild(1));
                        }
                    }
                }
            }
        } catch (NodeException e) {
            JOptionPane.showMessageDialog(null, "Error generating a problem, check scripts.", ERROR, JOptionPane.ERROR_MESSAGE);
        }
    }
    MathObject newObj = null;
    for (MathObject mObj : getObjects()) {
        newObj = mObj.clone();
        for (int i = 0; i < varNames.size(); i++) {
            newObj = subInVal(varNames.get(i), varVals.get(i), newObj);
        }
        //shift object down so it doesn't overlap the current problem
        newObj.setyPos(newObj.getyPos() + getHeight() + bufferSpace);
        //this line sets the bounds to the actual space it takes to render them
        if (getParentContainer() != null) {
            // if this problem formula is in the background storage for a document
            getParentDoc().getDocViewerPanel().drawObjectInBackground(newObj);
        } else {
            // if this problem formula is actually on a document
            getProblemHoldingDocument().getDocViewerPanel().drawObjectInBackground(newObj);
        }
        newObj.setParentContainer(newProblem.getParentContainer());
        newProblem.addObjectFromPage(newObj);
    }
    return new GeneratedProblem(newProblem.getParentContainer(), this.getProblemID(), newProblem);
}
Also used : Node(expression.Node) StringAttribute(doc.attributes.StringAttribute) NodeException(expression.NodeException) Identifier(expression.Identifier) Number(expression.Number) Expression(expression.Expression) Vector(java.util.Vector)

Example 5 with NodeException

use of expression.NodeException in project OpenNotebook by jaltekruse.

the class ExpressionObjectGUI method drawInteractiveComponents.

public void drawInteractiveComponents(ExpressionObject object, Graphics g, Point pageOrigin, float zoomLevel) {
    g.setColor(Color.BLACK);
    ScaledSizeAndPosition sap = getSizeAndPositionWithFontSize(object, pageOrigin, zoomLevel, object.getFontSize());
    int outerBufferSpace = (int) (5 * zoomLevel);
    int stepBufferSpace = (int) (10 * zoomLevel);
    Graphics2D g2d = (Graphics2D) g;
    RootNodeGraphic rootGraphic;
    if (!(object.getExpression().equals("") && object.allAnswersBlank())) {
        // if any of the steps cannot be rendered, this information will allow
        // space to be left for printing an error message in its place
        g.setFont(g.getFont().deriveFont(sap.getFontSize()));
        int errorMessageHeight = g.getFontMetrics().getHeight();
        int errorMessageWidth = g.getFontMetrics().stringWidth(EX_ERROR);
        Node n = null;
        int totalHeight = 0;
        int greatestWidth = 0;
        Vector<Integer> indeciesInError = new Vector<>();
        Vector<Integer> yPosOfSteps = new Vector<>();
        int currentIndex = 0;
        Vector<RootNodeGraphic> expressions = new Vector<>();
        // add the expression
        try {
            n = parser.parseNode(object.getExpression());
            boolean objectChanged = currentSelectionStep || current == null || currentExObj != object || !object.getDecimalRectangleBounds().equals(currentPosSize) || !currentEx.equals(object.getExpression());
            if (objectChanged) {
                rootGraphic = new RootNodeGraphic(n);
                rootGraphic.generateExpressionGraphic(g, outerBufferSpace + sap.getxOrigin(), outerBufferSpace + sap.getyOrigin(), (int) sap.getFontSize(), zoomLevel);
            } else if (currentZoom != zoomLevel) {
                rootGraphic = current;
                rootGraphic.requestSize(g, outerBufferSpace + sap.getxOrigin(), outerBufferSpace + sap.getyOrigin(), (int) sap.getFontSize(), zoomLevel);
            } else {
                rootGraphic = current;
                rootGraphic.setGraphics((Graphics2D) g);
            }
            // keep these next three lines in the try catch block, they should only happen
            // if they line above does not throw an error
            expressions.add(rootGraphic);
            yPosOfSteps.add(rootGraphic.yPos);
            totalHeight = rootGraphic.getHeight();
            greatestWidth = rootGraphic.getWidth();
            currentSelectionStep = false;
            current = rootGraphic;
            currentExObj = object;
            currentEx = object.getExpression();
            currentPosSize = object.getDecimalRectangleBounds();
            currentZoom = zoomLevel;
        } catch (Exception e) {
            indeciesInError.add(currentIndex);
            yPosOfSteps.add(outerBufferSpace + sap.getyOrigin());
            expressions.add(null);
            totalHeight += errorMessageHeight;
            greatestWidth = errorMessageWidth;
        }
        Vector<StringAttribute> steps = (Vector<StringAttribute>) object.getListWithName(ExpressionObject.STEPS).getValues();
        // TODO - confirm if this works with multiple correct answers
        for (StringAttribute strAtt : object.getCorrectAnswers()) {
            if (!strAtt.getValue().equals("")) {
                steps.add(strAtt);
            }
        }
        // add the steps to the list of expressions to render
        String s;
        int i = 0;
        for (StringAttribute mAtt : steps) {
            s = mAtt.getValue();
            currentIndex++;
            totalHeight += stepBufferSpace;
            try {
                n = parser.parseNode(s);
                rootGraphic = new RootNodeGraphic(n);
                //                    current = rootGraphic;
                rootGraphic.generateExpressionGraphic(g, sap.getxOrigin() + outerBufferSpace, outerBufferSpace + sap.getyOrigin() + totalHeight, (int) sap.getFontSize(), zoomLevel);
                expressions.add(rootGraphic);
                yPosOfSteps.add(rootGraphic.yPos);
                if (rootGraphic.getWidth() > greatestWidth) {
                    greatestWidth = rootGraphic.getWidth();
                }
                totalHeight += rootGraphic.getHeight();
                i++;
            } catch (Exception e) {
                indeciesInError.add(currentIndex);
                totalHeight += errorMessageHeight;
                if (errorMessageWidth > greatestWidth) {
                    greatestWidth = errorMessageWidth;
                }
                yPosOfSteps.add(outerBufferSpace + sap.getyOrigin() + totalHeight);
            }
        }
        // remove the correct answers, so they are not permanently added as steps
        steps.removeAll(object.getCorrectAnswers());
        if (object.getColor() != null) {
            g.setColor(object.getColor());
        } else {
            g.setColor(Color.white);
        }
        g.fillRect(sap.getxOrigin(), sap.getyOrigin(), greatestWidth + 2 * outerBufferSpace, totalHeight + 2 * outerBufferSpace);
        g.setColor(Color.BLACK);
        int index = 0;
        int numberOfSteps = steps.size() + 1;
        for (RootNodeGraphic r : expressions) {
            try {
                if (indeciesInError.contains(index)) {
                    g.setFont(g.getFont().deriveFont(sap.getFontSize()));
                    g.setColor(Color.RED);
                    g.drawString(EX_ERROR, sap.getxOrigin() + outerBufferSpace, yPosOfSteps.get(index) + errorMessageHeight);
                    g.setColor(Color.BLACK);
                    index++;
                    continue;
                } else {
                    if (index >= numberOfSteps) {
                        // draw the answers with a highlight
                        g.setColor(new Color(180, 255, 100));
                        g.fillRect(r.xPos - 4, r.yPos - 4, r.getWidth() + 8, r.getHeight() + 8);
                        g.setColor(Color.BLACK);
                    }
                    if (index != 0)
                        r.setCursor(new Cursor(null, 0));
                    r.draw();
                }
            } catch (NodeException e) {
                e.printStackTrace();
                g.setFont(g.getFont().deriveFont(sap.getFontSize()));
                g.setColor(Color.RED);
                g.drawString(EX_ERROR, r.xPos, r.yPos + errorMessageHeight);
            }
            index++;
        }
        if (greatestWidth > 0 && totalHeight > 0) {
            object.setWidth((int) ((greatestWidth + 2 * outerBufferSpace) / zoomLevel));
            object.setHeight((int) ((totalHeight + 2 * outerBufferSpace) / zoomLevel));
        }
    } else {
        g2d.setStroke(new BasicStroke());
        g2d.setPaint(Color.BLACK);
        g.drawRect(sap.getxOrigin(), sap.getyOrigin(), sap.getWidth(), sap.getHeight());
    }
}
Also used : BasicStroke(java.awt.BasicStroke) Node(expression.Node) Color(java.awt.Color) StringAttribute(doc.attributes.StringAttribute) NodeException(expression.NodeException) RootNodeGraphic(math_rendering.RootNodeGraphic) Cursor(math_rendering.Cursor) Point(java.awt.Point) NodeException(expression.NodeException) Graphics2D(java.awt.Graphics2D) Vector(java.util.Vector)

Aggregations

NodeException (expression.NodeException)10 Node (expression.Node)7 StringAttribute (doc.attributes.StringAttribute)4 Expression (expression.Expression)4 Number (expression.Number)3 Operator (expression.Operator)3 Vector (java.util.Vector)3 AttributeException (doc.attributes.AttributeException)2 Identifier (expression.Identifier)2 BasicStroke (java.awt.BasicStroke)2 Graphics2D (java.awt.Graphics2D)2 Point (java.awt.Point)2 GridPoint (doc.GridPoint)1 DoubleAttribute (doc.attributes.DoubleAttribute)1 GridPointAttribute (doc.attributes.GridPointAttribute)1 ListAttribute (doc.attributes.ListAttribute)1 ExpressionObject (doc.mathobjects.ExpressionObject)1 GeneratedProblem (doc.mathobjects.GeneratedProblem)1 GraphedCartFunction (doc_gui.graph.GraphedCartFunction)1 Multiplication (expression.Operator.Multiplication)1