To Refactor or Not to Refactor…

That is the question. And the answer is yes. Do it.

As we’re nearing the end of the term, and our Capstone projects are coming into something close to their final forms, I’m putting my focus and attention on refactoring. While I came into our project with knowledge of Flutter and Dart, it certainly was not advanced, and was constrained to the specific techniques taught in the Mobile Development class here at OSU. The unique requirements of our project, using Firestore in a much greater capacity, and developing on a team have resulted in a great deal of new learning.

One side effect of learning something new is that it’s not usually perfect the first time. And by not usually I mean almost never. So the code I have needs work. It’s accomplishing what it’s supposed to, but in terms of being DRY, of functions being short and doing one thing, and encapsulating code to avoid unnecessary dependencies, there is work to do. Part of the learning curve has been understanding Firestore, and the best way to write queries, and read and write data. Part of the refactoring work to be done will be to make sure I’m doing these database queries and writes consistently and efficiently. Then, having made sure that component is done well, I will take a look at the structure of my dart files, try to keep my model classes purely dart, and put other functions and classes in the most appropriate places. 

Aside from Firestore interactions, I’m hoping to make sure performance is most efficient by extracting widgets to their own classes, so that the build methods do not become over-encumbered with functions needlessly being rebuilt. Lastly, making sure conventions, line length, and comments are consistent across our program will be a priority.

While there is plenty to be done, I do find myself happy with how far I’ve come since the early days of my time here in the Online CS program. The quality between now and my first forays into programming is dramatic, and I can differentiate between quality code and poorly written code. And when I need to refactor I recognize the process for what offers – simply another opportunity to learn and improve. 

Don’t overthink it.

Simplify, simplify, simplify!

Henry David Thoreau

If there’s one thing I should know by now in my life, it’s that I am an over-thinker. You’d think someone who thinks so much would think about the fact that overthinking is not helping, but it turns out it doesn’t work that way. This plays out in programming projects sometimes by way of me overcomplicating or over engineering a solution that doesn’t need to be nearly so complex.

This week was a perfect reminder of this lesson: to always ask yourself, “Can this be simplified?” 

In our app, Bridge, comments are stored in Firestore and displayed on the screen through a StreamBuilder. The StreamBuilder is a widget which builds itself based on the latest snapshot of interaction with a stream. And a stream is a source of asynchronous data events, such as a changing Firestore collection. This all works dandy and our list of comments update instantly when is adding or upvoted/downvoted. I ran into a problem however, when I needed a piece of a comment – a User’s attribute – to update instantly when it was edited on their Profile Screen. Because the stream was ‘listening’ to a Comments subcollection, and not the Users collection, it didn’t know or care when a User updated their attribute. In true overthinker fashion I latched on to this concept of streams and proceeded to spend an inordinate amount of time researching different Flutter package dependencies for merging and managing multiple streams. I tried a couple options, adding them to the pubspec.yaml, changing up all the existing mapping and work done on the original stream. I could never get it to work, and making one thing work seemed to break something else. Eventually I thought, hey, maybe I don’t need to mess with the streams at all, maybe I’m overthinking this.

As soon as I let my brain step back, get out of tunnel-vision, and re-assess, I realized there was no need to be constantly getting a snapshot of the Users collection, like the stream does. I could just make the widget that displays a single comment be stateful, and put a query getting the author of the comment’s attribute (if any) in a function called in initState(). At first I couldn’t quite figure out where I would call setState() to trigger the widget tree rebuild. Normally, there would be some sort of interaction, like a tap or swipe to trigger this event, but I just wanted a rebuild when the user navigated from the Profile Screen back to the previous. For some reason I thought this was something that was already happening implicitly through Navigator.push(), Navigator.pop(), etc., but it’s not. I still don’t completely understand how some of the inner processes work, but I decided to try calling setState() right after pushing the route to the Profile Screen. I figured when the Navigator popped back, it would immediately run into this setState(), which would make the comment widgets rebuild. And it worked! Like a charm. I don’t know if it’s the most conventional method for accomplishing my goal, but not only does it work, but it is far easier than merging streams. 

Moral of the story: always try to simplify your approach. Ideally, before spending hours going on a deep dive into a complex, yet only potentially workable solution! Happy Coding!

10+ Resources For When the Tech Landscape is Kind of Bumming You Out.

I have a lot of thoughts about what the tech industry has become, and while some are generous and positive, some are less so: The Atlantic recently had a good article here. How do I enter the tech industry when I am so deeply suspicious that social media and the Internet at large have harmed democracies, eroded our common societal trust, and fundamentally transformed our psyches and social traits? For years now, people have been becoming more aware of these effects. How tightly tech, capitalism, and our political landscape are intertwined. How disinformation has metastasized on Facebook and Youtube. How generations (my own included) have unconsciously been shaped by technology to create cancel-culture. How Amazon transformed commerce, how Netflix made us into binge-watchers, how crypto has, and will continue to have, huge implications on our economies. On and on, there is not a facet of the world that has not been shaped by the digital age.

But this is not meant to be a downer of a post, so let’s pivot.

Thinking about these topics has led me to some amazing projects happening across academia, industry, and on the fringes. Whether they’re trying to guide policy, designing new algorithms with less bias, or teaching the public about tech ethics, here’s a ramshackle assortment of projects worth going down an Internet rabbit hole over:

  1. The Center for Humane Technology. With endeavors aimed at pressuring social media giants to make simple yet impactful changes to their platforms, offering courses on humane technology, and empowering us to counteract harmful algorithms in numerous ways. They produced The Social Dilemma, which should give an idea about their perspective.
  2. Numerous universities have projects focused on using tech for social good: The Oxford Internet Institute’s Programme on Democracy and Technology aims to engage in “real-time” social and information science, to make better tools for detecting and ending interference with democracy.
  3. The Notre Dame University Tech Ethics Lab “promotes human values in technology, helps develop standards related to the moral and ethical use of technology, and seeks to inform technology-related laws, policies, and governance”.
  4. The Freedom of the Press Foundation uses technology to protect public-interest journalism through projects like whistleblower submission system SecureDrop, and trainings in cybersecurity for newsrooms globally. They also funded Signal, the E2E encrypted messaging app, so another point there.
  5. The Stanford Internet Observatory offers, among other projects, a undergraduate course on Trust and Safety that aims to “An introduction to the ways consumer internet services are abused to cause real human harm and the potential operational, product and engineering responses.”
  6. While algorithmic bias is a big topic, lots of researchers are dedicated to lessening its negative impacts on marginalized communities. The University of Chicago has a team focused on reducing algorithmic bias in healthcare. The Brookings Institution gives a thorough documentation of the issue, then supplies best practices for mitigation and policy.
  7. Mila is a Canadian organization focused on the socially responsible development of AI. Their projects under AI for Humanity are pretty neat.
  8. In terms of sheer scale, there’s this hefty publication from the Program on Democracy and the Internet at Stanford University, which considers the scale, scope, and power exhibited by Big Tech: Google, Facebook, Amazon, Twitter, and Apple.
  9. As a counterpoint to MANGA, or whatever we’re calling them, check out this repo of co-op tech companies, providing an alternative job experience outside of Tech Giants and startup culture.
  10. Check out Mastodon, which is open-source, non-algorithmic, and independent. There’s /r/socialistprogrammers for general discussion with developers who hate Capitalism, and finally, Quantified Self, which aims to help people learn about themselves through their own data.

This is just a selection. I’m still somewhat cynical at times about our collective digital existence – but countless other bright minds are grappling with our position and finding the way through. If they can, so can I.

NoSQL? No Problem.

If you’re like me, and you had no coding or development experience before jumping into Computer Science program at somewhere like Oregon State, your introduction to databases, and the whole dynamic of Front End vs Back End development really, came in the form of classes like Web Development, and appropriately, Intro to Databases. These are foundational, and I’m not complaining about their content! But are they covering the current evolution of every type of software design and development architecture? Nope. And so here we are: months away from my graduation and I’m just now really learning about NoSQL databases and the many cloud computing infrastructures that use them. Without further ado, a brief rundown:

Come to find out, the days when relational databases were the de facto data storage solution are long gone. For many years (we’re talking the ’70s, the ’80s, the early ’90s), storing data was expensive, and the priority in software development was to reduce data duplication and easily write to the database. Relational Database Management Systems (RDBMS) used Structured Query Language (SQL) with painstakingly structured schema to achieve this goal, and RDBMSs like MySQL became ubiquitous. While it is certainly not true to say that relational databases have outlived their usefulness – They’re still widely used in tons of industries – it is true that so called NoSQL or non-relational databases provide an attractive alternative for some use cases. Maybe we touched on these in our database class, but it clearly wasn’t enough to stick. Moving on…

When the cost of storage began to rapidly decline, sometime in the 2000s, it became less important to focus on storage, and increasingly important that projects could iterate and adjust in keeping with Agile methodologies, scale easily, and run queries quickly. NoSQL databases use documents, key-value pairs, or sometimes graphs, instead of rigidly normalized (*shudder*) Tables. The idea, in some ways, is to store your data more similarly to how you actually think about it, and importantly, how you’ll use it. NoSQL documents can be nested JSON-like structures, which translate directly to the objects used in many programming languages. We can’t flat-out say NoSQL databases are faster than relational ones. Normalization in RDBMS seeks to make complex joins and queries as fast as possible, and yet as tables grow very large, these joins and queries are nevertheless going to become more expensive. With NoSQL however, if we will need to retrieve the data together, we simply store it together: we circumvent the need for joins almost entirely as queries can grab a single document, and are thus exceedingly quick. Hooray!  

In my Capstone Project, a cross-platform discussion app built with the Flutter SDK, our group has decided to use Firebase, Google’s nifty platform for developing mobile apps. Firebase is itself backed by Google Cloud Platform, so we’re clearly set-up for scale with Google servers. Firebase has many products and integrations, from backend infrastructure like Authorization and Cloud Firestore, to performance analysis products like Crashlytics. Cloud Firestore, being a NoSQL database, offers super easy methods for listening to data-changes, implemented in Flutter as Streams. So far reads and writes have been smooth and fast. While this suite of products is a tad overwhelming at first, diving in has been a great learning experience. I’m understanding the ‘serverless’ paradigm better, and recognize how much platforms like Firebase simplify traditional back-end development. Are cloud-native and serverless architecture with NoSQL databases the answer to every use case? Not remotely. But for many situations, including our app, it relieves the developer from having to reinvent the wheel standing up their back-end, and allows data storage to be intuitive, flexible, and scalable.  It’s a ‘yes’ from me! 

Beware the Tech Tangents

Beware the tech tangents.

I’m settling down to get some coding done, when I realize I need to install a dependency. I forget if I’m using Conda still or venv for virtual environments. Investigate. Get confused checking the Python installs on my machine. Did I use Homebrew? Better update and upgrade that for good measure. I realize I am using Miniconda after all, but I forgot the commands. Google a cheatsheet. Okay, virtual environment is set up, should I install the package with Conda, or pip? Try both, and cross my fingers that it works. We’re good to go! Start into what will surely be a long, highly productive coding session. My algorithm is not great, and I have a suspicion there’s a more efficient way I could be writing this. I can’t quite figure it out, so I turn to my trusty friend, the internet. I can’t figure out how to describe my situation and I try some weirdly worded searches in hopes that Google will somehow read between the lines and understand what I am struggling to articulate. It doesn’t work, but I do stumble across a Medium article about dynamic programming that is very good. The author is a good writer as well as a good programmer. There’s a link to an algorithm course on Udemy, which, I think to myself, would not be a bad idea. I could use more practice in that area. I’m on the algorithm course page, but look at all these other ones! I barely picked up JavaScript in my Web Development class, and that is an important language to know. After all, with my design background, Front-End might be the thing to focus on. On the other hand, I enjoyed Intro to Networks, and if I want to pursue that route, I really need to focus – there’s so much more to learn. After looking at several CompTIA courses, going so far as to read several other articles, in other tabs, discussing the value of various certifications, I feel that I am very nervous about committing to this particular career path. I reflexively Google “types of software engineers” and read several more articles, and now I think I should maybe consider DevOps or UX/UI. On one page I see a random stock photo showing a developer with two desktop monitors. Is that how “real” programmers work? Why am I doing all my work on a laptop? I need an office, with multiple screens for increased productivity. Google “best desktop for programming”. After looking at many models, with wildly divergent specs and price points, I remember a) I do not have money to buy a new computer, and b) even if I did, there is no “best”, just the most appropriate for a particular set of needs and/or restrictions. Admonishing myself, I close all these tabs, including the Udemy course pages (my realization about buying a computer has shocked me out of my rabbit hole). Blinking like I just stepped from a dark room to bright daylight: what was I doing? Oh yes, I was trying to think of an improvement of my code’s implementation. Opening my IDE again, and looking at the block in question – the answer comes to me instantly. It was in my head the whole time.

The beginning of the end, or the end of the beginning.

If you’d told me a few years ago that I would soon become a software developer, and with an actual degree no less, I would have laughed. I’m not the kid who grew up loving video games,  tinkering with technology, taking apart computers and trying to MacGyver together some scrappy engineering project in their teens. As a kid I played dress-up, made fairy houses, and read books. I made a lot of art and for some time I thought I’d do that, as a career. Then I went to college and got majorly distracted by English Lit, Medieval Studies, and Philosophy. Got myself a BS in Liberal Studies, which was great for Jeopardy watching and not much else. There was really not a sprinkle of computer science in my life. And then, after arriving in my late twenties without any career path I was excited about, I finally gave a real thought to what I wanted to do. It so happened that of all things, most of the fundamental qualities I was looking for in a job were fulfilled by programming. Progressive challenge, logic, problem-solving. It had never occurred to me to consider it. I started the OSU Online CS Post-Bacc program soon after, and now here we are: my final term.

I never spent a lot of time or effort communicating with other students during these past two years, for better or worse, meaning grades are my primary barometer to evaluate my ability. By this metric I’ve done just fine, but the nagging doubt certainly creeps in here and there. Other times I’m absolutely amazed at what I’ve learned. Casually (well, casually might be a bit of a stretch, lol) writing my own shell in C, or picking up an entirely new framework (or, enough of it anyway) in a couple weeks! I’m self-conscious that I’m still not the stereotypical tech person. I don’t have Twitter, nor do I want one. I’m not spending my free time working on personal development projects. I still don’t have much interest in taking apart a computer. But that doesn’t make me a less effective developer. It doesn’t mean I’m not serious about computer science. In fact, having different skills and different interests makes me stronger in some ways. 

For me, starting this term means the safety of academia is soon ending, and the time has come to own my new role. I’m ready.