[Logo]
Forums Register Login
Filtering data, based on job test (with a few changes)
(1 like)
Recently this was what I had to complete this before my job application was even accepted. I thought that this may be a nice little programming challenge/diversion.
Requirements:
1. Provide a way to get a product’s total number of customer reviews whose ratings are within a given range (inclusive).
2. Add the following additional checks before creating a customer review:
    a. Your service should read a list of curse words. This list should not be defined in Java class.
    b. Check if Customer’s comment contains any of these curse words. If it does, throw an exception with a message.
    c. Check if the rating is not < 0.  If it is < 0, throw an exception with a message.

There was more to this challenge, which required using the Spring framework and a number of other source files.

My solution is listed below:

ListLoader.java

ProductModel.java

ProductReviews.java

WordFilter.java

Main.java

badwords.txt

This all works, but it is not the best solution and I'm pretty sure that others could create a better solution in any JVM language including Java, Kotlin, Scala, etc.
One issue is in WordFilter.java where I only split the review on a space, and there are many other characters what should be included.
There was no requirement for creating product reviews, but I created that so that I could test out the logic.
I can't see what is wrong with filtering whole words. Not like the time I went to a well‑known university for some special training and sent an email home about some beer. The beer was so strong I had to wash it down with some lighter beer. The automated filter found the end of wash and the word before down, decided it was something naughty, and changed it to XXXX.

Why are you using a List<String> for the naughty words? I didn't think your list of words was actually too bad
Here the a solution done in Kotlin.
ListLoader.kt

ProductModel.kt


ProductReviews.kt

WordFilter.kt

Main.kt
 

Campbell Ritchie wrote:I can't see what is wrong with filtering whole words.


While it works, I do suspect that it can be done more efficiently.

Campbell Ritchie wrote:Why are you using a List<String> for the naughty words?


What do you think would be a better solution to this?  I have found it easy to use the List<String>, but that does not mean it's correct/proper.
What is wrong with a Set<String>?
 

Campbell Ritchie wrote:What is wrong with a Set<String>?


I'm not too sure, probably nothing in this case. Due to my lack of knowledge/experience I had not even thought of using Set<String>.
I need to get more familiar with all of the collection objects and properties.
Would you say that Set<String> is a better collection object then List<String> for this instance?
A List is an interface.
Because searching for elements can be done in linear time in an unsorted List, but in constant time in some Set implementations. If you have a Stream, you can do the testing in constant time.Yes, I know, peek is pretty awful. Another way you can do it is to add all the words in your input to another Set and look to see whether their intersection is empty.
Some really good points that I'll have to keep in mind as I move forward, continue to learn and program.

Thanks.
 

Pete Letkeman wrote:. . . Thanks.

That's a pleasure   It goes to show you, there are almost always different ways to implement something, and you will learn new things on this website.
The following took ages to write. Well over ten minutes:-KeyboardInput.getWholeLine() and KeyboardInput.getNextInt are similar to Scanner methods with similar names, but getWholeLine never returns an empty String. The naughtyWords file is a plain simple text file in UTF-8. I have tweked the code slightly since I first ran that app. I have also corrected the spellling mistake in cooks.

java NaughtyWordFinder
Enter message:
What a lovely restaurant. The food was good, the waiters polite, and they only charged £24.00 a head
Enter score as int: 8
All words OK.
[xxxx]$ java NaughtyWordFinder
Enter message:
The place was bl***y awful. Somebody tell the b****rd who cooks here to f**k off.                                                   
Enter score as int: 2
Exception in thread "main" java.lang.RuntimeException: Naughty words used: [b****rd, f**k, bl***y]
at NaughtyWordFinder.seekInput(NaughtyWordFinder.java:51)
at NaughtyWordFinder.main(NaughtyWordFinder.java:18)
[xxxx] java NaughtyWordFinder
Enter message:
What a lovely restaurant. The food was good, the waiters polite, and they only charged £24.00 a head
Enter score as int: -1
All words OK.
Exception in thread "main" java.lang.IllegalArgumentException: Negative score: -1
at NaughtyWordFinder.seekInput(NaughtyWordFinder.java:56)
at NaughtyWordFinder.main(NaughtyWordFinder.java:18)

If you print out the class for that Set
System.out.println(naughtyWordsSet.getClass().getName());
you get java.util.HashSet, which is a class I am familiar with. The rethrowing of Exceptions in line 32 is because I declared the Set as final.

[edit]Censor the naughty words with *****.
 

Pete Letkeman wrote:. . . . . .

!= ???
I may be mistaken about the next bit, but why are you not coming out of the loop as soon as found becomes true?

Campbell Ritchie wrote:!= ???
I may be mistaken about the next bit, but why are you not coming out of the loop as soon as found becomes true?


Where exactly is the loop in the above code?
I'm using findFirst() so that if a bad word is found then stop processing the stream.
If no bad word is found then I still want a value to test against so I'm using orElse("")
My code simply checks to see if any bad word is found. It does not provide any scoring.

Campbell Ritchie wrote:It goes to show you, there are almost always different ways to implement something, and you will learn new things on this website.


Yes, I am one those who is trying to constantly learn/improve.
 

Pete Letkeman wrote:. . . .Where exactly is the loop in the above code?  . . . .

D*mn! 💀☞🔪†🝏☠✊ There I  was reading the end of the code and thought it was the end of a loop.

Sorry

But do you really think you should use != on reference types as in the line 19 I quoted earlier? There is a String method which will do that sort of thing for you.
 

Campbell Ritchie wrote:There I  was reading the end of the code and thought it was the end of a loop.


No problem, we all make mistakes. I know that I have made plenty of mistakes and I will most likely continue to make mistakes.

Campbell Ritchie wrote:But do you really think you should use != on reference types as in the line 19 I quoted earlier? There is a String method which will do that sort of thing for you.


You are correct I should have used the equals() method so it would then become

Instead of what I previously wrote. Sometimes I get my programming languages mixed up. There is no need to use equals() in Kotlin.
 

Pete Letkeman wrote:, , , I should have used the equals() method . . .

Not with ""; there is another method for that.

Sometimes I get my programming languages mixed up. There is no need to use equals() in Kotlin.

Nor would there be in C#, where == is overloaded. It shows how careful one has to be when changing languages.
Do you mean isEmpty​()

API Docs wrote:public boolean isEmpty​()
Returns true if, and only if, length() is 0.
Returns:
true if length() is 0, otherwise false


https://docs.oracle.com/javase/9/docs/api/java/lang/String.html#isEmpty--

So I could have used

I wonder which method is more efficient equals() or isEmpty​()?
isEmpty() will give you slightly faster execution. You probably won't notice the speed difference. All it does is something like this. Field access, field access, and equality to 0. Only three actions. No need for things like instanceof, casts, and comparisons of the fields of the other object.
Using isEmpty() will also alert whoever is reading the code to the fact that you know some of the more recent methods of String. You probably will notice that difference
Wink, wink, nudge, nudge, say no more ... https://richsoil.com/cards


This thread has been viewed 152 times.

All times above are in ranch (not your local) time.
The current ranch time is
Jan 16, 2018 07:05:25.