Category Archives: Week 8

This Week In Software Process Management

In this week’s class, we delved into some intriguing topics that shed light on the dynamic world of project management and software development. So, let’s recap the highlights of our recent discussions.

New Project Initiation:

We kicked things off by exploring the essential steps in new project initiation. It all begins with reading product descriptions and commencing a basic requirements analysis. This initial phase sets the tone for the entire project, as it helps us understand what we’re about to embark on. Clarity at this stage is paramount.

Then, we moved on to the technical side of things by creating a new project on GitLab. We ensured that all the required files were in place and established a board structure tailored to support Scrum development. This pivotal step lays the foundation for collaborative, agile work and efficient progress tracking.

One concept that stood out this week was the “Definition of Done.” Understanding and defining what constitutes a complete task is vital to maintaining project integrity and ensuring that everyone is on the same page regarding project expectations.

Copyright and Licensing:

The second part of our class dived into the complex yet critical world of copyright and licensing. It’s not just about legalese; it’s about safeguarding your work and respecting the intellectual property of others.

We explored Free & Open Source Software Licensing, digging into the details of when a work becomes copyrighted and who owns that copyright. This knowledge is essential in avoiding potential legal pitfalls.

We also examined what you can and cannot do with unlicensed software. Knowing the boundaries here is crucial in preventing unintentional violations.

Licensing became a central theme in our discussions, as we explained its role and its significance in the realm of open-source software. We even delved into specific licenses like the GNU General Public License, Mozilla Public License, Eclipse Public License, and MOT License, each with its unique implications and considerations.

Lastly, we explored the importance of identifying the license of published software. It’s essential to be aware of the rules and limitations when using or contributing to open-source projects.

In summary, this week was an exciting journey through the early stages of project initiation, all the way to the intricate world of copyright and licensing. These insights will undoubtedly prove invaluable as we continue our education and venture into the realms of project management and software development. Stay tuned for more exciting insights in the coming weeks!

From the blog CS@Worcester – Dose Of Dev by msavice and used with permission of the author. All other rights reserved by the author.

Understanding Software Licensing

The article I chose for this week’s blog is “Understanding Software Licensing”. This blog discusses what a software license is, how it works, why it matters, a few types of software licenses, and how to decide the best type of license for your software. In class, we discussed the topics that were brought up in this blog so I decided to do a deeper dive into software licenses to refresh my mind on the information that we reviewed and possibly gain a better understanding of it. 

The author tackles the topic in an organized manner that makes each part easy to follow. In the section about why software licenses matter, the author outlines clear advantages from different standpoints. For example, he states that from a developer standpoint, they offer benefits like “preventing users from performing actions like copying and distributing your software, if the license prohibits it, limiting your own liability, spelling out your own rights as a developer, and allowing you to control the usage of your product”. He then outlines the benefits from a user’s standpoint; he mentions that it helps you manage your tools and resources,  prevents you from paying for tools that aren’t necessary for your business, and clarifies how the provider can use your private information. The choice to clearly outline the advantages from each standpoint aids in the reader’s understanding of the importance of licensing software.

The sections on the types of licenses were beneficial. The public domain license is a simple license to understand. The section that defines a copyleft license is an open-source license meaning that deviation of the code must have the same terms. Defining the GNU license as a weak copyleft license helped to simplify what it was. His explanation of a permissive license was helpful as well. He defined each type of license with a short, simple statement at the beginning and then went on to further explain them.

The other part of the article that I found to be very helpful is the section about how to figure out what the best type of license is for your software. Because software licensing is new to me, I was struggling to pick which license I should use for a project. The author mentions that you should “consider the different models, thinking about the purpose behind your code and what you want users to be able — and not be able — to do with it”. It can be very challenging to outline the true purpose of your code clearly. It was very helpful that the author clearly defined the types of licenses in simple terms and then gave simple advice on how to pick which one to use. I enjoyed reading this blog and will use the knowledge for my future projects.

From the blog CS@Worcester – Live Laugh Code by Shamarah Ramirez and used with permission of the author. All other rights reserved by the author.

CS343 – Week 8

API, or application programming interface, is a set of specifications that allow applications to interact with one another. They enable transfer of information and is treated as an intermediary level let companies open their application data to external third-party developers as well as internal departments within the company. An example of how APIs work is third-party payment processing. For instance, when making a payment online and being given an option to “Pay with PayPal”, the connection made between the third-party payment system and the website where the payment is being made is reliant on APIs. When selecting the option, an API calls to retrieve information or request. After processing the request from the application to the web server, the API makes a call to the external program/web server. In this situation, it would be the third-party payment system. The external system then sends the requested information back through the API to transfer to the initial requesting web server.

REST is a set of design principles and stands for “representational state transfer” architectural style. Sometimes referred to as RESTful APIs, they were first defined in 2000 by Dr. Roy Fielding and provides more flexibility and freedom for developers. They can support many different data formats and are required to follow the 6 principles, also known as architectural constraints. The six principles are the following: uniform interface, client-server decoupling, statelessness, cacheability, layered system architecture, and code on demand (optional).

Uniform interface means that all API requests from the same resource should have identical formats to ensure that a piece of data belongs to only one uniform resource identifier (URI). The resource should not be too large while still containing the information the client needs. Client and server applications must be completely independent of each other in REST API design. The client application only needs to know the URI of the requested resource and cannot interact with the server in any other ways. Statelessness means that each request needs to include all the information necessary for processing it, which means REST APIs do not require any server-side sessions. Resources should be cacheable on the client or server side and the server responses should contain the needed information about whether caching is allowed for the delivered resource. The purpose of this is to improve performance on the client side while also increasing scalability on the server side. REST APIs have different layers to them that calls and responses go through. To note, do not always assume the client and server applications connect directly to each other. These APIs need to be designed so that neither the client nor the server can tell whether it communicates with an intermediary or end application. In certain cases, responses can contain executable code when they usually send static resources. In the case that an executable code is added (such as Java applets), the code should only run on-demand.

What is a REST API? | IBM

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

Licensing Software

Overview

In order to be able to use someone else’s software for your own software project, you must attain a software license. This license establishes the rights and limitations that you have when using the product owner’s software. Software licenses are attained by licensing agreements, where you sign a contract with the owner of the software to use the patented technology.In that contract contain the rights, responsibilities, and limitations you have as a user. I think if you develop some sort of software, it is crucial that you and your team are recognized as the owners of it, and that outside users don’t use it however they feel like. There are many types of software licenses that have different terms and conditions. An article that I read by Ben Lutkevich went more into depth of what a software license and agreement will usually look like, as well as the different types.

Attaining a License

You are about to sign the licensing agreement to officially be able to use someone else’s software. Here’s what to expect. On it will be basic information about both sides. Your name, your address, contact information, as well as the lending party’s. It will contain when the agreement officially goes into effect, and you are able to use the software. It will contain the duration of how long you are able to use the software. It will include how much you have to pay for the software, how many users are eligible. It will give a disclaimer of warranties, as well as maintenance, upgrades and support. Most importantly, it will include the permissions and limitations on distributing the software, user rights of copying and modifying the software. These licensing agreements may differ depending on the type of software license.

Types of Software Licenses

The most common software licenses you find are Proprietary and FOSS. A proprietary software license is commonly referred to as closed-source. Proprietary licenses do not allow users to freely alter the software. Whereas FOSS (Free and Open-Source Software) is the opposite, where the customer is allowed to use the source code and alter the software. FOSS is commonly referred to as open-source. This is the type of license that we will be using in class. Two other licenses that are familiar are Permissive and Copyleft. Permissive software licenses establish some requirements for distribution or modification of the software, and Copyleft notes that licensed code may be distributed or modified as part of a software application or project if all code involved is distributed under the same license. New products containing old code with a copyleft license have the same restrictions as the old code’s license.

Conclusion

If planning to create a software product, it is a smart idea to establish copyright for it, so you are credited for the work you put in. And if you are using someone else’s product for your own product or project, it is the smart decision to attain a licensing agreement, avoiding any potential lawsuits.

Article URL

https://www.techtarget.com/searchcio/definition/software-license#:~:text=A%20software%20license%20is%20a,the%20software%20without%20violating%20copyrights.

From the blog CS@Worcester – William's Blog by William Cordor and used with permission of the author. All other rights reserved by the author.

Docker and Dev Containers – Understanding the Basics

Over the past few weeks, our in-class activities as well as our last assignment for CS-343 have required running Docker in conjunction with a Dev Container in VSCode. While I was able to follow the instructions given and complete our assignments using these tools, I struggled getting started and navigating through some of the components for in-class activities at times, impeding my ability to work efficiently and keep up with my team. To make things worse, I didn’t have much of an understanding of what each component did and why it’s being used. So, I decided to do some research on these topics, particularly the relevance, benefits and drawbacks of using Dev Containers and how they are connected to VSCode and Docker.

In my search, I found Getting Started With Dev Containers, a blog post by CS professional Dave Storey which clarifies a lot, beginning with addressing why Dev Containers are used. Setting up development environments can be a lengthy and tedious process depending on prerequisites, dependencies or other implementations. Dev Containers utilize the power of containerization – bundling all files, SDKs etc. needed to run an application for several benefits like lower overhead, portability, consistency, and more. 

There are some general advantages and disadvantages of using Dev Containers to be aware of. For starters, they guarantee a consistent development environment regardless of the hardware/operating system being used as long as it can run the container. Similarly, there’s guaranteed consistency across toolsets that each teammate is using, so everyone is familiar and there is no communication or project friction caused by inconsistent setups or toolkits. It’s also quick and easy to integrate a new member to a team/project by instantly setting them up with the same development environment in use by the rest of the team. Dev Containers are reusable and adaptable for other projects, providing long term value by saving time on project set-up.

While there’s lots of advantages, there are also drawbacks that should be considered when strategizing projects and contemplating the use of Dev Containers. There’s an upfront time/cost barrier in setting up the container and its configurations – though available templates make this process easier. To this point, you need to have a basic understanding of Docker and general containerization to set up and maximize benefits from Dev Containers. And, when dependencies and other components become deprecated, maintenance needs to be done to make sure that Dev Containers are up-to-date and usable as they are (usually) not part of main code repositories. 

This helped to clarify things based on what we’ve worked with in class. Dev Containers are using VSCode like an IDE/server which communicates with Git and runs our code in the Docker container. Our implementation in class lets everyone deal with the same tools and environments to leverage these mentioned benefits for group learning projects as well as individual assignments.

Sources:

  1. Getting Started With Dev Containers | by C:\Dave\Storey | Medium
  2. What is a software development kit (SDK)? – Definition from TechTarget

From the blog CS@Worcester – Tech. Worth Talking About by jelbirt and used with permission of the author. All other rights reserved by the author.

CS343 Blog Post for Week of November 30, 2023

This week, I wanted to continue writing about the SOLID software design principles. The next principle I have to cover is the Liskov substitution principle. This principle expands upon the Open/Closed principle I wrote about the previous week, providing a guideline on how a superclass and its child classes should behave.

This principle was first defined by Barbara Liskov in 1987, and later adopted by Robert C. Martin. From a paper that Barbara Liskov cowrote with Jeanette Wing, they defined the Liskov substitution principle as a mathematical property: “Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T.”

Translated into plain English, this principle states that instances of a superclass in a program should be able to be replaced by one of its subclasses without breaking the program. Overridden methods from a subclass must accept the same input as the superclass’s original method, and the return value of a subclass’s method must be able to be used the same way as the value returned by a superclass’s original method.

Creating code that abides by this principle isn’t simple, as the compiler can only verify that the structure of your code is correct, not that any specific behavior of your code always executes when desired. Creating robust test classes and cases is the best way to check if your code is following the Liskov substitution principle, checking portions of your program using all subclasses of a particular component to ensure there are no resulting errors or loss in performance.

The author of this article series has included another code example representing a coffee machine to illustrate this design principle, as they have done in their previous articles. They present the problem of creating different subclasses of coffee machines from a generic parent class, with two classes with an “addCoffee()” method that accepts two different types of objects, CoffeeBean and GroundCoffee. The author suggests two solutions, either creating a common Coffee class that can be utilized by both the BasicCoffeeMachine class and the PremiumCoffeeMachine class, or create a common implementation of a “brewCoffee()” method that also appears in both CoffeeMachine classes. The first solution would violate the Liskov substitution principle, because each CoffeeMachine class would need to validate that they are receiving the correct input type for the addCoffee() method, as the BasicCoffeeMachine class can only use the GroundCoffee type, and not the CoffeeBean type. The author’s preferred solution is to remove the addCoffee() method from both CoffeeMachine classes and implement a common brewCoffee() method in the CoffeeMachine interface implemented by BasicCoffeeMachine and PremiumCoffeeMachine. Since all CoffeeMachines are expected to brew filtered coffee grounds, this brewCoffee() method should have that responsibility.

I want to further understand this principle because in a past project, I made a simple video game that used lots of objects of different subtypes that inherited from a single GameObject parent class. If I want to return to that project, or begin a similar one in the future, I want to make sure that I am not losing any functionality as I design and implement subclasses of a broader parent class.

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

Week 8

The contents that I have been learning in this week is about the software license and copyright. I found this blog giving the general definition of these contents and in the time Covid-19.

For many instructors who just want to do what is right, the reality that copyright is complicated has been made worse by the significant transition to distant learning. The fact that over 900 individuals took time out of their days to watch the webinar is proof that copyright education is necessary.

Many publishers combined helpful content, offered free teaching aids, and canceled copyright costs for online learning during the pandemic. Many pieces of content were utilized without the copyright owners’ consent; some were used for legal “fair use,” others were used carelessly, and some were exploited for opportunistic purposes.

Five significant developments emerged in the licensing and reuse of protected information between March and June 2020:

  1. Print photocopying vastly increased as students lost access to materials in the classroom.
  2. Online learning platforms and other EdTech tools gained traction.
  3. Publishers created no-cost licenses to enable teaching under these new circumstances.
  4. More assessments moved online.
  5. Teachers taught using materials they copied or posted online, sometimes underpaid or free licenses, sometimes under fair use, and sometimes by committing infringements that rightsholders were willing to ignore.

Remote learning during COVID-19 resulted in an increasing number of queries about copyright, licensing, and practices for universities, schools, and academy centers as they seek to ensure better compliance.

A license is a permission given to use a property or to exercise rights belonging to another under agreed conditions. Copyright is the exclusive right of the creator of a work or her designees to make copies of that work. In order to reach a conclusion that a use was or was not a fair use, the judge has to analyze all the following factors:

  1. The purpose and character of the use, including whether such use is of a commercial nature or is for nonprofit educational purposes.
  2. The nature of copyrighted work.
  3. The amount and substantiality of the portion used in relation to the copyrighted work as a whole.
  4. The effect of the use upon the potential market for or value of the copyrighted work.

This blog provides educators with a deeper understanding of copyright, its relevance to remote learning, and strategies for managing copyright compliance while using published resources in this new paradigm.

From the blog CS@Worcester – Hong Huynh-CS348-WSU by hhuynh3 and used with permission of the author. All other rights reserved by the author.

Week 8: CS-343

SOLID Design Principles

SOLID is a subcategory of five principles, the first being:

Single Responsibility Principle (SRP)

SRP states that a class, module, or function should only have a singular function.

For example, having a class ‘Animal’ with methods ‘displayAnimalName()’, ‘animalSound()’, ‘feedAnimal()’ would be a violation of SRP because each method has a different function. Creating three separate classes that would each represent a functionality resolves the violation. This entails new classes are created for DisplayName, Sound, and Feeding. Although this may lead to more code overall, having separate classes allows for better maintainability. Without SRP, making changes to one functionality may break another.

Open-Closed Principle (OCP)

OCP states that code should be open for extension, but closed for modification. Therefore the code’s behavior should be extended by adding more code rather than modifying the existing code.

Function ‘getArea()’ calculates the area of a shape using a switch statement where there are cases for a square and circle. To add another shape, the switch statement must be modified to add a case for the new shape, violating OCP. To satisfy OCP, one would create separate classes for each shape that implements the Area interface. Now to add a new shape, one would add a new class and implement the Area interface rather than modify the original switch statement.

Liskov Substitution Principle (LSP)

LSP states that child class objects must be substitutable with objects of the parent class without affecting the correctness of the code.

Imagine a parent class ‘Bird’ with method ‘fly()’, and child classes ‘Penguin’ and ‘Eagle’. Both inherit ‘fly()’ because ‘Penguin’ and ‘Eagle’ are child classes of ‘Bird’. Because penguins cannot fly, the ‘fly()’ method in ‘Penguin’ has been overridden to do nothing. Doing this would violate LSP because objects of ‘Penguin’ would not be substitutable for objects of ‘Bird’.

Interface Segregation Principle (ISP)

ISP states that users should not be forced to implement interfaces they will not use.

Imagine an interface ‘Worker’ that has methods ‘work()’ and ‘eatOfficeLunch()’. Classes ‘FieldWorker’ and ‘OfficeWorker’ both implement the ‘Worker’ interface. Because ‘FieldWorker’ does not eat in office, the method ‘eatOfficeLunch()’ is unnecessary. This violates ISP because ‘FieldWorker’ is forced to implement ‘eatOfficeLunch()’ although the method will not be used.

Dependency Inversion Principle (DIP)

DIP states that high-level modules should not depend on low-level modules, keeping that as separate as possible.

For example, there’s a project with high-level systems (backend logic), that relies on low-level modules (database access). However the project’s team wants to change the database from one type to a different. Because the high-level systems are specifically written and depend on the database type, they would no longer work once the database type changes. Having high-level systems be more abstract and able to be implemented in different ways is ideal.

Conclusion

The article used was chosen because it gave examples with code, making understanding easy. As someone who wishes to have a career in software development, knowing the best practices for designing maintainable code is crucial. I expect to apply these principles to all future projects.

Resources:

https://www.freecodecamp.org/news/solid-design-principles-in-software-development/

From the blog CS@Worcester – Zack's CS Blog by ztram1 and used with permission of the author. All other rights reserved by the author.

Golden Rules for APIs

This week I have decided to view a source regarding APIs since that has been our focus in class recently. I had come across an article written by Jordan Ambra, an experienced software engineer from Pennsylvania, describing a few “rules” to keep in mind to create the best API possible and better maintain its health in the long run.

Jordan starts with his first point being proper documentation, he states “ask [a developer] to follow a tutorial or build something really basic in about 15 minutes. If they can’t have a basic integration with your API in 15 minutes, you have more work to do.” It’s important to have proper documentation because without such, having an expansive and robust API is great but what isn’t great is if the implementation of said API is very limited caused by developer confusion due to the lack of documentation.

The next point Jordan describes is the importance of API stability and consistency. This is key in having APIs last in the long run. Jordan uses Facebook as an example to show that while an API’s health won’t make or break a company, most people don’t have the capital or userbase Facebook does so recreating an API is going to be more costly for one person. Keeping track of version numbers by incorporating a change log is a great way to document changes so users know how and why to upgrade.

Another practice is to maintain API flexibility, if an API is or over time becomes too rigid it can cause integration to be difficult. Not all platforms are consistent, Jordan states, “It’s good to have at least some degree of flexibility or tolerance with regard to your input and output constraints.” So by keeping the API flexible, it’ll allow for the widest implementation without a large margin of error.

A very important aspect of APIs to prioritize is security. With malicious actors always looking for new weaknesses and ways to hijack or manipulate things for their gain, it is more important than ever to implement security safeguards to act as a preventive measure to prevent people with the wrong intentions from harming others.

Finally, the last thing Jordan brings up is the importance of an API’s ease of adoption. If things are overly complex or not universal enough it can turn people away from wanting to interact with your API. If you’re not able to efficiently use your API then how is anyone else going to be able to?

After reading this article, I hope to now be better equipped to create healthier and longer-lasting API(s) among a majority of APIs that are not easy to use which can be due to one, a combination, or all of the factors above. Focusing and prioritizing the rules set by Jordan will help in the future to improve my work.

Article Link: https://www.toptal.com/api-developers/5-golden-rules-for-designing-a-great-web-api

From the blog CS@Worcester – Eli's Corner of the Internet by Eli and used with permission of the author. All other rights reserved by the author.

Navigating Software Pitfalls: Understanding Anti-Patterns

In the intricate world of software development, as developers strive to create elegant and efficient solutions, they encounter not only best practices but also pitfalls to avoid. These pitfalls, often referred to as anti-patterns, are common design and coding practices that may initially seem like solutions but ultimately lead to more problems than they solve. Understanding and recognizing these anti-patterns is a crucial part of becoming a seasoned software developer.

At its core, an anti-pattern is a recurring design or coding practice that appears to be helpful but is counterproductive in the long run. It’s like a mirage in the desert – promising relief but ultimately leaving you more parched. Anti-patterns often arise from misapplications of well-intentioned ideas or a lack of experience in software development.

One common anti-pattern is known as “Spaghetti Code,” where the codebase becomes entangled and challenging to maintain. While quick fixes and shortcuts may seem like a solution, they often lead to a tangled mess that hampers productivity.

Another notorious anti-pattern is “Cargo Cult Programming,” where developers mimic code without understanding its purpose. This blind imitation can lead to code that lacks context and may introduce errors.

By studying anti-patterns, developers can proactively identify and avoid these pitfalls. It’s akin to recognizing warning signs on the road and taking detours to smoother coding practices. In the ever-evolving landscape of software development, understanding what not to do is as important as knowing what to do. Recognizing anti-patterns empowers developers to make informed decisions and craft robust and maintainable software solutions.

References:

From the blog CS-343 – Hieu Tran Blog by Trung Hiếu and used with permission of the author. All other rights reserved by the author.