-
Notifications
You must be signed in to change notification settings - Fork 80
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
1 task #346
base: master
Are you sure you want to change the base?
1 task #346
Conversation
Какой знакомый код. А Елена Смирнова точно дала своё согласие на его заимствование? |
public double calculate(String Expression) throws ParsingException { | ||
if (!isExpressionCorrect(Expression)) { | ||
throw new ParsingException("Invalid expression"); | ||
private String whatIsIt(Character Symbol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Ochen` ploxo", ochen'
Неужели нельзя это не так по-индуски сделать?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вынужден сообщить, что читаемость у этого кода далеко не на самом высоком уровне. Прочитав два десятка калькуляторов, я не могу понять, как работает твой, хотя идеологически он вряд ли отличается сильно. Проблема на мой взгляд в слишком больших switch
блоках, злоупотреблении ими и отсутствии хоть каких-то комментариев к происходящему.
Некоторые замечания, которые я оставил к твоему коду, относятся не только к той строчке, к которой привязаны, поэтому будь добр, пройдись по всему коду и исправь ошибки в аналогичных местах.
public double calculate(String Expression) throws ParsingException { | ||
if (!isExpressionCorrect(Expression)) { | ||
throw new ParsingException("Invalid expression"); | ||
private String whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Любой человек, который знает Java, понимает разницу между базовыми типами и их обёртками, а также про боксинг и анбоксинг, про который семинарист рассказывал вам ещё в начале семестра. Настоятельно рекомендую почитать материалы семинаров, документацию по java или stackoverflow.com и ознакомиться с тем, что такое primitive wrapper class, boxing и unboxing, а после этого со знанием дела объяснить, зачем тебе здесь именно Character
.
public double calculate(String Expression) throws ParsingException { | ||
if (!isExpressionCorrect(Expression)) { | ||
throw new ParsingException("Invalid expression"); | ||
private String whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ты можешь представить, какой оверхед создаёт эта функция? Если Java ничего не оптимизирует, а будет под каждый вызов твоей волшебной функции whatIsIT()
создавать новую строку, этот калькулятор будет съедать памяти раз в 50 больше нужного.
Теперь вопрос: а почему, собственно, возвращается строка? enum SymbolType
в списанном решении был таким хорошим, а тут у тебя аж строки возвращаются. Мне кажется, что ответ - чтобы код не был похож на предыдущее решение, но это не точно.
case '6': | ||
case '7': | ||
case '8': | ||
case '9': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Итак, у нас есть задача - нужно определить, является ли символ цифрой. У этой, не побоюсь этого слова, задачи есть несколько решений, из которых ты выбрал самое беспонтовое. Предлагаю ознакомиться с документацией к классу Character
(хотя бы пролистать список методов) и сказать, что нам предлагает сам язык в этом плане.
} | ||
case ' ': | ||
case '\t': | ||
case '\n': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Аналогично тому, что я писал выше про числа - для этого уже сделана стандартная функция, и тебе предлагается её отыскать.
private enum SymbolType { | ||
OPENING_BRACKET, CLOSING_BRACKET, NUMBER, OPERATOR, NOTHING | ||
|
||
private Integer getCode(Character first, Character second) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А какой именно код возвращает эта функция? Лично мне сходу вообще непонятна семантика этой функции, в которой к тому же ещё и вложенные switch
блоки, а значения кодов - тайна, покрытая мраком и нигде не задокументированная.
if (previousSymbol == SymbolType.OPENING_BRACKET || | ||
previousSymbol == SymbolType.OPERATOR) { | ||
return false; //открывающая-закрывающая, оператор-закрывающая | ||
for (int cnt = 0; cnt < expression.length(); ++cnt) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Название cnt
по меньшей мере чрезвычайно странное. Как минимум оно трактуется неоднозначно - у тебя оно ассоциируется со словом count, у меня со словом cunt (или наоборот), а двузначность в коде - плохо. И вообще count - это количество или подсчёт, но никак не индекс (счётчик здесь тоже не подходит, ты же ничего не считаешь, а только итерируешься по строке).
И привыкай не использовать в коде сокращения имён (кроме общепринятых). Они хороши только когда пишешь код на листочке без автодополнения.
private StringBuilder removeSpaces(String expression) { | ||
StringBuilder result = new StringBuilder(expression.length()); | ||
for (int cnt = 0; cnt < expression.length(); ++cnt) { | ||
if (!whatIsIt(expression.charAt(cnt)).equals("Space")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот это можно вообще без whatIsIt()
сделать также одной строчкой.
expression.append('~'); | ||
Character curSymbol; | ||
Character prevSymbol = '~'; | ||
Stack<Character> Texas = new Stack<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В java code conventions явно указывается, что переменные называются с маленькой буквы.
if (currChar == ' ' || currChar == '\n' || currChar == '\t') { | ||
continue; | ||
Integer cnt = 0; | ||
while (true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Как интересно ты в исходном решении заменил for
на while
.
@Override | ||
public double calculate(String expression) throws ParsingException { | ||
isAlmostValid(expression); | ||
StringBuilder withoutSpaces = removeSpaces(expression); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А зачем тебе именно StringBuilder
возвращать из функции? Ты же можешь вернуть return stringBuilder.toString()
, и тогда на выходе будет строка, и тип переменной withoutSpaces
будет вполне себе понятным - String
. А то пока это выглядит так, как будто ты планируешь дальше строить эту строку.
import ru.mipt.java2016.homework.base.task1.Calculator; | ||
import ru.mipt.java2016.homework.base.task1.ParsingException; | ||
|
||
import java.util.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Считается плохим тоном импортировать через *. Перечисли всё, что ты импортируешь отдельно
import java.util.*; | ||
|
||
// подробное описание работы кода | ||
// можно найти в файле description |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пиши комментарии прямо в коде
if (symbol.equals('~')) { | ||
return SymbolType.FIRST; | ||
} | ||
return SymbolType.INVALID; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Во многих языках программирования есть такая штука, как assert. Его используют, чтобы поймать некорректные состояния. Этот твой SymbolType.INVALID
- как раз такое состояние. Кидай отсюда исключение
OPENING_BRACKET, CLOSING_BRACKET, FIRST, INVALID } | ||
|
||
|
||
private SymbolType whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не слишком-то похоже на понятное название
Почему принимает Character
?
} | ||
|
||
|
||
private int getCode(char first, char second) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Как говорили Великие:
А какой именно код возвращает эта функция? Лично мне сходу вообще непонятна семантика этой функции, в которой к тому же ещё и вложенные switch блоки, а значения кодов - тайна, покрытая мраком и нигде не задокументированная.
Почему не сделать enum вместо цифр? С ним назначение функции слегка прояснится. Заодно можно будет переименовать getCode
во что-нибудь более определенное
Character curSymbol; | ||
Character prevSymbol = '~'; | ||
Stack<Character> texas = new Stack<>(); | ||
StringBuilder california = new StringBuilder(expression.length()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
То, что в статье, которую ты скинул, есть слова Техас и Калифорния, ещё не значит, что их нужно использовать, как названия переменных. Придумай что-нибудь более говорящее
Second attempt:)