Project: MyProject

Project background

MyProject is a command line desktop application that I helped design and implement as part of a team, for a school project for the NUS School of Computing. My team consisted of 5 computing students including me, and the task for this project was to modify a given application called the AddressBook into our own application, that serves a different purpose. As second year university students, we have always found it difficult to manage many different types of information across many different projects during our first year, and hence we decided to modify the AddressBook application into MyProject.

Overview

MyProject is a desktop application with a command line interface, which aims to be a one-stop project management application that will satisfy all the project management needs of a student. Our application specialises in storing, processing and displaying the information of the projects in a meaningful way to help students better manage their workload when it comes to dealing with multiple different projects at the same time. MyProject provides basic functionality such as storing the members, meetings and tasks of a given project, and also storing the contact information of the members. MyProject also boasts more complex functions such as calculating optimal meeting times based on the NUSMODS timetable of each member, and also tracking the finances of the project with different types of budgets.

A typical usage of the project looks like this:

picture

My team worked together tirelessly to put this application together. Each of us are in charge of different parts of the application’s functionality, and my role in the team was to integrate the Person model in the original AddressBook application into our application, and use it as a way to keep track of the member’s information.

In addition to that, I also implemented a way for the application to track each member’s performance in terms of a few tangible attributes such as by keeping track of how many tasks they have done. This is to allow anyone using the application to optimise their workflow, and better manage the progress of their project since they would know who has done what tasks and how much each member is contributing to the team. This would also aid in more even work distribution.

In the next section, I will summarise all my contributions to the project.

Summary of contributions

  • Major enhancements: Added the performance overview functionality of MyProject.

    • What it does: This feature consolidates all the information available, and uses it to calculate the performance of each member. The information is stored, and displayed to the user when the the user executes the showProjectOverview command. The calculated attributes of the performance is then displayed in the form of tables for easy comparison between the members. It will also show the individual performances of each member by itself. To see a clearer view of this, you may look at my contributions to the user guide which will be in the subsequent sections.

    • Justifications: This feature allows the user to conveniently keep track of what each member has done and their contributions to the project. This can help with distributing the workload between the members, and also helps if there is a need to assign credit to each member for their amount of work done.

    • Highlights: This feature does not require any additional storage as it is only calculated when the user requests for it, and all the information is already available within the Person and Project objects themselves. The feature also provides both an overview of their performances for easy comparison and a more individual view where the attributes are grouped and listed according to each member should there be a need to check the specific member’s performance. The user also only has to type in the showPerformanceOverview command and everything else will be handled internally because all the information needed is already supplied during the day to day interactions with the application when the user assignTask to members and markAttendance for meetings. (Both of which are commands that can be executed by the user).

    • Challenges: One of the challenges I faced when implementing this feature is finding a way to implement the PerformanceOverview model. I initially considered making it an attribute of the existing Project model which my teammate implemented, however I quickly realised that this would not be feasible, as calculating the performance of a member requires a information from both the Project and Person. Therefore I chose to implement PerformanceOverview as a new model instead which created less dependencies between the Project and Person models, and also reduced the need for the Project model to be associated with the Person model.

  • Minor enhancements: I also added the functionality to keep track of the members information within the application, such as what projects they are involved in, and the commands to add and remove members from projects. To facilitate my performance overview functionality, I also implemented 3 more commands which are the assignTask, unassignTask and markAttendance command. This is to supply the application with useful information to be used in the performance calculations when the performance overview is requested by the user.

  • Code contributed: [Functional code] ← Click this link to see my code contributions.

  • Other contributions:

    • Project Management:

      • Helped to report and sometimes fix the bugs which I found during the routine testing of our application.

    • Documentation:

      • Did the first round of general formatting of our user guide which included fixing the inconsistent formatting, and improving the overall organisation and style of the whole user guide. See more here → [Pull request #69]

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.

Add a new member: addMember [Checkout]

This command is similar to adding a person to your contacts shown previously, except that you have to be checked out into a project, and the person will be added to the working project as well.
Format: addMember n/NAME [p/PHONE_NUMBER] [e/EMAIL] [a/address] [t/tag]…​

Adding a member only requires his/her name!

However it will be good to add as much information as possible.

Example:

  • addMember n/John Doe a/John street, block 123, #01-01

  • addMember n/Betsy Crowe e/betsycrowe@example.com t/friend

To help you better understand how to use this command, here is a step-by-step guide, using the second example.

Step 1: You type in the addMember command, followed by all the information you want to store, which in this case is her email and also her tag as a friend. With this, before you press enter your screen should look like this:

AddMemberCommandInput
Figure 1. AddMemberCommand user input

If your screen looks like the picture above, just press enter and you’re done! Adding a new member is just a simple one step process.

After you press enter you will be able to see the member reflected in the project like this:

picture
Figure 2. AddMemberCommand success project overview display

And you will also be able to see her in your contacts like this:

picture
Figure 3. New Member displayed in your contacts as a new person added.

If you look closely at Figure 5. you will see that some of the information does not really seem right. That is because you have not input it yet, but don’t worry you can always do that later with our edit command which you will further down the guide.

Add from your contacts: addFromContacts [Checkout]

This command helps to add a person you already saved in your contacts into your project, reducing the need to type his information all over again. All you need to do is enter the index he is listed at.
Format: addFromContacts INDEX…​

INDEX is the number which the person is listed at, and it should be a positive integer eg. 1, 2, 3, …​.

You can put multiple indexes to add multiple people to your project at once isn’t that convenient! E.g. addFromContacts 1 3 5

Example:

  • addFromContacts 1

To help you better understand how to use this command, here is a step-by-step guide.

Step 1. Find the person you want to add, and take note of the index which the person is listed at. Referring to the picture below, let’s say you want to add 'Bernice Yu' into your project. Notice her index is 2.

picture
Figure 4. Finding the person to add

Step 2. Type in the addFomContacts command with the index 2

AddFromContactsCommandInput
Figure 5. addFromContacts command input.

Step 3. Press enter and you’re done! Refer to the picture below to see what your screen should look like.

picutre

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.
hello world

Member feature

Description of feature

In every project, it almost certain that there are members. Therefore we have allowed for the users to be able to track who are the members, and how many members there are within each project. Each Project stores its members as a list of strings representing their names, and similarly each Person stores the projects they are involved in as a list of strings representing the project titles. Below you will find 2 diagrams which represents this relationship.

picutre
Figure 6. Class diagram of Project
picture
Figure 7. Class diagram of a Person
Whenever member is mentioned it should be known that it is represented by a Person.

In order to facilitate this feature, 4 commands are implemented as a subclass of the Command class:

  1. addMember - Adds a new Person to the contacts an records the name as a member of the current working project.

  2. addFromContacts - Adds a Person to the current working project as a member.

  3. removeMember - Removes the record of the Person as a member of the current working project.

  4. addProfilePicture - Adds a profile picture to the specified Person.

Implementation

In this section, we will demonstrate how a member is added to the project from your contacts, and also how a member as a new Person.

We will start with adding a new Person to your contacts, and to your project at the same time.

Step 1. The user enters the addMember command with the following parameters n/David p/94328727 e/david97@hotmail.com a/Ang Mo kio avenue 3.

Full user input: addMember n/David p/94328727 e/david97@hotmail.com a/Ang Mo kio avenue 3

The user input is parsed into an ArgumentMultiMap by AddMemberCommandParser#parse so that every attribute of the person can be extracted, and put into a NewMemberDescriptor to be used to correctly create the Person.

ArgumentMultimap is a class that stores all the parsed parameters from the user input.
NewMemberDescriptor is a class that stores any all the information on the Person given by the user to be used to create the Person subsequently.

Step 2. The information of the person is stored in the NewMemberDescriptor, and used to create a new instance of the AddMemberCommand

Every Project keeps track of which members are involved by storing a list of strings of the names of the members. Similarly a Person keeps track of which projects they are involved in by storing a list of strings of the project titles.

The following commands are implemented to support this feature:

  1. addMember - Adds a new person to the contacts as well as to the current working project.

  2. addFromContacts - Adds a person currently stored in your contacts to the current working project.

  3. removeMember - Removes a person from the current working project.

  4. addProfilePicture - Adds a profile picture to a person in the contacts.

Performance Tracking

We allow users to be able to track the performance of every member in the project, by using information that the user has already input into MyProject.

Implementation

The Performance of each Person is consolidated and stored in a PerformanceOverview object inside the model.

Performance of a Person stores the information such as tasks assigned to the person, which are specific to the person. The actual performance of the person can only be calculated in PerformanceOverview with information from the Project as well.

PerformanceOverview is a separate model we have implemented, which consolidates all the data from each Person involved in the specific project, as well as from the project itself. The following is a class diagram for PerformanceOverview.

picture

A typical PerformanceOverview is created using the following constructor:

PerformanceOverview(project, memberList)

  • project - This is the Project that the user is concerned about.

  • memberList - This is the List<Person> which consists of all the Person(s) involved with this project. Note that they each have their own Performance as well.

All the calculations of the various components constituting the performance of an individual is calculated within the PerformanceOverview, and the results are accessed using each of the following commands:

  1. PerformanceOverview#getAttendanceOf(Person person) - Gets the number of meetings attended by the Person

  2. PerformanceOverview#getRateOfAttendanceOf(Person person) - Gets the percentage of meetings attended by the Person

  3. PerformanceOverview#getNumOfTaskDoneOf(Person person) - Gets the number of tasks completed by this Person

  4. PerformanceOverview#getTaskCompletionRateOf(Person person) - Gets the percentage of the assigned tasks, which the Person completed

Internally, every attribute of the performance of an individual a HashMap for that particular attribute. For example, the task completion rate of every individual is stored in a HashMap<String, RateOfTaskCompletion> where the key is the string of the name of the member, while the value is the rate of task completion. Every other attribute is stored in similar fashion.

Next, we will demonstrate the process of using this feature to see the performance of each member. The following sequence diagram shows the entire process of calculating the performance of member and showing it, after the showPerformanceOverview command is input by the user.

ShowPerformanceOverviewSequenceDiagram
Figure 8. Sequence diagram of the showPerformanceOverview command execution

With reference to the sequence diagram above, here are the steps of the command execution:

Step 1. The user input is parsed, and a ShowPerformanceOverviewCommand is created.

Step 2. The execution of the ShowPerformanceOverviewCommand fetches the Project that the user is working on, and also the Person(s) involved in the project and returns them as a List<Person>.

Step 3. The List<Person> and Project are used to create the PerformanceOverview. Here you can see that when a PerformanceOverview is created there are 4 methods being called internally. This is where all the necessary information is taken from the project and members, and used to calculate the different attributes of the member’s performance. It is also in those 4 methods, where the HashMaps are created.

Step 4. The PerformanceOverview is set in the Model, and displayed to the user subsequently.

The following activity diagram summarizes the general flow of the execution of the showPerformanceOverview command:

picture
Figure 9. Activity diagram for showPerformanceOverview

As shown in the activity diagram, there are only 2 main flows during the execution of this command. If there are members in the project, the performance of the members can be calculated, and the performance overview will be displayed to the user. If there are no members in the project, the user will be shown an error message to tell them that the performance overview cannot be computed.

Design Considerations

Data structure of PerformanceOverview

  • Alternative 1(Current implementation): Currently, every attribute is stored and paired to the member using a HashMap. The key is the string representation of the name of the members, and the value is the attribute itself.

    • Pros:

      • Easy to implement.

      • In order to add a new attribute to measure performance, there is only a need to add a new HashMap, a method to calculate the values, and a method to retrieve the values.

    • Cons:

      • It is more difficult to iterate through all HashMaps to retrieve the values based on your preferred ordering.