Introduction
I have always had a knack for movies, especially great ones that fit the mood I am in at the moment or how I'd like to feel after, and depending on who I am watching with. Finding the right movie is usually tiring since I would have to go jumping around whatever movie provider, streaming service or website and look for one by applying filters while looking at the ratings and summaries! Getting fed up with this cycle inspired me to build (or try to) a simple command-line tool to make the process a bit quicker and slightly more enjoyable.
In this article, I will walk you through how I designed it, why certain technical decisions were made, and all the challenges and problems I experienced along the way while making it.
Overview
The code is written purely in Java since it is versatile, has a strong object-oriented model, is powerful and easy to use, and is the main language used in the course. No external libraries were used in this case to ensure it is as simple as it gets, making it easier to understand how each feature works 'by hand' rather than relying on frameworks. The program is divided into several classes; the main class where everything comes together to make the command-line interface (CLI), different helper classes that handle authentication and movie data, and finally the testing classes to ensure the code runs smoothly. Keeping things modular made it easier to work on one part at a time, applying standard OOP ideas such as separation of concerns and encapsulation, easing maintenance and future extension.
Design and Workflow
From a user's point of view, the workflow is intentionally simple. You open a terminal, run the tool, get a welcome message and get prompted to login, then the tool proceeds to ask a few questions to gauge what you're in the mood for and if there is any company. Depending on the answers given, the program then suggests one or more movies that match them. Each suggestion includes the genres, title and a short description.
Because the user moves through the tool in a clear sequence; login, questions, recommendations; I structured the code in the same way. This mirrors the typical " input-processing-output" pattern. Each stage has its own class or method, which kept the logic clean and easy to follow.
Section 1: Description of Key Features
Feature 1: User Input and Validation
User input basically drives the CLI, as the recommendation logic depends on how the user answerd the questions and whether they can log in successfully. I used the scanner class to read input from the terminal, then used an if statement to validate the answer. For the validation, I checked if the answer given falls under the bounds of the index of the options per question.

Feature 2: Auth class and file-based authentication (objects, methods, collection)
Since I did not use any external libraries making this program, I handled authentication using only core Java and a simple text file. Usernames and passwords are stored in users.txt with a simple format that looks like "Username:password". per line as per the .txt file.
This class reads the file then loads the usernames and passwords into a hashmap, which is a data type that stores a key and its associated value, in our case a username and password. Using a method named 'log in' in the class, a user is able to log in and use the tool (CLI) if the credentials are correct and unable if not. Credentials for a guest user are provided.

Feature 3: Questions, preferences and loops.
This bit was kind of the 'body' of the tool, and it was a bit straightforward. The question and preference classes work together to transform abstract user feelings into solid genres that the scoring function can use. The question class contains a question string and an array of options, which prompt the user to determine their preference.
With a list of preferences, it was messy when trying to find a movie, so it needed to be converted into something useful. So I came up with a way to convert the different preferences into genres when, for example, a user prefers being calm, and the program subtly recognises to convert this into a suitable genre, e.g., drama, romance, slice of life, etc. This led to some genres overlapping, however, with some certain preferences that seemed similar. After converting all of the user preferences to genres, I had a list that looked like this: [“Drama”, “Action”, “Comedy”, “Drama”], which was to aid in picking a suitable film. Instead of treating this like an error, the implementation uses duplicates as an implicit weighting mechanism. If "drama" appears multiple times, movies tagged with drama will naturally score higher later on.
In the main class, this is where all the functionality came together. An array of question objects is processed using loops.

The outer for loop iterates over all questions, while the inner loop iterates over each option and prints it, demonstrating loops and arrays harmoniously operating to build a flexible questionnaire without manually inputting every line of text. Once a valid answer is selected, a preference object converts it into genres and appends them to the genres list, ready to be scored.
Feature 4: Movie objects and scoring algorithm (objects, methods, arrays, selection)
Movies are represented by a dedicated movie class, which stores a title, a list of genres, a description of the movie and the year of release. The object-oriented design keeps all movie-related data together and makes the recommendation logic much easier to follow, because it operates on movie objects rather than juggling parallel arrays. Methods in the main class called getMoviesFromPreference and getPoints act as the core recommendation logic for the program. Each genre holds different strengths; as mentioned before, drama would hold more of a significance than animation in this case, thus enabling a point-based system for different genres. This made it easier to calculate a suitable movie based on the points available and match it to the list of genres using nested loops and arrays to calculate scores.
Challenges and Issues Faced
Issue 1: Human Input
Converting subjective user preferences into something the algorithm could understand was one of the biggest hurdles I encountered. Since user inputs like mood and company are inherently abstract, it took some trial and error to translate them to specific movie genres. At first, this led to the addition of overlapping genres such as "Drama", "Action", "Comedy", and "Drama" to the choice list several times. I choose to use this overlap as a weighting system to affect suggestions instead of eliminating duplicates.
Issue 2: Designing a suitable scoring system
Choosing a suitable film when several genres were involved presented another difficulty. I created a points-based scoring system where each genre contributed a varied weight based on its relevancy because a straightforward random selection frequently yielded subpar results. To prevent recommendations that were unduly skewed, this needed to be carefully adjusted. Tuning the getPoints values and the 2.0‑point “window” around the highest score required some experimentation: too narrow, and only one movie would ever be chosen; too wide, and the results would feel random again. The final configuration strikes a balance between variety and relevance and illustrates how simple numerical tweaks can significantly affect the behaviour of an algorithm.
Issue 3: Constraints without external libraries (authentication, testing, UI)
There were additional restrictions while working without external libraries, especially for authentication and testing. Storing credentials in plain text (users.txt) is not the best option security-wise when it comes to an actual system, but it was the most practical to me given my level of skill.
Similarly, testing had to be done by hand without the use of testing frameworks like JUnit, which would normally automate and structure those tests, resulting in more boilerplate code but guaranteed accuracy.
Lastly, it was difficult to manage terminal output in a clear and easy-to-use manner. In order to prevent overwhelming the user, I had to manually clean the screen and manage the flow of shown content in the absence of UI libraries.
Conclusion
The result of all the above comes together beautifully to make this elegant tool for power terminal users who just wanted to find a movie to watch in whatever circumstance. Of course, improvement can be made in the future with the help of external libraries, like fetching movies from the IMDb API online instead of relying on a local one, which I would have to update regularly.





Top comments (1)
Top much boilerplates for replacing the Bash.