Overview
Flashy is an application to help users organise their flashcards to help them memorise better.
Summary of contributions
-
Major enhancement: Enhanced flashcards to be polymorphic.
-
What it does: Allows users to add and edit MCQ or fill-in-the-blanks flashcards (on top of normal ones).
-
Justification: This feature improves the product significantly because users learn differently (some need prompts) and the ability to add different kinds of flashcards would allow them to add those that suit their learning style.
-
Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands, and care has to be taken so as to not affect the existing features.
-
-
Minor enhancement: Added a delete flashcard feature so that flashcards can be deleted when users no longer have a use for them.
-
Code contributed: [Functional Code] [Test Code]
-
Other contributions:
-
Project management:
-
Added issues and milestones
-
-
Project enhancement:
-
Performed a refactor from the original addressbook to the current Flashy application.
-
-
Enhancements to existing features:
-
Documentation:
-
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Adding a flashcard: addc
You can add flashcards to Flashy. In Flashy, we support the feature of adding three different types of flashcards: normal, MCQ or fill blanks.
To add a normal flashcard, use addc f/FRONT b/BACK [t/TAGS]…
To add a fill blanks card, the input is the same as that for a normal card, the only difference is the presence of blanks _
in the f/FRONT
parameter.
To add a MCQ flashcard, use addc f/FRONT o/OPTION … b/BACK [t/TAGS] …
For a MCQ flashcard, ensure that the parameter for b/ falls between 1 the number of options inclusive.
|
Note that a blank is denoted by a single underscore _ .
|
For a fill blanks flashcard, ensure that the parameter for b/ should have the same number of answers (separated by , ) as there are blanks.
|
Examples:
-
addc f/What is the greatest flashcard application? b/Flashy t/Trivia
Adds a normal flashcard with the front and back of the first card beingWhat is the greatest flashcard application?
andFlashy
respectively, as well as tagging it asTrivia
. -
addc f/A square is a polygon with _ side meeting at _ angles. b/equal, right
Adds a fill-blanks card with the front and back of the card beingA square is a polygon with _ side meeting at _ angles.
andequal, right
respectively. -
addc f/Which continent is Singapore in? o/Asia o/Africa o/Australia o/South America b/1
Adds a MCQ-type flashcard with the front beingWhich continent is Singapore in?
, options includesAsia
,Africa
,Australia
andSouth America
and back being1
.
A flashcard can have any number of tags (including 0). |
Editing a flashcard : editc
You can edit an existing flashcard currently stored in Flashy. This comes in handy if you make a mistake when adding a card.
Format: editc INDEX [f/FRONT] [o/OPTION] .. [b/BACK] [+t/TAG]… [-t/TAG]…
A particular type of flashcard (normal, MCQ or fill blanks) can only be edited to the same type of flashcard (e.g. you cannot edit a normal flashcard to a MCQ flashcard). |
When removing a tag from a flashcard, ensure that the tag exists and the flashcard is associated with that tag. |
Ensure that the constraints on flashcard is not violated when editing. For constraints, refer to the Caution warning under Section 5.2.2. |
Examples:
-
editc 1 f/What is the greatest flashcard application? b/Flashy +t/Trivia
Edits the front and back of the 1st flashcard to beWhat is the greatest flashcard application?
andFlashy
respectively, and also add a Trivia tag to it. -
editc 2 b/Lee Hsien Loong -t/Trivia
Edits the back of the 2nd flashcard to beLee Hsien Loong
, and remove its tag Trivia. -
editc 1 o/Asia o/Australia o/Africa
Edits the options of the 1st flashcard to beAsia
,Australia
andAfrica
. (Only if that flashcard is a MCQ flashcard).
Deleting a flashcard : deletec
You can delete cards which you no use for, this helps to declutter your card bank.
Format: deletec INDEX
If a tag no longer has associated flashcards, the tag will also be removed. Don’t be alarmed if some of your tags are also removed in the process! |
Examples:
deletec 2
Deletes the 2nd flashcard in the list.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Polymorphic flashcards
Current Implementation
Allowing different types of cards is essential to Flashy. This enables the user to add and edit a normal, MCQ or fill-in-the-blanks flashcard so that the user can learn more efficiently, and use whichever that suits his learning style.
New classes McqCard
and FillBlanks
were created to implement this enhancement, and they inherit the Card class, as shown in Figure 11.

McqCard
and FillBlanksCard
from the Card
class
Card
, McqCard
and FillBlanksCard
.Aspect: Implementation of polymorphic flashcards
-
Alternative 1 (current choice): Have a class each for MCQ and fill blanks type flashcards and let them inherit the
Card
class.
MCQ flashcards have the constraint that the back of the card should be an integer between 1 and the number of options available.
For fill blanks flashcards, the constraint is that the number of answers should be the same as the number of blanks.-
Pros: In terms of usability, having constraints allows users to input the right arguments for different cards.
-
Cons: Additional classes have to be implemented.
-
-
Alternative 2: Just use a single
Card
class for all cards, so no constaints are set.-
Pros: No additional classes have to be implemented. Let the user add flashcards with any arguments.
-
Cons: No constraints for the flashcards.
-
Adding and editing of polymorphic flashcards
Current implementation
The addc
command is used to add all types of flashcards.
Design Considerations
Aspect: Implementation of add command for MCQ and fill blanks type flashcards.
-
Alternative 1 (current choice): Use
addc
for the adding of MCQ and fill blanks type flashcards.-
Pros: There would be less commands to keep track of and combining the command reduces repeated codes since there are similarities between adding of normal and other type cards.
One example of similarity is shown in the code snippet forseedu.flashy.logic.commands.AddCardCommand: executeUndoableCommand()
below. -
Cons: The add card command has to be changed which can result in undesired consequences if mistakes were made. Care has to be taken when implementing the add card feature for MCQ and fill blanks flashcards as both have constraints which cannot be violated.
Thus the constraints have to be checked before allowing the flashcard is added, as shown in the code snippet forseedu.flashy.logic.commands.AddCardCommandParser: parse()
-
public CommandResult executeUndoableCommand() throws CommandException { requireNonNull(model); try { model.addCard(cardToAdd); } // ... Catch exception ... if (tagsToAdd.isPresent()) { Set<Tag> tags = tagsToAdd.get(); try { model.addTags(cardToAdd, tags); } // ... Catch exception ... } // ... Return result ... }
public AddCardCommand parse(String args) {
// ...
try {
// ... Parse arguments ...
if (options.isEmpty()) {
if (FillBlanksCard.containsBlanks(front)) {
card = ParserUtil.parseFillBlanksCard(front, back);
} else {
card = new Card(front, back);
}
} else {
for (String option: options) {
ParserUtil.parseMcqOption(option);
}
card = ParserUtil.parseMcqCard(front, back, options);
card.setType(McqCard.TYPE);
}
return new AddCardCommand(card, tags);
} catch (IllegalValueException ive) {
throw new ParseException(ive.getMessage(), ive);
}
}
-
Alternative 2: Implement a different
addm
andaddf
command for adding of MCQ and fill blanks type flashcard respectively.-
Pros: No changes needs to be made to the
addc
command. Even ifaddm
oraddf
fails,addc
command can still work. -
Cons: Less commands for developers to keep track of. It is also less efficient to have similar codes for different commands.
If there is a change in implementation, developers would have to change code for three separate commands, which is troublesome.
-
Storage of flashcards
Current Implementation
The current implementation saves the flashcard data in XML format and reads it back when the card bank is loaded.
A single XmlAdaptedCard
class is used to convert the attributes of flashcards into XML Elements and XmlSerializableCardBank
stores a list of XmlAdaptedCard
.
Design Considerations
Aspect: Implementation of XmlAdaptedCard
class
-
Alternative 1 (current choice): Implement a single
XmlAdaptedCard
class to convert all types of flashcards into XML format.-
Pros: Flashcards would be stored in the order in which they were added.
-
Cons:
XmlAdaptedCard
has to be tweaked to take in theoptions
attribute from theMcqCard
class, and thetoModelType()
method has to check for the constraints of the MCQ and fill blanks flashcard as shown in the code snippets below:
Fromsrc.main.java.seedu.flashy.storage.XmlAdaptedCard
-
public class XmlAdaptedCard { // ... Other attributes ... @XmlElement(required = true) private List<String> option = new ArrayList<>(); // ... Constructors and methods ... } // ... public Card toModelType() throws IllegalValueException { // ... Check id, front, back constraints ... if (this.type.equals(FillBlanksCard.TYPE)) { if (!FillBlanksCard.isValidFillBlanksCard(this.front, this.back)) { // ... Catch exception ... } // ... Return card ...; } if (this.type.equals(McqCard.TYPE)) { if (!McqCard.isValidMcqCard(this.back, this.option)) { // ... Catch exception ... } // ... Return card ... } // ... Return card ... }
-
Alternative 2: Implementing a separate
XmlAdaptedMcqCard
andXmlAdaptedFillBlanksCard
to convert MCQ and fill blanks flashcards into XML format respectively.
Initially,XmlAdaptedMcqCard
was implemented to inheritXmlAdaptedCard
. InXmlSerializableCardBank
, there would be a separate list forXmlAdaptedMcqCard
, as shown in the code snippet below (which was implemented initially but later removed from source code):
public class XmlSerializableCardBank { // ... Other attributes ... @XmlElement private List<XmlAdaptedCard> cards; // New list for XmlAdaptedMcqCards @XmlElement private List<XmlAdaptedMcqCard> mcqCards; /** * Conversion */ public XmlSerializableCardBank(ReadOnlyCardBank src) { // ... for (Card card: src.getCardList()) { if (card.getType().equals(McqCard.TYPE)) { mcqCards.add(new XmlAdaptedMcqCard(...)); } else { cards.add(new XmlAdaptedCard(...)); } } } // ... }
-
Pros: No need to tweak
XmlAdaptedCard
and both classes would be separate, so mistakes inXmlAdaptedMcqCard
would not affect that inXmlAdaptedCard
. There’s no need to check forMcqCard
constraints. -
Cons:
XmlAdaptedCard
andXmlAdaptedMcqCard
would be stored in separate lists in XML format. When the card bank is loaded, both lists would be read separately and the order in which the cards were added would not be captured.
Use case: Add a flashcard
MSS
-
User adds a flashcard with an associated tag
-
CardBank adds the new flashcard
Use case ends.
Extensions
-
1a. The given parameters are invalid.
Use case ends.