B-Side: Lo-Fi Software Development

A brief look at the world of software development

In the days when we all got our music on vinyl, a single wasn’t something you played on Spotify or Apple Music—you went down to the record store and bought it. The single would take up one side of the record, and the artist could put another song on the back. The A-side was the hit everyone knew from the radio, and the B-side was a lesser-known track—sometimes a buried treasure, like "God Only Knows" on the B-side of "Wouldn’t It Be Nice".

These B-Side chapters cover some of the topics that are important, but don’t necessarily fit into the main flow of our learning.

Help Make These Materials Better!

I am actively working to complete and revise this eBook and the accompanying videos. Please consider using the following link to provide feedback and notify me of typos, mistakes, and suggestions for either the eBook or videos:

This is the working draft of a very incomplete eBook. Content will change as chapters are developed and refined. Most noticeably (other than stuff that’s just missing) is the presence of placeholder links where I haven’t quite finished videos. Check back later for a more complete version.

What’s the Point?

  • Identify a few habits and practice of professional software developers

  • Explain the importance of ethics to software developers

  • Describe differences between common programming paradigms

  • Explain the purpose of a version control system (VCS)

  • Describe the basic phases of the Software Development Life Cycle (SDLC)

Source code examples from this chapter and associated videos are available on GitHub.


Beginners learn to code by focusing on individual programming skills and concepts, like variables, loops, and methods. Typically, we write small programs that assess one or two of those concepts at a time; in a school setting, the teacher generally assigns problems that are intentionally limited, keeping the work simple and allowing the teacher to see how students are doing on specific skills. But for coding to be useful, we have to put those skills to use in larger projects that solve real problems.

That’s difficult to do in the context of a beginning coding class, where time is limited and the teacher is obligated to cover specific topics—​often at a demanding pace that leaves little room for exploration. So this chapter zooms out to look at the bigger picture of software development. If you go into a career as a developer—or engage in large-scale personal projects—these topics will be a part of your everyday work. If you aren’t a developer but work elsewhere in tech, understanding broad software development concepts will help you collaborate effectively with coders and technical teams. And even if you never write another line of code after this course, knowing a little about software development will help you understand how software works and why it sometimes doesn’t.

Habits and Mindset

Think Like a Professional Developer

Successful developers cultivate habits and attitudes that help them continuously improve their skills and make them effective members of a development team. When possible, I’ve tried to encourage these habits throughout our learning in this book and videos, but it’s important to identify some of them explicitly:

Iterative Development

Very few programs, algorithms, or features are written perfectly on the first try. Instead, most good developers write a small piece of code and focus on getting it working; then they repeat the process for the next piece, and the next, until the entire program is complete. This approach—called iterative development—helps keep us from getting overwhelmed by a large or complex task; just break it down into smaller pieces, and focus on one piece at a time.

If also helps us identify and fix problems early, before we have other code depending on it.

Beginning coders can develop this mindset in a few ways:

Work the important stuff first

Identify the core functionality for the code you’re developing, and work on that first. For example, get the calculations working correctly before you worry about getting user input or displaying output nicely.

Run your code frequently

After you write a few lines of code, run it and see how it behaves. If if it doesn’t produce visible evidence of how it’s working, you can at least verify that it compiles and runs without errors.

Test small pieces

Once you have a small piece of code working, test it with different inputs or data to make sure it behaves correctly in a variety of situations.

Refactoring

As part of our iterative development process, we might find that our code works correctly, but could be improved in some way. Maybe it’s repetitive, or too long, or hard to read, or inefficient. Or, maybe it doesn’t conform to best practices or coding standards. When we identify these kinds of issues, we can go back and improve the code without changing its behavior; this process is called refactoring. Refactoring is an important skill for developers to cultivate, as it helps keep code maintainable and adaptable to future changes.

Time To Watch!

Quick Track: Refactoring

Documentation

I’ll be honest; I’m not sure I’ve ever met a developer who wants to write documentation. But, whether we like it or not, documentation is an essential part of software development. And to reiterate: documenting our code is part of software development, not an extra thing we do at the end if we have time.

Good documentation helps others (and our future selves) understand how our code works, how to use it, and how to maintain it. Documentation can take many forms, including:

  • Comments within the code itself (inline comments, method headers, etc.)

  • README files (files that explain how to use a project or application)

  • API documentation (documents that explain how to use specific functions or classes)

  • User manuals (documentation for the end users of the software)

In a professional setting, documentation standards are often established by the development team or organization, and may be enforced through code reviews or other quality assurance processes. In other words, your code won’t get incorporated into the project until you’ve written high quality documentation. In other other words, you’re no use to an employer if you can’t or won’t document your work effectively.

In my classes, I ask students to include a comment block at the top of each program that includes some basic information, but not much beyond that—I’m really just trying to get beginners into the habit of including some documentation, and ingraining the idea that documentation is part of the coding process. You should be aware that most professional development teams have much more extensive documentation requirements, so be prepared to adapt to those expectations in your future work.

Software Development Ethics

Computers are embedded in nearly every aspect of our lives, making software developers an important influence on society. As developers, we have a responsibility to consider the ethical implications of our work.

The Golden Rule suggests that we should treat others as we would like to be treated; in software development, we could adapt that to say:

Don’t build software you wouldn’t want used on you.

Here are a few thoughts to consider as you develop software:

You’re responsible for the software you develop

Your software will be used by real people and on real data. Be aware of the consequences of your work—and the consequences of errors in your work. Another professor I know asks his students, "Would you fly in an airplane that depended on your code to stay in the air?"

Consider privacy and data handling

We’ve all grown accustomed to the idea that data is collected about us whenever we use software. But as developers, we need to be thoughtful about what data we collect, how we store it, how we protect it, and who we share it with.

Think about security

Most security issues are beyond our scope here, but as you continue to learn, be mindful of security best practices. Design software with security in mind from the beginning, rather than as something you add when you’re done.

Think about accessibility

Software should be usable by as many people as possible, including those with disabilities. Consider accessibility features and best practices to ensure your software is inclusive. Remember that accessible design is good design for everyone!

Respect intellectual property

Copyright applies to code just as it does to other creative works. Don’t use code you’re not authorized to use, and always respect the licensing terms of any libraries or frameworks you incorporate into your projects. And just like in other ares of your life, cite your sources!

The Therac-25 was a radiation therapy machine involved in several accidents in the 1980s that resulted in patients being exposed to massive overdoses of radiation, leading to permanent damage and multiple deaths. There were multiple causes for the accidents, but software errors and inadequate testing were significant factors. The Therac-25 incidents highlight the critical importance of software safety, rigorous testing, and ethical responsibility in software development, especially in fields where human lives are at stake.

Commitment to Lifelong Learning

Software development is constantly evolving. While my goal is to teach you fundamental skills and concepts to serve you over a lifetime of coding, the nature of technology means that you’ll need to continue learning throughout your career.

Staying current with new programming languages, frameworks, tools, and best practices is essential for long-term success as a developer. It also critical for making you marketable to employers!

Learn how to learn from text

Plenty of students don’t like to read, and this eBooks exists in part to reduce the amount of reading required in my courses. But the harsh reality is that reading documentation, articles, and books is an essential skill for developers. YouTube is great, but you simply cannot stay current without reading.

Engage with other developers

There are tons of great online communities where developers share knowledge and help each other solve problems. Participating in these communities helps you keep learning and connects you with people who can support your growth as a developer—and who you can support in return.

Consider joining the Association of Computing Machinery (ACM), which offers student memberships for as little as $20.

Programming Paradigms

Different Ways to Think About Code

Programming paradigms are different approaches or styles of programming that provide distinct ways to think about and structure code. Different paradigms offer different techniques for solving problems and different philosophies about how code should be developed and organized. These paradigms are huge topics that could be entire books and courses of their own, so we’re just going to identify a few of the most common ones here.

Procedural Programming

Programs are organized around procedures or routines—what we have been calling methods. To design a program from this perspective, we break down the program into a series of steps or procedures that execute in a specific order. We were using this approach throughout the first six chapters of this book, but it’s usefulness is not limited to beginners; procedural programming is still widely used in industry for many types of applications.

Object-Oriented Programming (OOP)

OOP programs are organized around objects, which bundle code with the data it operates on, and a program works by creating and interacting with these objects. OOP is popular in industry and lends itself well to large, complex software systems. We began exploring OOP in the chapter on [_classes_and_objects].

Object-oriented programming is a type of procedural programming, and both of those fall under the broader category of imperative programming.
Declarative Programming

Instead of specifying how to perform tasks step-by-step, declarative programming focuses on what the program should accomplish. In this paradigm, we describe what we want to achieve, and the underlying system figures out how to do it. SQL (Structured Query Language) is a common example of a declarative language used for database queries.

Version Control

Git, Code Repositories, Branches and Merges

A large-scale development project involves many developers working simultaneously on different parts of the codebase. There is a high potential for conflicts and errors if two people are making changes to the same files at the same time. In addition to this, teams need to keep track of changes over time, with the ability to revert to previous versions if necessary.

To manage this development environment, teams use a version control system, or VCS. A VCS allows developers to maintain different versions of the codebase; for example, you might have a version that’s been released or deployed to users and a version that’s still being worked on. You still need to be able to update and improve the deployed version, especially to address bugs or security issues, while new features are being developed for the next release.

While you could just copy your project to a new folder to start working on a new version, that quickly becomes difficult to manage as the project grows and more versions are created. A VCS manages all of this for you.

Some of the key features of a VCS include:

*Tracking changes

A VCS records every change made to files in the project, along with information about who made the change and when. This allows the team to keep track of changes and see the history of the project over time. It also lets us blame the coder who broke everything!

*Reversion functionality

A VCS allows developers to revert to a previous version of the code if a problem is discovered. So the coder who got blamed for breaking everything is able to go back to a working version without too much trouble.

*Collaboration

A VCS facilitates collaboration by allowing developers to create branches of the project. A branch is like a separate copy of the project where we can work without impacting the main codebase or deployed project. Once we’re satisfied with our changes, we can merge our branch back into the main codebase—and the VCS will help sort out any conflicts that the merge might create.

Git

The most popular software for version control is Git, which was created by Linus Torvalds—the same guy who created Linux. It is free and open-source, so anybody can set it up and use it to manage their projects. Projects are stored in a repository (or repo for short), which contains all of the files and the history of changes made to those files.

Git is a distributed version control system, meaning that every developer working on a project has a complete copy of the repository on their local machine. When a developer joins the project, they clone the repository to their computer. Then they can work offline and make whatever changes they want. When they’re ready to share their changes with the rest of the team, they sync their changes back to the central repository.

If you don’t want to set up your own Git server, you can use a cloud-based solution, such as GitHub. GitHub uses the Git version control system and provides a web-based user interface for managing your repositories (along with a handful of other features); other cloudbased Git services include GitLab and Bitbucket offer similar services. Though it has paid plans and features, you can manage individual and small team projects on GitHub for free, and it’s become a popular platform for open-source projects.

Git can manage files of any type, so it can be used for projects in any programming language—and for projects that aren’t even code-related. This eBook is managed on GitHub and published on their webhosting platform, "GitHub Pages". Although I work on the project alone, I like that Git allows me to work on the project from any of my computers (office, home, and laptop) and it keeps everything in sync.

The use of Git is a pretty big topic, and another one that’s beyond the scope of this book, but it’s important to at least know about it. Some of my classes include an introduction to Git (and use GitHub), but there are also a ton of resources out there if you want to explore it on your own.

Software Development Life Cycle

The Basic Phases of a Software Project

Learning to write code means creating a lot of programs—mostly small, straightforward programs at first. Remember those awful word problems where a train leaves Chicago traveling 40 mph, and another train leaves Denver at 35 mph? That kind of stuff; but in my course, we don’t get too caught up in the math part of it. But we care a lot about understanding the requirements of a program and implementing it successfully.

All software development projects, regardless of size or complexity, incluse some common elements. The more complex the project, the more formalized these elements become—but even small projects benefit from a thoughtful approach to development.

There are many ways to manage a software development project, but regardless of the specific methodology, most projects include some version of the following phases:

Planning and Analysis

Identify the goals and scope of the program. As a rule, keep it small and focused—we can always add features later. Ask yourself, What does this program need to do?

Testing Plan

Determine how the final program will be tested. The testing plan itself will be useful, but just as importantly, the time spent creating the plan ensures forces us to understand the program thoroughly. If we don’t know how the program will work, we’re not yet ready to begin coding. Ask yourself, How will I ensure the program works correctly?

Implementation

Write and test the code. We say that this is an iterative (or "repeating") process, meaning we’ll write and test one small piece, staying with it until we know it’s good. Then we’ll move on to the next piece and repeat. Ask yourself, What code do I need in order to get the next part of the program working?

Deployment

Once the program is complete and has passed all tests, it’s time to deploy. This might mean sharing it with users, installing it on a server, or simply submitting it for a class assignment. Ask yourself, How will I deliver this program to end users?

Revise or maintain

If our needs or program requirements change, we’ll need to go back to the first step and begin planning the next version. If not, we’ll need to monitor that the program continues to perform as expected over time. Ask yourself, What’s next for this program?

We can think of these general components as a cycle that repeats whenever we create or update software, and we refer to this cycle as the Software Development Life Cycle (SDLC).

There are different methodologies for managing the SDLC; they still include the same basic phases, but they traverse those phases in different ways.

Waterfall Software Development

Waterfall development is a traditional software development methodology that follows a linear and sequential approach. It treats the components of the SDLC as distinct phases that flow downward, like a waterfall, following strictly from one phase to the next. Each phase has specific deliverables that must be complete before moving on to the next phase.

For example, the project will begin with a detailed planning and analysis phase, where all requirements are gathered and documented.

  1. Developers will meet with clients or stakeholders to understand their needs and expectations, using that information to create a comprehensive requirements document.

  2. Once the requirements are finalized (and no sooner!), the project moves to the design phase, where the overall architecture and structure of the software are planned out.

  3. After the design is complete (and no sooner!), the implementation phase begins, where programmers write the actual code that puts the design into action.

  4. Once the code is complete (and no sooner! Sort of…​), the testing phase begins, where the software is rigorously tested to make sure it meets all of the requirements specified in the planning phase. And, to be clear, some testing does occur during the implementation phase, because developers test their code as they write it. But this phase focuses on comprehensive testing of the entire system.

  5. Finally, once the software has passed all tests (and no sooner!), it is deployed to users.

  6. After deployment, the software enters the maintenance phase, where it is monitored for issues and updated as needed.

This waterfall approach is pretty common for a handful of reasons. It is a very straightforward and easy to manage process, since everyone focuses on one phase at a time. The structured and linear nature of waterfall development often appeals to programmers, who tend to be logical and methodical thinkers. And managers like it to, since the heavy emphasis on planning and documentation can identify potential issues early in the process—before they bome too costly to fix.

However, waterfall development has some significant drawbacks. Most notably, it is rigid and does not adapt well to changes in requirements along the way.

Agile Software Development

In response to the limitations of waterfall development, the software industry has moved toward more flexible project management approaches, such as Agile software development.

Where traditional software development approaches rely on a detailed plan created at the beginning of a project, Agile shifts the focus to adaptability and responsiveness to change.

Based on the Manifesto for Agile Software Development, agile development prioritizes:

  • Individuals and interactions over processes and tools

  • Working software over comprehensive documentation

  • Customer collaboration over contract negotiation

  • Responding to change over following a plan

One analogy for the differences between Waterfall and Agile is planning a road trip to Key West (which is, incidentally, spectacular, and best experienced in a convertible). In a Waterfall approach, you would plan the entire trip in advance, mapping out every stop, hotel, and activity along the way. You would stick to that plan no matter what, even if you discovered a better route or a more interesting destination. In an Agile approach, you would plan only the first leg of the trip, then reassess your plans at each stop based on new information and opportunities. If you heard about a great festival in New Orleans, you might alter your route to include that stop, even if it wasn’t really on your radar when you started.

Agile is actually an umbrella term or general philosophy, and there are a handful of methodologies for implementing Agile principles in practice. Some of the most popular Agile methodologies include Scrum, Kanban, and Extreme Programming (XP).

We’ll identify a few key concepts in Scrum, which is one of the most widely used Agile methodologies:

User Stories

Requirements are captured as user stories, which are short descriptions of a feature from the perspective of an end user. User stories help prioritize work based on user needs.

Sprints

Scrum projects are divided into short, timeboxed iterations called sprints, typically lasting two to four weeks. Each sprint focuses on delivering a small, usable piece of functionality.

Daily Stand-ups

Teams hold brief daily meetings, called stand-ups, to discuss progress, identify obstacles, and plan the day’s work. These meetings help keep everyone aligned and informed.

Sprint Reviews and Retrospectives

At the end of each sprint, the team conducts a sprint review to demonstrate the completed work to stakeholders and gather feedback. They also hold a retrospective to reflect on the sprint process and identify areas for improvement.

Product Owner

The Product Owner represents the stakeholders and is responsible for defining and prioritizing the product backlog (the list of user stories and features to be developed). The Product Owner might be an external client, a project manager, or another team member.

Scrum Master

A Scrum Master facilitates the Scrum process, helping the team adhere to Agile principles and removing obstacles that impede progress.

Other Agile methodologies have their own specific practices and terminologies, but they all share the core principles of flexibility, collaboration, and continuous improvement. Beginning developers may not have the opportunity to work on Agile teams right away, but a basic understanding these concepts will prepare you for future roles in software development.


Check Yourself Before You Wreck Yourself (on the assignments)

Chapter Review Questions

  1. What does “iterative development” mean, and why is it a useful habit for a programmer?

  2. What is refactoring? Why do we refactor code?

  3. Compare object-oriented programming and procedural programming. How are they similar, and how are they different?

  4. What is the most popular version control system used by software developers today? What are two key features of a version control system?

  5. How does the waterfall development methodology implement the phases of the Software Development Life Cycle?

  6. What are some key principles of Agile software development?

Sample answers provided in the Liner Notes.