diff --git a/homework-g595-popovkin/pom.xml b/homework-g595-popovkin/pom.xml index f6fa0d541..3330cc74d 100644 --- a/homework-g595-popovkin/pom.xml +++ b/homework-g595-popovkin/pom.xml @@ -25,7 +25,38 @@ 1.0.0 test - + + org.springframework.boot + spring-boot-starter-web + 1.4.2.RELEASE + + + com.h2database + h2 + 1.4.192 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-releases + https://repo.spring.io/libs-release + + + + + spring-releases + https://repo.spring.io/libs-release + + + \ No newline at end of file diff --git a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/LexicalUnit.java b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/LexicalUnit.java index 7f09773ca..1bc48324e 100644 --- a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/LexicalUnit.java +++ b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/LexicalUnit.java @@ -2,6 +2,8 @@ import ru.mipt.java2016.homework.base.task1.ParsingException; +import java.util.List; + /** * Created by Howl on 11.10.2016. */ @@ -10,7 +12,9 @@ private enum UnitType { OpenBracer, CloseBracer, Double, - MathSign + MathSign, + Function, + Comma } private UnitType type; @@ -45,6 +49,14 @@ boolean isMathSign() { return type == UnitType.MathSign; } + boolean isFunc() { + return type == UnitType.Function; + } + + boolean isComma() { + return type == UnitType.Comma; + } + LexicalUnit(String val) throws ParsingException { value = val; switch (value) { @@ -66,18 +78,67 @@ boolean isMathSign() { case "/": type = UnitType.MathSign; return; + case ",": + type = UnitType.Comma; + return; default: // may be there I should to find another way to throw exception, outside the constructor try { doubleValue = new Double(value); type = UnitType.Double; } catch (NumberFormatException exception) { + type = UnitType.Function; + //return; + /* throw new ParsingException( "something wrong with parsing double from \"" + value + "\" expression", exception ); + */ + } + } + } + + public double eval(List arg) throws ParsingException { + int argc = arg.size(); + if (type != UnitType.Function) { + throw new ParsingException("evaluate of not function exp"); + } + if (argc == 0 && value.equals("rnd")) { + return Math.random(); + } + if (argc == 2) { + if (value.equals("pow")) { + return Math.pow(arg.get(0), arg.get(1)); + } else if (value.equals("log")) { + return Math.log(arg.get(0)) / Math.log(arg.get(1)); + } else if (value.equals("max")) { + return Math.max(arg.get(0), arg.get(1)); + } else if (value.equals("min")) { + return Math.min(arg.get(0), arg.get(1)); + } + } + if (argc == 1) { + if (value.equals("sin")) { + return Math.sin(arg.get(0)); + } else if (value.equals("cos")) { + return Math.cos(arg.get(0)); + } else if (value.equals("tg")) { + return Math.tan(arg.get(0)); + } else if (value.equals("sqrt")) { + return Math.sqrt(arg.get(0)); + } else if (value.equals("abs")) { + return Math.abs(arg.get(0)); + } else if (value.equals("sign")) { + if (arg.get(0) == 0) { + return 0; } + return (arg.get(0) >= 0 ? 1 : -1); + } else if (value.equals("log2")) { + return Math.log(arg.get(0)) / Math.log(2); + } } + throw new ParsingException("evaluate of an unknown function"); } public double getDoubleValue() throws ParsingException { diff --git a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyCalculator.java b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyCalculator.java index aa1171546..9a96fc4df 100644 --- a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyCalculator.java +++ b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyCalculator.java @@ -10,7 +10,7 @@ public class MyCalculator implements ru.mipt.java2016.homework.base.task1.Calculator { //private Map priority; - private static final Character[] SET_VALUES = new Character[]{'(', ')', '*', '/', '+', '-' }; + private static final Character[] SET_VALUES = new Character[]{'(', ')', '*', '/', '+', '-', ',' }; private static final Set ALONE_SYMBOL_LEXEMS = new HashSet(Arrays.asList(SET_VALUES)); private List lexicalUnits; private static final String UNARY_MINUS = "M"; @@ -29,6 +29,7 @@ private int getOpenedMathSign(String sign, int leftId, int rightId) throws Parsi && sign.equals(lexicalUnits.get(i).getValue())) { return i; } + //System.out.println(balance); if (balance < 0) { throw new ParsingException("wrong number of bracers"); } @@ -50,6 +51,7 @@ private double parceAndCalc(int leftId, int rightId) throws ParsingException { throw new ParsingException("stops on parsing not double one token expression"); } int id = -1; + // staying "err" means, what something has broken String operation = "err"; if (id == -1) { id = getOpenedMathSign("+", leftId, rightId); @@ -75,6 +77,36 @@ private double parceAndCalc(int leftId, int rightId) throws ParsingException { operation = "/"; } } + if (id == -1) { + //System.out.println("!"); + LexicalUnit unit = lexicalUnits.get(leftId); + LexicalUnit open = lexicalUnits.get(leftId + 1); + LexicalUnit close = lexicalUnits.get(rightId - 1); + if (unit.isFunc() && open.isOpenBracer() && close.isCloseBracer()) { + //int argc = 0; + List argv = new ArrayList<>(); + int commaScaner = leftId + 2; + int lastPoint = leftId + 2; + int balance = 0; + while (commaScaner < rightId - 1) { + if (lexicalUnits.get(commaScaner).isOpenBracer()) { + ++balance; + } else if (lexicalUnits.get(commaScaner).isCloseBracer()) { + --balance; + } else if (lexicalUnits.get(commaScaner).isComma() && balance == 0) { + //System.out.print(lastPoint); + //System.out.println(commaScaner); + argv.add(parceAndCalc(lastPoint, commaScaner)); + lastPoint = commaScaner + 1; + } + ++commaScaner; + } + if (lastPoint != commaScaner) { + argv.add(parceAndCalc(lastPoint, commaScaner)); + } + return unit.eval(argv); + } + } if (id != -1) { double leftOperand = parceAndCalc(leftId, id); double rightOperand = parceAndCalc(id + 1, rightId); @@ -118,6 +150,7 @@ private List parseToLexicalUnits(String expression) throws ParsingE } public double calculate(String expression) throws ParsingException { + //System.out.println(expression); if (expression == null) { throw new ParsingException("Null expression"); } diff --git a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExamleApplication.java b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExamleApplication.java new file mode 100644 index 000000000..196227b31 --- /dev/null +++ b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExamleApplication.java @@ -0,0 +1,15 @@ +package ru.mipt.java2016.homework.g595.popovkin.task4; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Created by malchun on 11/26/16. + */ +@SpringBootApplication +public class ExamleApplication { + + public static void main(String[] args) { + SpringApplication.run(ExamleApplication.class, args); + } +} \ No newline at end of file diff --git a/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExampleHandler.java b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExampleHandler.java new file mode 100644 index 000000000..b77431c1f --- /dev/null +++ b/homework-g595-popovkin/src/main/java/ru/mipt/java2016/homework/g595/popovkin/task4/ExampleHandler.java @@ -0,0 +1,60 @@ +package ru.mipt.java2016.homework.g595.popovkin.task4; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.mipt.java2016.homework.base.task1.ParsingException; +import ru.mipt.java2016.homework.g595.popovkin.task1.*; + +import java.util.List; + +/** + * Updated by Howl on 19/12/16. + */ + +@RestController +public class ExampleHandler { + private MyCalculator calculator = new MyCalculator(); + + @RequestMapping(value = "/{expression}", method = RequestMethod.GET) + public ResponseEntity eval(@PathVariable String expression) { + String ans = "ans2"; + try { + ans = Double.toString(calculator.calculate(expression)); + } catch (ParsingException ex) { + ans = "(Error:can't calculate)"; + } + + System.out.println(expression); + System.out.println(ans); + ResponseEntity resp; + resp = new ResponseEntity<>("Example

" + + "Hello, World!\n" + expression + " = " + + ans + + "

", HttpStatus.OK); + return resp; + } + + @RequestMapping(value = "/put/{name}", method = RequestMethod.PUT) + public ResponseEntity put(@RequestParam(value = "args", defaultValue = "x") List vars, + @PathVariable String name, @RequestBody String body) { + System.out.println("PUT"); + String expression = body; + String ans = "ans2"; + try { + ans = Double.toString(calculator.calculate(expression)); + } catch (ParsingException ex) { + ans = "(Error:can't calculate)"; + } + System.out.println(expression); + System.out.println(ans); + ResponseEntity resp = + new ResponseEntity<>("" + expression + " = " + + ans + "", HttpStatus.CREATED); + //new ResponseEntity<>(new ExampleEntity(name, vars, body), HttpStatus.CREATED); + return resp; + } +} + +// curl -v -X PUT localhost:8080/put/myfunc?args=a,b,v -H "Content-Type: text/plain" -d "test string" +// curl -v -X PUT localhost:8080/put/myfunc?args=a -H "Content-Type: text/plain" -d "test string" diff --git a/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/LocalCalculatorTestsMy.java b/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/LocalCalculatorTestsMy.java new file mode 100644 index 000000000..3a89f5132 --- /dev/null +++ b/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/LocalCalculatorTestsMy.java @@ -0,0 +1,15 @@ +package ru.mipt.java2016.homework.g595.popovkin.task1; + +import ru.mipt.java2016.homework.base.task1.Calculator; +import ru.mipt.java2016.homework.tests.task1.AbstractCalculatorTest; + +/** + * @author Andrey A. Popovkin + * @since 10.10.16 + */ +public class LocalCalculatorTestsMy extends MyTests { + @Override + protected Calculator calc() { + return new MyCalculator(); + } +} diff --git a/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyTests.java b/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyTests.java new file mode 100644 index 000000000..ad34803ea --- /dev/null +++ b/homework-g595-popovkin/src/test/java/ru/mipt/java2016/homework/g595/popovkin/task1/MyTests.java @@ -0,0 +1,36 @@ +package ru.mipt.java2016.homework.g595.popovkin.task1; + +import org.junit.Assert; +import org.junit.Test; +import ru.mipt.java2016.homework.base.task1.Calculator; +import ru.mipt.java2016.homework.base.task1.ParsingException; + +public abstract class MyTests { + + protected abstract Calculator calc(); + + protected void test(String expression, double expected) throws ParsingException { + String errorMessage = String.format("Bad result for expression '%s', %.2f expected", expression, expected); + double actual = calc().calculate(expression); + Assert.assertEquals(errorMessage, expected, actual, 1e-6); + } + + protected void tryFail(String expression) throws ParsingException { + calc().calculate(expression); + } + + @Test + public void functionTests() throws ParsingException { + test("sqrt(25)", 5.0); + test("sqrt(cos(0) * 25)", 5.0); + test("5 + 6", 11.0); + test("cos(0) * 24", 24); + test("cos(0) * 24 + log(2, 2)", 25); + test("sqrt(cos(0) * 24 + log(2, 2))", 5); + } + + @Test(expected = ParsingException.class) + public void trashTest() throws ParsingException { + tryFail("solve"); + } +} \ No newline at end of file