Pages

CodeEval Cash Register

Given in input the price of a certain item and the cash that the client has passed to us to get it, we have to provide to the cashier a list of what he has to get back. More details in the problem page on CodeEval.

We assume the register has an infinite amount of coins and bills in the given denominations:
'PENNY': .01,
'NICKEL': .05,
'DIME': .10,
'QUARTER': .25,
'HALF DOLLAR': .50,
'ONE': 1.00,
'TWO': 2.00,
'FIVE': 5.00,
'TEN': 10.00,
'TWENTY': 20.00,
'FIFTY': 50.00,
'ONE HUNDRED': 100.00
To better clarify what we should do, the first thing I have done is converting the given examples in a Python test case:
def test_provided_1(self):
    self.assertEqual('NICKEL,PENNY', solution(15.94, 16))

def test_provided_2(self):
    self.assertEqual('ERROR', solution(17, 16))

def test_provided_3(self):
    self.assertEqual('ZERO', solution(35, 35))

def test_provided_4(self):
    self.assertEqual('FIVE', solution(45, 50))
The first number passed to the function is the price, the second one is the amount given in.

It shouldn't be to difficult to get a working solution in Python. The core of the problem is looping on all the available denominations, starting from the highest one down to the smallest, selecting each denomination the maximum possible times.

Since working with floating point numbers when a currency is expected is rarely a good idea, I have decided to store in my dictionary of denomination the values as multiple of cents. Something like that:
DENOMINATIONS = {
    'PENNY': 1,
    'NICKEL': 5,

    # ...

    'FIFTY': 5000,
    'ONE HUNDRED': 10000
}
Besides, I payed attention in converting the floating point numbers in integers so to avoid truncation problems:
change = int(cash * 100) - int(price * 100)
However, the interesting part is the loop to check if a given denomination has to be used and how many times:
for name, value in sorted(DENOMINATIONS.items(), key=lambda x: x[1], reverse=True):
    # ...
I want to loop on all the items() in the DENOMINATIONS dictionary, to operate on its key and value - where the key represent the name of the denomination.

I can't rely on the order chosen by Python in scanning the dictionary, I must start from ONE HUNDRED, and proceed in sorted fashion down to the PENNY. So I sorted() it.

I don't want to sort them by the key, it won't make any sense, but by value. So I specify as key that I want to use the second component. I say that to Python using a lambda, that gets the current item in input and returns its second component (index 1, since we are 0 based).

As said above, I want to start from the highest value, that's way I specify that the sorting order is reversed.

The rest of the code should be quite simple to figure out. In any case, my full solution is on GitHub, both the test case and the actual python script.

Go to the full post

A view on Spring error messages

We have seen in the previous post how to let Spring validate the data coming from the view against a bean (in the sense of a plain Java one) defined in the model of our web app, thanks to the Java Validation protocol, in the Hibernate implementation. Now we see how to let the resulting view acknowledge the errors, so that the user could correct them.

First thing, let's slightly change the controller, so that a empty spitter object is passed to the register view when we GET it.
@RequestMapping(value = "/register", method = GET)
public String showRegistrationForm(Model model) {
    model.addAttribute(new Spitter());
    return "registerForm";
}
Spring sees we want to push on the model a new Spitter. By default it names it as the class, first letter lowercase, "spitter".

The registerForm JSP now changes to use it. Our job is made simpler by using a Spring tag library, form, that provides a nice support for manage HTML forms. I associated the "sf" prefix to it, and I am going to use only a few of the many functionality it makes available.
I have rewritten the form in this way:
<sf:form method="POST" commandName="spitter">  <!-- 1 -->
  First Name: <sf:input path="firstName" />    <!-- 2 -->
 <sf:errors path="firstName" />         <!-- 3 -->
 <br />
  Last Name: <sf:input path="lastName" />
 <sf:errors path="lastName" />
 <br />
  Email: <sf:input path="email" />
 <sf:errors path="email" />
 <br />
  Username: <sf:input path="username" />
 <sf:errors path="username" />
 <br />
  Password: <sf:password path="password" />    <!-- 4 -->
 <sf:errors path="password" />
 <br />
 <input type="submit" value="Register" />
</sf:form>
1. Instead of using the standard HTML form, I used the Spring Form version. The attribute (in XML sense) commandName shows the name of the attribute that has to be used to populate the fields in the form. If we arrive here from GETting "/register", spitter would be empty. If we arrive here POSTing "/register", after detecting validation errors, spitter would contain the fields as entered by the user.
2. The Spring Form input tag uses its attribute path to select the field from the commandName object that is associated to it. In this case, firstName.
3. The Spring Form errors tag is just like a plain text label, but linked to the Spring Validation Errors object generated by the validation process - when available. Again, its path attribute refers to the specific field in it.
4. The Spring Form password tag is a sort of Spring aware HTML input-password tag.

And with this, we could claim that the job is done. However, we would like to have a better control on the messages showed to the user in case of errors. That is very easily done, as it is providing localized version of those messages.

To do that I have created a file named ValidationMessages.properties in the src/main/resources folder, and its ValidationMessages_it.properties counterpart for its Italian version. Each line represents an error message. For instance:
firstName.size=First name must be between {min} and {max} characters long.
Notice the words included in curly braces. These are variables that Spring will resolve when creating the actual message.

I am going to use the custom messages in the Spitter class:
@Size(min = 2, max = 30, message="{firstName.size}")
private String firstName;
Now, if I push the Register button without entering anything, I get:
(Notice that there is no error message for the empty email address - no email is considered a valid alternative)

In a browser localized for Italy, I have this alternative result:
Reference: Rendering web views, from Spring in Action, Fourth Edition by Craig Walls. Chapter six.

I have pushed the project changes to GitHub.

Go to the full post

Using tha Java Validation API

The user registration shown in the previous post has one very visible issue, there is no validation at all. The user could enter whatever value in each required field and the web app happily register it. Using Java Validation we could easily solve this problem.

We need to add an implementation of the javax.validation validation API, the Hibernate validator is a good candidate. So I add its dependency to my Spring Web App POM configuration file:
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>
Then I modify the Spitter bean (in the sense of plain Java Bean), annotating its properties so to impose the rules I want the registration to observe.
For instance, I want the first name to be not null and having a size in [2 .. 30]:
@NotNull
@Size(min = 2, max = 30)
private String firstName;
NotNull and Size are standard Java Validation annotations. Since I use the Hibernate implementation of that JSR, I can use a non-standard, hibernate specific annotation to enforce that the email field represents a valid e-mail address:
@NotNull
@Email
private String email;
These checks are enforced in the controller. I change the processRegistration() method in this way:
@RequestMapping(value = "/register", method = POST)
public String processRegistration(@Valid Spitter spitter, Errors errors) {  // 1
    if (errors.hasErrors()) {  // 2
        return "registerForm";
    }

    spitterRepository.save(spitter);  // 3
    return "redirect:/spitter/" + spitter.getUsername();
}
1. The Spitter input parameter is tagged with the Valid Java Validation annotation, in this way I'm saying to the Hibernate Validator to check its fields accordingly to the annotations specified on this data members. Any error on the validation is pushed in the Errors object.
2. In a real app I would do much more than simply check if there is any validation error. For sure we need to say something to the user, so to help him to correct his mistakes. And it would be probably a good idea to log them.
3. Only if no validation error is detected we go on saving the user and giving a confirmation to the caller.

Reference: Validating form, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section 4.2.

The complete Java Spring Web App project is on GitHub.

Go to the full post

Spitter registration

We need to provide a way to let people register to our spittr web application, this is done here relying on the support offered by the Spring framework, that easily support the forms, giving a natural way for processing them.

The Model

A registered user is defined as a Spitter:
public class Spitter {

    private Long id;

    private String username;
    private String password;
    private String firstName;
    private String lastName;
    private String email;
    // ...
}
We'll need to check for equality on different Spitters, so we need to override both equals() and hashCode(). I did it using Objects.equals() and Objects.hash() in their implementions. I feel they helps to keep the code compact and readable without using external libraries.

We'll have a repository where storing our spitters, but we don't need to fix its type here, just the interface that each spitter repository has to implements:
public interface SpitterRepository {
    Spitter save(Spitter spitter);
    Spitter findByUsername(String username);
}
Actually, just to do some smoke testing, it is nice to have a concrete repository to play with:
@Repository
public class JdbcSpitterRepository implements SpitterRepository {
    @Override
    public Spitter save(Spitter spitter) {
        // TODO: actual implementation
        return spitter;
    }

    @Override
    public Spitter findByUsername(String username) {
        // TODO: actual implementation
        return new Spitter(username, "password", "John", "Doe", "jdoe@somesite.dd");
    }
}
I assumed it will be refactored in future to become a real JDBC repository, hence its name. Notice that the class is annotated as Spring repository.

Data Configuration

Having introduced a new repository in the web app, we should say to Spring how to get it. To do that I added a bean (in the sense of Spring Bean) in the already existing DataConfig java class, annotated as Spring configuration.
@Configuration
public class DataConfig {
    // ...

    @Bean
    public SpitterRepository spitterRepository() {
        return new JdbcSpitterRepository();
    }
}
The View

The user enters data filling a simple HTML form, something like that:
<form method="POST">
    First Name: <input type="text" name="firstName" /><br />
    Last Name: <input type="text" name="lastName" /><br />
    Email: <input type="email" name="email" /><br />
    Username: <input type="text" name="username" /><br />
    Password: <input type="password" name="password" /><br />
    <input type="submit" value="Register" />
</form>
Being no action attribute specified in the form tag, the post is done referring to the same URL accessed originally. Not much more to say on this part, you could see the full registerForm.jsp file on GitHub.

We'll also have a way to show a registration, accessing profile.jsp. Our Spring web app should take care of putting in a variable named spitter, an instance of the above discussed Spitter class, that represents the currently registered user. So, to display it, using JSP EL, we'll write something like:
<c:out value="${spitter.username}" /><br />
<c:out value="${spitter.firstName}" />
<c:out value="${spitter.lastName}" /><br />
<c:out value="${spitter.email}" />
The Controller

As usual, the controller keeps model and view together. The Spitter controller reacts to calls based in "/spitter". We want it to convert a call to "/spitter/register" showing the register form view or redirecting it to /spitter/xxx, where xxx is the username, accordingly to the HTTP command used. GET is for the first one, POST for the second. Any "/spitter/xxx" GET call will drive to the profile view.
@Controller
@RequestMapping("/spitter")
public class SpitterController {  // 1
    private SpitterRepository spitterRepository;  // 2

    public SpitterController(SpitterRepository spitterRepository) {
        this.spitterRepository = spitterRepository;
    }

    @RequestMapping(value = "/register", method = GET)  // 3
    public String showRegistrationForm() {
        return "registerForm";
    }

    @RequestMapping(value = "/register", method = POST)  // 4
    public String processRegistration(Spitter spitter) {
        spitterRepository.save(spitter);
        return "redirect:/spitter/" + spitter.getUsername();
    }

    @RequestMapping(value = "/{username}", method = GET)  // 5
    public String showSpitterProfile(@PathVariable String username, Model model) {  // 6
        Spitter spitter = spitterRepository.findByUsername(username);  // 7
        model.addAttribute(spitter);
        return "profile";
    }
}
1. This class is annotated as Spring controller, and it maps calls rooted in "/spitter".
2. We are going to use a repository that has to implement the SpitterRepository.
3. Maps a GET to "/spitter/register" to the registerForm view.
4. Redirects a POST to "/spitter/register" to the "/spitter/xxx" view. A spitter is expected as parameter, and it is going to be saved to the repository before the redirect is performed.
5. Maps a GET to "/spitter/xxx" to the profile view.
6. The username is extracted from the path by the PathVariable Spring binding annotation.
7. The repository is asked to give the spitter associated with the username, then we push it to the model.

Testing

The controller design has been driven by a couple of mock JUnit tests, using Mockito, defined in the SpitterControllerTest class. Besides, having provided a (fake) concrete implementation for the spitter repository, it is possible to run the web app and see its general behavior.

So, GETting "/spitter/register", we'll see the input form:
As soon as we push the Register button, a POST will be generated for the same URL. As seen above, the controller will redirect to "/spitter/jdoe"

So. Our app works. At least in a sort of demo mode. It is easy to spot how weak is, however. We are going to improve its robustness in the next post.

Reference: Processing forms, from Spring in Action, Fourth Edition by Craig Walls. Chapter five, section four.

Full Java Spring code available on GitHub.

Go to the full post