Responsive columns






CSCI-462 SOFTWARE ENGINEERING BLOG





1.13.21 - Introduction

Hello World! Thank you for visiting my blog. I will use this space to discuss my experiences in Dr. Jim Bowring's sofware engineering course. This is my final semester at the College of Charleston. I am studying Computer Information Systems and hope to work in either the software industry or in renewable energy in some facet. This semester I am going to complete a project with several other classmates working with open source software. My teamates are Bradley Odac, Patrick McCabe, and Cormac Conahan. Our group is using the name of "The Open Source Mafia."



1.20.21 - Reflections on FOSS

In “The Cathedral and the Bazaar” Eric Raymond reflects on Linux, open source software design, and his own projects. Raymond walks us through his lessons for creating good open source software. The essay is an interesting read with insights into software development. It really gets you thinking about the benefits of inclusivity with product design and development. People seeking out bugs to fix and features to add produce better code than those doing it for work.

Raymond lists 19 lessons throughout the essay all of which could have their own summary but I’m just going to touch on a few(in non particular order)

1) "Every good work of software starts by scratching a developer's personal itch."

A motivated developer is a good developer. If the problem is something personal and interferes with the way a developer can use the software it is much more motivating. Imagine if your favorite game, sport statistic page, or tinder didn’t work properly. People will work hard to personally benefit from bug fixing.

2) "Good programmers know what to write. Great ones know what to rewrite."

This is an example of the old expression “if it aint broke, don’t fix it.” When writing open source code you are provided with a foundation to build upon. There is no need to go in and destroy someone elses product to build yours over. Take what they have and use it to develop what you envision. Waste as little as possible.

3)"Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging."/"Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone."

I grouped these ones together because its really the essence of the essay in my opinion. When people use your software they are going to explore areas you could never have thought of. They are going to find bugs. Lucky for you they are developers! Rapid code improvements will happen which will lead to less deep structural bugs. Your code is constantly exposed and getting improved. Embrace your users and especially your beta testers!

The Bazaar approach to open source software design seems radical and chaotic but in reality the incessant updates and iterations allow it to be more streamlined in development. The code is more efficient and of higher quality because the people writing it are building on the work of others. A communal herd of developers proves more effective than the specialized Cathedral builder. While the team of Cathedral builders may be the most highly skilled they can not do the work the herd can.

 “...given enough eyeballs, all bugs are shallow.”





1.27.21 - Reflections On Open Source In Today's World

Open Source in devOps

One key way to keep devOps teams fully functional during this unprecedented time is by applying open source principles. This is not a new or novel concept but rather something that needs to be stressed during the pandemic. Some team members may be working from home for the first time while others have done it plenty of times. The key is to remain a cohesive unit. There are two types of devOps teams, those that are hybrid and those that are fully remote. Each type has their own unique problems and advantages. A fully remote team can be more agile because they may be working in different time zones allowing them to take advantage of different delivery cycles. This could also pose a problem because they may not be able to meet as easily. A hybrid team may still have to attend useless meetings and struggle with deciding who works from home and who does not.

Some key components from the open source world that can be applied to devOps include focusing on community, collaboration, transparency, inclusive meritocracy, releasing early and often, and pivoting. With the current situation going on around the world fostering a sense of community brings a sense of normalcy to some people and allows them to forget the stress of the outside world. Working remotely presents a great opportunity to be transparent, with all project information and materials being centralized. This helps teams to make powerful and effective decisions and understand how they affect the whole team. DevOps teams must remember to be inclusive and hear all ideas, no matter who it may come from.

A big key to remember is that successful remote teams need to be more agile than ever. This doesn’t just apply to software delivery but how your team communicates and collaborates. Teams need to be open to new ideas and willing to try new things.

DevOps vs Agile

Agile and devOps are distinct, even though people think they are one in the same because of their many similarities. The two software development models are not adversaires, they are just different schools of thought. Agile was officially started 20 years ago, after the release of the agile manifesto. Previously, most software development was some form of the waterfall model. The waterfall model was a linear track to development that worked well in manufacturing and engineering but was not the most effective method for software development.

Agile invites and embraces uncertainty. Agile is build around the idea of change, and reacting to change. Focus on delivering software frequently and building projects around motivated people. This includes lots of face to face meetings and code review. Teams must work together and be open, honest, and transparent with each other.



2.4.21 - This bugs me

GitHubs issues is the bug tracker for sugar labs Sugarlabs, like many other current FOSS use the “issues” function of Github to track their bugs. Developers and users alike are free to report issues as well as feature suggestions and work on them. It seems that most bugs get attention relatively quickly, especially on the more active modules. While looking through the bug reports I was able to spot a few developers who were actively reporting bugs and responding to others reports. The most notable is a developer named “quozi”, but there are others who contribute consistently as well. The oldest bug I was able to find was from late 2016. It seems that their was a real effort to find bugs by one developer in April 2017. In 3 days they opened ~7 new bug reports on various modules.

For the sake of this exercise I tried to focus on bugs that were in modules we had considered working on such as pippy, calculate, paint etc.

The bugs I chose include:

An svg rendering different colors on different systems


Reported by “quozi”. The report includes different systems in which an svg renders different colors. “Quozi” later comments more systems in which the svg renders different.

Error with bouncing objects in the pysics activiy


Bug reported by “quozi”. He walks through the steps to recreate the bug and than specifies the particular bug. No one has responded to this bug report.

A feature request for stats at the end of memorize activity


Feature request from “sanjaymaniam”, one of the more active developers of the project. He provides a nice explanation of what he would like the game to feature and why. No one has responded to this feature request.

Pressing up arrow in chat


This bug was reported by “quozi” and has not been commented on by any other developers. Quozi provided a short summary of how to recreate the bug and the observed result vs the expected result.

Sound button not working


This was reported by “ayushnawai” he posted a quick and summarizing title of his issue. He provided the error message as well. At the time of writing this has not been commented on by any other developers.



2.11.21 - What's Happening

This article was written by a collective of 6 computer scientists. This article is focused on the disconnect between modern computer science research and modern mobile computing. The article also poses several challenges to mobile software engineers and up and coming students.

Mobile apps are being created daily and some are extremely creative and complex. With the rise of Iot and edge computing it is more important than ever to think about the mobile environment. By taking steps now, we can ensure the best growth for the mobile environment in the future.

Modern apps interact with physical entities inside and outside the phone, as well as integrating diverse services in the cloud. Apps have to navigate through poor connectivity, sensor inaccuracies, low battery levels and much more. This creates a huge challenge as users expect apps to always be functional and operating.

End users want a seamless experience in their home, at work, and out and about. This “Always On” mentality is difficult for software engineers to deal with. We must practice defensive programming and expect that the worst will always happen when designing applications.

Cyber foraging is the concept of mobile devices offloading computing to other “surrogate” machines in the vicinity. With the amount of data that modern apps are using it is increasingly important to find ways to divy up work. Instead of your smartphone using all of its processing power other devices can pick up the slack. It is important that we figure out how to properly place data and computation closer to mobile devices and tablets. Cloud based systems will need to push work to their surrogates and devices should automatically locate these proxies.

Android has been the focus of the majority of mobile software research. Largely because 88% of all smartphones run on it and largely because it is an open source project. This makes it easy for them to customize their own solutions and research. Because Android has been an open source project from the beginning there are many data analysis tools available which makes conducting research easier as well. However, this has made research stagnant and researchers have not dug into other cross platforms like Kotlin and React Native. The majority of research has also been higher level and needs to focus more on specific problems and challenges.

Iot, wearables, and smartphones are going to be some of the most important areas of software development for years to come. Devices are going to get more and more complex and connected until computing is a seamless process between all connected devices. To achieve this there needs to be a concerted effort by software developers to bring this about. Research needs to be introduced into industry. Specific challenges need to be addressed and those solutions must be implemented



2.17.21 - STUPID or SOLID

Software development is a generally fluid concept without solid rules or rights and wrongs. In most cases if it works, it works . As long as the desired outcome is achieved all is well. However, this article presents the idea of going from STUPID code to SOLID code.

S - (Singleton Pattern) - using a global variable in your code is a dangeround process that requires special attention at all times. These patterns should only be used when there are no other options.

T - (Tight Coupling) - This can be a symptom of using Singleton patterns. If making a change in a specific module requires changing in another this is coupling. This creates redundancy that will lead to re-writing code.

U - (Untestability) - Testing is absolutely mandatory and when writing code you should be thinking of how you are going to test while you write it. If you having a tough time writing unit tests for your code that is a sign of bad code and often happens from tight coupling mentioned above.

P - (Premature Optimization) - Think twice when attempting to optimize code. You may be tempted to try and tweak an algorithm here and there to run more efficiently. Though this may save you tiny bits of time it may require adjusting much more than you think. Its often unnecessary to try and optimize working code.

I - (Indescreptive Naming) - Pretty descriptive title. Make your variable names, methods and classes have descriptive names that relate to what they do. This helps others understand your code better.

D - (Duplication) - Don’t repeat yourself. Write methods and classes that work across applications that way you don’t have to write and rewrite code.

As you can see these are not strict rules that a developer can follow. Rather, it is a set of instructions to keep in mind while working. Many of these problems are interrelated and lead to other issues. These issues are evidenced even more when trying to scale. Code smart to save yourself down the line.

S - (Single Responsibility Issue) - Classes should only have one responsibility. Just because you can make a single class do numerous different things doesnt mean it's a good idea. There should never be more than one reason for a class to change.

O - (Open/Closed Principle) - Variable types should be made variable by default. Getters and setters can be written where needed.

L - (Liskov Substitution Principle) - Subtypes of objects should be able to replace objects. It should not require a change of code to make a sub type an object.

I - (Interface Segregation Principle) - Interfaces should serve direct client needs. You should not try and create an all encompassing interface. Tailor these interfaces to specific needs.

D - (Dependency Inversion Principle) - Abstractions should not depend upon details rather details should depend upon abstractions. Refrain from adding concrete classes to method signatures of an interface.

Although application of some of these concepts is currently beyond the scope of my knowledge, it was still interesting and helpful to lean these principles. If I can remember to use these as a guideline it will help my development abilities in the future.



3.10.21 - RELEASE EARLY and RELEASE OFTEN

During all of these readings it became clear that there are well established guidelines on how to support software through documentation. Documentation is a vital lifeline of software development, not only to users but developers as well. Documentation generally falls into one of two categories, user or developer. It doesn't matter who you are writing the documentation for there are some key structural characteristics:

Oranization, Illustration, Style, and Tone



Keep your documentation organized and arranged in a manner that is easy to read and navigate. Provide illustrations such as images or other media where it is appropriately helpful. This helps users who may learn better through images. Structure your grammar well to help readers understand the details. Use a tone of voice that conveys a peer to peer relationship. You must be wholly aware of who your audience is.

Documentation can be written for either new users or experienced users. Usually the guide for new users is referred to as a tutorial and the guide for experienced users is referred to as the user manual. It is helpful to have a channel on which there can be open discussion about the software and issues facing users. Oftentimes these are forums on the softwares website or general forums such as stackoverflow. A “Help” tab is often embedded in the main menu. When answering user questions be sure to be direct and deliberate in your explanation. There are most likely different use cases for your software. To write good documentation you must try and cover all situations a user could encounter. A user manual can be organized by use case by arranging each use case as its own chapter. Cover the entire variable task from beginning to end.

User manuals and tutorials are generally kept in .pdf form. While the “Help” tab is hosted on the application. With regard to FOSS products I assume most have documentation in .pdf and hosted on their github. Bigger projects may have hard copies of documentation for their users. This is found more in proprietary software however. Make sure your user manuals and especially tutorials have illustrations. Keep your text to a minimum where possible. Huge blocks of text can give users anxiety. Use literal language that won't confuse users. Avoid humor and metaphors. Also, keep in mind that some users may not be native english speakers. Avoid adding unnecessary words and phrases.

Simplify the process to the point of redundancy and then 
				simplify it more.



Before diving into technical specifics make sure to create an outline and understand the higher level. Use language that’s in the application. A user is more likely to relate to the documentation if they are familiar with unique language and wording. Use the active voice, walking users through step by step. Avoid acronyms unless you clarify them in the document. Users may not be familiar with what an acronym stands for and will be confused. Two columns can be very effective in certain instances such as one column showing the user point of view and the other the system output.

Writing documentation is a tedious affair that often gets overlooked. However, good documentation is essential to a successful FOSS product.

Good documentation will onboard new users to your 
				product and give experienced users the tools to maximize the software.





3.18.21 - Chapter 5 - Domain Classes

A fundamental part of software development is testing. Without appropriate testing software will not be able to fulfill its capabilities and will cause problems for users and developers. There are many components to software testing including unit testing, integration testing, and using software metric guidelines.

Oftentimes when developing software you work with an existing codebase known as legacy code. These legacy codebases are usually divided into large classes known as domain classes. Domain classes generally evolve through numerous iterations during their lifetime. However, there are usually similarities between all the domain classes. It is standard practice to have testing that is specifically focused on each domain class. These tests are known as unit tests.

Unit tests allow for a software to be tested via a test suite that tests each individual domain class as part of a larger whole. A unit test can not succeed in two different ways, an assertion in the code that is not confirmed is called a “failure”, or if the code itself experience s a runtime error this is a “bug.” When unit testing it’s important to test the all instance variables, getter methods, and their different functionality.

After unit testing each domain class of the software it is important to test how the different domain classes interact with each other, this is known as integration testing. Before integration testing, make sure the respective classes and modules have been tested separately, all tests have been merged into the codebase, and that the new code has been pulled into the developers own copies of the code base.

No matter who writes code and how well it is written, you will run into bugs in the software. Luckily with open source projects you have users that oftentimes are capable of helping with the workload. Whether that be through debugging, refactoring code, or even writing documentation. Users are the first line of defense because just by using the product they will subert the software to situations that you did not test. It is nearly impossible to test all use cases and edge cases specifically. Without knowing it users will be stress testing the software all the time.

Even if your software is performing as expected and does not seem to have any existing bugs there could still be work to do. Refactoring is the process of changing how existing software is written to make it more concise or functional. These changes are not designed to affect the external processes of the software being refactored. Some reasons for refactoring include poorly named variables and functions, duplicate code, functions or classes that are too long, and poorly commented code.

While this may seem like a very strenuous process there are some tools to help you. Generally whatever language you are coding in has tools to build unit and integration tests. GitHub is a great resource for exposing your project to a wide array of users as well as providing excellent version control. There are also several metrics you can use to judge your software. These include count metrics, clarity metrics, cohesion metrics, and coupling metrics. All of these are pretty standardized and give you an idea of how well written your code is.



3.25.21 - Chapter 6 - Database Modules

When most people think of software engineering they think of linked lists, arrays, for loops, and if/else statements. Databases often get ignored because they may be seen as less exciting to a lot of developers. Databases are essential systems to the storage and retrieval of information.

Databases are the backbone of most software applications and differ from a domain class or object because its data remains in permanent memory , separate from the memory where the program runs. Oftentimes data will be stored as part of a server. Databases are unique because their lifetime often lasts longer than the program its associated with, this is known as persistence.

Databases can be broken into several different models such as the “relational model” and the “non relational model.” Relational models of databases store data as a collection of two-dimensional tables. This is convenient because they can be accessed easily and efficiently by SQL. The Structured Query Language(SQL) is a widely used almost exclusive database modeling language. SQL is generally based on relational algebra and matrices.

Manipulating data in SQL is generally accomplished through queries. Although this seems like an obvious term for retrieving data, it is also the term used to insert, update, or delete data. Some common queries include CREATE TABLE - to create a table in a database, DROP TABLE - to remove a database, SELECT * FROM - to return data based on certain conditions stated, INSERT INTO - to insert new data into a table, DELETE FROM - to delete rows from a table, and UPDATE - to change data values in the table.

A main strategy in database design is normalization. This strategy is in place so that tables can support queries and ensure data integrity but eliminating data redundancy. A relational database can be considered “normatlized” if it meets all of the following:

1) The rows can be rearranged without changing the meaning of the table (i.e., there’s no implicit ordering or functional interdependency among the rows).
2) The columns (attributes) can be rearranged without changing the mean- ing of the table (i.e., there’s no implicit ordering or functional interde- pendency among the columns).
3) No two rows of a table are identical. This is often accomplished by defining one column whose values are mutually unique. This column is known as the table’s primary key.
4) No row has any hidden components, such as an object id or a timestamp.
5) Every entry in the table has exactly one value of the appropriate type.
6) No attribute in the table is redundant with (i.e., appears as an explicit substring of) the primary key.

Security plays a huge role in database design. To ensure security, tables should be limited to who can access and perform different queries. This is called designating privilege. Many developers also implement encryption to secure their data. Overall, databases are an extremely important part of software engineering and is often the heart of any application.



3.30.21 - Chapter 7 - User Interface Dev

The user interface of a software application is where the code meets the client. UI represents the glue holding all other components together. This isnt just true for code but the whole development process hinges on the UI. When speaking with a client they are going to want to know about the functionality, bugs, and new features relating to the user interface.

The book outlines several principles to facilitate a “good user interface.”
1. Task-Oriented There is a clear mapping between the steps of each use case in the design document and a page or group of related pages in the user interface.
2. Language The language of the interface must be consistent with the lan- guage of the domain and the user. All labels and user options that appear on individual pages must be consistent with their counterparts in the design document and the domain classes.
3. Simplicity No page should contain too much information or too little. Each page should be pleasant to view, yet its functionality should not be buried by elaborate stylistics.
4. Navigability Navigation within a page and between related pages should be simple, explicit, and intuitive.
5. Visual consistency All pages in the user interface should have a similar look and navigation style.
6. Discoverability Each page should provide the user with clear feedback on what has just been done, what can be done next, how to do it, and how to undo it.
7. Data integrity The types and valid values for individual user data entries must be clearly indicated. The software should validity-check all data at the time of entry and the user should be required to correct errors before the entries are saved in the database.
8. Client-server integrity The activities of several different users who hap- pen to be using the system at the same time must be kept separate and independent.
9. Security An individual user should have access to the system’s function- ality, but only that functionality for which he/she is authorized.
10. Documentation Every page or group of pages in the user interface should be linked to a step-by-step instruction that teaches a user how that page can be used to accomplish a task.

Because the user interface has a multitude of different elements there has been a widely used strategy called the “model-view-controller” pattern. The MVC pattern separates code into three different pieces: The model - code that underlies the application’s logic and underlying data, The view - code that presents the components of the interface to the user, and The controller - code that controls the user’s input, output, and navigational functionality for that component.

The MVC pattern encourages independent coding, testing, and maintenance of each component. This layered architecture encapsulates the database and domain layers, while the code in the view and controller is encapsulated within the user interface layer.



4.1.21 - Meeting Charleston

The alumni symposium was very informative and interesting. It’s always nice hearing from people who have been in the situation us students are. Graduating is an exciting, nerve wracking, and confusing time. A lot of people may be searching for jobs, figuring out where they want to live, and the next step in their life.

It’s especially nice hearing about the day in day out life of some of our alumni. Its great for perspective and knowing what to expect. Some of the knowledge passed on I will remember for a long time. I really appreciate these alumni taking time out of their daily lives to speak with us.