Exercise: Checking if a sentence is considered valid under the following conditions:
- Numbers less than 13 are only allowed in their written form, e.g "twelve", but "14" is considered valid.
- Only 1 period marker is allowed and it must be the final character
- First letter must be uppercase
- number of quotation marks in the sentence must be even
if the sentence meets all above criteria, it is considered valid.
Here is my approach:
public class SentenceValidator implements ValidatesSentences {
private static final int MINIMUM_ALLOWED_NUMBER = 13;
public SentenceValidator() {
//default (auto-generated without explicit declaration anyway)
}
/**
* Takes a string sentence and returns if it meets the requirements
* @param sentence -> The string sentence to analyze for validity
* @return boolean -> if the string meets the validation requirements
*/
@Override
public final boolean isSentenceConsideredValid(String sentence) {
String temporary = guardTheSentence(sentence);
return temporary.length() > 1 && areConditionsValid(temporary);
}
private boolean areConditionsValid(String sentence) {
return isTheFirstCharacterAnUppercaseLetter(sentence)
&& isTheCountOfQuotationMarksEven(sentence)
&& isTheOnlyPeriodMarkTheLastCharacterOfTheSentence(sentence)
&& isTheLowestNumberInTheSentenceGreaterThan13(sentence);
}
private String guardTheSentence(String sentence) {
Objects.requireNonNull(sentence, "null is not an acceptable value");
return sentence.trim();
}
private boolean isTheFirstCharacterAnUppercaseLetter(String sentence) {
return Character.isLetter(sentence.charAt(0))
&& sentence.charAt(0) == sentence.toUpperCase().charAt(0);
}
private boolean isTheCountOfQuotationMarksEven(String sentence) {
return (retrieveCountOfAGivenCharacter(sentence,'"') % 2) == 0;
}
private boolean isTheOnlyPeriodMarkTheLastCharacterOfTheSentence(String sentence) {
return sentence.charAt(sentence.length() - 1) == '.' && retrieveCountOfAGivenCharacter(sentence,'.') == 1;
}
private int retrieveCountOfAGivenCharacter(String sentence, Character charToCount) {
int counter = 0;
for (char c : sentence.toCharArray()) {
if (c == charToCount) {
counter++;
}
}
return counter;
}
/**
* We don't need really need to care about words for the numbers, that is trivial All we want to
* check is for all numeric value(s) within the string and ensure none are below 13
* supports negative numbers using the optional (?:-)
*/
private boolean isTheLowestNumberInTheSentenceGreaterThan13(String sentence) {
String temp = sentence.replaceAll("[^-?0-9]+", " ");
temp = temp.trim();
if (temp.isEmpty()) {
return true;
}
int lowestNumber = MINIMUM_ALLOWED_NUMBER;
for (String number : temp.split(" ")) {
lowestNumber = Math.min(lowestNumber, Integer.parseInt(number));
}
return lowestNumber >= MINIMUM_ALLOWED_NUMBER;
}
}
public interface ValidatesSentences {
boolean isSentenceConsideredValid(String sentence);
}
A jump out problem I see already is the NumberFormatException when number is greater than a max int, I should use a long/Big Integer there and handle a NumberFormatException.