Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rest api calculator (only evaluation) #330

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion homework-g595-popovkin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,38 @@
<version>1.0.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.List;

/**
* Created by Howl on 11.10.2016.
*/
Expand All @@ -10,7 +12,9 @@ private enum UnitType {
OpenBracer,
CloseBracer,
Double,
MathSign
MathSign,
Function,
Comma
}

private UnitType type;
Expand Down Expand Up @@ -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) {
Expand All @@ -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<Double> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

public class MyCalculator implements ru.mipt.java2016.homework.base.task1.Calculator {
//private Map<Character, Integer> priority;
private static final Character[] SET_VALUES = new Character[]{'(', ')', '*', '/', '+', '-' };
private static final Character[] SET_VALUES = new Character[]{'(', ')', '*', '/', '+', '-', ',' };
private static final Set<Character> ALONE_SYMBOL_LEXEMS = new HashSet<Character>(Arrays.asList(SET_VALUES));
private List<LexicalUnit> lexicalUnits;
private static final String UNARY_MINUS = "M";
Expand All @@ -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");
}
Expand All @@ -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);
Expand All @@ -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<Double> 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);
Expand Down Expand Up @@ -118,6 +150,7 @@ private List<LexicalUnit> parseToLexicalUnits(String expression) throws ParsingE
}

public double calculate(String expression) throws ParsingException {
//System.out.println(expression);
if (expression == null) {
throw new ParsingException("Null expression");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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<String> 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<String> resp;
resp = new ResponseEntity<>("<head><title>Example</title></head><body><p style='color:red'> "
+ "Hello, World!\n" + expression + " = "
+ ans
+ "</p></body>", HttpStatus.OK);
return resp;
}

@RequestMapping(value = "/put/{name}", method = RequestMethod.PUT)
public ResponseEntity<String> put(@RequestParam(value = "args", defaultValue = "x") List<String> 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<String> 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"
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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");
}
}