use of expression.Number in project OpenNotebook by jaltekruse.
the class BasicDistributiveProperty method generateExpression.
@Override
protected Node[] generateExpression(int difficulty) throws NodeException {
Node[] n = new Node[2];
if (difficulty == ProblemGenerator.EASY) {
double bigNum = ExUtil.randomInt(2, 10, true) * 10, smallNum = ExUtil.randomInt(1, 5, true), multiplier = ExUtil.randomInt(2, 9, true);
if (ExUtil.randomBoolean()) {
n[0] = new Expression(new Operator.Addition(), new Number(bigNum), new Number(smallNum));
} else {
n[0] = new Expression(new Operator.Subtraction(), new Number(bigNum), new Number(smallNum));
}
n[0].setDisplayParentheses(true);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Multiplication(), n[0], new Number(multiplier));
} else if (difficulty == ProblemGenerator.MEDIUM) {
double multiplier = ExUtil.randomInt(2, 9, true);
n[0] = ExUtil.randomLinearExpression(ExUtil.randomVarName(), 1, 8);
n[0].setDisplayParentheses(true);
n[0].setDisplayParentheses(true);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Multiplication(), n[0], new Number(multiplier));
} else {
double multiplier = ExUtil.randomInt(2, 14, true);
String varName = ExUtil.randomVarName();
n[0] = ExUtil.randomLinearExpression(varName, 1, 12);
Node newNode = null;
if (ExUtil.randomBoolean())
newNode = new Number(ExUtil.randomInt(2, 15, true));
else
newNode = ExUtil.randomTerm(1, varName, 2, 9);
if (ExUtil.randomBoolean()) {
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Addition(), n[0], newNode);
} else {
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Subtraction(), n[0], newNode);
}
n[0].setDisplayParentheses(true);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Multiplication(), n[0], new Number(multiplier));
}
n[1] = n[0].cloneNode().smartNumericSimplify().standardFormat();
return n;
}
use of expression.Number 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);
}
use of expression.Number in project OpenNotebook by jaltekruse.
the class PropertyOfOppositiesWithVariables method generateExpression.
@Override
protected Node[] generateExpression(int difficulty) throws NodeException {
Node[] n = new Node[2];
if (difficulty == ProblemGenerator.EASY) {
double num = ExUtil.randomInt(2, 9, true);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Addition(), new Number(num), ExUtil.randomTerm(1, ExUtil.randomVarName(), 3, 12), new Number(-1 * num), new Number(ExUtil.randomInt(2, 9, true)));
} else if (difficulty == ProblemGenerator.MEDIUM) {
double[] numPair = ExUtil.pairOfCleanAddingNumbers(100);
Node var = ExUtil.randomTerm(1, ExUtil.randomVarName(), 3, 12);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Addition(), new Number(ExUtil.randomInt(2, 9, true)), var, new Number(ExUtil.randomInt(2, 9, true)), new Expression(new Operator.Negation(), var));
} else if (difficulty == ProblemGenerator.HARD) {
double[] numPair2 = ExUtil.pairOfCleanAddingNumbers(200);
Vector<String> varNames = ExUtil.randomUniqueVarNames(2);
Node var = ExUtil.randomTerm(1, ExUtil.randomVarName(), 3, 12);
n[0] = ExUtil.randomlyStaggerOperation(new Operator.Addition(), new Number(ExUtil.randomInt(2, 9, true)), ExUtil.randomTerm(1, varNames.get(1), 3, 12), new Number(numPair2[0]), var, new Number(numPair2[0]), new Expression(new Operator.Negation(), var));
}
n[0] = ExUtil.randomlyAddParenthesis((Expression) n[0], 0, 3);
n[1] = n[0].collectLikeTerms().smartNumericSimplify().standardFormat();
return n;
}
use of expression.Number 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);
}
use of expression.Number in project OpenNotebook by jaltekruse.
the class AdditionPropertyOfEquality method generateExpression.
@Override
protected Node[] generateExpression(int difficulty) throws NodeException {
Node[] n = new Node[2];
if (difficulty == ProblemGenerator.EASY) {
double[] numPair = ExUtil.pairOfCleanAddingNumbers(100);
if (ExUtil.randomBoolean()) {
numPair[1] = -1 * numPair[1];
}
n[1] = new Expression(new Operator.Equals(), ExUtil.randomVar(), new Number(numPair[0]));
n[0] = ((Expression) n[1]).applyOpToBothSides(new Operator.Addition(), new Number(numPair[1]), true);
n[0] = n[0].smartNumericSimplify();
} else if (difficulty == ProblemGenerator.MEDIUM) {
n[1] = new Expression(new Operator.Equals(), ExUtil.randomVar(), new Number(ExUtil.randomInt(5, 30, true)));
n[0] = ((Expression) n[1]).applyOpToBothSides(new Operator.Addition(), new Number(ExUtil.randomInt(5, 30, true)), true);
n[0] = n[0].smartNumericSimplify();
} else if (difficulty == ProblemGenerator.HARD) {
n[1] = new Expression(new Operator.Equals(), ExUtil.randomVar(), new Number(ExUtil.randomInt(5, 30, true)));
Expression sumNode = ExUtil.randomAdditionOrSubtraction(5, 30);
Node sum = sumNode.numericSimplify();
n[0] = n[1].cloneNode();
Node newLeft = null, newRight = null;
if (ExUtil.randomBoolean()) {
newLeft = ((Expression) n[0]).getChild(0).addNodeToExpression(sumNode);
newRight = ((Expression) n[0]).getChild(1).addNodeToExpression(sum);
} else {
newLeft = ((Expression) n[0]).getChild(0).addNodeToExpression(sum);
newRight = ((Expression) n[0]).getChild(1).addNodeToExpression(sumNode);
}
n[0] = new Expression(new Operator.Equals(), newLeft, newRight);
}
n[0] = ExUtil.flipSides((Expression) n[0]);
return n;
}
Aggregations