├── .github ├── FUNDING.yml └── workflows │ └── maven.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── java │ ├── interfaces │ ├── Computable.java │ ├── Decodeable.java │ ├── Doable.java │ ├── Encodeable.java │ ├── PollCapable.java │ ├── Savable.java │ └── Solvable.java │ ├── logic │ ├── BASE_MODE.java │ ├── CalcLogic.java │ ├── DRG_MODE.java │ ├── OperatingSystem.java │ ├── POWER_MODE.java │ ├── TRIG_MODE.java │ └── USE_MODE.java │ ├── math │ ├── BigDecimalNthRootCalculation.java │ ├── Line.java │ ├── Main.java │ ├── Maths.java │ ├── Point.java │ ├── Size.java │ ├── complex │ │ ├── ComplexNumber.java │ │ └── ComplexState.java │ ├── differentialcalculus │ │ ├── CodeGenerator.java │ │ ├── Derivative.java │ │ ├── DerivativeScanner.java │ │ ├── DerivativeStructureBuilder.java │ │ ├── Differentiable.java │ │ ├── DifferentiableManager.java │ │ ├── ExpressionSimplifier.java │ │ ├── Formula.java │ │ ├── FormulaManager.java │ │ ├── Methods.java │ │ ├── Parser.java │ │ ├── SemanticAnalyzer.java │ │ ├── Test.java │ │ └── Utilities.java │ ├── fractions │ │ ├── FractionalNumber.java │ │ └── PrimeNumber.java │ ├── matrix │ │ ├── MatrixVariableManager.java │ │ ├── equationParser │ │ │ └── LinearSystemParser.java │ │ ├── expressParser │ │ │ ├── HalfDet.java │ │ │ ├── MAdditionOperator.java │ │ │ ├── MAssignmentOperator.java │ │ │ ├── MBinaryOperator.java │ │ │ ├── MBracket.java │ │ │ ├── MLogic.java │ │ │ ├── MNumber.java │ │ │ ├── MOperator.java │ │ │ ├── MSet.java │ │ │ ├── MSubtractionOperator.java │ │ │ ├── MUnaryPostOperator.java │ │ │ ├── Matrix.java │ │ │ ├── MatrixBinaryOperator.java │ │ │ ├── MatrixExpressionScanner.java │ │ │ ├── MatrixFunction.java │ │ │ ├── MatrixOperator.java │ │ │ ├── MatrixValueParser.java │ │ │ ├── MatrixVariable.java │ │ │ ├── MmathScanner.java │ │ │ ├── MmultiplicationOperator.java │ │ │ └── PrecisionMatrix.java │ │ └── util │ │ │ └── LinearSystemGenerator.java │ ├── numericalmethods │ │ ├── Fmath.java │ │ ├── FunctionExpander.java │ │ ├── Integration.java │ │ ├── NumericalDerivative.java │ │ ├── NumericalIntegral.java │ │ └── RootFinder.java │ ├── otherBaseParser │ │ └── BaseNFunction.java │ ├── quadratic │ │ ├── QuadraticExpressionParser.java │ │ ├── QuadraticSolver.java │ │ └── Quadratic_Equation.java │ └── tartaglia │ │ ├── TartagliaExpressionParser.java │ │ ├── TartagliaSolver.java │ │ └── Tartaglia_Equation.java │ ├── parser │ ├── AdditionOperator.java │ ├── AntiLogToAnyBase.java │ ├── AssignmentOperator.java │ ├── BinaryOperator.java │ ├── Bracket.java │ ├── CombinationOperator.java │ ├── CustomScanner.java │ ├── DataSetFormatter.java │ ├── DivisionOperator.java │ ├── ExpandingExpression.java │ ├── Function.java │ ├── GenericBracket.java │ ├── LISTS.java │ ├── ListReturningStatsOperator.java │ ├── LogOrAntiLogToAnyBase.java │ ├── LogToAnyBase.java │ ├── Logic.java │ ├── LogicOperator.java │ ├── LogicalExpression.java │ ├── MathExpression.java │ ├── MathScanner.java │ ├── MultiplicationOperator.java │ ├── Number.java │ ├── NumberReturningStatsOperator.java │ ├── Operator.java │ ├── Parser_Result.java │ ├── PermutationOperator.java │ ├── PolynomialExpression.java │ ├── PowerOperator.java │ ├── Precedence.java │ ├── RemainderOperator.java │ ├── STRING.java │ ├── Set.java │ ├── SubtractionOperator.java │ ├── TYPE.java │ ├── UnaryPostOperator.java │ ├── UnaryPreOperator.java │ ├── Validatable.java │ ├── Variable.java │ ├── cmd │ │ └── ParserCmd.java │ ├── expanding │ │ └── ExpandingExpressionParser.java │ ├── logical │ │ ├── AbstractSplittingParser.java │ │ ├── AlgebraExpressionParser.java │ │ ├── ComparingExpressionParser.java │ │ ├── ExpressionLogger.java │ │ ├── LogicalExpressionMemberFactory.java │ │ └── LogicalExpressionParser.java │ ├── methods │ │ ├── BasicNumericalMethod.java │ │ ├── Declarations.java │ │ ├── Help.java │ │ ├── Method.java │ │ └── ext │ │ │ ├── Abs.java │ │ │ ├── Avg.java │ │ │ ├── AvgN.java │ │ │ ├── CeilFloor.java │ │ │ ├── Count.java │ │ │ ├── Echo.java │ │ │ ├── Geom.java │ │ │ ├── GeomN.java │ │ │ ├── Gsum.java │ │ │ ├── Lengths.java │ │ │ ├── Rounding.java │ │ │ ├── Sum.java │ │ │ └── Utils.java │ └── package-info.java │ └── util │ ├── Dimension.java │ ├── ErrorLog.java │ ├── Formulae.java │ ├── FormulaeManager.java │ ├── FunctionManager.java │ ├── GenerateCharString.java │ ├── HistoryManager.java │ ├── Log.java │ ├── MathExpressionManager.java │ ├── MatrixFormatException.java │ ├── MatrixFunctionManager.java │ ├── Mode.java │ ├── Serializer.java │ ├── Settings.java │ ├── SimplePoint.java │ ├── Time.java │ ├── Utils.java │ ├── VariableGenerator.java │ ├── VariableManager.java │ ├── help │ └── Topic.java │ └── io │ ├── FunctionsBackup.java │ ├── TextFileReader.java │ ├── TextFileWriter.java │ └── VariableBackup.java └── test └── java ├── math ├── BigDecimalNthRootCalculationTest.java └── MainTest.java └── parser ├── LogicalExpressionTest.java ├── MathExpressionTest.java ├── SetTest.java ├── expanding ├── ExpandingExpressionParserTest.java └── ExpandingExpressionParserWithReplacableLogicTest.java ├── logical ├── AlgebraExpressionParserTest.java ├── ComparingExpressionParserTest.java ├── LogicalExpressionFactoryTest.java ├── LogicalExpressionParserTest.java └── PrintingExpressionLogger.java └── methods ├── DeclarationsTest.java ├── ProdTest.java └── ext ├── AbsTest.java ├── AvgNTest.java ├── FloorCeilTests.java ├── GeomNTest.java ├── GsumAvgGeomCountTest.java ├── LengthsTest.java ├── RoundingTests.java ├── SinTest.java ├── SumTest.java └── UtilsTest.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: gbenroscience 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.github/workflows/maven.yaml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | os: [ubuntu-latest, windows-latest] 19 | java-version: [ 8, 11, 17 ] 20 | fail-fast: false 21 | 22 | name: ${{ matrix.os }} - Java ${{ matrix.java-version }} - Maven 23 | steps: 24 | - name: Checkout ParserNG repo 25 | uses: actions/checkout@v2 26 | 27 | - name: Set up JDK ${{ matrix.java-version }} 28 | uses: actions/setup-java@v2 29 | with: 30 | java-version: ${{ matrix.java-version }} 31 | distribution: 'adopt' 32 | - name: Set up Maven 33 | uses: stCarolas/setup-maven@v4.4 34 | with: 35 | maven-version: 3.8.2 36 | 37 | - name: Build ParserNG with Maven 38 | run: mvn "-Dgpg.skip" "--batch-mode" "--update-snapshots" "clean" "install" 39 | 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | parser-ng.iml 3 | target 4 | mvn-keys 5 | .DS_Store 6 | src/.DS_Store 7 | src/main/.DS_Store 8 | src/main/java/.DS_Store 9 | 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | In the interest of fostering an open and welcoming environment, we as 7 | contributors and maintainers pledge to making participation in our project and 8 | our community a harassment-free experience for everyone, regardless of age, body 9 | size, disability, ethnicity, sex characteristics, gender identity and expression, 10 | level of experience, education, socio-economic status, nationality, personal 11 | appearance, race, religion, or sexual identity and orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to creating a positive environment 16 | include: 17 | 18 | * Using welcoming and inclusive language 19 | * Being respectful of differing viewpoints and experiences 20 | * Gracefully accepting constructive criticism 21 | * Focusing on what is best for the community 22 | * Showing empathy towards other community members 23 | 24 | Examples of unacceptable behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual attention or 27 | advances 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | * Public or private harassment 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or 42 | reject comments, commits, code, wiki edits, issues, and other contributions 43 | that are not aligned to this Code of Conduct, or to ban temporarily or 44 | permanently any contributor for other behaviors that they deem inappropriate, 45 | threatening, offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies both within project spaces and in public spaces 50 | when an individual is representing the project or its community. Examples of 51 | representing a project or community include using an official project e-mail 52 | address, posting via an official social media account, or acting as an appointed 53 | representative at an online or offline event. Representation of a project may be 54 | further defined and clarified by project maintainers. 55 | 56 | ## Enforcement 57 | 58 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 59 | reported by contacting the project team at gbenroscience@yahoo.com. All 60 | complaints will be reviewed and investigated and will result in a response that 61 | is deemed necessary and appropriate to the circumstances. The project team is 62 | obligated to maintain confidentiality with regard to the reporter of an incident. 63 | Further details of specific enforcement policies may be posted separately. 64 | 65 | Project maintainers who do not follow or enforce the Code of Conduct in good 66 | faith may face temporary or permanent repercussions as determined by other 67 | members of the project's leadership. 68 | 69 | ## Attribution 70 | 71 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 72 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 73 | 74 | [homepage]: https://www.contributor-covenant.org 75 | 76 | For answers to common questions about this code of conduct, see 77 | https://www.contributor-covenant.org/faq 78 | 79 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Computable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | public interface Computable { 4 | 5 | 6 | 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Decodeable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | 4 | 5 | /** 6 | * 7 | * @author JIBOYE Oluwagbemiro Olaoluwa on 7/9/2017. 8 | */ 9 | public interface Decodeable { 10 | 11 | public Decodeable parseJson(String json); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Doable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | /** 4 | * Models something that can be performed. 5 | */ 6 | public interface Doable { 7 | 8 | public void eval(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Encodeable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | 4 | 5 | /** 6 | * 7 | * @author gbemirojiboye 8 | */ 9 | public interface Encodeable { 10 | 11 | 12 | public String stringify(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/interfaces/PollCapable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | /** 4 | * Created by Imaxinacion on 2/13/2018. 5 | */ 6 | 7 | public interface PollCapable { 8 | 9 | 10 | public void startPolling(); 11 | 12 | public void stopPolling(); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Savable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 GBEMIRO JIBOYE . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package interfaces; 17 | 18 | import java.io.Serializable; 19 | 20 | /** 21 | * 22 | * @author GBEMIRO JIBOYE 23 | */ 24 | public interface Savable extends Serializable{ 25 | 26 | public String serialize(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/interfaces/Solvable.java: -------------------------------------------------------------------------------- 1 | package interfaces; 2 | 3 | public interface Solvable { 4 | 5 | String solve(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/logic/BASE_MODE.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | public enum BASE_MODE { 4 | 5 | BIN, OCT, DEC; 6 | 7 | /** 8 | * @return the number base from the {@link CalcLogic#baseMode value} 9 | */ 10 | public final int getBase() { 11 | switch (this) { 12 | case BIN: 13 | return 2; 14 | case OCT: 15 | return 8; 16 | case DEC: 17 | return 10; 18 | default: 19 | return 10; 20 | 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/logic/CalcLogic.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | import interfaces.Savable; 4 | 5 | import java.util.ArrayList; 6 | 7 | import util.FormulaeManager; 8 | import util.HistoryManager; 9 | import util.MathExpressionManager; 10 | import util.Mode; 11 | import util.Serializer; 12 | import util.Settings; 13 | 14 | 15 | public class CalcLogic implements Savable{ 16 | 17 | /** 18 | * Stores the commands used on the CommandLineActivity 19 | */ 20 | private final ArrayList commandHistory = new ArrayList<>(); 21 | 22 | private final HistoryManager histMan = new HistoryManager(); 23 | 24 | private final MathExpressionManager funcMan = new MathExpressionManager(); 25 | 26 | private final FormulaeManager formMan = new FormulaeManager(); 27 | 28 | private final Mode mode = Mode.CALCULATOR;// The usage MODE of this tool..either via the command line or in the calculator MODE. 29 | 30 | /** 31 | * When true, the calculator is in a state wherein the last action it performed 32 | * was the evaluation of an expression. 33 | */ 34 | private boolean justEvaluated = false; 35 | 36 | 37 | private Settings settings = new Settings(); 38 | 39 | private OperatingSystem manager; 40 | private boolean vibrateOn = true; 41 | private BASE_MODE baseMode = BASE_MODE.DEC; 42 | 43 | private TRIG_MODE trigMode = TRIG_MODE.NORMAL; 44 | 45 | 46 | private DRG_MODE drgMode = DRG_MODE.DEG; 47 | private POWER_MODE powerMode = POWER_MODE.ON; 48 | 49 | private USE_MODE useMode = USE_MODE.NORMAL; 50 | 51 | 52 | private boolean running = true; 53 | 54 | 55 | 56 | 57 | public CalcLogic(){ 58 | 59 | } 60 | 61 | public void setRunning(boolean running) { 62 | this.running = running; 63 | } 64 | 65 | public boolean isRunning() { 66 | return running; 67 | } 68 | 69 | 70 | 71 | public ArrayList getCommandHistory() { 72 | return commandHistory; 73 | } 74 | 75 | 76 | 77 | public HistoryManager getHistMan() { 78 | return histMan; 79 | } 80 | 81 | public MathExpressionManager getFuncMan() { 82 | return funcMan; 83 | } 84 | 85 | public FormulaeManager getFormMan() { 86 | return formMan; 87 | } 88 | 89 | public Mode getMode() { 90 | return mode; 91 | } 92 | 93 | public void setJustEvaluated(boolean justEvaluated) { 94 | this.justEvaluated = justEvaluated; 95 | } 96 | 97 | public boolean isJustEvaluated() { 98 | return this.justEvaluated; 99 | } 100 | 101 | public Settings getSettings() { 102 | return settings; 103 | } 104 | 105 | public void setSettings(Settings settings) { 106 | this.settings = settings; 107 | } 108 | 109 | public void setManager(OperatingSystem manager) { 110 | this.manager = manager; 111 | } 112 | 113 | public OperatingSystem getManager() { 114 | return this.manager; 115 | } 116 | 117 | public void setVibrateOn(boolean vibrateOn) { 118 | this.vibrateOn = vibrateOn; 119 | } 120 | 121 | public boolean isVibrateOn() { 122 | return vibrateOn; 123 | } 124 | 125 | public void setBaseMode(BASE_MODE baseMode) { 126 | this.baseMode = baseMode; 127 | } 128 | 129 | public BASE_MODE getBaseMode() { 130 | return baseMode; 131 | } 132 | 133 | public int getBase(){ 134 | return baseMode.getBase(); 135 | } 136 | 137 | public void setTrigMode(TRIG_MODE trigMode) { 138 | this.trigMode = trigMode; 139 | } 140 | 141 | public TRIG_MODE getTrigMode() { 142 | return this.trigMode; 143 | } 144 | 145 | public void setDrgMode(DRG_MODE drgMode) { 146 | this.drgMode = drgMode; 147 | } 148 | 149 | public DRG_MODE getDrgMode() { 150 | return drgMode; 151 | } 152 | 153 | public void setPowerMode(POWER_MODE powerMode) { 154 | this.powerMode = powerMode; 155 | } 156 | 157 | public POWER_MODE getPowerMode() { 158 | return powerMode; 159 | } 160 | 161 | public void setUseMode(USE_MODE useMode) { 162 | this.useMode = useMode; 163 | } 164 | 165 | public USE_MODE getUseMode() { 166 | return useMode; 167 | } 168 | 169 | @Override 170 | public String serialize() { 171 | return Serializer.serialize(this); 172 | } 173 | 174 | 175 | public static CalcLogic parse(String enc) { 176 | return (CalcLogic) Serializer.deserialize(enc); 177 | } 178 | 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/logic/DRG_MODE.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | public enum DRG_MODE { 4 | 5 | DEG, RAD, GRAD; 6 | 7 | public static final String DEG_MODE_VARIABLE = "RADDEGDRAD_PNG"; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/logic/OperatingSystem.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | 4 | import java.util.ArrayList; 5 | 6 | import interfaces.Doable; 7 | import util.Log; 8 | 9 | /** 10 | * Objects of this class will control the running modes of the calculator. 11 | * And so enable the user to use a single button such as the equals button to act on many kinds of input. 12 | * e.g calculate,integrate,solve equations,store objects and so on. 13 | * This class will be involved with the different threads that may be spawned by the software in future. 14 | * @author GBEMIRO 15 | */ 16 | public class OperatingSystem { 17 | private Doable task;//task executor 18 | 19 | /** 20 | * 21 | * @return the Task object 22 | */ 23 | public Doable getTask() { 24 | return task; 25 | } 26 | /** 27 | * 28 | * @param task sets the Task object 29 | */ 30 | public void setTask(Doable task) { 31 | this.task = task; 32 | } 33 | 34 | 35 | /** 36 | * method responsible for recognizing commands entered into the command line or text field and executing them. 37 | * @param task the command to be executed. 38 | */ 39 | public void execute(CalcLogic calcLogic,final Doable task){ 40 | try{ 41 | if(calcLogic.getMode().isCalculator()){ 42 | task.eval(); 43 | }//end if 44 | else{ 45 | Log.e("Error", "Unrecognized Operation!"); 46 | } 47 | 48 | }//end try 49 | 50 | catch(NullPointerException nolian){ 51 | }//end catch 52 | catch(IndexOutOfBoundsException indexErr){ 53 | 54 | }//end catch 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | }//end method execute 64 | 65 | 66 | 67 | 68 | 69 | }//end class OperatingSystem -------------------------------------------------------------------------------- /src/main/java/logic/POWER_MODE.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | public enum POWER_MODE { 4 | ON, LOCK,OFF 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/logic/TRIG_MODE.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | public enum TRIG_MODE { 4 | 5 | /** 6 | * No shift or hyp 7 | */ 8 | NORMAL, 9 | /** 10 | * Shift pressed 11 | */ 12 | INVERSE, 13 | /** 14 | * Hyp pressed 15 | */ 16 | HYP, 17 | /** 18 | * Shift and hyp pressed. 19 | */ 20 | INVERSE_HYP 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/logic/USE_MODE.java: -------------------------------------------------------------------------------- 1 | package logic; 2 | 3 | public enum USE_MODE { 4 | NORMAL, SHIFT,ALPHABET, ALPHABET_SM 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/math/BigDecimalNthRootCalculation.java: -------------------------------------------------------------------------------- 1 | package math; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | /** 8 | * Based on https://stackoverflow.com/questions/22695654/computing-the-nth-root-of-p-using-bigdecimals 9 | */ 10 | public final class BigDecimalNthRootCalculation { 11 | 12 | private static MathContext default_mode = new MathContext(10, RoundingMode.HALF_DOWN); 13 | 14 | private BigDecimalNthRootCalculation() { 15 | } 16 | 17 | public static BigDecimal nthRoot(final int n, final BigDecimal a) { 18 | return nthRoot(n, a, default_mode); 19 | } 20 | 21 | public static BigDecimal nthRoot(final int n, final BigDecimal a, MathContext mc) { 22 | return nthRoot(n, a, BigDecimal.valueOf(0.1).movePointLeft(mc.getPrecision()), mc); 23 | } 24 | 25 | private static BigDecimal nthRoot(final int n, final BigDecimal a, final BigDecimal p, MathContext mc) { 26 | if (a.compareTo(BigDecimal.ZERO) < 0) { 27 | throw new IllegalArgumentException("nth root can only be calculated for positive numbers"); 28 | } 29 | if (a.equals(BigDecimal.ZERO)) { 30 | return BigDecimal.ZERO; 31 | } 32 | BigDecimal xPrev = a; 33 | BigDecimal x = a.divide(new BigDecimal(n), mc); 34 | while (x.subtract(xPrev).abs().compareTo(p) > 0) { 35 | xPrev = x; 36 | x = BigDecimal.valueOf(n - 1.0) 37 | .multiply(x) 38 | .add(a.divide(x.pow(n - 1), mc)) 39 | .divide(new BigDecimal(n), mc); 40 | } 41 | return x; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/main/java/math/Size.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math; 7 | 8 | import util.Dimension; 9 | 10 | 11 | /** 12 | * 13 | * @author GBEMIRO 14 | */ 15 | public class Size { 16 | public double width; 17 | public double height; 18 | /** 19 | * Creates a new object of this class. 20 | * @param width Stores the width. 21 | * @param height Stores the height. 22 | */ 23 | public Size(double width, double height) { 24 | this.width = width; 25 | this.height = height; 26 | }//end constructor 27 | /** 28 | * Creates a Size object from 29 | * a java.awt.Dimension object. 30 | * @param dim The givem Dimension object. 31 | */ 32 | public Size(Dimension dim){ 33 | this.width=dim.width; 34 | this.height=dim.height; 35 | } 36 | 37 | /** 38 | * Creates a new Size object from 39 | * a given Size object. 40 | * The created object is exactly similar in value to the 41 | * given one, but is not the same as that one.It is a sort of twin. 42 | * @param size The given Size object. 43 | */ 44 | public Size(Size size){ 45 | this.width=size.width; 46 | this.height=size.height; 47 | } 48 | 49 | /** 50 | * 51 | * @return The height 52 | */ 53 | public double getHeight() { 54 | return height; 55 | }//end method 56 | /** 57 | * 58 | * @param height sets the height 59 | */ 60 | public void setHeight(double height) { 61 | this.height = height; 62 | }//end method 63 | /** 64 | * 65 | * @return the width 66 | */ 67 | public double getWidth() { 68 | return width; 69 | }//end method 70 | /** 71 | * 72 | * @param width sets the height 73 | */ 74 | public void setWidth(double width) { 75 | this.width = width; 76 | }//end method 77 | /** 78 | * 79 | * @param width sets the width attribute of this object 80 | * @param height sets the height attribute of this object 81 | */ 82 | public void setSize(double width,double height){ 83 | this.width=width; 84 | this.height=height; 85 | }//end method 86 | 87 | /** 88 | * 89 | * @param size sets the size of object of this class 90 | * using an already known one. 91 | * 92 | */ 93 | public void setSize(Size size){ 94 | this.width=size.width; 95 | this.height=size.height; 96 | }//end method 97 | 98 | 99 | /** 100 | * 101 | * @return a new instance of Size containing 102 | * information about the size of this object 103 | */ 104 | public Size getSize(){ 105 | return new Size(width,height); 106 | }//end method 107 | 108 | /** 109 | * 110 | * @param scaleFactor the factor by which this Size object is to be scaled. 111 | */ 112 | public void scale(double scaleFactor){ 113 | setSize(scaleFactor*width, scaleFactor*height); 114 | } 115 | 116 | /** 117 | *returns a new Size object scaled to the value given by scaleFactor 118 | * @param scaleFactor the factor by which this Size object is to be scaled. 119 | */ 120 | public Size getScaledInstance(double scaleFactor){ 121 | return new Size(scaleFactor*width, scaleFactor*height); 122 | } 123 | /** 124 | *returns a new Size object scaled to the value given by scaleWidth 125 | * and scaleHeight, both being muktipliers for the width and the 126 | * height. 127 | * @param scaleWidth the factor by which the width of this Size object is to be scaled. 128 | * @param scaleHeight the factor by which the height of this Size object is to be scaled. 129 | */ 130 | public Size getScaledInstance(double scaleWidth,double scaleHeight){ 131 | return new Size(scaleWidth*width, scaleHeight*height); 132 | } 133 | 134 | 135 | @Override 136 | public String toString() { 137 | return "( width = "+width+ ",height = "+height+" )."; 138 | 139 | } 140 | 141 | /** 142 | * 143 | * @return the Dimension object 144 | * closest in value to this Size object. 145 | */ 146 | public Dimension getAWTDimension(){ 147 | return new Dimension((int)width,(int)height ); 148 | } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | }//end class 162 | -------------------------------------------------------------------------------- /src/main/java/math/complex/ComplexState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.complex; 7 | 8 | /** 9 | * 10 | * @author JIBOYE Oluwagbemiro Olaoluwa 11 | */ 12 | public enum ComplexState { 13 | CARTESIAN,POLAR,EXPONENTIAL; 14 | 15 | public boolean isCartesian(){ 16 | return this == CARTESIAN; 17 | } 18 | public boolean isPolar(){ 19 | return this == POLAR; 20 | } 21 | public boolean isExponential(){ 22 | return this == EXPONENTIAL; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/math/differentialcalculus/Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package math.differentialcalculus; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public class Test { 15 | 16 | 17 | 18 | public static void main(String[]args){ 19 | 20 | class Box{ 21 | int width; 22 | int height; 23 | 24 | public Box(int width, int height) { 25 | this.width = width; 26 | this.height = height; 27 | } 28 | 29 | public void setHeight(int height) { 30 | this.height = height; 31 | } 32 | 33 | public void setWidth(int width) { 34 | this.width = width; 35 | } 36 | 37 | public int getHeight() { 38 | return height; 39 | } 40 | 41 | public int getWidth() { 42 | return width; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "Box width = "+width+", height = "+height+" id = "+super.toString(); 48 | } 49 | 50 | 51 | 52 | } 53 | 54 | ArrayListboxes = new ArrayList(); 55 | 56 | boxes.add(new Box(2,3)); 57 | boxes.add(new Box(4,30)); 58 | boxes.add(new Box(22,32)); 59 | boxes.add(new Box(41,51)); 60 | boxes.add(new Box(42,51)); 61 | boxes.add(new Box(43,51)); 62 | boxes.add(new Box(44,51)); 63 | boxes.add(new Box(45,51)); 64 | boxes.add(new Box(46,51)); 65 | boxes.add(new Box(47,51)); 66 | boxes.add(new Box(48,51)); 67 | boxes.add(new Box(49,51)); 68 | boxes.add(new Box(50,51)); 69 | 70 | Listboxers = boxes.subList(4, boxes.size()); 71 | for(Box box:boxers){ 72 | System.out.println("The box is "+box); 73 | } 74 | 75 | 76 | }//end method 77 | }//end class -------------------------------------------------------------------------------- /src/main/java/math/fractions/FractionalNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.fractions; 7 | 8 | 9 | import static java.lang.Math.*; 10 | /** 11 | * 12 | * @author JIBOYE Oluwagbemiro Olaoluwa 13 | */ 14 | public class FractionalNumber { 15 | 16 | private long numerator; 17 | 18 | private long denominator; 19 | 20 | public FractionalNumber(long numerator, long denominator) { 21 | this.numerator = numerator; 22 | this.denominator = denominator; 23 | 24 | reduce(); 25 | 26 | }//end constructor 27 | 28 | public FractionalNumber() { 29 | this.numerator = 1; 30 | this.denominator = 1; 31 | } 32 | 33 | public long getDenominator() { 34 | return denominator; 35 | } 36 | 37 | public void setDenominator(int denominator) { 38 | this.denominator = denominator; 39 | } 40 | 41 | public long getNumerator() { 42 | return numerator; 43 | } 44 | 45 | public void setNumerator(int numerator) { 46 | this.numerator = numerator; 47 | } 48 | /** 49 | * Reduces the rational number to its simplest form. 50 | */ 51 | public void reduce(){ 52 | 53 | double den = numerator>=denominator?numerator:denominator; 54 | 55 | for(int i=2;iscan){ 18 | super("|"); 19 | if(this.getName().equals("")){ 20 | throw new IndexOutOfBoundsException("Invalid Name For Half-Determinant MOperator." ); 21 | }//end if 22 | 23 | else{ 24 | this.index=(index>=0&&scan.get(index).equals("|"))?index:-1; 25 | }//end else 26 | 27 | if(this.index==-1){ 28 | throw new IndexOutOfBoundsException("Invalid Index" ); 29 | } 30 | 31 | } 32 | 33 | public void setIndex(int index) { 34 | this.index = index; 35 | } 36 | 37 | public int getIndex() { 38 | return index; 39 | } 40 | 41 | public void setComplement(HalfDet complement) { 42 | this.complement = complement; 43 | } 44 | 45 | public HalfDet getComplement() { 46 | return complement; 47 | } 48 | /** 49 | * 50 | * @param isleftHalf A boolean condition that is true if the object (whose complement we seek) itself is the opening 51 | * half of the determinant brace...i.e the one to the left. If false, then it is the one to the right...i.e the one to the right. 52 | * @param start The index of the HalfDet object whose complement we seek. 53 | * @param scan The ArrayList that this object resides in. 54 | * @return the index where the complement is to be found in the ArrayList object. 55 | */ 56 | public static int getComplementIndex( boolean isleftHalf, int start, ArrayListscan ){ 57 | 58 | int index=0; 59 | if(isleftHalf){ 60 | 61 | for(index=start+1;index=0;index--){ 70 | if(scan.get(index).equals("|")){ 71 | return index; 72 | } 73 | }//end for 74 | 75 | }//end else if 76 | return -1; 77 | 78 | 79 | } 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | }//end class 90 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MAdditionOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class MAdditionOperator extends MBinaryOperator { 15 | 16 | //Č 17 | 18 | /** 19 | * Creates an object of class 20 | * MAdditionOperator 21 | * 22 | * @param index the index of this object in its 23 | * parent Function object's scanner. 24 | * @param scan The scanner output 25 | */ 26 | public MAdditionOperator(int index, ArrayListscan){ 27 | super("+", index, scan); 28 | }//end constructor 29 | 30 | 31 | 32 | 33 | }//end class MAdditionOperator 34 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MAssignmentOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public class MAssignmentOperator { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MLogic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | /** 9 | * 10 | * @author GBENRO 11 | */ 12 | public class MLogic { 13 | 14 | static boolean on = true; 15 | boolean off = false; 16 | 17 | 18 | public static boolean and(MNumber num1, MNumber num2){ 19 | 20 | return on; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MSubtractionOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * 13 | * @author GBEMIRO 14 | */ 15 | public final class MSubtractionOperator extends MatrixBinaryOperator{ 16 | 17 | //Č 18 | 19 | /** 20 | * Creates an object of class 21 | * MSubtractionOperator 22 | * 23 | * @param index the index of this object in its 24 | * parent Function object's scanner. 25 | * @param scan the scanner tokesn 26 | * MSubtractionOperator exists. 27 | * 28 | */ 29 | public MSubtractionOperator(int index, ArrayListscan){ 30 | super("-", index, scan); 31 | }//end constructor 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | }//end class MSubtractionOperator 44 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MUnaryPostOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | import parser.Precedence; 9 | import parser.Validatable; 10 | 11 | 12 | import java.util.ArrayList; 13 | import static parser.Number.*; 14 | import static parser.Variable.*; 15 | 16 | 17 | /** 18 | * 19 | * Models a post-operand MOperator 20 | * object e.g the !, inverse, square, cube operators 21 | * 22 | * @author GBEMIRO 23 | */ 24 | public class MUnaryPostOperator extends MOperator implements Validatable { 25 | 26 | 27 | /** 28 | * The precedence of this MUnaryPostOperator object. 29 | */ 30 | private final Precedence precedence; 31 | /** 32 | * The index of this operator 33 | * in the scanned Function that it belongs to. 34 | */ 35 | private int index; 36 | /** 37 | * Creates a new MUnaryPostOperator object 38 | * 39 | * @param name The name that identifies this MUnaryPostOperator object 40 | * @param scan The scanner tokens object that contains this object 41 | */ 42 | public MUnaryPostOperator(String name, int index, ArrayListscan) { 43 | super( isUnaryPostOperator(name)?name:""); 44 | 45 | if(this.getName().equals("")){ 46 | throw new IndexOutOfBoundsException("Invalid Name For Unary Post-MNumber MOperator." ); 47 | }//end if 48 | else{ 49 | this.index=(index>=0&&scan.get(index).equals(name))?index:-1; 50 | this.precedence=MOperator.getPrecedence(name); 51 | }//end else 52 | 53 | if(this.index==-1){ 54 | throw new IndexOutOfBoundsException("Invalid Index" ); 55 | } 56 | 57 | } 58 | /** 59 | * 60 | * @return the Precedence of this MOperator object. 61 | */ 62 | public Precedence getPrecedence() { 63 | return precedence; 64 | } 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | /** 80 | * 81 | * @param scan The scanner output 82 | * that this MUnaryPostOperator object exists in. 83 | * validates the grammatical usage of this operator (by leaving the correctFunction attribute of the function object un-modified) 84 | * if the usage of this operator 85 | * in its immediate environment i.e to its left and right is correct. 86 | * @return true if the grammatical usage of this token with repect to its 2 immediate neighbouring 87 | * tokens to the left and to the right is correct. 88 | */ 89 | @Override 90 | public boolean validate(ArrayListscan){ 91 | 92 | boolean correct = true; 93 | 94 | try{ 95 | //specify valid tokens that can come before a post-number operator 96 | if(!isNumber(scan.get(index-1))&&!isClosingBracket(scan.get(index-1))&& 97 | !isVariableString(scan.get(index-1))&&!isUnaryPostOperator(scan.get(index-1)) 98 | ){ 99 | util.Utils.logError( 100 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index-1)+"\" And \""+scan.get(index)+"\""+ 101 | " As You Have Done."+ 102 | "ParserNG Error Detector For Post-number operators!" ); 103 | correct=false; 104 | scan.clear(); 105 | }//end if 106 | //specify valid tokens that can come after a post-number operator 107 | if(!isUnaryPreOperator(scan.get(index+1))&& 108 | !isBinaryOperator(scan.get(index+1))&&!isUnaryPostOperator(scan.get(index+1)) 109 | &&!isClosingBracket(scan.get(index+1)) 110 | ){ 111 | util.Utils.logError( 112 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index)+"\" And \""+scan.get(index+1)+"\""+ 113 | " As You Have Done."+ 114 | "ParserNG Error Detector Post-number operators!" ); 115 | correct=false; 116 | scan.clear(); 117 | }//end if 118 | }//end try 119 | catch(IndexOutOfBoundsException ind){ 120 | 121 | }//end catch 122 | 123 | return correct; 124 | } 125 | 126 | 127 | 128 | /** 129 | * Carefully interpretes the correct arrangement of a loose 130 | * math statement for objects of this class and applies the correct 131 | * one to the Function object. 132 | * @param scan The ArrayList object that is the scanner of the Function object and so contains this MUnaryPostOperator object 133 | */ 134 | public static void assignCompoundTokens(ArrayListscan){ 135 | 136 | for(int i=0;i0){ 126 | return n.substring(0,1).equals("#")&&Variable.isVariableString(n.substring(1)); 127 | } 128 | else{ 129 | return false; 130 | }//end else. 131 | } 132 | catch(IndexOutOfBoundsException indexErr){ 133 | return false; 134 | } 135 | } 136 | 137 | /** 138 | * 139 | * @return the view of the matrix in the format...A = num1, num2, num3 ....numi 140 | * numi+1,numi+2,numi+3....numj 141 | * numj+1,numj+2,numj+3....numk 142 | * e.t.c. 143 | */ 144 | @Override 145 | public String toString(){ 146 | return name+" = "+matrix; 147 | } 148 | 149 | public static void main(String args[]){ 150 | MatrixVariable var = new MatrixVariable("#A","[2,3,7,9,3,4:89,2,-28,12,4,5:,1,1,0,1,0,1:]"); 151 | System.out.println(var); 152 | MatrixVariable reduced = new MatrixVariable("#B", var.getMatrix().reduceToTriangularMatrix()); 153 | System.out.println(reduced); 154 | 155 | 156 | System.out.println(var.getCreatingExpression()+"\n"+reduced.getCreatingExpression()); 157 | 158 | } 159 | 160 | 161 | 162 | }//end class MatrixVariable 163 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/expressParser/MmultiplicationOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.expressParser; 7 | 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * 13 | * @author GBEMIRO 14 | */ 15 | public final class MmultiplicationOperator extends MatrixBinaryOperator{ 16 | 17 | 18 | 19 | //Č 20 | 21 | /** 22 | * Creates an object of class 23 | * MmultiplicationOperator 24 | * 25 | * @param index the index of this object in its 26 | * parent Function object's scanner. 27 | * @param scan the scanner tokens 28 | * MmultiplicationOperator exists. 29 | * 30 | */ 31 | public MmultiplicationOperator(int index, ArrayListscan){ 32 | super("*", index, scan); 33 | }//end constructor 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | }//end class MmultiplicationOperator 44 | -------------------------------------------------------------------------------- /src/main/java/math/matrix/util/LinearSystemGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.matrix.util; 7 | 8 | import parser.STRING; 9 | import java.util.ArrayList; 10 | import java.util.Random; 11 | 12 | /** 13 | * Objects of this class have the ability to generate a 14 | * system of linear equations, randomly. 15 | * 16 | * 17 | * @author JIBOYE Oluwagbemiro Olaoluwa 18 | */ 19 | public class LinearSystemGenerator { 20 | 21 | /** 22 | * The absolute value of the largest possible number 23 | * that may be found in the system. 24 | */ 25 | private int maximumPossibleNumberInSystem; 26 | /** 27 | * The number of unknowns in the system. 28 | */ 29 | private int size; 30 | /** 31 | * The letter of alphabet that will 32 | * start the name of the variables 33 | * that will be used to build the 34 | * linear system. 35 | * The system will geerate the variables as x1,x2...... 36 | * where x is any uppercase or lowercase letter of the alphabet 37 | */ 38 | private String startingLetterOfUnknownName; 39 | /** 40 | * 41 | * @param size The number of unknowns that the system will have. 42 | * @param maximumPossibleNumberInSystem The absolute value of the largest possible number 43 | * that may be found in the system. 44 | * @param startingLetterOfUnknownName The letter of the alphabet that will start the name of the unknown. 45 | */ 46 | public LinearSystemGenerator(int size, int maximumPossibleNumberInSystem,String startingLetterOfUnknownName) { 47 | this.size = size; 48 | this.maximumPossibleNumberInSystem = maximumPossibleNumberInSystem; 49 | this.startingLetterOfUnknownName = STRING.isWord(startingLetterOfUnknownName)?startingLetterOfUnknownName:"x"; 50 | }//end constructor 51 | 52 | public void setStartingLetterOfUnknownName(String startingLetterOfUnknownName) { 53 | this.startingLetterOfUnknownName = startingLetterOfUnknownName; 54 | } 55 | 56 | public String getStartingLetterOfUnknownName() { 57 | return startingLetterOfUnknownName; 58 | } 59 | 60 | public void setSize(int size) { 61 | this.size = size; 62 | } 63 | 64 | public int getSize() { 65 | return size; 66 | } 67 | 68 | public void setMaximumPossibleNumberInSystem(int maximumPossibleNumberInSystem) { 69 | this.maximumPossibleNumberInSystem = maximumPossibleNumberInSystem; 70 | } 71 | 72 | public int getMaximumPossibleNumberInSystem() { 73 | return maximumPossibleNumberInSystem; 74 | } 75 | 76 | 77 | 78 | /** 79 | * 80 | * @return an ArrayList containing the unknowns 81 | */ 82 | private ArrayList generateUnknowns(){ 83 | ArrayListvars=new ArrayList(); 84 | for(int i=1;i<=size;i++){ 85 | vars.add(startingLetterOfUnknownName+i); 86 | }//end for 87 | return vars; 88 | } 89 | /** 90 | * @return a double number randomly generated. 91 | */ 92 | private double generateCoefficient(){ 93 | 94 | Random ran = new Random(); 95 | double number = 1.0; 96 | int choiceOfSign=ran.nextInt(2); 97 | 98 | /** 99 | * Generate a number greater than zero or equal to zero 100 | */ 101 | if(choiceOfSign==0){ 102 | number = 1+ran.nextInt(maximumPossibleNumberInSystem); 103 | 104 | /** 105 | * Generate a divisor randomly between zero and the value generated for number. 106 | */ 107 | int val=(int) number; 108 | double divisor = 1+ran.nextInt(val); 109 | number/=divisor; 110 | 111 | 112 | 113 | } 114 | /** 115 | * Generate a number less than zero 116 | */ 117 | else if(choiceOfSign==1){ 118 | number = 1+ran.nextInt(maximumPossibleNumberInSystem); 119 | /** 120 | * Generate a divisor randomly between zero and the value generated for number. 121 | */ 122 | int val=(int) number; 123 | double divisor = 1+ran.nextInt(val); 124 | number/=(-1.0*divisor); 125 | } 126 | 127 | return number; 128 | }//end method 129 | 130 | 131 | /** 132 | * Builds the liinear system. 133 | * @return the system after build 134 | */ 135 | private String buildSystem(){ 136 | String myLinearSystem=""; 137 | ArrayListunknowns =generateUnknowns(); 138 | 139 | for(int rows=0;rows1 && baseOfOperation <= 10)?baseOfOperation:10; 53 | } 54 | 55 | public int getBaseOfOperation() { 56 | return baseOfOperation; 57 | } 58 | 59 | 60 | 61 | 62 | /** 63 | * Checks if the numbers in the input 64 | * are only of the specified base. 65 | * @return An {@link ArrayList} containing the indices 66 | * of all numbers in the scanner. 67 | */ 68 | private ArrayList isBaseCompatible(){ 69 | ArrayListscanner = getScanner(); 70 | ArrayListnumIndices= new ArrayList();//stores the indices of all numbers. 71 | 72 | for(int j=0;j= baseOfOperation) { 85 | setCorrectFunction(false); 86 | break; 87 | }//end if 88 | }//end inner for loop 89 | } 90 | if(!isCorrectFunction()){ 91 | break; 92 | }//end if 93 | 94 | 95 | }//end outer for loop 96 | return numIndices; 97 | }//end method 98 | 99 | 100 | /** 101 | * Converts all numbers to base 10 system. 102 | */ 103 | private void convertNumbersToDecimal() { 104 | ArrayListscanner = getScanner(); 105 | ArrayListnumIndices = isBaseCompatible(); 106 | 107 | ArrayListhandledVariables = new ArrayList(); 108 | if(isCorrectFunction()){ 109 | 110 | for(int i=0;i=0 ){ 85 | result=String.valueOf ( (-b/(2*a))+ ( sqrt( pow(b, 2) - 4*a*c)/(2*a) ) )+", "+String.valueOf ( (-b/(2*a))- ( sqrt( pow(b, 2) - 4*a*c)/(2*a) ) ); 86 | } 87 | else if( (pow(b,2)-4*a*c)<0 ){ 88 | result=String.valueOf (-b/(2*a))+"+"+String.valueOf( ( sqrt( 4*a*c - pow(b, 2) )/(2*a) ) )+" i ,\n"+ 89 | String.valueOf (-b/(2*a))+"-"+String.valueOf( ( sqrt( 4*a*c - pow(b, 2) )/(2*a) ) )+" i "; 90 | } 91 | //2p^2-3p-4.09=0 92 | result=result.replace("+-", "-"); 93 | result=result.replace("-+", "-"); 94 | result=result.replace("--", "+"); 95 | return result; 96 | } 97 | /** 98 | * 99 | * @return the solutions as an array of values 100 | */ 101 | public String[] soln(){ 102 | 103 | String result[]=new String[2]; 104 | 105 | if( (pow(b,2)-4*a*c)>=0 ){ 106 | result[0]=String.valueOf ( (-b/(2*a))+ ( sqrt( pow(b, 2) - 4*a*c)/(2*a) ) ); 107 | result[1]=String.valueOf ( (-b/(2*a))- ( sqrt( pow(b, 2) - 4*a*c)/(2*a) ) ); 108 | } 109 | else if( (pow(b,2)-4*a*c)<0 ){ 110 | result[0]= String.valueOf (-b/(2*a))+"+"+String.valueOf( ( sqrt( 4*a*c - pow(b, 2) )/(2*a) ) )+" i"; 111 | result[1]= String.valueOf (-b/(2*a))+"-"+String.valueOf( ( sqrt( 4*a*c - pow(b, 2) )/(2*a) ) )+" i "; 112 | } 113 | //2p^2-3p-4.09=0 114 | 115 | result[0]=result[0].replace("+-", "-"); 116 | result[0]=result[0].replace("-+", "-"); 117 | result[0]=result[0].replace("--", "+"); 118 | 119 | result[1]=result[1].replace("+-", "-"); 120 | result[1]=result[1].replace("-+", "-"); 121 | result[1]=result[1].replace("--", "+"); 122 | 123 | return result; 124 | } 125 | 126 | 127 | 128 | 129 | @Override 130 | public String toString(){ 131 | return a+"x²+"+b+"x+"+c+"=0"; 132 | } 133 | 134 | public static void main(String args[]){ 135 | QuadraticSolver ohMy = new QuadraticSolver(3,-9,6); 136 | System.out.println(ohMy.soln()[0]+", "+ohMy.soln()[1]); 137 | 138 | System.out.println(ohMy ); 139 | } 140 | 141 | 142 | }//end class QuadraticSolver 143 | -------------------------------------------------------------------------------- /src/main/java/math/quadratic/Quadratic_Equation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.quadratic; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author JIBOYE Oluwagbemiro Olaoluwa 13 | */ 14 | public class Quadratic_Equation { 15 | private QuadraticExpressionParser parser;//The equation parser 16 | private QuadraticSolver algorithm;//The equation solver. 17 | 18 | public Quadratic_Equation(String equation) { 19 | this.parser = new QuadraticExpressionParser(equation); 20 | ArrayListcoeffs=parser.getCoefficients(); 21 | this.algorithm = new QuadraticSolver(coeffs.get(0),coeffs.get(1),coeffs.get(2) ); 22 | } 23 | 24 | public void setParser(QuadraticExpressionParser parser) { 25 | this.parser = parser; 26 | } 27 | 28 | public QuadraticExpressionParser getParser() { 29 | return parser; 30 | } 31 | 32 | 33 | public void setAlgorithm(QuadraticSolver algorithm) { 34 | this.algorithm = algorithm; 35 | } 36 | 37 | public QuadraticSolver getAlgorithm() { 38 | return algorithm; 39 | } 40 | 41 | 42 | /** 43 | * 44 | * @return the reduced form of the system in the form Ax²+Bx+C=0; 45 | */ 46 | public String interpretedSystem(){ 47 | return parser.interpretedSystem(); 48 | } 49 | 50 | /** 51 | * 52 | * @return The solutions to the equation as 53 | * a string of values 54 | * 55 | */ 56 | public String solutions(){ 57 | return algorithm.solve(); 58 | } 59 | 60 | 61 | 62 | public static void main(String args[]){ 63 | Quadratic_Equation eqn=new Quadratic_Equation("-2*X^2+3*X+1+X=-9-9X^2"); 64 | System.out.println(eqn.solutions()); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/math/tartaglia/TartagliaSolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.tartaglia; 7 | 8 | import math.quadratic.QuadraticSolver; 9 | import static java.lang.Math.*; 10 | 11 | /** 12 | * 13 | * Objects of this class are 14 | * real value solvers of the system: 15 | * cx^3+ax+b=0. 16 | * @author JIBOYE OLuwagbemiro Olaoluwa 17 | */ 18 | public class TartagliaSolver { 19 | private double a;//coefficient of x. 20 | private double b;//coefficient of the constant. 21 | private double c;//coefficient of x^3. 22 | 23 | public TartagliaSolver(double c, double a, double b) { 24 | this.a=a; 25 | this.b=b; 26 | this.c=c; 27 | normalizeCofficients(); 28 | 29 | } 30 | 31 | 32 | 33 | 34 | public double getA() { 35 | return a; 36 | } 37 | 38 | public void setA(double a) { 39 | this.a = a; 40 | } 41 | 42 | public double getB() { 43 | return b; 44 | } 45 | 46 | public void setB(double b) { 47 | this.b = b; 48 | } 49 | 50 | public double getC() { 51 | return c; 52 | } 53 | 54 | public void setC(double c) { 55 | this.c = c; 56 | } 57 | 58 | 59 | 60 | 61 | /** 62 | * Make the value of c to be equal to one by 63 | * dividing through a,b,c by its value 64 | * 65 | */ 66 | public void normalizeCofficients(){ 67 | try{ 68 | setA(a/c); 69 | setB(b/c); 70 | setC(1.0); 71 | 72 | } 73 | catch(ArithmeticException arit){ 74 | util.Utils.logError( "THE COEFFICIENT OF x^3 MUST NOT BE ZERO".toUpperCase()); 75 | } 76 | } 77 | /** 78 | * Finds the real roots 79 | * of the equation. 80 | */ 81 | public String solve(){ 82 | 83 | String x1="0.0"; 84 | 85 | if(a>0){ 86 | 87 | try{ 88 | double lhs=(b/2.0); 89 | double rhs= sqrt( ( pow(a,3)/27.0 ) + ( pow(b,2)/4.0 ) ); 90 | x1=String.valueOf( cbrt( -lhs+rhs)+cbrt( -lhs-rhs) ); 91 | 92 | QuadraticSolver solver = new QuadraticSolver(1.0,Double.valueOf(x1), a+ pow( Double.valueOf(x1),2) ); 93 | 94 | String allSolutions=x1+",\n"+solver.solve(); 95 | 96 | return allSolutions; 97 | }//end try 98 | catch(NumberFormatException numErr){ 99 | return "SYNTAX ERROR"; 100 | }//end catch 101 | 102 | }//end if 103 | else{ 104 | return "THE COEFFICIENT OF X CANNOT BE LESS THAN OR EQUAL TO ZERO."; 105 | }//end else 106 | 107 | 108 | 109 | }//end method 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | }//end class 118 | -------------------------------------------------------------------------------- /src/main/java/math/tartaglia/Tartaglia_Equation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package math.tartaglia; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author JIBOYE OLuwagbemiro Olaoluwa 13 | */ 14 | public class Tartaglia_Equation { 15 | private TartagliaExpressionParser parser;//The equation parser 16 | private TartagliaSolver algorithm;//The equation solver. 17 | 18 | public Tartaglia_Equation(String equation) { 19 | this.parser = new TartagliaExpressionParser(equation); 20 | ArrayListcoeffs=parser.getCoefficients(); 21 | this.algorithm = new TartagliaSolver(coeffs.get(0),coeffs.get(1),coeffs.get(2) ); 22 | } 23 | 24 | public void setParser(TartagliaExpressionParser parser) { 25 | this.parser = parser; 26 | } 27 | 28 | public TartagliaExpressionParser getParser() { 29 | return parser; 30 | } 31 | 32 | 33 | public void setAlgorithm(TartagliaSolver algorithm) { 34 | this.algorithm = algorithm; 35 | } 36 | 37 | public TartagliaSolver getAlgorithm() { 38 | return algorithm; 39 | } 40 | 41 | 42 | /** 43 | * 44 | * @return the reduced form of the system in the form Ax²+Bx+C=0; 45 | */ 46 | public String interpretedSystem(){ 47 | return parser.interpretedSystem(); 48 | } 49 | 50 | /** 51 | * 52 | * @return The solutions to the equation as 53 | * a string of values 54 | * 55 | */ 56 | public String solutions(){ 57 | return algorithm.solve(); 58 | } 59 | 60 | 61 | 62 | public static void main(String args[]){ 63 | Tartaglia_Equation eqn=new Tartaglia_Equation("-X^3-5X-7=0"); 64 | System.out.println(eqn.solutions()); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/parser/AdditionOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class AdditionOperator extends BinaryOperator{ 15 | 16 | //Č 17 | 18 | /** 19 | * Creates an object of class 20 | * AdditionOperator 21 | * 22 | * @param index the index of this object in its 23 | * parent Function object's scanner. 24 | * @param scan the Function object in which this 25 | * AdditionOperator exists. 26 | * 27 | */ 28 | public AdditionOperator( int index,ArrayListscan){ 29 | super(PLUS, index, scan); 30 | }//end constructor 31 | 32 | 33 | 34 | 35 | }//end class AdditionOperator 36 | -------------------------------------------------------------------------------- /src/main/java/parser/AntiLogToAnyBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package parser; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 11 | * @author GBEMIRO 12 | */ 13 | public final class AntiLogToAnyBase extends LogOrAntiLogToAnyBase { 14 | 15 | //Č 16 | /** 17 | * 18 | * @param index the index of this object in its parent Function object's 19 | * scanner. 20 | * @param scan the Function object in which this RemainderOperator exists. 21 | */ 22 | public AntiLogToAnyBase(int index, ArrayList scan) { 23 | super("log-¹", index, scan); 24 | }//end constructor 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/parser/AssignmentOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | /** 9 | * 10 | * @author GBEMIRO 11 | */ 12 | public class AssignmentOperator { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/parser/CombinationOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class CombinationOperator extends BinaryOperator{ 15 | 16 | 17 | 18 | //Č 19 | 20 | /** 21 | * Creates an object of class 22 | * CombinationOperator 23 | * 24 | * @param index the index of this object in its 25 | * parent Function object's scanner. 26 | * @param scan the List object in which this 27 | * CombinationOperator exists. 28 | * 29 | */ 30 | public CombinationOperator( int index,ArrayListscan){ 31 | super(COMBINATION, index,scan); 32 | }//end constructor 33 | 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/parser/DivisionOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package parser; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 11 | * @author GBEMIRO 12 | */ 13 | public final class DivisionOperator extends BinaryOperator { 14 | 15 | /** 16 | * 17 | * @param index the index of this object in its parent Function object's 18 | * scanner. 19 | * @param scan The scanner output 20 | */ 21 | public DivisionOperator(int index, ArrayList scan) { 22 | super(DIVIDE, index, scan); 23 | }//end constructor 24 | 25 | }//end class DivisionOperator 26 | -------------------------------------------------------------------------------- /src/main/java/parser/LogOrAntiLogToAnyBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import parser.methods.Method; 9 | 10 | import java.util.ArrayList; 11 | 12 | import static parser.Number.*; 13 | import static parser.Variable.*; 14 | 15 | /** 16 | * 17 | * @author GBEMIRO 18 | */ 19 | 20 | public class LogOrAntiLogToAnyBase extends Operator implements Validatable{ 21 | /** 22 | * The index of objects of this 23 | * class in the scanned Function object 24 | * in which they exist. 25 | */ 26 | private int index; 27 | /** 28 | * 29 | * @param name The name of this Operator with which it is represented in a math 30 | * function. 31 | * @param index the location of this Operator object in its parent Function 32 | * object's scanned ArrayList object. 33 | * @param scan The scanned output 34 | */ 35 | public LogOrAntiLogToAnyBase(String name,int index,ArrayListscan) { 36 | super((Method.isLogOrAntiLogToAnyBase(name))?name:""); 37 | this.index=index; 38 | if(this.getName().equals("")){ 39 | throw new IndexOutOfBoundsException("Invalid Name For Log or antilog to any base type Operator." ); 40 | }//end if 41 | else{ 42 | this.index=(index>=0&&scan.get(index).equals(name))?index:-1; 43 | }//end else 44 | if(this.index==-1){ 45 | throw new IndexOutOfBoundsException("Invalid Index" ); 46 | }//end if 47 | }//end constructor 48 | /** 49 | * 50 | * @param index sets the index 51 | */ 52 | public void setIndex(int index) { 53 | this.index = index; 54 | } 55 | 56 | public int getIndex() { 57 | return index; 58 | } 59 | 60 | 61 | /** 62 | * 63 | * @param scan The scanner output 64 | * @return true if valid 65 | */ 66 | @Override 67 | public boolean validate(ArrayListscan){ 68 | boolean correct=true; 69 | try{ 70 | 71 | //specify valid tokens that can come before a LogOrAntiLogToAnyBase operator 72 | if(!isNumber(scan.get(index-1))&&!isBinaryOperator(scan.get(index-1))&& 73 | !isVariableString(scan.get(index-1))&&!isBracket(scan.get(index-1)) 74 | ){ 75 | util.Utils.logError( 76 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index-1)+"\" And \""+scan.get(index)+"\""+ 77 | " As You Have Done."+ 78 | "ParserNG Error Detector For LogOrAntiLogToAnyBase Operators!" ); 79 | correct=false; scan.clear(); 80 | }//end if 81 | //specify valid tokens that can come after a LogOrAntiLogToAnyBase operator 82 | if(!isNumber(scan.get(index+1))&&!isOpeningBracket(scan.get(index+1))&&!Method.isNumberReturningStatsMethod(scan.get(index+1)) 83 | &&!isUnaryPreOperator(scan.get(index+1)) 84 | &&!Method.isLogToAnyBase(scan.get(index+1))&&!Method.isAntiLogToAnyBase(scan.get(index+1))&&!Method.isStatsMethod(scan.get(index+1)) 85 | ){ 86 | util.Utils.logError( 87 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index)+"\" And \""+scan.get(index+1)+"\""+ 88 | " As You Have Done."+ 89 | "ParserNG Error Detector For LogOrAntiLogToAnyBase Operators!" ); 90 | correct=false; scan.clear(); 91 | }//end if 92 | }//end try 93 | catch(IndexOutOfBoundsException ind){ 94 | 95 | }//end catch 96 | return correct; 97 | }//end method validateLogOrAntiLogToAnyBase 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | }//end class 111 | -------------------------------------------------------------------------------- /src/main/java/parser/LogToAnyBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class LogToAnyBase extends LogOrAntiLogToAnyBase{ 15 | /** 16 | * Creates an object of class 17 | * LogTOperator 18 | * 19 | * @param index the index of this object in its 20 | * parent Function object's scanner. 21 | * @param scan The scanner output 22 | * 23 | */ 24 | public LogToAnyBase( int index,ArrayListscan){ 25 | super("log", index, scan); 26 | }//end constructor 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/parser/Logic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | /** 9 | * 10 | * @author GBENRO 11 | */ 12 | public class Logic { 13 | 14 | static boolean on = true; 15 | boolean off = false; 16 | 17 | 18 | public static boolean and(Number num1, Number num2){ 19 | 20 | return on; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/parser/MultiplicationOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class MultiplicationOperator extends BinaryOperator{ 15 | 16 | 17 | 18 | //Č 19 | 20 | /** 21 | * Creates an object of class 22 | * MultiplicationOperator 23 | * 24 | * @param index the index of this object in its 25 | * parent Function object's scanner. 26 | * @param scan The scanner output 27 | * 28 | */ 29 | public MultiplicationOperator( int index,ArrayListscan){ 30 | super(MULTIPLY, index, scan); 31 | }//end constructor 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | }//end class MultiplicationOperator 42 | -------------------------------------------------------------------------------- /src/main/java/parser/NumberReturningStatsOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import parser.methods.Method; 9 | 10 | import java.util.ArrayList; 11 | 12 | import static parser.Number.*; 13 | import static parser.Variable.*; 14 | 15 | /** 16 | * 17 | * Deals with number returning statistical operators 18 | * e.g sum,avg,mode e.t.c and log and antilog 19 | * to any base operators 20 | * 21 | * @author GBEMIRO 22 | */ 23 | public class NumberReturningStatsOperator extends Operator implements Validatable{ 24 | /** 25 | * The index of this operator 26 | * in the scanned Function that it belongs to. 27 | */ 28 | private int index; 29 | /** 30 | * 31 | * @param name The name of this Operator with which it is represented in a math 32 | * function. 33 | * @param index the location of this Operator object in its parent Function 34 | * object's scanned ArrayList object. 35 | * @param scan The scanner output 36 | */ 37 | public NumberReturningStatsOperator(String name,int index,ArrayListscan) { 38 | super((Method.isNumberReturningStatsMethod(name)|| Method.isLogOrAntiLogToAnyBase(name))?name:""); 39 | this.index=index; 40 | if(this.getName().equals("")){ 41 | throw new IndexOutOfBoundsException("Invalid Name For Number Returning Statistical Operator." ); 42 | }//end if 43 | else{ 44 | this.index=(index>=0&&scan.get(index).equals(name))?index:-1; 45 | }//end else 46 | 47 | if(this.index==-1){ 48 | throw new IndexOutOfBoundsException("Invalid Index" ); 49 | } 50 | 51 | }//end constructor 52 | 53 | 54 | /** 55 | * 56 | * @param index sets the index of this operator 57 | * in the scanned Function that it belongs to. 58 | * @param scan The scanner output 59 | */ 60 | public void setIndex(int index,ArrayListscan) { 61 | 62 | this.index=(index>=0&&scan.get(index).equals(this.getName()))?index:-1; 63 | 64 | if(this.index==-1){ 65 | throw new IndexOutOfBoundsException("Invalid Index" ); 66 | } 67 | } 68 | /** 69 | * 70 | * @return the index of this operator 71 | * in the scanned Function that it belongs to. 72 | */ 73 | public int getIndex() { 74 | return index; 75 | } 76 | 77 | 78 | 79 | /** 80 | * @param scan the ArrayList object 81 | * that this NumberReturningStatsOperator object exists in. 82 | * validates the grammatical usage of this operator 83 | * (by leaving the correctFunction attribute of the Function object un-modified) 84 | * if the usage of this operator 85 | * in its immediate environment i.e to its left and right is correct. 86 | * @return true if valid 87 | */ 88 | @Override 89 | public boolean validate(ArrayListscan){ 90 | boolean correct = true; 91 | 92 | //Number returning stats operators 93 | try{ 94 | //specify valid tokens that can come before a number returning stats operator 95 | if(!isNumber(scan.get(index-1))&&!isBinaryOperator(scan.get(index-1))&& 96 | !isVariableString(scan.get(index-1))&&!isUnaryPostOperator(scan.get(index-1)) 97 | &&!isLogicOperator(scan.get(index-1))&&!isAssignmentOperator(scan.get(index-1)) 98 | &&!Method.isAntiLogToAnyBase(scan.get(index-1)) 99 | &&!Method.isLogToAnyBase(scan.get(index-1))&&!isUnaryPreOperator(scan.get(index-1)) 100 | &&!isOpeningBracket(scan.get(index-1)) 101 | ){ 102 | util.Utils.logError( 103 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index-1)+"\" And \""+scan.get(index)+"\""+ 104 | " As You Have Done."+ 105 | "ParserNG Error Detector For Number Returning Stats operators!" ); 106 | correct = false; 107 | scan.clear(); 108 | }//end if 109 | //specify valid tokens that can come after a number returning stats operator 110 | if(!isOpeningBracket(scan.get(index+1))&&!isVariableString(scan.get(index+1)) 111 | &&!Method.isLogToAnyBase(scan.get(index+1))&&!Method.isAntiLogToAnyBase(scan.get(index+1)) 112 | &&!isUnaryPreOperator(scan.get(index+1))&&!isNumber(scan.get(index+1)) 113 | ){ 114 | util.Utils.logError( 115 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index)+"\" And \""+scan.get(index+1)+"\""+ 116 | " As You Have Done."+ 117 | "ParserNG Error Detector For Number Returning Stats operators!" ); 118 | correct = false; 119 | scan.clear(); 120 | }//end if 121 | }//end try 122 | catch(IndexOutOfBoundsException ind){ 123 | 124 | }//end catch 125 | return correct; 126 | }//end method validateNumberReturningStatsOperator. 127 | 128 | 129 | 130 | 131 | 132 | 133 | }//end class NumberReturningStatsOperator 134 | -------------------------------------------------------------------------------- /src/main/java/parser/Parser_Result.java: -------------------------------------------------------------------------------- 1 | package parser; 2 | 3 | public enum Parser_Result{ 4 | SYNTAX_ERROR,INVALID_FUNCTION,INCOMPLETE_PARAMS,PARENTHESES_ERROR,NULL_ERROR,STRANGE_INPUT,VALID; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/parser/PermutationOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class PermutationOperator extends BinaryOperator{ 15 | 16 | 17 | 18 | //Р 19 | 20 | /** 21 | * Creates an object of class 22 | * PermutationOperator 23 | * 24 | * @param index the index of this object in its 25 | * parent Function object's scanner. 26 | * @param scan the Function object in which this 27 | * PermutationOperator exists. 28 | * 29 | */ 30 | public PermutationOperator( int index,ArrayListscan){ 31 | super(PERMUTATION, index, scan); 32 | }//end constructor 33 | 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/parser/Precedence.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | /** 9 | * 10 | * @author GBEMIRO 11 | */ 12 | public class Precedence { 13 | private int value; 14 | 15 | public Precedence(int value) { 16 | setValue(value); 17 | } 18 | 19 | public void setValue(int value) { 20 | this.value = (value>=0)?value:0; 21 | } 22 | 23 | public int getValue(){ 24 | return value; 25 | } 26 | 27 | 28 | 29 | @Override 30 | public String toString() { 31 | return " Precedence = "+value; 32 | } 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/parser/RemainderOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class RemainderOperator extends BinaryOperator{ 15 | 16 | 17 | 18 | //Č 19 | 20 | /** 21 | * Creates an object of class 22 | * RemainderOperator 23 | * 24 | * @param index the index of this object in its 25 | * parent Function object's scanner. 26 | * @param scan the Function object in which this 27 | * RemainderOperator exists. 28 | * 29 | */ 30 | public RemainderOperator( int index,ArrayListscan){ 31 | super(REMAINDER, index, scan); 32 | }//end constructor 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | }//end class RemainderOperator 44 | -------------------------------------------------------------------------------- /src/main/java/parser/SubtractionOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public final class SubtractionOperator extends BinaryOperator{ 15 | 16 | //Č 17 | 18 | /** 19 | * Creates an object of class 20 | * SubtractionOperator 21 | * 22 | * @param index the index of this object in its 23 | * parent Function object's scanner. 24 | * @param scan the Function object in which this 25 | * SubtractionOperator exists. 26 | * @param // STOPSHIP: 6/30/2016 27 | * 28 | */ 29 | public SubtractionOperator( int index,ArrayListscan){ 30 | super(MINUS, index, scan); 31 | }//end constructor 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | }//end class SubtractionOperator 44 | -------------------------------------------------------------------------------- /src/main/java/parser/TYPE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package parser; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * Defines the allowed return types 12 | * 13 | * @author JIBOYE Oluwagbemiro Olaoluwa 14 | */ 15 | public enum TYPE implements Serializable{ 16 | 17 | MATRIX, LIST, NUMBER, STRING, VOID, ALGEBRAIC_EXPRESSION, ERROR 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/parser/UnaryPreOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import parser.methods.Method; 9 | 10 | import java.util.ArrayList; 11 | import static parser.Number.*; 12 | import static parser.Variable.*; 13 | 14 | 15 | /** 16 | * 17 | * Models a post-operand Operator 18 | * object e.g the trigonometric,logarithmic,exponential e.t.c. operators. 19 | * 20 | * @author GBEMIRO 21 | */ 22 | public final class UnaryPreOperator extends Operator implements Validatable{ 23 | /** 24 | * The precedence of this BinaryOperator object. 25 | */ 26 | private final Precedence precedence; 27 | 28 | 29 | /** 30 | * The index of this operator 31 | * in the scanned MathExpression that it belongs to. 32 | */ 33 | private int index; 34 | /** 35 | * Creates a new UnaryPreOperator object 36 | * 37 | * @param name The name of the operator 38 | * @param index The index of the operator in the list 39 | * @param scan The scanner output 40 | */ 41 | public UnaryPreOperator(String name,int index,ArrayListscan) { 42 | super( isUnaryPreOperator(name)?name:""); 43 | if(this.getName().equals("")){ 44 | throw new IndexOutOfBoundsException("Invalid Name For Unary Pre-Number Operator." ); 45 | }//end if 46 | else{ 47 | 48 | this.index=(index>=0&&scan.get(index).equals(name))?index:-1; 49 | this.precedence= getPrecedence(name); 50 | }//end else 51 | 52 | if(this.index==-1){ 53 | throw new IndexOutOfBoundsException("Invalid Index" ); 54 | } 55 | 56 | }//end constructor 57 | 58 | /** 59 | * 60 | * @return the precedence of this operator 61 | */ 62 | public Precedence getPrecedence() { 63 | return precedence; 64 | } 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | /** 77 | * @param scan the ArrayList object 78 | * that this UnaryPreOperator object exists in. 79 | * validates the grammatical usage of this operator (by leaving the correctFunction attribute of the function object un-modified) 80 | * if the usage of this operator 81 | * in its immediate environment i.e to its left and right is correct. 82 | * @return true if the grammatical usage of this token with repect to its 2 immediate neighbouring 83 | * tokens to the left and to the right is correct. 84 | */ 85 | @Override 86 | public boolean validate(ArrayListscan){ 87 | 88 | boolean correct = true; 89 | try{ 90 | //specify valid tokens that can come before a pre-number operator 91 | if(!isBinaryOperator(scan.get(index-1))&&!isNumber(scan.get(index-1))&& 92 | !isUnaryPreOperator(scan.get(index-1))&&!isBracket(scan.get(index-1))&& 93 | !isVariableString(scan.get(index-1))&&!isUnaryPostOperator(scan.get(index-1))&& 94 | !isLogicOperator(scan.get(index-1)) 95 | &&!isAssignmentOperator(scan.get(index-1)) 96 | ){ 97 | util.Utils.logError( 98 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index-1)+"\" And \""+scan.get(index)+"\""+ 99 | " As You Have Done."+ 100 | "ParserNG Error Detector For Pre-number operators!" ); 101 | correct = false; 102 | scan.clear(); 103 | }//end if 104 | //specify valid tokens that can come after a pre-number operator 105 | if(!isOpeningBracket(scan.get(index+1))&&!isNumber(scan.get(index+1)) 106 | &&!Method.isUnaryPreOperatorORDefinedMethod(scan.get(index+1))&& 107 | !isVariableString(scan.get(index+1))&&!Method.isNumberReturningStatsMethod(scan.get(index+1)) 108 | &&!Method.isLogToAnyBase(scan.get(index+1))&&!Method.isAntiLogToAnyBase(scan.get(index+1)) 109 | ){ 110 | util.Utils.logError( 111 | "ParserNG Does Not Allow "+getName()+" To Combine The Function Members \""+scan.get(index)+"\" And \""+scan.get(index+1)+"\""+ 112 | " As You Have Done."+ 113 | "ParserNG Error Detector For Pre-number operators!" ); 114 | correct = false; 115 | scan.clear(); 116 | }//end if 117 | 118 | }//end try 119 | catch(IndexOutOfBoundsException ind){ 120 | 121 | }//end catch 122 | 123 | 124 | return correct; 125 | } 126 | 127 | 128 | 129 | /** 130 | * 131 | * @param function the MathExpression object that contains the power operator 132 | */ 133 | public static void assignCompoundTokens(MathExpression function){ 134 | ArrayListscan=function.getScanner(); 135 | 136 | 137 | 138 | } 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | }//end class UnaryPreOperator 151 | -------------------------------------------------------------------------------- /src/main/java/parser/Validatable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package parser; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author JIBOYE OLuwagbemiro Olaoluwa 13 | */ 14 | public interface Validatable { 15 | 16 | public boolean validate(ArrayList scan); 17 | 18 | } -------------------------------------------------------------------------------- /src/main/java/parser/cmd/ParserCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package parser.cmd; 7 | 8 | import java.io.BufferedReader; 9 | import java.io.IOException; 10 | import java.io.InputStreamReader; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import interfaces.Solvable; 15 | import math.Main; 16 | import parser.ExpandingExpression; 17 | import parser.LogicalExpression; 18 | import parser.MathExpression; 19 | import parser.logical.ExpressionLogger; 20 | 21 | /** 22 | * @author GBEMIRO JIBOYE 23 | */ 24 | public class ParserCmd { 25 | 26 | private static final String divider = "\n______________________________________________________\n"; 27 | 28 | public static void main(String[] args) throws IOException { 29 | 30 | if (args.length > 0) { 31 | if (Main.getLogcalSwitch().isIn(args[0])) { 32 | Main.setLogic(true); 33 | } 34 | if (Main.getExpandableSwitch().isIn(args[0])) { 35 | Main.setExpandable(true); 36 | } 37 | } 38 | BufferedReader sc = new BufferedReader(new InputStreamReader(System.in)); 39 | 40 | System.err.println("Welcome To ParserNG Command Line"); 41 | String title = Main.isTrim() ? Main.isLogic() ? "Logical Line" : "Math Line" : Main.isLogic() ? "Logical Question" : "Math Question"; 42 | int i = 0; 43 | List batch = new ArrayList<>(); 44 | while (true) { 45 | System.err.printf("\n" + title + " %d:%s", (++i), divider); 46 | String cmd = sc.readLine(); 47 | if (cmd == null || cmd.equals("exit") || cmd.equals("quit") || cmd.equals("done")) { 48 | if (Main.isTrim()) { 49 | String all = Main.joinArgs(batch, true); 50 | if (Main.isVerbose()) { 51 | System.err.println(all); 52 | } 53 | calWitOutput(all); 54 | } 55 | break; 56 | } 57 | batch.add(cmd); 58 | if (Main.isVerbose()) { 59 | System.err.println(cmd); 60 | } 61 | System.err.flush(); 62 | if (!Main.isTrim()) { 63 | calWitOutput(cmd); 64 | } 65 | 66 | } 67 | 68 | 69 | } 70 | 71 | private static void calWitOutput(String cmd) { 72 | String ans = null; 73 | try { 74 | 75 | Solvable expression = Main.isLogic() ? 76 | new LogicalExpression(cmd, LogicalExpression.verboseStderrLogger) : 77 | Main.isExpandable() ? 78 | new ExpandingExpression(cmd, ExpandingExpression.getValuesFromVariables(), ExpandingExpression.verboseStderrLogger) : 79 | new MathExpression(cmd); 80 | ans = expression.solve(); 81 | }catch (Exception ex) { 82 | ans = ex.getMessage(); 83 | } 84 | System.err.printf("Answer%s\n", divider); 85 | System.err.flush(); 86 | System.out.println(ans); 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/parser/logical/AlgebraExpressionParser.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | import parser.MathExpression; 4 | 5 | import java.math.BigDecimal; 6 | 7 | public class AlgebraExpressionParser { 8 | 9 | private final MathExpression mathExpression; 10 | private final String original; 11 | private final ExpressionLogger log; 12 | 13 | public AlgebraExpressionParser(String expr, ExpressionLogger log) { 14 | original = expr; 15 | this.log = log; 16 | mathExpression = new MathExpression(original); 17 | } 18 | 19 | public BigDecimal evaluate() { 20 | log.log("evaluating math: " + original); 21 | BigDecimal r = new BigDecimal(mathExpression.solve()); 22 | log.log("is: " + r.toString()); 23 | return r; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/parser/logical/ComparingExpressionParser.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Arrays; 5 | 6 | public class ComparingExpressionParser extends AbstractSplittingParser implements LogicalExpressionMemberFactory.LogicalExpressionMember { 7 | 8 | private static final String[] primaryChars1 = new String[]{"!=", "==", ">=", "<="}; 9 | private static final String[] primaryChars2 = new String[]{"le", "ge", "lt", "gt"}; 10 | private static final String[] secondaryChars1 = new String[]{"<", ">"}; 11 | private static final String[] secondaryChars2 = new String[]{}; 12 | 13 | public ComparingExpressionParser(String expression, ExpressionLogger log) { 14 | super(expression, log); 15 | } 16 | 17 | public ComparingExpressionParser() { 18 | super(); 19 | } 20 | 21 | 22 | @Override 23 | public boolean isLogicalExpressionMember(String originalExpression) { 24 | for (String s : primaryChars1) { 25 | if (originalExpression.contains(s)) { 26 | return true; 27 | } 28 | } 29 | for (String s : primaryChars2) { 30 | if (originalExpression.contains(s)) { 31 | return true; 32 | } 33 | } 34 | for (String s : secondaryChars1) { 35 | if (originalExpression.contains(s)) { 36 | return true; 37 | } 38 | } 39 | for (String s : secondaryChars2) { 40 | if (originalExpression.contains(s)) { 41 | return true; 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | @Override 48 | public String[] getPrimaryChars1() { 49 | return Arrays.copyOf(primaryChars1, primaryChars1.length); 50 | } 51 | 52 | @Override 53 | public String[] getPrimaryChars2() { 54 | return Arrays.copyOf(primaryChars2, primaryChars2.length); 55 | } 56 | 57 | @Override 58 | public String[] getSecondaryChars1() { 59 | return Arrays.copyOf(secondaryChars1, secondaryChars1.length); 60 | } 61 | 62 | @Override 63 | public String[] getSecondaryChars2() { 64 | return Arrays.copyOf(secondaryChars2, secondaryChars2.length); 65 | } 66 | 67 | @Override 68 | public boolean evaluate() { 69 | log.log("evaluating comparison: " + getOriginal()); 70 | if (split.size() == 1) { 71 | boolean r = parseBooleanStrict(split.get(0).trim(), log); 72 | log.log("is: " + r); 73 | return r; 74 | } else if (split.size() == 3) { 75 | BigDecimal result1 = new AlgebraExpressionParser(split.get(0), new ExpressionLogger.InheritingExpressionLogger(log)).evaluate(); 76 | BigDecimal result2 = new AlgebraExpressionParser(split.get(2), new ExpressionLogger.InheritingExpressionLogger(log)).evaluate(); 77 | String op = split.get(1); 78 | log.log("... " + result1.toString() + " " + op + " " + result2.toString()); 79 | if (">".equals(op) || "gt".equals(op)) { 80 | boolean r = result1.compareTo(result2) > 0; 81 | log.log("is: " + r); 82 | return r; 83 | } else if ("<".equals(op) || "lt".equals(op)) { 84 | boolean r = result1.compareTo(result2) < 0; 85 | log.log("is: " + r); 86 | return r; 87 | } else if (">=".equals(op) || "ge".equals(op)) { 88 | boolean r = result1.compareTo(result2) >= 0; 89 | log.log("is: " + r); 90 | return r; 91 | } else if ("<=".equals(op) || "le".equals(op)) { 92 | boolean r = result1.compareTo(result2) <= 0; 93 | log.log("is: " + r); 94 | return r; 95 | } else if ("!=".equals(op)) { 96 | boolean r = result1.compareTo(result2) != 0; 97 | log.log("is: " + r); 98 | return r; 99 | } else if ("==".equals(op)) { 100 | boolean r = result1.compareTo(result2) == 0; 101 | log.log("is: " + r); 102 | return r; 103 | } else { 104 | throw new ArithmeticException("unknown comparison operator" + op); 105 | } 106 | } else { 107 | throw new ArithmeticException("The comparison operator needs to be operand between operators or true/false. Is " + getOriginal()); 108 | } 109 | } 110 | 111 | public static boolean parseBooleanStrict(String trim, ExpressionLogger log) { 112 | if ("true".equalsIgnoreCase(trim)) { 113 | return true; 114 | } else if ("false".equalsIgnoreCase(trim)) { 115 | return false; 116 | } else { 117 | throw new ArithmeticException(trim + " is not true/false"); 118 | } 119 | } 120 | 121 | @Override 122 | public String getName() { 123 | return "Comparing operators"; 124 | } 125 | 126 | public static class ComparingExpressionParserFactory implements LogicalExpressionMemberFactory { 127 | 128 | @Override 129 | public LogicalExpressionMember createLogicalExpressionMember(String expression, ExpressionLogger log) { 130 | return new ComparingExpressionParser(expression, log); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/parser/logical/ExpressionLogger.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | public interface ExpressionLogger { 4 | 5 | public static final class InheritingExpressionLogger implements ExpressionLogger { 6 | 7 | private final ExpressionLogger parent; 8 | 9 | public InheritingExpressionLogger(ExpressionLogger parent) { 10 | this.parent = parent; 11 | } 12 | 13 | @Override 14 | public void log(String s) { 15 | parent.log(" " + s); 16 | } 17 | } 18 | public static ExpressionLogger DEV_NULL = new ExpressionLogger() { 19 | @Override 20 | public void log(String s) { 21 | } 22 | }; 23 | 24 | public void log(String s); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/parser/logical/LogicalExpressionMemberFactory.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | public interface LogicalExpressionMemberFactory { 4 | 5 | LogicalExpressionMember createLogicalExpressionMember(String expression, ExpressionLogger log); 6 | 7 | interface LogicalExpressionMember { 8 | 9 | /** 10 | * Help for this parser 11 | */ 12 | String getHelp(); 13 | 14 | /** 15 | * The method should understand true/false strings, if it is supposed to be used in more complicated expressions. 16 | * 17 | * @return evaluated expression, usually parsed in constructor 18 | */ 19 | boolean evaluate(); 20 | 21 | /** 22 | * ParserNG have a habit, that expression is parsed in constructor, and later evaluated in methood. 23 | * So this methid is takin parameter, of future expression, created over dummy example, so we know, 24 | * whether it will be viable for future constructor. 25 | * 26 | * @param futureExpression future expression to be passed to constructor 27 | * @return whether the expression is most likely targeted for this parser 28 | */ 29 | boolean isLogicalExpressionMember(String futureExpression); 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/parser/logical/LogicalExpressionParser.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | 4 | import java.util.Arrays; 5 | 6 | import parser.methods.Declarations; 7 | 8 | public class LogicalExpressionParser extends AbstractSplittingParser implements LogicalExpressionMemberFactory.LogicalExpressionMember { 9 | 10 | private static final String[] chars1 = new String[]{}; 11 | private static final String[] chars2 = new String[]{"impl", "xor"}; 12 | private static final String[] secchars1 = new String[]{"|", "&"}; 13 | private static final String[] secchars2 = new String[]{"imp", "eq", "or", "and"}; 14 | private final LogicalExpressionMemberFactory subexpressionFactory; 15 | 16 | public LogicalExpressionParser(String expression, ExpressionLogger log) { 17 | this(expression, log, new ComparingExpressionParser.ComparingExpressionParserFactory()); 18 | } 19 | 20 | public LogicalExpressionParser(String expression, ExpressionLogger log, LogicalExpressionMemberFactory subexpressionFactory) { 21 | super(expression, log); 22 | this.subexpressionFactory = subexpressionFactory; 23 | } 24 | 25 | @Override 26 | public boolean isLogicalExpressionMember(String originalExpression) { 27 | String[] methods = Declarations.getInbuiltMethods(); 28 | for (String method : methods) { 29 | //otherwise eg floor would match or, and thus delegate to Logical parser 30 | originalExpression = originalExpression.replace(method, "kNoWnMeThOd"); 31 | } 32 | for (String s : new String[]{"false", "true"}) { 33 | if (originalExpression.toLowerCase().contains(s)) { 34 | return true; 35 | } 36 | } 37 | for (String s : chars1) { 38 | if (originalExpression.contains(s)) { 39 | return true; 40 | } 41 | } 42 | for (String s : chars2) { 43 | if (originalExpression.contains(s)) { 44 | return true; 45 | } 46 | } 47 | for (String s : secchars1) { 48 | if (originalExpression.contains(s)) { 49 | return true; 50 | } 51 | } 52 | for (String s : secchars2) { 53 | if (originalExpression.contains(s)) { 54 | return true; 55 | } 56 | } 57 | if (subexpressionFactory.createLogicalExpressionMember("", log).isLogicalExpressionMember(originalExpression)) { 58 | return true; 59 | } 60 | return false; 61 | } 62 | 63 | 64 | public String[] getPrimaryChars1() { 65 | return Arrays.copyOf(chars1, chars1.length); 66 | } 67 | 68 | public String[] getPrimaryChars2() { 69 | return Arrays.copyOf(chars2, chars2.length); 70 | } 71 | 72 | public String[] getSecondaryChars1() { 73 | return Arrays.copyOf(secchars1, secchars1.length); 74 | } 75 | 76 | public String[] getSecondaryChars2() { 77 | return Arrays.copyOf(secchars2, secchars2.length); 78 | } 79 | 80 | public boolean evaluate() { 81 | log.log("evaluating logical: " + getOriginal()); 82 | boolean result = subexpressionFactory.createLogicalExpressionMember(split.get(0), new ExpressionLogger.InheritingExpressionLogger(log)).evaluate(); 83 | for (int i = 1; i <= split.size() - 2; i = i + 2) { 84 | String op = split.get(i); 85 | LogicalExpressionMemberFactory.LogicalExpressionMember comp2 = subexpressionFactory.createLogicalExpressionMember(split.get(i + 1), new ExpressionLogger.InheritingExpressionLogger(log)); 86 | boolean r2 = comp2.evaluate(); 87 | log.log("... " + result + " " + op + " " + r2); 88 | if ("&".equals(op) || "and".equals(op)) { 89 | result = result && r2; 90 | } else if ("|".equals(op) || "or".equals(op)) { 91 | result = result || r2; 92 | } else if ("impl".equals(op) || "imp".equals(op)) { 93 | if (result && !r2) { 94 | return false; 95 | } else { 96 | return true; 97 | } 98 | } else if ("eq".equals(op)) { 99 | result = result == r2; 100 | } else if ("xor".equals(op)) { 101 | result = (result != r2); 102 | } else { 103 | throw new ArithmeticException("invalid operator " + op); 104 | } 105 | } 106 | log.log("is: " + result); 107 | return result; 108 | } 109 | 110 | @Override 111 | public String getName() { 112 | return "Logical operators"; 113 | } 114 | 115 | public LogicalExpressionMemberFactory getSubexpressionFactory() { 116 | return subexpressionFactory; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/BasicNumericalMethod.java: -------------------------------------------------------------------------------- 1 | package parser.methods; 2 | 3 | import java.util.List; 4 | 5 | public interface BasicNumericalMethod { 6 | 7 | String solve(List tokens); 8 | 9 | String getHelp(); 10 | 11 | String getName(); 12 | 13 | String getType(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/Help.java: -------------------------------------------------------------------------------- 1 | package parser.methods; 2 | 3 | import logic.DRG_MODE; 4 | import parser.ExpandingExpression; 5 | 6 | import static parser.methods.Declarations.*; 7 | 8 | public class Help { 9 | 10 | 11 | public static String getHelp() { 12 | StringBuilder sb = new StringBuilder(); 13 | sb.append("List of currently known methods:").append("\n"); 14 | for (String op : getInbuiltMethods()) { 15 | sb.append(getHelp(op)).append("\n"); 16 | } 17 | sb.append("List of functions is just tip of iceberg, see: https://github.com/gbenroscience/ParserNG for all features").append("\n"); 18 | sb.append(getEnvVariables()).append("\n"); 19 | return sb.toString(); 20 | } 21 | 22 | public static String getEnvVariables() { 23 | return " Environment variables/java properties (so setup-able) in runtime):\n" + 24 | " " + DRG_MODE.DEG_MODE_VARIABLE + " - DEG/RAD/GRAD - allows to change units for trigonometric operations. Default is RAD. It is same as MathExpression().setDRG(...)\n" + 25 | " " + ExpandingExpression.VALUES_PNG + "/" + ExpandingExpression.VALUES_IPNG + " - space separated numbers - allows to set numboers for " + ExpandingExpression.class.getName(); 26 | } 27 | public static String getHelp(String op) { 28 | for(BasicNumericalMethod basicNumericalMethod: Declarations.getBasicNumericalMethods()){ 29 | if (op.equals(basicNumericalMethod.getName())){ 30 | return basicNumericalMethod.getHelp(); 31 | } 32 | } 33 | switch (op) { 34 | case PROD: 35 | return toLine(op, "product of all elements. s. Eg: " + op + "(1,2) will evaluate 1*2 to 2"); 36 | case MEDIAN: 37 | return toLine(op, "median from set. s. Eg: " + op + "(1,2,3) will evaluate as 2"); 38 | default: 39 | return toLine(op, "help not yet written. See https://github.com/gbenroscience/ParserNG"); 40 | } 41 | } 42 | 43 | 44 | static String align(String op) { 45 | for (String s : getInbuiltMethods()) { 46 | while (s.length() > op.length()) { 47 | op = op + " "; 48 | } 49 | } 50 | return op; 51 | } 52 | 53 | public static String toLine(String op, String text) { 54 | return Help.align(op) + " - " + text; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Abs.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.List; 5 | 6 | import parser.TYPE; 7 | import parser.methods.BasicNumericalMethod; 8 | import parser.methods.Help; 9 | 10 | public class Abs implements BasicNumericalMethod { 11 | 12 | 13 | @Override 14 | public String solve(List tokens) { 15 | Utils.checkTokensCount("Abs", 1, tokens); 16 | return new BigDecimal(tokens.get(0)).abs().toString(); 17 | } 18 | 19 | @Override 20 | public String getHelp() { 21 | return Help.toLine(getName(), "absolute value abs(1.3)-> 1.3 abs(-2.5) -> 2.5"); 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "abs"; 27 | } 28 | 29 | @Override 30 | public String getType() { 31 | return TYPE.NUMBER.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Avg.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.math.MathContext; 9 | import java.math.RoundingMode; 10 | import java.util.List; 11 | 12 | public class Avg implements BasicNumericalMethod { 13 | 14 | 15 | @Override 16 | public String solve(List tokens) { 17 | List convertedTokens = Utils.tokensToNumbers(tokens); 18 | if (convertedTokens.size() == 0) { 19 | return "0"; 20 | } 21 | BigDecimal summ = Utils.sum(convertedTokens); 22 | return summ.divide(new BigDecimal(convertedTokens.size()), new MathContext(10, RoundingMode.HALF_DOWN)).toString(); 23 | } 24 | 25 | @Override 26 | public String getHelp() { 27 | return Help.toLine(getName(), "avarage of all elements. s. Eg: " + getName() + "(1,2) will evaluate (1*2)/2 to 0.5"); 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "avg"; 33 | } 34 | 35 | @Override 36 | public String getType() { 37 | return TYPE.NUMBER.toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/AvgN.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.math.MathContext; 9 | import java.math.RoundingMode; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class AvgN implements BasicNumericalMethod { 14 | 15 | public static final int DEFAULT_AVGN_MISIZE = 2; 16 | 17 | @Override 18 | public String solve(List tokens) { 19 | List convertedTokens = Utils.tokensToNumbers(tokens); 20 | Utils.checkAtLeastArgs(getName(), 1, convertedTokens); 21 | if (convertedTokens.size() == 1) { 22 | return "0"; 23 | } 24 | int toRemove = Utils.getFirstBigDeciamalTokenAsInt(convertedTokens); 25 | List l = convertedTokens.subList(1, convertedTokens.size()); 26 | Collections.sort(l); 27 | Utils.trimList(l, toRemove, DEFAULT_AVGN_MISIZE); 28 | BigDecimal summ = Utils.sum(l); 29 | return summ.divide(new BigDecimal(l.size()), new MathContext(10, RoundingMode.HALF_DOWN)).toString(); 30 | } 31 | 32 | @Override 33 | public String getHelp() { 34 | return Help.toLine(getName(), " this is counting limited avg value. First argument is not part of the sum, but is pointing, how much tokens have to be remove from sorted arguments list from both ends, before avg is calculated from the rest. avgN(1,2,4,2) is actually not 9/4 but 2, as first 2 and last 4 from 2,2,4 (as 1 is argument) were removed. Always at least two items are left list"); 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return "avgN"; 40 | } 41 | 42 | @Override 43 | public String getType() { 44 | return TYPE.NUMBER.toString(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/CeilFloor.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.math.RoundingMode; 9 | import java.util.List; 10 | 11 | public class CeilFloor { 12 | 13 | public static class Ceil implements BasicNumericalMethod { 14 | 15 | 16 | @Override 17 | public String solve(List tokens) { 18 | List tt = Utils.tokensToNumbers(tokens); 19 | Utils.checkTokensCount("Ceil", 1, tt); 20 | return Rounding.naturalRound(0, tt.get(0), RoundingMode.CEILING).toString(); 21 | } 22 | 23 | @Override 24 | public String getHelp() { 25 | return Help.toLine(getName(), "ceiling fractional digits towards positive infinity. Same as ceilN(0,...)"); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "ceil"; 31 | } 32 | 33 | @Override 34 | public String getType() { 35 | return TYPE.NUMBER.toString(); 36 | } 37 | } 38 | 39 | public static class Floor implements BasicNumericalMethod { 40 | 41 | 42 | @Override 43 | public String solve(List tokens) { 44 | List tt = Utils.tokensToNumbers(tokens); 45 | Utils.checkTokensCount("Floor", 1, tt); 46 | return Rounding.naturalRound(0, tt.get(0), RoundingMode.FLOOR).toString(); 47 | } 48 | 49 | @Override 50 | public String getHelp() { 51 | return Help.toLine(getName(), "flooring fractional digits towards negative infinity. Same as floorN(0,...)"); 52 | } 53 | 54 | @Override 55 | public String getName() { 56 | return "floor"; 57 | } 58 | 59 | @Override 60 | public String getType() { 61 | return TYPE.NUMBER.toString(); 62 | } 63 | } 64 | public static class CeilN implements BasicNumericalMethod { 65 | 66 | 67 | @Override 68 | public String solve(List tokens) { 69 | List tt = Utils.tokensToNumbers(tokens); 70 | Utils.checkTokensCount("CeilN", 2, tt); 71 | int fractionalDigits = Utils.getFirstBigDeciamalTokenAsInt(tt); 72 | return Rounding.naturalRound(fractionalDigits, tt.get(1), RoundingMode.CEILING).toString(); 73 | } 74 | 75 | @Override 76 | public String getHelp() { 77 | return Help.toLine(getName(), "ceiling fractional digits towards positive infinity to N valid fractional digits"); 78 | } 79 | 80 | @Override 81 | public String getName() { 82 | return "ceilN"; 83 | } 84 | 85 | @Override 86 | public String getType() { 87 | return TYPE.NUMBER.toString(); 88 | } 89 | } 90 | 91 | public static class FloorN implements BasicNumericalMethod { 92 | 93 | 94 | @Override 95 | public String solve(List tokens) { 96 | List tt = Utils.tokensToNumbers(tokens); 97 | Utils.checkTokensCount("FloorN", 2, tt); 98 | int fractionalDigits = Utils.getFirstBigDeciamalTokenAsInt(tt); 99 | return Rounding.naturalRound(fractionalDigits, tt.get(1), RoundingMode.FLOOR).toString(); 100 | } 101 | 102 | @Override 103 | public String getHelp() { 104 | return Help.toLine(getName(), "flooring fractional digits towards negative infinity to N valid fractional digits"); 105 | } 106 | 107 | @Override 108 | public String getName() { 109 | return "floorN"; 110 | } 111 | 112 | @Override 113 | public String getType() { 114 | return TYPE.NUMBER.toString(); 115 | } 116 | } 117 | 118 | 119 | public static class CeilDigitsN implements BasicNumericalMethod { 120 | 121 | 122 | @Override 123 | public String solve(List tokens) { 124 | List tt = Utils.tokensToNumbers(tokens); 125 | Utils.checkTokensCount("CeilDigitsN", 2, tt); 126 | int digits = Utils.getFirstBigDeciamalTokenAsInt(tt); 127 | return Rounding.roundDigits(digits, tt.get(1), RoundingMode.CEILING); 128 | } 129 | 130 | @Override 131 | public String getHelp() { 132 | return Help.toLine(getName(), "ceiling digits towards positive infinity to N valid digits"); 133 | } 134 | 135 | @Override 136 | public String getName() { 137 | return "ceilDigitsN"; 138 | } 139 | 140 | @Override 141 | public String getType() { 142 | return TYPE.NUMBER.toString(); 143 | } 144 | } 145 | 146 | public static class FloorDigitsN implements BasicNumericalMethod { 147 | 148 | 149 | @Override 150 | public String solve(List tokens) { 151 | List tt = Utils.tokensToNumbers(tokens); 152 | Utils.checkTokensCount("FloorDigitsN", 2, tt); 153 | int digits = Utils.getFirstBigDeciamalTokenAsInt(tt); 154 | return Rounding.roundDigits(digits, tt.get(1), RoundingMode.FLOOR); 155 | } 156 | 157 | @Override 158 | public String getHelp() { 159 | return Help.toLine(getName(), "flooring digits towards negative infinity to N valid digits"); 160 | } 161 | 162 | @Override 163 | public String getName() { 164 | return "floorDigitsN"; 165 | } 166 | 167 | @Override 168 | public String getType() { 169 | return TYPE.NUMBER.toString(); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Count.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | public class Count implements BasicNumericalMethod { 11 | 12 | 13 | @Override 14 | public String solve(List tokens) { 15 | List convertedTokens = Utils.tokensToNumbers(tokens); 16 | return "" + convertedTokens.size(); 17 | } 18 | 19 | 20 | @Override 21 | public String getHelp() { 22 | return Help.toLine(getName(), "number of elements in the function. Eg: " + getName() + "(1,1.1) will evaluate 3"); 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "count"; 28 | } 29 | 30 | @Override 31 | public String getType() { 32 | return TYPE.NUMBER.toString(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Echo.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import java.io.File; 4 | import java.nio.file.Files; 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | import parser.TYPE; 9 | import parser.methods.BasicNumericalMethod; 10 | import parser.methods.Help; 11 | 12 | public class Echo implements BasicNumericalMethod { 13 | 14 | 15 | @Override 16 | public String solve(List tokens) { 17 | return tokens.stream().collect(Collectors.joining(" ")); 18 | } 19 | 20 | @Override 21 | public String getHelp() { 22 | return Help.toLine(getName(), " simply reprints its space dleimited arguments. Result is final, and no other operations possible"); 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "echo"; 28 | } 29 | 30 | @Override 31 | public String getType() { 32 | return TYPE.NUMBER.toString(); 33 | } 34 | 35 | public static class EchoN implements BasicNumericalMethod { 36 | 37 | @Override 38 | public String solve(List tokens) { 39 | return tokens.stream().collect(Collectors.joining(System.lineSeparator())); 40 | } 41 | 42 | @Override 43 | public String getHelp() { 44 | return Help.toLine(getName(), " simply reprints its new-line delimited arguments. Result is final, and no other operations possible"); 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return "echon"; 50 | } 51 | 52 | @Override 53 | public String getType() { 54 | return TYPE.NUMBER.toString(); 55 | } 56 | } 57 | 58 | public static class EchoNI implements BasicNumericalMethod { 59 | 60 | @Override 61 | public String solve(List tokens) { 62 | StringBuilder stringBuilder = new StringBuilder(); 63 | for (int i = 0; i < tokens.size(); i++) { 64 | stringBuilder.append(i).append(":").append(tokens.get(i)).append(System.lineSeparator()); 65 | } 66 | return stringBuilder.toString(); 67 | } 68 | 69 | @Override 70 | public String getHelp() { 71 | return Help.toLine(getName(), " simply reprints its new-line delimited arguments with its Index. Result is final, and no other operations possible"); 72 | } 73 | 74 | @Override 75 | public String getName() { 76 | return "echoni"; 77 | } 78 | 79 | @Override 80 | public String getType() { 81 | return TYPE.NUMBER.toString(); 82 | } 83 | } 84 | 85 | public static class EchoI implements BasicNumericalMethod { 86 | 87 | @Override 88 | public String solve(List tokens) { 89 | StringBuilder stringBuilder = new StringBuilder(); 90 | for (int i = 0; i < tokens.size(); i++) { 91 | stringBuilder.append(i).append(":").append(tokens.get(i)).append(" "); 92 | } 93 | return stringBuilder.toString(); 94 | } 95 | 96 | @Override 97 | public String getHelp() { 98 | return Help.toLine(getName(), " simply reprints its space delimited arguments with its Index. Result is final, and no other operations possible"); 99 | } 100 | 101 | @Override 102 | public String getName() { 103 | return "echoi"; 104 | } 105 | 106 | @Override 107 | public String getType() { 108 | return TYPE.NUMBER.toString(); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Geom.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import math.BigDecimalNthRootCalculation; 4 | import parser.TYPE; 5 | import parser.methods.BasicNumericalMethod; 6 | import parser.methods.Help; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.List; 10 | 11 | public class Geom implements BasicNumericalMethod { 12 | 13 | @Override 14 | public String solve(List tokens) { 15 | List convertedTokens = Utils.tokensToNumbers(tokens); 16 | if (convertedTokens.size() == 0) { 17 | return "0"; 18 | } 19 | BigDecimal gsumm = Utils.gsum(convertedTokens); 20 | return BigDecimalNthRootCalculation.nthRoot(convertedTokens.size(), gsumm).toString(); 21 | } 22 | 23 | @Override 24 | public String getHelp() { 25 | return Help.toLine(getName(), "returns geometrical average of elements. s. Eg: " + getName() + "(1,2,4) will evaluate (1*2*4)^1/3 thus na 8^1/3 thus to 2"); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "geom"; 31 | } 32 | 33 | @Override 34 | public String getType() { 35 | return TYPE.NUMBER.toString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/GeomN.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import math.BigDecimalNthRootCalculation; 8 | import parser.TYPE; 9 | import parser.methods.BasicNumericalMethod; 10 | import parser.methods.Help; 11 | 12 | public class GeomN implements BasicNumericalMethod { 13 | 14 | @Override 15 | public String solve(List tokens) { 16 | List convertedTokens = Utils.tokensToNumbers(tokens); 17 | Utils.checkAtLeastArgs(getName(), 1, convertedTokens); 18 | if (convertedTokens.size() == 1) { 19 | return "0"; 20 | } 21 | int toRemove = Utils.getFirstBigDeciamalTokenAsInt(convertedTokens); 22 | List l = convertedTokens.subList(1, convertedTokens.size()); 23 | Collections.sort(l); 24 | Utils.trimList(l, toRemove, AvgN.DEFAULT_AVGN_MISIZE); 25 | BigDecimal gsumm = Utils.gsum(l); 26 | return BigDecimalNthRootCalculation.nthRoot(l.size(), gsumm).toString(); 27 | } 28 | 29 | @Override 30 | public String getHelp() { 31 | return Help.toLine(getName(), 32 | " this is counting limited geom-avg value. First argument is not part of the sum, but is pointing, how much tokens have to be remove from sorted arguments list from both ends, " 33 | + "before geom-avg is calculated from the rest. geomN(1,2,4,2) is actually not 16^1/4 but 2, as first 2 and last 4 from 2,2,4 (as 1 is argument) were removed."); 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "geomN"; 39 | } 40 | 41 | @Override 42 | public String getType() { 43 | return TYPE.NUMBER.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Gsum.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | public class Gsum implements BasicNumericalMethod { 11 | 12 | @Override 13 | public String solve(List tokens) { 14 | List convertedTokens = Utils.tokensToNumbers(tokens); 15 | if (convertedTokens.size() == 0) { 16 | return "0"; 17 | } 18 | return Utils.gsum(convertedTokens).toString(); 19 | } 20 | 21 | @Override 22 | public String getHelp() { 23 | return Help.toLine(getName(), "product of all elements. s. Eg: " + getName() + "(1,2) will evaluate 1*2 to 2"); 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "gsum"; 29 | } 30 | 31 | @Override 32 | public String getType() { 33 | return TYPE.NUMBER.toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Lengths.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.util.List; 8 | 9 | public class Lengths { 10 | 11 | public static class Length implements BasicNumericalMethod { 12 | 13 | 14 | @Override 15 | public String solve(List tokens) { 16 | Utils.checkTokensCount("Length", 1, tokens); 17 | int[] l = Utils.decimalAndFractionalParts(tokens.get(0)); 18 | return "" + (l[0] + l[1]); 19 | } 20 | 21 | @Override 22 | public String getHelp() { 23 | return Help.toLine(getName(), "number of both fractional and decimal digits"); 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "length"; 29 | } 30 | 31 | @Override 32 | public String getType() { 33 | return TYPE.NUMBER.toString(); 34 | } 35 | } 36 | 37 | public static class LengthDecimal implements BasicNumericalMethod { 38 | 39 | @Override 40 | public String solve(List tokens) { 41 | Utils.checkTokensCount("LengthDecimal", 1, tokens); 42 | int[] l = Utils.decimalAndFractionalParts(tokens.get(0)); 43 | return "" + l[0]; 44 | } 45 | 46 | @Override 47 | public String getHelp() { 48 | return Help.toLine(getName(), "number of decimal digits"); 49 | } 50 | 51 | @Override 52 | public String getName() { 53 | return "lengthDecimal"; 54 | } 55 | 56 | @Override 57 | public String getType() { 58 | return TYPE.NUMBER.toString(); 59 | } 60 | } 61 | 62 | public static class LengthFractional implements BasicNumericalMethod { 63 | 64 | @Override 65 | public String solve(List tokens) { 66 | Utils.checkTokensCount("LengthFractional", 1, tokens); 67 | int[] l = Utils.decimalAndFractionalParts(tokens.get(0)); 68 | return "" + l[1]; 69 | } 70 | 71 | @Override 72 | public String getHelp() { 73 | return Help.toLine(getName(), "number of fractional digits "); 74 | } 75 | 76 | @Override 77 | public String getName() { 78 | return "lengthFractional"; 79 | } 80 | 81 | @Override 82 | public String getType() { 83 | return TYPE.NUMBER.toString(); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Rounding.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | import java.util.List; 7 | 8 | import parser.TYPE; 9 | import parser.methods.BasicNumericalMethod; 10 | import parser.methods.Help; 11 | 12 | public class Rounding { 13 | 14 | /* Implemented is only round, rundN, roundDigitsN and roundX ( 5 up) 15 | * Whole set is to add also 5 down): 16 | * round, roundDown 17 | * roundN, roundDownN 18 | * roundDigitsN, roundDigitsDown 19 | * roundX, roundDownX 20 | */ 21 | 22 | public static class RoundN implements BasicNumericalMethod { 23 | 24 | @Override 25 | public String solve(List tokens) { 26 | List tt = Utils.tokensToNumbers(tokens); 27 | Utils.checkTokensCount("RoundN", 2, tt); 28 | int fractionalDigits = Utils.getFirstBigDeciamalTokenAsInt(tt); 29 | return naturalRound(fractionalDigits, tt.get(1), RoundingMode.HALF_UP).toString(); 30 | } 31 | 32 | @Override 33 | public String getHelp() { 34 | return Help.toLine(getName(), "natural round of decimal number to another decimal by rounding to N fractional digits. eg roudN(4, 4.2585) -> 4.259"); 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return "roundN"; 40 | } 41 | 42 | @Override 43 | public String getType() { 44 | return TYPE.NUMBER.toString(); 45 | } 46 | } 47 | 48 | public static class Round implements BasicNumericalMethod { 49 | 50 | @Override 51 | public String solve(List tokens) { 52 | List tt = Utils.tokensToNumbers(tokens); 53 | Utils.checkTokensCount("Round", 1, tt); 54 | return naturalRound(0, tt.get(0), RoundingMode.HALF_UP).toString(); 55 | } 56 | 57 | @Override 58 | public String getHelp() { 59 | return Help.toLine(getName(), "natural round of decimal number to integer: 1.1->1, 1,4->1, 1.44->1, 1.45->1, 1.5->2, 1.9->2. It is same as calling roundN(0, ..)"); 60 | } 61 | 62 | @Override 63 | public String getName() { 64 | return "round"; 65 | } 66 | 67 | @Override 68 | public String getType() { 69 | return TYPE.NUMBER.toString(); 70 | } 71 | } 72 | 73 | public static class RoundX implements BasicNumericalMethod { 74 | 75 | 76 | @Override 77 | public String solve(List tokens) { 78 | List tt = Utils.tokensToNumbers(tokens); 79 | Utils.checkTokensCount("RoundX", 2, tt); 80 | int fractionalDigits = Utils.getFirstBigDeciamalTokenAsInt(tt); 81 | return unnaturalRound(fractionalDigits, tt.get(1)).toString(); 82 | } 83 | 84 | @Override 85 | public String getHelp() { 86 | return Help.toLine(getName(), "unnatural round of decimal number to another decimal by rounding to N digits. eg roundX(1, 4.445)-> 4.5 unlike natural 4.4. 12.444 would remain natural."); 87 | } 88 | 89 | @Override 90 | public String getName() { 91 | return "roundX"; 92 | } 93 | 94 | @Override 95 | public String getType() { 96 | return TYPE.NUMBER.toString(); 97 | } 98 | 99 | } 100 | 101 | public static class RoundDigitsN implements BasicNumericalMethod { 102 | 103 | @Override 104 | public String solve(List tokens) { 105 | List tt = Utils.tokensToNumbers(tokens); 106 | Utils.checkTokensCount("roundDigitsN", 2, tt); 107 | int digits = Utils.getFirstBigDeciamalTokenAsInt(tt); 108 | return roundDigits(digits, tt.get(1), RoundingMode.HALF_UP); 109 | } 110 | 111 | @Override 112 | public String getHelp() { 113 | return Help.toLine(getName(), "round the input to number of N digits roundDigitsN(2,125.134) -> 130"); 114 | } 115 | 116 | @Override 117 | public String getName() { 118 | return "roundDigitsN"; 119 | } 120 | 121 | @Override 122 | public String getType() { 123 | return TYPE.NUMBER.toString(); 124 | } 125 | } 126 | 127 | 128 | public static String roundDigits(int digits, BigDecimal bd, RoundingMode m) { 129 | return bd.round(new MathContext(digits, m)).toString(); 130 | } 131 | 132 | 133 | static BigDecimal naturalRound(int origScale, BigDecimal orig, RoundingMode m) { 134 | if (origScale < 0) { 135 | throw new RuntimeException("Scale must be 0 or positive"); 136 | } 137 | BigDecimal rounded = orig.setScale(origScale, m); 138 | return rounded; 139 | } 140 | 141 | static BigDecimal unnaturalRound(int origScale, String orig) { 142 | return unnaturalRound(origScale, new BigDecimal(orig)); 143 | } 144 | 145 | static BigDecimal unnaturalRound(int origScale, BigDecimal orig) { 146 | if (origScale < 0) { 147 | throw new RuntimeException("Scale must be 0 or positive"); 148 | } 149 | BigDecimal rounded = orig; 150 | while (Utils.decimalAndFractionalParts(rounded)[1] > origScale) { 151 | int[] l = Utils.decimalAndFractionalParts(rounded); 152 | rounded = rounded.setScale(l[1] - 1, RoundingMode.HALF_UP); 153 | } 154 | return rounded; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/parser/methods/ext/Sum.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import parser.TYPE; 4 | import parser.methods.BasicNumericalMethod; 5 | import parser.methods.Help; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | public class Sum implements BasicNumericalMethod { 11 | 12 | 13 | @Override 14 | public String solve(List tokens) { 15 | List numericalTokens = Utils.tokensToNumbers(tokens); 16 | BigDecimal result = new BigDecimal("0"); 17 | for(BigDecimal numericalToken: numericalTokens){ 18 | result = result.add(numericalToken); 19 | } 20 | return result.toString(); 21 | } 22 | 23 | @Override 24 | public String getHelp() { 25 | return Help.toLine(getName(), " sum of arguments sum(1,2+2) is 1+2+2=5"); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "sum"; 31 | } 32 | 33 | @Override 34 | public String getType() { 35 | return TYPE.NUMBER.toString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/parser/package-info.java: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Classes designed to parse a mathematical expression. 4 | * @author JIBOYE, Oluwagbemiro Olaoluwa 5 | * 6 | */ 7 | package parser; -------------------------------------------------------------------------------- /src/main/java/util/Dimension.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | public class Dimension { 4 | 5 | public int width; 6 | 7 | public int height; 8 | public Dimension() { 9 | 10 | } 11 | public Dimension(int width,int height){ 12 | this.width = width; 13 | this.height = height; 14 | } 15 | public Dimension(Dimension d){ 16 | this.width = d.width; 17 | this.height = d.height; 18 | } 19 | 20 | public void setWidth(int width) { 21 | this.width = width; 22 | } 23 | public int getWidth() { 24 | return width; 25 | } 26 | public void setHeight(int height) { 27 | this.height = height; 28 | } 29 | public int getHeight() { 30 | return height; 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/util/ErrorLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author JIBOYE Oluwagbemiro Olaoluwa 13 | */ 14 | public class ErrorLog{ 15 | final ArrayListlogBook = new ArrayList(); 16 | 17 | 18 | 19 | public void writeLog(String error){ 20 | logBook.add(error); 21 | } 22 | /** 23 | * Displays the contents of this logBook on a JTextArea object and then clears its memory. 24 | */ 25 | public void printLog(){ 26 | StringBuilder builder = new StringBuilder(logBook.toString()); 27 | 28 | clearLog(); 29 | } 30 | 31 | 32 | 33 | public void clearLog(){ 34 | logBook.clear(); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/util/Formulae.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util; 7 | 8 | /** 9 | * 10 | * @author GBEMIRO 11 | */ 12 | import parser.Variable; 13 | import static parser.STRING.*; 14 | public class Formulae { 15 | private String expression=""; 16 | private String variable=""; 17 | private boolean validFormula = true; 18 | private String description;//describes the formula 19 | public Formulae(String expr){ 20 | parseFormulae(expr) ; 21 | } 22 | /** 23 | * 24 | * @return the formula's expression 25 | * i.e the quantity to the right of the equals sign. 26 | */ 27 | public String getExpression() { 28 | return expression; 29 | } 30 | /** 31 | * sets the formula or rather the expression( to the right of the equals sign ) 32 | * to be equal to the parameter given below. 33 | * @param expression the formula itself i.e the quantity to the right of the equals sign. 34 | */ 35 | public void setFormula(String expression) { 36 | this.expression = expression; 37 | } 38 | /** 39 | * 40 | * @return the variable string that we set to be equal to the formula 41 | */ 42 | public String getVariable() { 43 | return variable; 44 | } 45 | /** 46 | * sets the variable name to the given value. 47 | * @param variable the dependent variable that the formulae after evaluation will 48 | * store its value in. 49 | */ 50 | public void setVariable(String variable) { 51 | this.variable = variable; 52 | } 53 | /** 54 | * 55 | * @return returns true if the software can model 56 | * a valid Formula object from the user's input 57 | */ 58 | public boolean isValidFormula() { 59 | return validFormula; 60 | } 61 | /** 62 | * 63 | * @param validFormula set this to true if the software can model 64 | * a valid Formula object from the user's input 65 | */ 66 | public void setValidFormula(boolean validFormula) { 67 | this.validFormula = validFormula; 68 | } 69 | /** 70 | * 71 | * @return the description of the Formula 72 | */ 73 | public String getDescription() { 74 | return description; 75 | } 76 | /** 77 | * Sets the description of the Formula 78 | * @param description the description of the Formulae 79 | */ 80 | public void setDescription(String description) { 81 | this.description = description; 82 | } 83 | 84 | 85 | 86 | /** 87 | * 88 | * @return the String representaion of the Formulae object 89 | */ 90 | @Override 91 | public String toString(){ 92 | return variable+"="+expression; 93 | } 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | /* 102 | * the format of a formula storing command is: 103 | * STORE:variable=expression 104 | */ 105 | private void parseFormulae(String formulae){ 106 | formulae=purifier(formulae); 107 | 108 | if(!formulae.substring(0,6).equals("store:")){ 109 | setValidFormula(false); 110 | } 111 | else{ 112 | formulae=formulae.substring(6); 113 | int indexOfEquals=formulae.indexOf("="); 114 | 115 | try{ 116 | String var=formulae.substring(0,indexOfEquals); 117 | if(Variable.isVariableString( var ) ){ 118 | 119 | 120 | 121 | if(indexOfEquals!=-1){ 122 | this.variable=var; 123 | this.expression=formulae.substring(indexOfEquals+1); 124 | }//end if 125 | else{ 126 | Utils.logError( "The formula lacks a dependent variable...\n" + 127 | "An example of a valid formula format is y=7*x^5. Formula Format Error" ); 128 | setValidFormula(false); 129 | } 130 | 131 | 132 | }//end if 133 | else if(!Variable.isVariableString(var)){ 134 | Utils.logError( "The formula lacks a dependent variable...\n" + 135 | "An example of a valid formula format is y=7*x^5. Formula Format Error" ); 136 | setValidFormula(false); 137 | } 138 | 139 | }//end try 140 | catch(IndexOutOfBoundsException ind){ 141 | Utils.logError( "Error Occured During Formula Parse:\n" + 142 | "Cause:\n" + 143 | "Invalid Or No Formula Variable used.\n" + 144 | "Use The Format When Storing Your Formula:\n" + 145 | "Formula Variable = Formula Expression. e.g:" + 146 | "y = a*x^6. Formula Variable Error" ); 147 | setValidFormula(false); 148 | } 149 | 150 | 151 | 152 | }//end else 153 | 154 | 155 | 156 | }//end method parseFormulae 157 | 158 | 159 | 160 | 161 | 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/util/FormulaeManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util; 7 | 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 12 | * @author GBEMIRO 13 | */ 14 | public class FormulaeManager { 15 | ArrayListformulaStore=new ArrayList(); 16 | 17 | 18 | /** 19 | * records formulae as they are stored by the user 20 | * @param expr the formula to store 21 | */ 22 | public void recordFormula(String expr){ 23 | Formulae formulae=new Formulae(expr); 24 | if(!hasFormula(formulae)){ 25 | formulaStore.add( formulae ); 26 | } 27 | } 28 | /** 29 | * deletes Formulae objects based on their indices 30 | * @param index the position of the Formulae object within the store 31 | */ 32 | public void deleteFormula(int index){ 33 | formulaStore.remove(index); 34 | } 35 | /** 36 | * deletes Formulae objects based on their original expressions 37 | * @param expr The expression 38 | */ 39 | public void deleteFormula(String expr){ 40 | for(int i=0;i upStack = new Stack<>(); 22 | 23 | public static Stack downStack = new Stack<>(); 24 | 25 | public HistoryManager(){ 26 | } 27 | 28 | 29 | 30 | public void recordHistory(String expr){ 31 | try { 32 | String peekVal = upStack.peek(); 33 | if(expr!=null && !expr.isEmpty() ) { 34 | if (!peekVal.equals(expr)) { 35 | upStack.push(expr); 36 | } 37 | } 38 | } 39 | catch (EmptyStackException e){ 40 | if(expr!=null && !expr.isEmpty() ) { 41 | upStack.push(expr); 42 | } 43 | } 44 | 45 | 46 | 47 | 48 | 49 | } 50 | public String getNext( String currDisplayingInput){ 51 | try { 52 | 53 | 54 | String history = upStack.pop(); 55 | 56 | if (history != null) { 57 | downStack.push(history); 58 | } 59 | 60 | if(history.equals(currDisplayingInput)) { 61 | history = upStack.pop(); 62 | if (history != null) { 63 | downStack.push(history); 64 | } 65 | } 66 | 67 | 68 | return history; 69 | } 70 | catch (EmptyStackException ex){ 71 | return null; 72 | } 73 | } 74 | public String getPrevious( String currDisplayingInput){ 75 | try { 76 | 77 | 78 | String history = downStack.pop(); 79 | 80 | if (history != null) { 81 | upStack.push(history); 82 | } 83 | 84 | if(history.equals(currDisplayingInput)) { 85 | history = downStack.pop(); 86 | if (history != null) { 87 | upStack.push(history); 88 | } 89 | } 90 | 91 | 92 | return history; 93 | } 94 | catch (EmptyStackException ex){ 95 | return null; 96 | } 97 | } 98 | 99 | 100 | public void clearHistory(){ 101 | upStack.clear();downStack.clear(); 102 | } 103 | 104 | }//end class -------------------------------------------------------------------------------- /src/main/java/util/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package util; 7 | 8 | /** 9 | * 10 | * @author GBEMIRO JIBOYE , gbenroscience@gmail.com 11 | */ 12 | public class Log { 13 | 14 | public static final void e(String tag ,String msg) { 15 | System.err.printf("%s , %s",tag, msg); 16 | } 17 | 18 | public static final void d(String tag ,String msg) { 19 | System.out.printf("%s , %s",tag, msg); 20 | } 21 | 22 | public static final void i(String tag ,String msg) { 23 | System.out.printf("%s , %s",tag, msg); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/util/MatrixFormatException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util; 7 | 8 | /** 9 | * Is thrown whenever an illegal matrix string is found. 10 | * @author JIBOYE Oluwagbemiro Olaoluwa 11 | */ 12 | public class MatrixFormatException extends Exception { 13 | 14 | /** 15 | * Creates a new instance of MatrixFormatException without detail message. 16 | */ 17 | public MatrixFormatException() { 18 | super("Invalid Matrix Input"); 19 | } 20 | 21 | 22 | /** 23 | * Constructs an instance of MatrixFormatException with the specified detail message. 24 | * @param msg the detail message. 25 | */ 26 | public MatrixFormatException(String msg) { 27 | super(msg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/util/MatrixFunctionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util; 7 | 8 | import java.util.ArrayList; 9 | 10 | import math.matrix.expressParser.MatrixFunction; 11 | 12 | /** 13 | * 14 | * @author GBEMIRO 15 | */ 16 | public class MatrixFunctionManager { 17 | private ArrayList functions=new ArrayList(); 18 | 19 | /** 20 | * 21 | * @return all function objects stored by this FunctionManager object 22 | */ 23 | public ArrayList getFunctions() { 24 | return functions; 25 | } 26 | /** 27 | * 28 | * @param functions the store of Function objects that this FunctionManager object will store 29 | */ 30 | public void setFunctions(ArrayList functions) { 31 | this.functions = functions; 32 | } 33 | 34 | /** 35 | * checks if the Function object passed to it as an argument can be optimized or not 36 | * @param name 37 | * @return true if the Function is optimizable 38 | */ 39 | public boolean canOptimizeFunction(String name){ 40 | return getFunctionByName(name)!=null; 41 | } 42 | 43 | /** 44 | * stores a Function in objects of this class. 45 | * The storage is done in such a way that the object is inserted 46 | * from the front. 47 | * @param function the new Function to store 48 | */ 49 | public void storeFunction(MatrixFunction function){ 50 | if(!contains(function)){ 51 | functions.add(0,function); 52 | } 53 | } 54 | /** 55 | * 56 | * @param func the Function object to search for 57 | * @return true if the Function object is found 58 | */ 59 | public boolean contains(MatrixFunction func){ 60 | return functions.indexOf(func)!=-1; 61 | } 62 | 63 | 64 | public MatrixFunction getFunction(MatrixFunction function){ 65 | return functions.get(functions.indexOf(function)); 66 | } 67 | 68 | 69 | /** 70 | * 71 | * @param index the location from which we wish to retrieve the Function object 72 | * @return the Function object stored at the specified index. 73 | */ 74 | public MatrixFunction getFunctionAt(int index){ 75 | if(index>=0&&indexscanner){ 104 | int size=functions.size(); 105 | for(int i=0;iscanner){ 140 | int size=functions.size(); 141 | for(int i=0;i map, File file){ 33 | if(map==null||map.isEmpty()){ 34 | return; 35 | } 36 | 37 | FileWriter fw = null; 38 | BufferedWriter bw = null; 39 | try{ 40 | 41 | String newLine = System.getProperty("line.separator"); 42 | fw = new FileWriter(file.getAbsoluteFile()); 43 | bw = new BufferedWriter(fw); 44 | 45 | for(Map.Entryentry:map.entrySet()) { 46 | Function f = entry.getValue(); 47 | if (f!=null && !f.isAnonymous()){ 48 | String s = f.serialize(); 49 | bw.write(s + newLine); 50 | } 51 | } 52 | 53 | bw.flush(); 54 | } catch (Exception e) { 55 | 56 | } 57 | finally { 58 | if(fw!=null){ 59 | try { 60 | fw.close(); 61 | } 62 | catch (Exception e){} 63 | } 64 | if(bw!=null){ 65 | try { 66 | bw.close(); 67 | } 68 | catch (Exception e){} 69 | } 70 | } 71 | 72 | } 73 | 74 | /** 75 | * This reads the lines of text in a file into a {@link Map}. 76 | * Such that individual file lines become individual indexes on the {@link Map}. 77 | * 78 | * @param map A {@link Map} 79 | * @param fileToRead The file 80 | */ 81 | public static void readFileLinesToMap(Map map, File fileToRead){ 82 | if(map==null){ 83 | return; 84 | } 85 | 86 | BufferedReader in; 87 | try { 88 | FileReader stream = new FileReader(fileToRead); 89 | in = new BufferedReader( stream ); 90 | } 91 | catch (Exception e) { 92 | util.Utils.logError( 93 | "Sorry, but an error occurred \nwhile trying to open the file:/n" + e); 94 | return; 95 | } 96 | try { 97 | while (true) { 98 | String lineFromFile = in.readLine(); 99 | if (lineFromFile == null){ 100 | break; // End-of-file has been reached. 101 | } 102 | if(lineFromFile != null && !lineFromFile.equals("null")){ 103 | Function function = Function.parse(lineFromFile); 104 | map.put(function.getName(), function); 105 | } 106 | }//end while 107 | 108 | }//end try 109 | catch (Exception e) { 110 | util.Utils.logError("Sorry, but an error occurred \nwhile trying to read the data:/n" + e); 111 | } 112 | finally { 113 | if(in!=null) { 114 | try { 115 | in.close(); 116 | } catch (Exception e) { 117 | } 118 | } 119 | } 120 | }//end read method 121 | 122 | 123 | 124 | 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/util/io/TextFileReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package util.io; 7 | 8 | import java.io.*; 9 | 10 | 11 | /** 12 | * 13 | *@author JIBOYE Oluwagbemiro Olaoluwa 14 | */ 15 | public class TextFileReader { 16 | 17 | private File fileToRead; 18 | 19 | public TextFileReader(File fileToRead) { 20 | this.fileToRead = fileToRead; 21 | } 22 | 23 | public TextFileReader(String pathToFileToRead) { 24 | this.fileToRead = new File(pathToFileToRead); 25 | } 26 | 27 | public File getFileToRead() { 28 | return fileToRead; 29 | } 30 | 31 | public void setFileToRead(File fileToRead) { 32 | this.fileToRead = fileToRead; 33 | } 34 | 35 | public void setFileToRead(String fileToRead) { 36 | this.fileToRead = new File(fileToRead); 37 | } 38 | 39 | 40 | public String read(){ 41 | String text = ""; 42 | BufferedReader in; 43 | try { 44 | FileReader stream = new FileReader(fileToRead); 45 | in = new BufferedReader( stream ); 46 | } 47 | catch (Exception e) { 48 | util.Utils.logError( 49 | "Sorry, but an error occurred \nwhile trying to open the file:/n" + e); 50 | return ""; 51 | } 52 | try { 53 | while (true) { 54 | String lineFromFile = in.readLine(); 55 | if (lineFromFile == null){ 56 | break; // End-of-file has been reached. 57 | } 58 | text = text + lineFromFile; 59 | }//end while 60 | }//end try 61 | catch (Exception e) { 62 | util.Utils.logError( "Sorry, but an error occurred \nwhile trying to read the data:/n" + e); 63 | } 64 | return text; 65 | }//end read method 66 | 67 | 68 | 69 | 70 | 71 | 72 | } -------------------------------------------------------------------------------- /src/main/java/util/io/TextFileWriter.java: -------------------------------------------------------------------------------- 1 | package util.io; 2 | 3 | /* 4 | * To change this template, choose Tools | Templates 5 | * and open the template in the editor. 6 | */ 7 | 8 | 9 | 10 | import java.io.File; 11 | import java.io.FileNotFoundException; 12 | import java.io.FileOutputStream; 13 | import java.io.IOException; 14 | import java.io.ObjectOutputStream; 15 | import java.io.PrintWriter; 16 | import java.io.Serializable; 17 | import java.util.logging.Level; 18 | import java.util.logging.Logger; 19 | 20 | /** 21 | * 22 | * @author JIBOYE OLuwagbemiro Olaoluwa 23 | */ 24 | public class TextFileWriter implements Serializable{ 25 | private ObjectOutputStream output; // outputs data to file 26 | 27 | private String filePath; 28 | 29 | public TextFileWriter(String filePath){ 30 | this.filePath=filePath; 31 | File file=new File(filePath); 32 | if(!file.exists()){ 33 | try{ 34 | file.createNewFile(); 35 | } 36 | catch(IOException ion){ 37 | 38 | } 39 | } 40 | 41 | openFile(); 42 | } 43 | 44 | /** 45 | * Opens a file and prepares it for reading. 46 | */ 47 | private void openFile() 48 | { 49 | try // open file 50 | { 51 | output = new ObjectOutputStream( 52 | new FileOutputStream( filePath ) ); 53 | } // end try 54 | catch ( IOException ioException ) 55 | { 56 | System.err.println( "Error opening file." ); 57 | } // end catch 58 | } // end method openFile 59 | 60 | /** 61 | * Writes object data to the file 62 | * @param obj The data to be written. 63 | */ 64 | public void write(Object obj){ 65 | try{ 66 | output.writeObject(obj); 67 | } 68 | catch(IOException ioErr){ 69 | 70 | } 71 | close(); 72 | }//end method 73 | 74 | /** 75 | * Writes object data to the file 76 | * @param file The file 77 | * @param text The data to be written. 78 | */ 79 | public static void writeText(File file,String text){ 80 | 81 | PrintWriter writer; 82 | try { 83 | writer = new PrintWriter(new FileOutputStream(file), true); 84 | writer.write(text); 85 | writer.flush(); 86 | } catch (FileNotFoundException ex) { 87 | Logger.getLogger(TextFileWriter.class.getName()).log(Level.SEVERE, null, ex); 88 | } 89 | 90 | }//end method 91 | 92 | // close file and terminate application 93 | private void close() 94 | { 95 | try // close file 96 | { 97 | if ( output != null ) 98 | output.close(); 99 | } // end try 100 | catch ( IOException ioException ) 101 | { 102 | System.err.println( "Error closing file."); 103 | System.exit( 1 ); 104 | } // end catch 105 | } // end method closeFile 106 | 107 | public String getFilePath() { 108 | return filePath; 109 | } 110 | 111 | public void setFilePath(String filePath) { 112 | this.filePath = filePath; 113 | File file=new File(filePath); 114 | if(!file.exists()){ 115 | try{ 116 | file.createNewFile(); 117 | } 118 | catch(IOException ion){ 119 | 120 | } 121 | } 122 | 123 | openFile(); 124 | } 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | public static void main( String args[] ){ 135 | TextFileWriter.writeText( new File("Gbemiro's Friends.txt"), "But the word is nigh thee, even the word of faith, which we preach" 136 | + "that if thou wouldest confess with thy mouth Adonai Yeshua and thou wouldest believe" 137 | + "in thy heart that God hath raised Him from the dead,thou wilt be saved." 138 | + "For with the heart man believes unto righteousness and with the mouth confession is made unto salvation."); 139 | 140 | 141 | } 142 | 143 | } -------------------------------------------------------------------------------- /src/main/java/util/io/VariableBackup.java: -------------------------------------------------------------------------------- 1 | package util.io; 2 | 3 | 4 | import java.io.BufferedReader; 5 | import java.io.File; 6 | import java.io.FileReader; 7 | import java.util.Map; 8 | import java.util.Scanner; 9 | import java.io.BufferedWriter; 10 | import java.io.FileWriter; 11 | 12 | import parser.Variable; 13 | import util.Serializer; 14 | 15 | /** 16 | * 17 | * @author JIBOYE, OLUWAGBEMIRO OLAOLUWA on 8/17/2016. 18 | * 19 | */ 20 | public class VariableBackup { 21 | 22 | 23 | 24 | 25 | 26 | 27 | /** 28 | * This writes items on a queue to a file. 29 | * Individual items on the queue ocuupy 30 | * distinct lines in the file. 31 | * @param map The map of items 32 | * @param file The File 33 | */ 34 | public static void writeMapItemsToFileLineByLine(Map map, File file){ 35 | if(map==null||map.isEmpty()){ 36 | return; 37 | } 38 | 39 | FileWriter fw = null; 40 | BufferedWriter bw = null; 41 | try{ 42 | 43 | String newLine = System.getProperty("line.separator"); 44 | fw = new FileWriter(file.getAbsoluteFile()); 45 | bw = new BufferedWriter(fw); 46 | 47 | for(Map.Entryentry:map.entrySet()){ 48 | String s = entry.getValue().serialize(); 49 | if(s!=null && !s.equals("null")){ 50 | bw.write(s + newLine); 51 | } 52 | } 53 | 54 | bw.flush(); 55 | } catch (Exception e) { 56 | 57 | } 58 | finally { 59 | if(fw!=null){ 60 | try { 61 | fw.close(); 62 | } 63 | catch (Exception e){} 64 | } 65 | if(bw!=null){ 66 | try { 67 | bw.close(); 68 | } 69 | catch (Exception e){} 70 | } 71 | } 72 | 73 | } 74 | /** 75 | * This reads the lines of text in a file into a {@link Map}. 76 | * Such that individual file lines become individual indexes on the {@link Map}. 77 | * 78 | * @param map A {@link Map} 79 | * @param file The file 80 | */ 81 | public static void read(Map map, File file){ 82 | if(map==null){ 83 | System.out.println("Vars read failed!"); 84 | return; 85 | } 86 | 87 | Scanner s = null; 88 | try{ 89 | s = new Scanner(file); 90 | while (s.hasNextLine()){ 91 | String text = s.nextLine(); 92 | if(text != null && !text.equals("null")){ 93 | Variable v = Variable.parse(text); 94 | map.put(v.getName(), v); 95 | } 96 | }//end while loop\ 97 | System.out.println("Vars read ended!"); 98 | } catch (Exception ex) { 99 | ex.printStackTrace(); 100 | } 101 | finally { 102 | if(s!=null){ 103 | try{ 104 | s.close(); 105 | } 106 | catch (Exception e){ 107 | 108 | } 109 | } 110 | } 111 | 112 | 113 | } 114 | 115 | /** 116 | * This reads the lines of text in a file into a {@link Map}. 117 | * Such that individual file lines become individual indexes on the {@link Map}. 118 | * 119 | * @param map A {@link Map} 120 | * @param fileToRead The file 121 | */ 122 | public static void readFileLinesToMap(Map map, File fileToRead){ 123 | if(map==null){ 124 | return; 125 | } 126 | 127 | BufferedReader in; 128 | try { 129 | FileReader stream = new FileReader(fileToRead); 130 | in = new BufferedReader( stream ); 131 | } 132 | catch (Exception e) { 133 | util.Utils.logError( 134 | "Sorry, but an error occurred \nwhile trying to open the file:/n" + e); 135 | return; 136 | } 137 | try { 138 | while (true) { 139 | String lineFromFile = in.readLine(); 140 | if (lineFromFile == null){ 141 | break; // End-of-file has been reached. 142 | } 143 | if(lineFromFile != null && !lineFromFile.equals("null")){ 144 | Variable v = Variable.parse(lineFromFile); 145 | map.put(v.getName(), v); 146 | } 147 | }//end while 148 | 149 | }//end try 150 | catch (Exception e) { 151 | util.Utils.logError("Sorry, but an error occurred \nwhile trying to read the data:/n" + e); 152 | } 153 | finally { 154 | if(in!=null) { 155 | try { 156 | in.close(); 157 | } catch (Exception e) { 158 | } 159 | } 160 | } 161 | }//end read method 162 | 163 | 164 | 165 | 166 | 167 | 168 | } 169 | -------------------------------------------------------------------------------- /src/test/java/math/BigDecimalNthRootCalculationTest.java: -------------------------------------------------------------------------------- 1 | package math; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.math.BigDecimal; 7 | import java.math.MathContext; 8 | import java.math.RoundingMode; 9 | 10 | class BigDecimalNthRootCalculationTest { 11 | 12 | @Test 13 | void geomTest() { 14 | Assertions.assertEquals(0, new BigDecimal("2").compareTo(BigDecimalNthRootCalculation.nthRoot(2, new BigDecimal("4")))); 15 | Assertions.assertEquals(0, new BigDecimal("3").compareTo(BigDecimalNthRootCalculation.nthRoot(3, new BigDecimal("27")))); 16 | Assertions.assertEquals(0, new BigDecimal("2").compareTo(BigDecimalNthRootCalculation.nthRoot(8, new BigDecimal("256")))); 17 | Assertions.assertEquals(0, new BigDecimal("2").compareTo(BigDecimalNthRootCalculation.nthRoot(6, new BigDecimal("64")))); 18 | Assertions.assertEquals(0, new BigDecimal("3.36").compareTo(BigDecimalNthRootCalculation.nthRoot(3, new BigDecimal("38"), new MathContext(3, RoundingMode.HALF_DOWN)))); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/test/java/math/MainTest.java: -------------------------------------------------------------------------------- 1 | package math; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.Arrays; 7 | 8 | class MainTest { 9 | 10 | @Test 11 | void help() { 12 | Main.help(); 13 | } 14 | 15 | @Test 16 | void examples() { 17 | Main.examples(); 18 | } 19 | 20 | @Test 21 | void joinArgs() { 22 | String r; 23 | r = Main.joinArgs(Arrays.asList("1", "+", "1"), true); 24 | Assertions.assertEquals("1 + 1 ", r); 25 | r = Main.joinArgs(Arrays.asList("1", "+", "1"), false); 26 | Assertions.assertEquals("1 + 1 ", r); 27 | r = Main.joinArgs(Arrays.asList("1\n", "+\n", "1\n"), true); 28 | Assertions.assertEquals("1 + 1 ", r); 29 | r = Main.joinArgs(Arrays.asList("1\n", "+\n", "1\n"), false); 30 | Assertions.assertEquals("1\n" 31 | + " +\n" 32 | + " 1\n" 33 | + " ", r); 34 | } 35 | } -------------------------------------------------------------------------------- /src/test/java/parser/SetTest.java: -------------------------------------------------------------------------------- 1 | package parser; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.math.BigDecimal; 7 | import java.util.Arrays; 8 | 9 | class SetTest { 10 | 11 | @Test 12 | void gsumTest() { 13 | Set s = new Set(Arrays.asList("2","3","4")); 14 | Assertions.assertEquals(0, new BigDecimal("24").compareTo(s.gsum())); 15 | } 16 | 17 | @Test 18 | void sizeTest() { 19 | Set s = new Set(Arrays.asList("2","3","4")); 20 | Assertions.assertEquals(3, s.size()); 21 | } 22 | 23 | @Test 24 | void geomTest() { 25 | Set s = new Set(Arrays.asList("2","8", "4")); 26 | Assertions.assertEquals(0, new BigDecimal("4").compareTo(s.geom())); 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/java/parser/expanding/ExpandingExpressionParserWithReplacableLogicTest.java: -------------------------------------------------------------------------------- 1 | package parser.expanding; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | 7 | import java.util.Arrays; 8 | 9 | import parser.ExpandingExpression; 10 | import parser.logical.LogicalExpressionFactoryTest; 11 | import parser.logical.PrintingExpressionLogger; 12 | 13 | 14 | import static parser.expanding.ExpandingExpressionParserTest.revert; 15 | 16 | class ExpandingExpressionParserWithReplacableLogicTest { 17 | 18 | private static PrintingExpressionLogger log = new PrintingExpressionLogger(); 19 | 20 | @Test 21 | void weirdRegressions() { 22 | Assertions.assertTrue(new ExpandingExpressionParser("1+1 < ((2+0)*1) impl false eq false", revert(Arrays.asList("1", "2", "3")), log).evaluate()); 23 | Assertions.assertFalse(new ExpandingExpressionParser("L0L1 and L2>L3", (Arrays.asList("0", "1", "-1", "2")), log).evaluate()); 32 | //custom 33 | Exception ex = null; 34 | try { 35 | Assertions.assertTrue(new ExpandingExpressionParser("L0>L1 and L2>L3", (Arrays.asList("0", "1", "-1", "2")), log, new LogicalExpressionFactoryTest.HogwartsMemberFactory()).evaluate()); 36 | } catch (Exception ex1) { 37 | ex = ex1; 38 | } 39 | Assertions.assertTrue(new ExpandingExpressionParser("harry(L0..L2) and ron(L0..L2)", (Arrays.asList("0", "1", "-1", "2")), log, new LogicalExpressionFactoryTest.HogwartsMemberFactory()).evaluate()); 40 | Assertions.assertFalse(new ExpandingExpressionParser("tom(L0..L2) and ron(L0..L2)", (Arrays.asList("0", "1", "-1", "2")), log, new LogicalExpressionFactoryTest.HogwartsMemberFactory()).evaluate()); 41 | Assertions.assertNotNull(ex); 42 | //not affected 43 | Assertions.assertTrue(new ExpandingExpressionParser("true and true", (Arrays.asList("0", "1", "-1", "2")), log).evaluate()); 44 | Assertions.assertFalse(new ExpandingExpressionParser("false and true", (Arrays.asList("0", "1", "-1", "2")), log).evaluate()); 45 | } 46 | 47 | @Test 48 | void replacableLogicalExpressionBracketsWithExpansion() { 49 | //correct 50 | Assertions.assertEquals("true", new ExpandingExpression("[ L0L1 and L2<2L3] or [L0>L1 and L2L1 and L2<2L3] or [L0>L1 and L2L1 and L2<2L3] or [L0>L1 and L2 s; 14 | ComparingExpressionParser comp; 15 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 < 5"); 16 | Assertions.assertEquals(3, s.size()); 17 | Assertions.assertEquals("1+2+3", s.get(0)); 18 | Assertions.assertEquals("<", s.get(1)); 19 | Assertions.assertEquals("5", s.get(2)); 20 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 > 5"); 21 | Assertions.assertEquals(3, s.size()); 22 | Assertions.assertEquals("1+2+3", s.get(0)); 23 | Assertions.assertEquals(">", s.get(1)); 24 | Assertions.assertEquals("5", s.get(2)); 25 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 == 5"); 26 | Assertions.assertEquals(3, s.size()); 27 | Assertions.assertEquals("1+2+3", s.get(0)); 28 | Assertions.assertEquals("==", s.get(1)); 29 | Assertions.assertEquals("5", s.get(2)); 30 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 != 5"); 31 | Assertions.assertEquals(3, s.size()); 32 | Assertions.assertEquals("1+2+3", s.get(0)); 33 | Assertions.assertEquals("!=", s.get(1)); 34 | Assertions.assertEquals("5", s.get(2)); 35 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 >= 5"); 36 | Assertions.assertEquals(3, s.size()); 37 | Assertions.assertEquals("1+2+3", s.get(0)); 38 | Assertions.assertEquals(">=", s.get(1)); 39 | Assertions.assertEquals("5", s.get(2)); 40 | s = new ComparingExpressionParser("not important now", log).split("1+2+3 <= 5"); 41 | Assertions.assertEquals(3, s.size()); 42 | Assertions.assertEquals("1+2+3", s.get(0)); 43 | Assertions.assertEquals("<=", s.get(1)); 44 | Assertions.assertEquals("5", s.get(2)); 45 | 46 | } 47 | 48 | @org.junit.jupiter.api.Test 49 | void evalTest() { 50 | ComparingExpressionParser comp; 51 | comp = new ComparingExpressionParser("1+2+3 < 2*2", log); 52 | Assertions.assertFalse(comp.evaluate()); 53 | comp = new ComparingExpressionParser("1+2+3 > 2*2", log); 54 | Assertions.assertTrue(comp.evaluate()); 55 | comp = new ComparingExpressionParser("1+2 <= 3*2", log); 56 | Assertions.assertTrue(comp.evaluate()); 57 | comp = new ComparingExpressionParser("1+2+3 <= 3*2", log); 58 | Assertions.assertTrue(comp.evaluate()); 59 | comp = new ComparingExpressionParser("30 <= 3*2", log); 60 | Assertions.assertFalse(comp.evaluate()); 61 | comp = new ComparingExpressionParser("1+2+3 == 3*2", log); 62 | Assertions.assertTrue(comp.evaluate()); 63 | comp = new ComparingExpressionParser("1+2+3 == 3*2+1", log); 64 | Assertions.assertFalse(comp.evaluate()); 65 | comp = new ComparingExpressionParser("1+2+3 != 3*2+1", log); 66 | Assertions.assertTrue(comp.evaluate()); 67 | comp = new ComparingExpressionParser("10 >= 6", log); 68 | Assertions.assertTrue(comp.evaluate()); 69 | comp = new ComparingExpressionParser("1+2+3 >= 6", log); 70 | Assertions.assertTrue(comp.evaluate()); 71 | comp = new ComparingExpressionParser("1+2+3 >= 7", log); 72 | Assertions.assertFalse(comp.evaluate()); 73 | 74 | comp = new ComparingExpressionParser(" true", log); 75 | Assertions.assertTrue(comp.evaluate()); 76 | comp = new ComparingExpressionParser("false ", log); 77 | Assertions.assertFalse(comp.evaluate()); 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /src/test/java/parser/logical/PrintingExpressionLogger.java: -------------------------------------------------------------------------------- 1 | package parser.logical; 2 | 3 | public class PrintingExpressionLogger implements ExpressionLogger { 4 | 5 | private final boolean tests_verbose = true; 6 | 7 | @Override 8 | public void log(String s) { 9 | if (tests_verbose) { 10 | System.out.println(s); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/parser/methods/DeclarationsTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods; 2 | 3 | import logic.DRG_MODE; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | import parser.MathExpression; 7 | import parser.TYPE; 8 | import parser.methods.ext.Utils; 9 | 10 | import java.math.BigDecimal; 11 | import java.util.List; 12 | 13 | class DeclarationsTest { 14 | @Test 15 | void fromJunk() { 16 | MathExpression me = new MathExpression("x=10;sin(ln(x))"); 17 | Assertions.assertTrue("0.743980336957493".equals(me.solve()) || "0.7439803369574931".equals(me.solve()));//different on jdk11+ and 8- 18 | } 19 | 20 | @Test 21 | void hardcodedFunctionCanBeOverwritten() { 22 | MathExpression me; 23 | me = new MathExpression("prod(1+1,2+2)"); 24 | Assertions.assertEquals("8.0", me.solve()); 25 | me = new MathExpression("prod(1+1)"); 26 | Assertions.assertEquals("2.0", me.solve()); 27 | BasicNumericalMethod override = new BasicNumericalMethod() { 28 | @Override 29 | public String solve(List tokens) { 30 | List numericalTokens = Utils.tokensToNumbers(tokens); 31 | BigDecimal result = new BigDecimal("1"); 32 | for(BigDecimal numericalToken: numericalTokens){ 33 | result = result.multiply(numericalToken); 34 | } 35 | return result.toString(); 36 | } 37 | 38 | @Override 39 | public String getHelp() { 40 | return "fake prod"; 41 | } 42 | 43 | @Override 44 | public String getName() { 45 | return "prod"; 46 | } 47 | 48 | @Override 49 | public String getType() { 50 | return TYPE.NUMBER.toString(); 51 | } 52 | }; 53 | int before = Declarations.getInbuiltMethods().length; 54 | Declarations.registerBasicNumericalMethod(override); 55 | int during = Declarations.getInbuiltMethods().length; 56 | try { 57 | me = new MathExpression("prod(1+1)"); 58 | Assertions.assertEquals("2.0", me.solve()); 59 | } finally { 60 | Declarations.unregisterBasicNumericalMethod(override.getClass()); 61 | } 62 | int after = Declarations.getInbuiltMethods().length; 63 | me = new MathExpression("prod(1+1)"); 64 | Assertions.assertEquals("2.0", me.solve()); 65 | Assertions.assertEquals(before, after); 66 | Assertions.assertEquals(before+1, during); 67 | } 68 | 69 | @Test 70 | void changeDegRadGradViaProperty() { 71 | try { 72 | MathExpression me; 73 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "DEG"); 74 | me = new MathExpression("sin(1)"); 75 | Assertions.assertEquals("0.01745240643728351", me.solve()); 76 | me = new MathExpression("sin(1)"); 77 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "RAD"); 78 | me = new MathExpression("sin(1)"); 79 | Assertions.assertEquals("0.8414709848078965", me.solve()); 80 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "GRAD"); 81 | me = new MathExpression("sin(1)"); 82 | Assertions.assertEquals("0.015707317311820675", me.solve()); 83 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "GRAD"); 84 | me = new MathExpression("sin(1)"); 85 | Assertions.assertEquals("0.015707317311820675", me.solve()); 86 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "RAD"); 87 | Assertions.assertEquals("0.015707317311820675", me.solve()); //do not affect existing instances 88 | me = new MathExpression("sin(1)"); //is affecting all future nstance 89 | Assertions.assertEquals("0.8414709848078965", me.solve()); 90 | } finally { 91 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "RAD"); 92 | } 93 | } 94 | 95 | @Test 96 | void changeDegRadGradViaSetter() { 97 | try { 98 | MathExpression meR = new MathExpression("sin(1)"); 99 | meR.setDRG(DRG_MODE.RAD); 100 | Assertions.assertEquals("0.8414709848078965", meR.solve()); 101 | MathExpression meG = new MathExpression("sin(1)"); 102 | meG.setDRG(DRG_MODE.GRAD); 103 | Assertions.assertEquals("0.015707317311820675", meG.solve()); 104 | MathExpression meD = new MathExpression("sin(1)"); 105 | meD.setDRG(DRG_MODE.DEG); 106 | Assertions.assertEquals("0.01745240643728351", meD.solve()); 107 | Assertions.assertEquals("0.8414709848078965", meR.solve()); 108 | Assertions.assertEquals("0.015707317311820675", meG.solve()); 109 | Assertions.assertEquals("0.01745240643728351", meD.solve()); 110 | } finally { 111 | System.setProperty(DRG_MODE.DEG_MODE_VARIABLE, "RAD"); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/test/java/parser/methods/ProdTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import parser.MathExpression; 7 | 8 | public class ProdTest { 9 | 10 | @Test 11 | void prodAcceptsOnePlainArgument() { 12 | MathExpression me; 13 | me = new MathExpression("prod(5)"); 14 | Assertions.assertEquals("5.0", me.solve()); 15 | } 16 | 17 | @Test 18 | void prodAcceptsOnePlainExpression() { 19 | MathExpression me; 20 | me = new MathExpression("prod(5+5)"); 21 | Assertions.assertEquals("10.0", me.solve()); 22 | } 23 | 24 | 25 | @Test 26 | void prodAcceptsTwoPlainArguments() { 27 | MathExpression me; 28 | me = new MathExpression("prod(5,6)"); 29 | Assertions.assertEquals("30.0", me.solve()); 30 | } 31 | 32 | @Test 33 | void prodAcceptsTwoPlainExpressions() { 34 | MathExpression me; 35 | me = new MathExpression("prod(5+5, 4+4)"); 36 | Assertions.assertEquals("80.0", me.solve()); 37 | } 38 | 39 | @Test 40 | void prodAcceptsStatFunction() { 41 | MathExpression me; 42 | me = new MathExpression("prod(prod(5))"); 43 | Assertions.assertEquals("5.0", me.solve()); 44 | } 45 | 46 | @Test 47 | void prodAcceptsNumFunction() { 48 | MathExpression me; 49 | me = new MathExpression("prod(sin(5))"); 50 | Assertions.assertEquals("-0.9589242746631385", me.solve()); 51 | } 52 | 53 | @Test 54 | void prodAcceptsTwoStatFunction() { 55 | MathExpression me; 56 | me = new MathExpression("prod(prod(5),prod(6))"); 57 | Assertions.assertEquals("30.0", me.solve()); 58 | } 59 | 60 | @Test 61 | void prodAcceptsTwoNumFunction() { 62 | MathExpression me; 63 | me = new MathExpression("prod(sin(5),sin(5))"); 64 | Assertions.assertEquals("0.9195357645382262", me.solve()); 65 | } 66 | 67 | @Test 68 | void prodAcceptsStatAndNumFunction() { 69 | MathExpression me; 70 | me = new MathExpression("prod(prod(5),sin(5))"); 71 | Assertions.assertEquals("-4.794621373315692", me.solve()); 72 | me = new MathExpression("prod(sin(5),prod(5))"); 73 | Assertions.assertEquals("-4.794621373315692", me.solve()); 74 | } 75 | } -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/AbsTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import parser.MathExpression; 9 | 10 | class AbsTest { 11 | 12 | @Test 13 | void absWorks() { 14 | MathExpression me; 15 | me = new MathExpression("abs(1)"); 16 | Assertions.assertEquals("1", me.solve()); 17 | me = new MathExpression("abs(1.1259)"); 18 | Assertions.assertEquals("1.1259", me.solve()); 19 | me = new MathExpression("abs(-1)"); 20 | Assertions.assertEquals("1.0", me.solve()); 21 | me = new MathExpression("abs(-1.1259)"); 22 | Assertions.assertEquals("1.1259", me.solve()); 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/AvgNTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import parser.MathExpression; 6 | 7 | public class AvgNTest { 8 | 9 | @Test 10 | void zeroZero() { 11 | MathExpression me = new MathExpression("avgN(0,0)"); 12 | Assertions.assertEquals("0", me.solve()); 13 | me = new MathExpression("avgN(1,0)"); 14 | Assertions.assertEquals("0", me.solve()); 15 | me = new MathExpression("avgN(2,0)"); 16 | Assertions.assertEquals("0", me.solve()); 17 | me = new MathExpression("avgN(3,0)"); 18 | Assertions.assertEquals("0", me.solve()); 19 | me = new MathExpression("avgN(0,1)"); 20 | Assertions.assertEquals("1", me.solve()); 21 | me = new MathExpression("avgN(0,1,2)"); 22 | Assertions.assertEquals("1.5", me.solve()); 23 | me = new MathExpression("avgN(0,1,2,3)"); 24 | Assertions.assertEquals("2", me.solve()); 25 | } 26 | 27 | @Test 28 | void decimalsInCountWorksAsHould() { 29 | MathExpression me; 30 | me = new MathExpression("avgN(0.4, 1, 2, 3, 4, 15)"); 31 | Assertions.assertEquals("5", me.solve()); 32 | me = new MathExpression("avgN(0.6, 1, 2, 3, 4, 15)"); 33 | Assertions.assertEquals("3", me.solve()); 34 | } 35 | 36 | @Test 37 | void limitWorks() { 38 | MathExpression me = new MathExpression("avgN(1,45,1,55,1000)"); 39 | Assertions.assertEquals("50", me.solve()); 40 | me = new MathExpression("avgN(2,45,1,1000,55)"); 41 | Assertions.assertEquals("50", me.solve()); 42 | me = new MathExpression("avgN(2,45,1,1000,80,55)"); 43 | // the avgN default size DEFAULT_AVGN_MISIZE is two, thus 45,1,1000,80,55 -> 1,45,55,80,1000-> 45,55,70 => 180/3 44 | Assertions.assertEquals("60", me.solve()); 45 | me = new MathExpression("avgN(3,45,1,1000,80,55)"); 46 | Assertions.assertEquals("60", me.solve()); 47 | me = new MathExpression("avgN(3,45,1,1000,80,55,0)"); 48 | Assertions.assertEquals("50", me.solve()); 49 | me = new MathExpression("avgN(3,45,1,1000,80,55,0,0)"); 50 | // the avgN default size DEFAULT_AVGN_MISIZE is two, thus 45,1,1000,80,55,0,0 -> 0,0,1,45,55,80,1000-> 1,45,55=> 101/3 51 | Assertions.assertEquals("33.66666667", me.solve()); 52 | me = new MathExpression("avgN(3,45,1,1000,80,55,0,0,0)"); 53 | Assertions.assertEquals("23", me.solve()); 54 | } 55 | 56 | @Test 57 | void testEmpty() { 58 | MathExpression me; 59 | me = new MathExpression("avgN(1+1)"); 60 | Assertions.assertEquals("0", me.solve()); 61 | me = new MathExpression("avgN(1)"); 62 | Assertions.assertEquals("0", me.solve()); 63 | } 64 | 65 | @Test 66 | void testExpres() { 67 | MathExpression me; 68 | me = new MathExpression("avgN(0+1, 0+1)"); 69 | Assertions.assertEquals("1.0", me.solve()); 70 | me = new MathExpression("avgN(avgN(0,1), avgN(0,1))"); 71 | Assertions.assertEquals("1", me.solve()); 72 | } 73 | 74 | @Test 75 | void avgNFromExpressions() { 76 | MathExpression me; 77 | me = new MathExpression("avgN(0,4+0,2+0)"); 78 | Assertions.assertEquals("3.0", me.solve()); 79 | me = new MathExpression("avg(4+0,2+0)"); 80 | Assertions.assertEquals("3.0", me.solve()); 81 | me = new MathExpression("avg(0,3/2,2/3)"); 82 | Assertions.assertEquals("0.7222222222", me.solve()); 83 | me = new MathExpression("avg(round(0.5),round(0.5))"); 84 | Assertions.assertEquals("1", me.solve()); 85 | me = new MathExpression("avgN(0,round(0.5),round(0.5))"); 86 | Assertions.assertEquals("1", me.solve()); 87 | me = new MathExpression("round(avg(0,3/2,2/3))"); 88 | Assertions.assertEquals("1", me.solve()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/GeomNTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import parser.MathExpression; 7 | 8 | public class GeomNTest { 9 | 10 | @Test 11 | void zeroZero() { 12 | MathExpression me = new MathExpression("geomN(0,0)"); 13 | Assertions.assertEquals("0", me.solve()); 14 | me = new MathExpression("geomN(1,0)"); 15 | Assertions.assertEquals("0", me.solve()); 16 | me = new MathExpression("geomN(2,0)"); 17 | Assertions.assertEquals("0", me.solve()); 18 | me = new MathExpression("geomN(3,0)"); 19 | Assertions.assertEquals("0", me.solve()); 20 | me = new MathExpression("geomN(0,1)"); 21 | Assertions.assertEquals("1", me.solve()); 22 | me = new MathExpression("geomN(0,1,2)"); 23 | Assertions.assertEquals("1.414213562", me.solve()); 24 | me = new MathExpression("geomN(0,1,2,3)"); 25 | Assertions.assertEquals("1.817120593", me.solve()); 26 | } 27 | 28 | @Test 29 | void decimalsInCountWorksAsHould() { 30 | MathExpression me; 31 | me = new MathExpression("geomN(0.4, 1, 2, 3, 4, 15)"); 32 | Assertions.assertEquals("3.245342223", me.solve()); 33 | me = new MathExpression("geomN(0.6, 1, 2, 3, 4, 15)"); 34 | Assertions.assertEquals("2.884499141", me.solve()); 35 | } 36 | 37 | @Test 38 | void limitWorks() { 39 | MathExpression me = new MathExpression("geomN(1,2,1,4,1000,8)"); 40 | Assertions.assertEquals("4.000000000", me.solve()); 41 | me = new MathExpression("geomN(2,10,1,1000,10)"); 42 | Assertions.assertEquals("10.00000000", me.solve()); 43 | me = new MathExpression("geomN(2,2,1,1000,8,4)"); 44 | Assertions.assertEquals("4.000000000", me.solve()); 45 | me = new MathExpression("geomN(3,4,1,1000,8,2)"); 46 | Assertions.assertEquals("4.000000000", me.solve()); 47 | me = new MathExpression("geomN(3,45,1,1000,70,55,0)"); 48 | Assertions.assertEquals("49.74937185", me.solve()); 49 | me = new MathExpression("geomN(3,45,1,1000,70,55,0,0)"); 50 | Assertions.assertEquals("13.52669614", me.solve()); 51 | me = new MathExpression("geomN(3,45,1,1000,70,55,0,0,0)"); 52 | Assertions.assertEquals("6.708203932", me.solve()); 53 | } 54 | 55 | @Test 56 | void testEmpty() { 57 | MathExpression me; 58 | me = new MathExpression("geomN(1+1)"); 59 | Assertions.assertEquals("0", me.solve()); 60 | me = new MathExpression("geomN(1)"); 61 | Assertions.assertEquals("0", me.solve()); 62 | } 63 | 64 | @Test 65 | void testExpres() { 66 | MathExpression me; 67 | me = new MathExpression("geomN(0+1, 0+1)"); 68 | Assertions.assertEquals("1.0", me.solve()); 69 | me = new MathExpression("geomN(geomN(0,1), geomN(0,1))"); 70 | Assertions.assertEquals("1", me.solve()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/GsumAvgGeomCountTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import parser.MathExpression; 6 | 7 | public class GsumAvgGeomCountTest { 8 | 9 | @Test 10 | void issue25() { 11 | MathExpression me; 12 | me = new MathExpression("avg(1+13)"); 13 | Assertions.assertEquals("14.0", me.solve()); 14 | me = new MathExpression("count(1+13)"); 15 | Assertions.assertEquals("1", me.solve()); 16 | me = new MathExpression("geom(1+13)"); 17 | Assertions.assertEquals("14.0", me.solve()); 18 | me = new MathExpression("gsum(1+13)"); 19 | Assertions.assertEquals("14.0", me.solve()); 20 | } 21 | 22 | @Test 23 | void avg() { 24 | MathExpression me = new MathExpression("avg(1,3)"); 25 | Assertions.assertEquals("2", me.solve()); 26 | me = new MathExpression("avg(1,3,1)"); 27 | Assertions.assertEquals("1.666666667", me.solve()); 28 | } 29 | 30 | @Test 31 | void geom() { 32 | MathExpression me = new MathExpression("geom(1,2,4)"); 33 | Assertions.assertEquals("2.000000000", me.solve()); 34 | me = new MathExpression("geom(1,3,1)"); 35 | Assertions.assertEquals("1.442249570", me.solve()); 36 | } 37 | 38 | @Test 39 | void gsumExpression() { 40 | MathExpression me = new MathExpression("gsum(1,1,2,3)"); 41 | Assertions.assertEquals("6", me.solve()); 42 | } 43 | 44 | @Test 45 | void geomExpression() { 46 | MathExpression me = new MathExpression("geom(2,8,4)"); 47 | Assertions.assertEquals("4.000000000", me.solve()); 48 | } 49 | 50 | 51 | @Test 52 | void countExpression() { 53 | MathExpression me = new MathExpression("count(1,1,2,3,3)"); 54 | Assertions.assertEquals("5", me.solve()); 55 | } 56 | 57 | 58 | @Test 59 | void geomExpressionMultipleBrackets() {//((2+0.0)(16.0-8)4) 60 | MathExpression me = new MathExpression("geom((2+((2-2)),(8+8)-(((8))),4))"); 61 | Assertions.assertEquals("4.000000000", me.solve()); 62 | me = new MathExpression("(geom(((2,8,4))))"); 63 | Assertions.assertEquals("4.000000000", me.solve()); 64 | me = new MathExpression("geom((2,8,4))+geom(((2,8,4)))"); 65 | Assertions.assertEquals("8.0", me.solve()); 66 | me = new MathExpression("(geom((2+((2-2)),(8+8)-(((8))),4))+geom(((2,8,4))))"); 67 | Assertions.assertEquals("8.0", me.solve()); 68 | me = new MathExpression("((((geom((2,8,4))+geom(((2,8,4)))))))"); 69 | Assertions.assertEquals("8.0", me.solve()); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/LengthsTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import parser.MathExpression; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | class LengthsTest { 10 | 11 | @Test 12 | void lengthsTest() { 13 | MathExpression me; 14 | me = new MathExpression("lengthFractional(20)"); 15 | Assertions.assertEquals("0", me.solve()); 16 | me = new MathExpression("length(1)"); 17 | Assertions.assertEquals("1", me.solve()); 18 | me = new MathExpression("length(-1.35)"); 19 | Assertions.assertEquals("3", me.solve()); 20 | me = new MathExpression("lengthFractional(-1.35)"); 21 | Assertions.assertEquals("2", me.solve()); 22 | me = new MathExpression("lengthDecimal(-1.35)"); 23 | Assertions.assertEquals("1", me.solve()); 24 | me = new MathExpression("length(-1.35)"); 25 | Assertions.assertEquals("3", me.solve()); 26 | me = new MathExpression("length(1E5)"); 27 | Assertions.assertEquals("6", me.solve()); 28 | me = new MathExpression("length(-1E-5)"); 29 | Assertions.assertEquals("5", me.solve()); 30 | me = new MathExpression("lengthFractional(1E-5)"); 31 | Assertions.assertEquals("5", me.solve()); 32 | me = new MathExpression("lengthDecimal(-1E-5)"); 33 | Assertions.assertEquals("0", me.solve()); 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/SinTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import parser.MathExpression; 6 | 7 | public class SinTest { 8 | 9 | @Test 10 | void sinAcceptsOnePlainArgument() { 11 | MathExpression me; 12 | me = new MathExpression("sin(5)"); 13 | Assertions.assertEquals("-0.9589242746631385", me.solve()); 14 | } 15 | 16 | @Test 17 | void sinAcceptsOnePlainExpression() { 18 | MathExpression me; 19 | me = new MathExpression("sin(5+5)"); 20 | Assertions.assertEquals("-0.5440211108893698", me.solve()); 21 | } 22 | 23 | 24 | @Test 25 | void sinDontAcceptsTwoPlainArguments() { 26 | MathExpression me; 27 | me = new MathExpression("sin(5,6)"); 28 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 29 | } 30 | 31 | @Test 32 | void sinDontAcceptsTwoPlainExpressions() { 33 | MathExpression me; 34 | me = new MathExpression("sin(5+5, 4+4)"); 35 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 36 | } 37 | 38 | @Test 39 | void sinAcceptsStatFunction() { 40 | MathExpression me; 41 | me = new MathExpression("sin(sum(5))"); 42 | Assertions.assertEquals("-0.9589242746631385", me.solve()); 43 | } 44 | 45 | @Test 46 | void sinAcceptsNumFunction() { 47 | MathExpression me; 48 | me = new MathExpression("sin(sin(5))"); 49 | Assertions.assertEquals("-0.8185741444617193", me.solve()); 50 | } 51 | 52 | @Test 53 | void sinDontAcceptsTwoStatFunction() { 54 | MathExpression me; 55 | me = new MathExpression("sin(sum(5),sum(6))"); 56 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 57 | } 58 | 59 | @Test 60 | void sinDontAcceptsTwoNumFunction() { 61 | MathExpression me; 62 | me = new MathExpression("sin(sin(5),sin(5))"); 63 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 64 | } 65 | 66 | @Test 67 | void sinDontAcceptsStatAndNumFunction() { 68 | MathExpression me; 69 | me = new MathExpression("sin(sin(5),sum(5))"); 70 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 71 | me = new MathExpression("sin(sum(5),sin(5))"); 72 | Assertions.assertEquals("SYNTAX ERROR", me.solve()); 73 | } 74 | } -------------------------------------------------------------------------------- /src/test/java/parser/methods/ext/SumTest.java: -------------------------------------------------------------------------------- 1 | package parser.methods.ext; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import parser.MathExpression; 6 | 7 | public class SumTest { 8 | 9 | @Test 10 | void sumAcceptsOnePlainArgument() { 11 | MathExpression me; 12 | me = new MathExpression("sum(5)"); 13 | Assertions.assertEquals("5", me.solve()); 14 | } 15 | 16 | @Test 17 | void sumAcceptsOnePlainExpression() { 18 | MathExpression me; 19 | me = new MathExpression("sum(5+5)"); 20 | Assertions.assertEquals("10.0", me.solve()); 21 | } 22 | 23 | 24 | @Test 25 | void sumAcceptsTwoPlainArguments() { 26 | MathExpression me; 27 | me = new MathExpression("sum(5,6)"); 28 | Assertions.assertEquals("11", me.solve()); 29 | } 30 | 31 | @Test 32 | void sumAcceptsTwoPlainExpressions() { 33 | MathExpression me; 34 | me = new MathExpression("sum(5+5, 4+4)"); 35 | Assertions.assertEquals("18.0", me.solve()); 36 | } 37 | 38 | @Test 39 | void sumAcceptsStatFunction() { 40 | MathExpression me; 41 | me = new MathExpression("sum(sum(5))"); 42 | Assertions.assertEquals("5", me.solve()); 43 | } 44 | 45 | @Test 46 | void sumAcceptsNumFunction() { 47 | MathExpression me; 48 | me = new MathExpression("sum(sin(5))"); 49 | Assertions.assertEquals("-0.9589242746631385", me.solve()); 50 | } 51 | 52 | @Test 53 | void sumAcceptsTwoStatFunction() { 54 | MathExpression me; 55 | me = new MathExpression("sum(sum(5),sum(6))"); 56 | Assertions.assertEquals("11", me.solve()); 57 | } 58 | 59 | @Test 60 | void sumAcceptsTwoNumFunction() { 61 | MathExpression me; 62 | me = new MathExpression("sum(sin(5),sin(5))"); 63 | Assertions.assertEquals("-1.9178485493262770", me.solve()); 64 | } 65 | 66 | @Test 67 | void sumAcceptsStatAndNumFunction() { 68 | MathExpression me; 69 | me = new MathExpression("sum(sum(5),sin(5))"); 70 | Assertions.assertEquals("4.0410757253368615", me.solve()); 71 | me = new MathExpression("sum(sin(5),sum(5))"); 72 | Assertions.assertEquals("4.0410757253368615", me.solve()); 73 | } 74 | } --------------------------------------------------------------------------------