The Master Branch team has successfully completed Iteration 2 to satisfactory success, reaching the intended target for code completion, at a comfortable rate and time to spare
A successful and well-tested paradigm, forms the backbone of the project
Taking advice from seasoned coders, Agile programming was the decided approach . Agile proved most suitable for our team providing a balance between adaptation and order. Agile mindset was in play from the release of the specification, our development framework embodied three phases of sprints, where members would build, test and review each module in an iterative procedure.
Test Driven Development was a significant agile trait that had followed. Written tests from iteration 1 were continuously updated as the core functions changed, to ensure every fragment of the core functions worked. Pytest coverage was an important indicator as to ensure all the code implemented was correct. As such, striving for 100% coverage was ideal to assure all our functions were working as intended.
As time progressed, more information regarding implementation, as well as the clarity of specification, were released, prompting the need to constantly re-evaluate our tasks. Point poker was used to determine
effort for the new tasks. This was done through our weekly group chat in order relay our ideas to one another. Point poker established the importance of the auth/
functions as the literal cornerstone of our iteration. Since
everything else would be built around them, these tasks were handled with the highest priority. Code sprints followed point poker, with 3 days of focused code implementation, supported by intrinsic testing and a team meeting
for reflection. This would typically coincide with an update on the task, thus the short cycle of planning and implementing, started again.
Thus, agile proved to be the suitable approach for our team, countering our inexperience, and strengthening the perceptive attitude of our team.
Communication is the heart, in keeping an oriented and well-functioning team.
Our team was no different, embracing messaging applications such as Facebook's Messenger and Discord to disclose any concerns or problems at mind. Communication was constant, as any possible controversy was raised, and posed as a question. We intentionally set the bar low on what was message worthy to promote discussion and improve team cohesion on which member was tasked with what.
Voice interaction was scheduled every 5 days in order to more effectively communicate larger topics that were less efficient by writing. An example of this would be how we planned to organise our directories so improve accessibility and readability of our project. Discord was the main platform with calls lasting between 1 and 3 hours, detailing what progress was made since the last, as well as a agreement on the standard of work done by each member.
Communication was not only restricted to digital mediums. Weekly meetups in tutorials and labs gave a physical interaction that culminated in walk-throughs of problems to others. Over the designated weeks for Iteration 2, we met up physically on the last week for 2 hours in a computer lab, in order to synchronize and direct work for the final assembly.
Overall, we can all proudly endorse the effects of communication on our team's work, minimizing problems and streamlining code production.
A planned approach to any seemingly difficult task, will augment the capability of the team.
During our communication sessions, we agreed to follow a set structure to maximize the benefits of communicating.
- First person reflects on what they have completed since the last group call
- They highlight any potential problems or issues they have or had with implementation
- In depth analysis on the code they implemented, familiarizing other members with the context
- Other members voice feedback on any issue
- Progress to the next member
As a result, these coherent discussions served as an imperative inclusion as the feedback to be considered was important and reduced consecutive problems later on.
It is well known that "Nothing goes to plan"
Preparation for failure is a critical part of ensuring success. For our team, any problem could be overcome with enough time, thus we attempted to be tactical with our time. We scheduled our own due date to be 2 days before the course-wide specification. By this determined day, all work should be completed to a satisfactory standard of submission. The 2 day buffer zone was created as a contingency, a dedicated time to tackle any unscheduled complication. This proved to be very effective since some members have discovered missing elements of our project which allowed us to complete still with time to spare.
One of the most biggest challenges faced during this iteration was resolving merge conflicts. At one point, the frontend servers went from fully functional to completely broken after accepting a merge request to Master. This caused a lot of concern since it was extremely difficult to individually pinpoint the exact place which contained the wrong code after merging. However, after very clear communication to immediately stop pulling/pushing code to master, as well as organising an emergency voice call meeting, our repository was restored to its original working state - an accomplishment that could not have been done without the collective work of everyone.
On a lower-level, small issues came up which were tackled professionally by the team. Any self-focused or deeper issues were asked on Piazza, with the responses forwarded to the group. Furthermore, most issues that arose, were solved by other members, thus removing the need to search for external solutions. The installation of Flask and other Python third-party services was a prime illustration. Some virtual environments required the installation of Flask servers, luckily, it was a concern that was tackled before, thus could be solved simply by the input of another team member.
Some obstacles were not time-constrained, such as vague definitions and expectations. These were settled quickly by correspondence with staff, such as tutors and lecturers. Occasionally team members met in-person for pair programming which served as a valuable tool for mitigating inconsistencies in our overall style and formatting of code.
To summarise, the team was vigilant to handle an unfavourable outcome on a large scale. Although it never occurred, the preparation was respected and followed.
Teams will perform at peak efficiency when coordination is valued and appreciated
Team work is only progressive when each team member is valued and taken into consideration. Working on the backend functions put this theory into play. Despite being tasked with non-conflicting functions to complete, the final fabrication of code required all members to access the central server.py file in order to update their work and ensure it would run. Although the Git open resource deters conflicts, we as a team, largely found it to complicate matters. Fortunately, it did not take long to update the server.py with necessary information, thus each team member wrote out their wrapper-functions on a separate document, before taking turns to integrate their work, to prevent having to sort out merge complications.
Coordination was only constructive for our team, and nothing less. Often, our code implementations would share the same algorithm of code, thus to remain efficient, helper functions were created. These reduced the time and code-length required, allowing all team members to call the same helper functions to simplify their own implementations. An ideal application of this is the shared helper functions to decode a token and return the necessary ID. As the majority of functions specified tokens in their parameters, this helper function was a productive asset that diminished the length and complexity of code.
In continuation, our meetings concluded we needed a benchmark for layout. As such, we nominated the cleanest layout in order to maintain readability and ease of use, standardizing our code to the same expectations.
In closure, our co-ordination permitted us to implement a efficient, simple and capable design of the back end functions.