Record What You Learn

The Apprenticeship Pattern “Record What You Learn” emphasizes the importance of documenting the journey and lessons that a software developer has learned to enhance personal and professional growth. This pattern addresses the common issue that many developers share of repeatedly encountering similar tasks or problems without retaining valuable insights. By maintaining a record of experiences in a journal, personal wiki, or blog, individuals can create a chronological account of the lessons they’ve learned, serving as both inspiration and a valuable resource.

Recording the solutions made to problems encountered along the software journey involves actively documenting experiences, insights, and solutions encountered. The primary problem of not documenting lessons learned is that it causes a lack of learning from past experiences, leading to repetition and inefficiency. Without a record of lessons learned, individuals may find themselves continuously getting slowed down by the same challenges without making much progress.

Maintaining a record of experiences offers several benefits. Firstly, it enables individuals to mentor others by making their journey explicit, sharing insights, and providing guidance based on past learnings. Additionally, it makes it easier to reflect, allowing individuals to identify patterns, make connections, and discover new insights.

To avoid falling into the trap of forgetting valuable lessons, individuals are encouraged to regularly revisit and review their records. By engaging in this process, they can prevent stagnation, identify areas for improvement, and continue evolving. Moreover, have access to and using both internal and external feedback allows the developer to receive more accurate self-assessment which motivates continuous learning and growth.

There are several examples in Apprenticeship Patterns that illustrate how individuals can implement this pattern in practice. For example, maintaining two instances of the same wiki — one for private thoughts and the other for shared lessons — allows for effective self-reflection. Similarly, transcribing ideas that shaped one’s learning into a text file allows it to be kept as a valuable resource for future reference and inspiration.

I believe that recording one’s learning progress it super important to any skill. So often I find myself making the same mistakes over and over again, but then I remember to look at my notes and the past resources I’ve logged for myself, and I find them super helpful in guiding my work to be more efficient and effective.

In conclusion, “Record What You Learn” encourages proactive documentation of experiences and insights to help developers apply what they’ve learned to everyday problems they may face. By methodically recording and reflecting on the lessons learned, programmers can discover valuable insights, avoid repeating past mistakes, and progress on their journey towards mastery.

From Chapter Five, “Record What You Learn” in Apprenticeship Patterns by Dave Hoover and Adewale Oshineye

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Combinatorial Testing

One of the last types of testing techniques that we learned about this semester is known is Combinatorial Testing. Combinatorial testing is a testing technique that is used for software applications with a lot of different input possibilities and a high complexity. Even if you create a large number of different test cases, you will most likely still miss a test scenario. I’m not the best at explaining what something is, so I did some research in order to find an article that helps describe the aspects of combinatorial testing as well as how to use it and what its benefits are. This website is called testsigma.com

I think that this website does a great job at explaining what combinatorial testing is as well as all of its different benefits. In the article by Shanika Wickramasinghe, it states “Combinatorial testing is a testing method that uses multiple combinations of input parameters to perform testing for a software application. The main goal of combinatorial testing is to make sure that the software product can handle different combinations of test data as input parameters and configuration options.” This means that combinatorial testing takes a bunch of different input parameters, similar to pairwise testing, and uses it to test a bunch of different cases for the program. This can be extremely useful because some of the errors with a program can only be found with specific inputs. I’ve actually had this happen to me before in one of my classes. I wrote a program and testing a bunch of different inputs and they all worked, but when my teacher tried an input I never used, it failed. I think combinational testing is going to be extremely useful for me in the future. I know it seems like combinatorial testing can only be used in certain scenarios so it might be better to not learn it, but it actually has a lot of benefits according to Wickramasinghe:

  • Covers a broad range of input combinations using a minimum number of test cases.
  • Increases test coverage compared to normal component testing since it always considers multiple input combinations.
  • Helps to detect bugs, defects, vulnerabilities, and unexpected outputs that might not be detected during the usual component and regression testing phases.
  • Reduces testing effort, cost, and time. (Since combinatorial tests use fewer test cases to cover a wide scope of testing.)
  • Identifies issues at the earliest while allowing the team to address and fix those earlier in the software development life cycle.
  • Optimizes the testing process by removing unwanted test cases while ensuring that the cost and effort are not wasted on repeating the same test scenarios again and again.
  • Helps to test complex software applications with a large number of parameters, settings, and options.
  • Reduces the risk of critical defects going unnoticed, which can occur only when handling specific input combinations.

I recommend that everyone tries to use combinatorial testing at least once so they know how it works in case they ever need to use it again in the future to make sure all of their different input possibilities work.

Link: https://testsigma.com/blog/combinatorial-testing/

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Blog #8: Intro to Security Testing

Throughout the cumulative experience I’ve had with testing, most of it focuses on the program’s logic and ensuring that it yields a correct result. One aspect of testing I have no experience with is security testing. Here one must find flaws within a system/program’s security and report them to developers so they cannot be exploited later in the product’s lifespan. Security testing has much higher stakes than that of unit testing as vital information such as consumer personal information and system source code may be leaked if there is a security breach. Therefore, testing security is of utmost importance when releasing a service to the public, as failing to do so will damage the service’s integrity.

Security testing hosts several different types of tests, each of which focuses on different aspects of a system. The article Security Testing posted by user pp_pankaj highlights the principles upheld by this testing and what each test achieves. Some of these tests, Posture Assessment, I found quite interesting. Posture Assessment combines the testing methods of ethical hacking, risk assessment, and security scanning into one report to provide an overall security posture of a system (pp_pankaj). Each of these subtests has a shared goal of having a hacker, hired by the development team, find security vulnerabilities within their system and report it to the team. Another form of testing I found interesting was social engineering testing. This deviates drastically from what we as programmers come to understand tests as. These are emulated attacks through communication such as email. The purpose of this test is to train developers to avoid suspicious engagement and to find new ways to breach a system without making direct contact. Whether a development team gets successfully breached through the socially engineered test is dependent on the team’s understanding of who they must respond to. A few weeks ago I was researching a data breach that happened earlier this year at Microsoft. Hackers were able to control a testing account and had direct access to employees on the project. From here they were able to obtain information they naturally should not have access to. All of this occurred due to developers not knowing that they must not communicate with a testing account.

A general metric as to whether security testing is vital to a project is to consider whether your product is liable for holding personal information that is not your own. If this is the case, then it’s in the development team’s best interest to uphold their principle of confidentiality and integrity by running security tests throughout the lifespan of your product.

-AG

Source: https://www.geeksforgeeks.org/security-testing/

From the blog CS@Worcester – Computer Science Progression by ageorge4756 and used with permission of the author. All other rights reserved by the author.

Blog #7: Intro to Combinatorial Testing

Beyond Unit Testing, there are several ways one may go about testing a developed system. One of these ways is through combinatorial testing. While researching this topic I’ve seen a couple of steps that I’ve taken in testing that match with this testing method. For example, earlier this semester I learned about how behavior tables can help guide Unit Testing by showing what aspects of a program will be covered by one test. Combinatorial testing achieves a similar effect by first taking all possible inputs (from a pool of predetermined inputs) and then creating a set of tests that will test each unique combination from the pool. A source that helped me grasp this topic is Combinatorial Testing by Shanika Wickramasinghe. In this article, Wickramasinghe provides an example of how they would develop tests. It’s important to note that in this example only combinations are created, NOT permutations, meaning that overall much fewer tests would be needed to fulfill a combinatorial test. This does raise a question for future reading of whether there is such thing as “permutative” testing and how that and combinatorial testing differ.

Using combinatorial testing does provide benefits despite the time it may take to achieve a successful test. Combinatorial tests are all designed to try multiple inputs simultaneously, meaning that both single-fault and multi-fault assumptions will be made in a full combinatorial test. Once these tests are complete, the developer can better understand which inputs cause a problem within their code. Additionally, once the pool of potential inputs is determined, the tester will have a set number of tests they must conduct. These tests may find faults in the program that require specific input that the development team may not have accounted for. Through feedback such as this, the development team can resolve the bug and create ways of handling errors caused by unexpected input. These benefits do come with equally heavy drawbacks. Manual combinatorial testing is possible, however the testers may struggle with creating combinations from a larger input pool. A way this can be solved is by using an automated combinatorial tester. It’s important to note that this can be limited by how intensive the tests are on the hardware of the automated tester. Lastly, the combinations that the test may provide could be so random that it’s nonsensical to test such a thing. This becomes an issue of resources which will vary from developer to developer. Ultimately whether one uses combinatorial testing or not is up to the developer. There are some instances where the cost of conducting one of these tests would be beneficial to the development process, but this is not a “one size fits all” type of test. By using some of the team’s resources, whether it be labor or hardware-bound, combinatorial tests will yield meaningful results as to which areas of the program need further testing.

-AG

Source: https://testsigma.com/blog/combinatorial-testing/

From the blog CS@Worcester – Computer Science Progression by ageorge4756 and used with permission of the author. All other rights reserved by the author.

Sprint Retrospective

Sprint 3 Retrospective

Introduction

  • In this sprint, our primary focus was on rigorously testing the frontend developed during sprint 2, applying the insights and frameworks we had discussed with team 2. This sprint appeared significantly shorter than the extensive sprint 2, partly due to the lighter workload with a target of only 16 points. This more manageable workload allowed us some capacity to address and rectify lingering issues from the previous sprint.
  • The brevity of this sprint highlighted the importance of continuous integration and testing, which enabled us to quickly identify and resolve issues. Our collaborative efforts with team 2 proved invaluable, as their feedback directly influenced our troubleshooting and refining processes. Moving forward, maintaining this synergy and applying these practices consistently will be crucial for smoothing out any future bumps in our development process and enhancing the overall quality of our project.

Links to Activity on GitLab

Reflections on the Sprint

What Worked Well:

The standout success of this sprint was our group communication. Facing challenges as a team, rather than individually, significantly eased our problem-solving process. Our review procedures were effective, facilitating a focused approach towards achieving our objectives.

Areas for Improvement:

The primary challenge we encountered was time management, particularly as progress on the front end depended on having a working template. This dependency delayed our efforts, resulting in a hectic sprint conclusion. Better planning or earlier template availability might mitigate similar issues in future sprints.


Improvements for Team Performance

The team’s collaborative communication and problem-solving were key strengths this sprint, continuing a positive trend from the previous sprint. It’s crucial to sustain this momentum into the next sprint, incorporating some strategic improvements:

Improvements for the Next Sprint:

  1. Consistent Scheduling: To avoid the congestion experienced towards the end of the last sprint, establishing a more consistent schedule for meetings could help in better time management and distribute tasks more evenly throughout the sprint.
  2. Balanced Division of Labor: We should continue to monitor and adjust the workload among team members to ensure tasks are evenly distributed, preventing any team member from being overwhelmed while others have less to do.
  3. Streamlined Communication Channels: Building on our previous success, maintaining all critical communications in a centralized, organized, and easily accessible system will enhance clarity and continuity, aiding in more effective decision-making and problem-solving.

Personal Improvements

Reflecting on my personal challenges during this sprint, specifically around managing merge requests correctly, I see valuable opportunities for growth:

  1. Proactive Communication: To prevent and swiftly address any uncertainties or errors in my work, I commit to being more proactive in seeking feedback and clarifications from team members.

From the blog CS@Worcester – Abe's Programming Blog by Abraham Passmore and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective

This was our third and final sprint for the semester and I believe we improved greatly when it came to working as a team compared to our previous sprints.We completed all of our issues during this sprint as a team during our various meetings which allowed us to collaborate more and learn about the project together. These issues included getting our frontend properly running in gitpod, figuring out which files were needed from guest info frontend and changing the existing scripts as well as updating documentation in order to leave the frontend in a good state for the next team to work on it.

Overall I did not have any trouble with working on any of the issues this sprint and I feel as though our collaboration on the issues helped us complete them more efficiently. The issue we worked on regarding getting the frontend to run in gitpod was straightforward and we were able to complete it without much delay as we were able to effectively reference the guest info frontend as it was already able to run in gitpod. The second issue that we worked on as a team regarding the addition of more frontend files/file structure and changing the scripts also went well and we were able to complete that as a team without any major issues.. The final issue we worked on as a team included updating the documentation which was rather easy to complete as a team as we had good references and experience with documentation between all of us. We had two other issues regarding making a confirm page but we were not able to finish those during the sprint as we did not want to leave unfinished work for the next team to have to deal with.

We did not have many problems during this sprint and I feel as though we all improved and worked together efficiently as a team. We all attended every meeting that we had scheduled and we all contributed directly to the project through code, documentation etc. The more collaborative nature of the work we did this sprint with each issue relying on the previous issues being completed first allowed collaboration to be a vital part of the process as we were able to finish issues in a timely manner when having all of our ideas going towards the completion of each issue. I feel as though we were all able to draw on one another’s strengths when working during this sprint which is something we were lacking slightly in the previous sprints. We also improved even more when it came to usage of Gitlab as we are all more experienced in both gitlab and gitpod now and able to understand the processes used as well as the workflow. The two issues we were unable to complete regarding a confirmation page are set up so that the next team can work on them when they begin their first sprint and we made sure to update the wireframe along with the documentation to provide the best start possible for the next team.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/addinventoryfrontend/-/issues/46

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/documentation/-/issues/12

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/addinventoryfrontend/-/issues/48

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/addinventoryfrontend/-/issues/51

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/addinventoryfrontend/-/issues/52

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/addinventoryfrontend/-/issues/49

From the blog CS@Worcester – Dylan Brown Computer Science by dylanbrowncs and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective

 


In Sprint 3 I worked on finishing the checkinventoryfrontend. With the
shorter time of the sprint, I went to work on fixing an issue I encountered
in the previous sprint where the frontend would only display an error
message saying that there was some problem in the html. At the same time I
was trying to figure out how to get npm to work in the new file structure,
since when I try calling npm in the terminal it kept failing. For the
longest time I couldn’t figure out how to get the frontend to display
correctly, trying all sorts of solutions from moving the package.json file
around to deleting the deprecated yarnlock file. Eventually, I settled on
figuring out how to change the npm files to allow npm to reach the new
frontend folder I made. At some point, Jason asked if there was anything the
rest of the team could work on in checkinventoryfrontend, and I said the
documentation needed to be updated and that nodemon needed to be
implemented. Jason then created a separate branch based on mine called
implementing-nodemon, where he changed the package.json and gitpod.yaml files to have nodemon
and other dependencies. 

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/tree/implementing-nodemon?ref_type=heads


Somehow, over the course of these dependencies being added, the frontend
started working again. The error must have been rooted in one of the
dependencies not working properly, or something to that effect. I looked int
o the changes Jason made, and he added a section to the gitpod.yaml that
would of implemented certain npm dependencies.


https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/997bd2bd2197def31c8ae29efea071f9d07e077f


 Either way I’m just happy to be able to finish up the work in the
frontend. I went into Jason’s branch and cleaned up some of the shell files
so that they work as intended. The frontend-dev-up.sh file needed to use
frontend-dev instead of dev since that is what npm recognises in this repo.
Also, frontend restart needed to use the proper name of frontend-prod-down
and up.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/480596810546e3286f8821d24cafe68bcd0fc1df

Then I started on cleaning up my own work for the next semester. I removed
the branches I had created since they either were redundant or straight up
didn’t work. Then I cleaned some deprecated files out of the implementing
nodemon branch while I was fixing the shell files, like an extra package
json file that was created in the base repo. 

I learned a lot about working with the frontend throughout this sprint, and
the entirety of the semester for that matter. I definitely want to brush up
on how npm works and functions, because I feel like most of my problems stem
from a lack of understanding. I also want to give credit to my team, who
have helped me out more than they realize, especially since I have been
balancing my work and school life. Hopefully the final presentation
represents all of our efforts over the semester.

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective

 


In Sprint 3 I worked on finishing the checkinventoryfrontend. With the
shorter time of the sprint, I went to work on fixing an issue I encountered
in the previous sprint where the frontend would only display an error
message saying that there was some problem in the html. At the same time I
was trying to figure out how to get npm to work in the new file structure,
since when I try calling npm in the terminal it kept failing. For the
longest time I couldn’t figure out how to get the frontend to display
correctly, trying all sorts of solutions from moving the package.json file
around to deleting the deprecated yarnlock file. Eventually, I settled on
figuring out how to change the npm files to allow npm to reach the new
frontend folder I made. At some point, Jason asked if there was anything the
rest of the team could work on in checkinventoryfrontend, and I said the
documentation needed to be updated and that nodemon needed to be
implemented. Jason then created a separate branch based on mine called
implementing-nodemon, where he changed the package.json and gitpod.yaml files to have nodemon
and other dependencies. 

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/tree/implementing-nodemon?ref_type=heads


Somehow, over the course of these dependencies being added, the frontend
started working again. The error must have been rooted in one of the
dependencies not working properly, or something to that effect. I looked int
o the changes Jason made, and he added a section to the gitpod.yaml that
would of implemented certain npm dependencies.


https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/997bd2bd2197def31c8ae29efea071f9d07e077f


 Either way I’m just happy to be able to finish up the work in the
frontend. I went into Jason’s branch and cleaned up some of the shell files
so that they work as intended. The frontend-dev-up.sh file needed to use
frontend-dev instead of dev since that is what npm recognises in this repo.
Also, frontend restart needed to use the proper name of frontend-prod-down
and up.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/480596810546e3286f8821d24cafe68bcd0fc1df

Then I started on cleaning up my own work for the next semester. I removed
the branches I had created since they either were redundant or straight up
didn’t work. Then I cleaned some deprecated files out of the implementing
nodemon branch while I was fixing the shell files, like an extra package
json file that was created in the base repo. 

I learned a lot about working with the frontend throughout this sprint, and
the entirety of the semester for that matter. I definitely want to brush up
on how npm works and functions, because I feel like most of my problems stem
from a lack of understanding. I also want to give credit to my team, who
have helped me out more than they realize, especially since I have been
balancing my work and school life. Hopefully the final presentation
represents all of our efforts over the semester.

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective

 


In Sprint 3 I worked on finishing the checkinventoryfrontend. With the
shorter time of the sprint, I went to work on fixing an issue I encountered
in the previous sprint where the frontend would only display an error
message saying that there was some problem in the html. At the same time I
was trying to figure out how to get npm to work in the new file structure,
since when I try calling npm in the terminal it kept failing. For the
longest time I couldn’t figure out how to get the frontend to display
correctly, trying all sorts of solutions from moving the package.json file
around to deleting the deprecated yarnlock file. Eventually, I settled on
figuring out how to change the npm files to allow npm to reach the new
frontend folder I made. At some point, Jason asked if there was anything the
rest of the team could work on in checkinventoryfrontend, and I said the
documentation needed to be updated and that nodemon needed to be
implemented. Jason then created a separate branch based on mine called
implementing-nodemon, where he changed the package.json and gitpod.yaml files to have nodemon
and other dependencies. 

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/tree/implementing-nodemon?ref_type=heads


Somehow, over the course of these dependencies being added, the frontend
started working again. The error must have been rooted in one of the
dependencies not working properly, or something to that effect. I looked int
o the changes Jason made, and he added a section to the gitpod.yaml that
would of implemented certain npm dependencies.


https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/997bd2bd2197def31c8ae29efea071f9d07e077f


 Either way I’m just happy to be able to finish up the work in the
frontend. I went into Jason’s branch and cleaned up some of the shell files
so that they work as intended. The frontend-dev-up.sh file needed to use
frontend-dev instead of dev since that is what npm recognises in this repo.
Also, frontend restart needed to use the proper name of frontend-prod-down
and up.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/480596810546e3286f8821d24cafe68bcd0fc1df

Then I started on cleaning up my own work for the next semester. I removed
the branches I had created since they either were redundant or straight up
didn’t work. Then I cleaned some deprecated files out of the implementing
nodemon branch while I was fixing the shell files, like an extra package
json file that was created in the base repo. 

I learned a lot about working with the frontend throughout this sprint, and
the entirety of the semester for that matter. I definitely want to brush up
on how npm works and functions, because I feel like most of my problems stem
from a lack of understanding. I also want to give credit to my team, who
have helped me out more than they realize, especially since I have been
balancing my work and school life. Hopefully the final presentation
represents all of our efforts over the semester.

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Sprint 3 Retrospective

 


In Sprint 3 I worked on finishing the checkinventoryfrontend. With the
shorter time of the sprint, I went to work on fixing an issue I encountered
in the previous sprint where the frontend would only display an error
message saying that there was some problem in the html. At the same time I
was trying to figure out how to get npm to work in the new file structure,
since when I try calling npm in the terminal it kept failing. For the
longest time I couldn’t figure out how to get the frontend to display
correctly, trying all sorts of solutions from moving the package.json file
around to deleting the deprecated yarnlock file. Eventually, I settled on
figuring out how to change the npm files to allow npm to reach the new
frontend folder I made. At some point, Jason asked if there was anything the
rest of the team could work on in checkinventoryfrontend, and I said the
documentation needed to be updated and that nodemon needed to be
implemented. Jason then created a separate branch based on mine called
implementing-nodemon, where he changed the package.json and gitpod.yaml files to have nodemon
and other dependencies. 

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/tree/implementing-nodemon?ref_type=heads


Somehow, over the course of these dependencies being added, the frontend
started working again. The error must have been rooted in one of the
dependencies not working properly, or something to that effect. I looked int
o the changes Jason made, and he added a section to the gitpod.yaml that
would of implemented certain npm dependencies.


https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/997bd2bd2197def31c8ae29efea071f9d07e077f


 Either way I’m just happy to be able to finish up the work in the
frontend. I went into Jason’s branch and cleaned up some of the shell files
so that they work as intended. The frontend-dev-up.sh file needed to use
frontend-dev instead of dev since that is what npm recognises in this repo.
Also, frontend restart needed to use the proper name of frontend-prod-down
and up.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/checkinventoryfrontend/-/commit/480596810546e3286f8821d24cafe68bcd0fc1df

Then I started on cleaning up my own work for the next semester. I removed
the branches I had created since they either were redundant or straight up
didn’t work. Then I cleaned some deprecated files out of the implementing
nodemon branch while I was fixing the shell files, like an extra package
json file that was created in the base repo. 

I learned a lot about working with the frontend throughout this sprint, and
the entirety of the semester for that matter. I definitely want to brush up
on how npm works and functions, because I feel like most of my problems stem
from a lack of understanding. I also want to give credit to my team, who
have helped me out more than they realize, especially since I have been
balancing my work and school life. Hopefully the final presentation
represents all of our efforts over the semester.

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.