I should preface this by reminding that I am not a software engineer, but an electrical engineer. I took an ICS class in spite of that, however, since coding is a useful skill for EEs to have. Coming out of the class, I found that I learned not about coding, but almost everything else that surrounds coding.
For EEs, code is a means to an end. We code to simulate and to interface with hardware. In both cases, code may end up being static, small, and not need maintenance. ICS-314 gave us a project that didn’t behave the same way. Web applications evolve as business requirements and dependencies change. The only hardware required are the servers that run the deployment, whose controls are abstracted away through web interfaces. There is greater complexity and significance to the code, and software engineering practices provide means to work with this added complexity in a way that gives it greater care.
There is a multitude of concepts that were taught in ICS-314 that encapsulate software engineering:
I would like to take the time to go through each of these topics by explaining what they are, what I’ve learned, and how I might be able to integrate that into my own EE work to hold my code up to higher standards.
This is a catch-all smorgasbord of software engineering topics that teach how to build software in a collaborative manner. If the scope of collaboration is large enough, it’s most likely an open source project, in which anyone can inspect the code and modify it to their own respective needs. A common example of contributing to an OSS project hosted on GitHub for example would entail the following:
This isn’t something that EEs typically have to deal with, since most of our work is not meant to be accessible to the public. However, if we need to do some data analysis or run simulations, we may find ourselves dipping into open source software or libraries and find bugs or areas of improvement with the software that we use. Prior to this class, I may have just worked around that issue or patched the source code myself, but I now know how to bring up this issue and a possible solution to the main project so that future engineers need not struggle with the same problem that I encountered.
When working with code, we’re always using tools of some sort. At the bare
minimum, we’re using a code editor or an IDE to write the code. Which will we
use though? If it’s C code through an SSH session, we might have to use built-in
Linux tools like vi. If it’s MATLAB code for simulations and modeling, we
might use the MATLAB IDE or maybe some personalized editor like VS Code with the
MATLAB language server used for syntax highlighting and code completion. What if
we have multiple people working on the same project and need to use the same set
of tools for uniformity?
This is configuration management: managing the configuration associated with
the tools used for development. In the case of the web applications we work on,
we have to configure our libraries, our testing mechanisms, and either include
editor-based files for an easy-to-start code editing experience or ignore them
in the .gitignore to avoid clutter and allow for editor-agnostic
contributions. We’ll sometimes even have to configure how testing works for
ourselves and the many other developers that may clone our repository and run
tests themselves.
One of my personal software engineering heroes often says the following as one of his biggest advice to software engineers, coders, and any other craftspeople in general:
Know your tools and optimize your workflow.
In most cases, code is a write-and-forget once-in-a-while occurrence for EEs, and it takes effort to learn the tools and optimize one’s workflow. However, for EEs that do extensive and frequent coding, that extra time spent becomes an investment that saves time in the long run.
Most programming languages have a notion of state, in which external factors can affect how code runs. Variables are assigned, files are read, APIs are fetched, and so forth. One of the concepts touched upon in ICS-314 is functional programming, in which code is written or executed in a way that produces consistent, reproducible results at all times. The code is a function, whose outputs depend solely on its inputs.
As interesting as this concept is, it fundamentally contradicts computer architecture: computers are inherently stateful. Memory is allocated and freed, and registers are written to and read from. For most hardware tasks, this method of programming adds a layer that prevents EEs from fully speaking the same language as the computer underlying the hardware. However, functional programming fixes code and makes assumptions that allow the computer underneath to make certain operations easier, like reproducibility and parallelism. Not something to be used directly when programming hardware, but something to consider when doing the “other things” involved in hardware coding.
Different EEs develop code in different environments, just as they use different tools. They may code on and deploy to different chip architectures, or their firmware supports different operations. EEs normally learn on the fly and move on to different environments as needed, but if they’re able to optimize their environment as they did when working with tooling, they’ll find themselves quicker (and possibly specialized and competitive) if they encounter the same environment repeatedly. That is an extension to their capabilities that ICS-314 has exposed to them.
EEs often use language servers to catch errors and bugs in their code prior to compiling, interpreting, or deploying it. However, the conventions used between EEs and even different files of the same EE projects may differ greatly, producing a mishmash of a codebase due to a lack of coding standards. In ICS-314 however, coding standards were set forth and enforced on the language server level within the project thanks to ESLint. This makes the web applications built much easier to navigate and follow, similar to an essay that has consistent formatting. When maintaining long-lived code that is subject to change in the future, EEs may benefit greatly by adopting a coding standard to ease their navigation of their own complex code.
In most cases, EEs never touch UI frameworks that abstract most of the user interface construction away to a few simple, extendable primitive objects. After all, EEs write code that manifests only in the performance of their hardware, not in the interface used to interact with the hardware. There is something to be said about frameworks in general, which get
Agile is a software development methodology that comes from the Agile Manifesto places emphasis in working in small, independent teams that can move quickly to work on different parts of a project (among other things). Engineers typically work so separate from each other that this methodology doesn’t really apply to them, so it isn’t necessary for the most part. There are a few cases in which a few engineers might work tightly to write code though, and in those cases, having a development methodology that works extremely well may allow for smoother work as a team.
Ethics is a concept that doesn’t need any introduction, I believe. Out of all the different facets of software engineering, I feel that this is virtually identical to that of electrical engineering. Electrical, mechanical, and civil engineers create constructs that improve society when done well, and wreak havoc when done poorly. All engineers that graduate even receive a ring that reminds them of this fact. In recent times however, the prevalence of software has made it so central to society that there are codes of ethics established for software engineers, such as the ACM Code of Ethics and Professional Conduct. There isn’t much to take from the ethics of software engineering since we already have our own sets of ethics, but it is reassuring to know software engineers that steward the code integral to society are aware of the significance of their work.
Electrical engineering is a broad field that touches on many topics, but one thing that’s encountered often enough is coding. Coding is a means to the end, and electrical engineers are often just adequate in their ability to write code. I hope that by taking the things I learned about software engineering, I will be able to use “everything else that surrounds coding” and become an electrical engineer that’s unusually good with code, since I had a class in which I learned from a field that lives and breathes code.