From the blog #Khoa'sCSBlog by and used with permission of the author. All other rights reserved by the author.
Further reading into chapter 2 I find that I relate to many of the patterns in this chapter, However, in my reading tonight I felt a specific interest in UnleashYour Enthusiasm. Unleashing Your Enthusiasm is about taking your passion for the work you do and exercising that passion. Think of it like starting at a new gym. You may not know what to do or the correct ways to do things, you may feel weak, confused, and embarrassed. Even with all of these negative feelings you know that you are excited to learn and get stronger. You may need to ask trainers for help and exercise your want for learning despite the embarrassment. This pattern is primarily about understanding that your passion used correctly is itself a valuable attribute to contribute to a team or teacher.
I find that this pattern goes hand in hand with Exposing Your Ignorance and that are one in the same. In order to unleash your enthusiasm you must be willing to expose your ignorance. If you are new to a team or project you are undoubtedly going to have to learn. You have to know that other more senior members will know more than you and will have to take the time to teach you, which for them may seem counterproductive. Being alright with your ignorance is the first step toward unleashing your enthusiasm. UnleashYour Enthusiasm is more about seeing the value in your ignorance. With this drive for knowledge it can help rekindle the flames of other more senior members who have plateaued and have their fire of passion die down to a smolder.
I find I experience the fear of exposing my ignorance quite often. At this point in my education I am always learning in everything I do. It sounds silly because it’s so obvious, but everything I have learned was once something I did not know. This means I had to overcome some fear and pursue that knowledge. Working with teams of my peers there is often a wide range of knowledge based on experience and backgrounds. It is scary to put myself out there and explain that I may not know something that they are all talking about it, but I have had the courage to do so. Many times I have done this and then had a pleasant conversation with my peers about having the drive for knowledge. It doesn’t pay to be afraid of taking the chance, that chance is knowledge and it gives others the opportunity to share something with you. I find that this unleashing of enthusiasm sparks a great pep talk for any team.
Last week, I gave an overview of my planned independent study project. This week, I’ll give a bit more detail on what I’ve done.
I have a habit of preparing for classes before they start. I buy the text books, get an overview of the material, and prepare to apply learning techniques throughout the semester. This helps me identify problems before the semester starts and address them in class as I go. Likewise with this project, I had hoped to get as much as I could done with machine learning before this semester started to hit the ground running with the software portion. Naturally, my ignorance led me to assume the problem was easier than it actually is. After a great conversation with a communications professor, I realized the problems I was trying to solve had to be broken down.
Counter-intuitively, the broken down problem is more difficult. To recap, my project involves machine learning and audio signal processing. Although great leaps have been made in this field and many problems have been solved, they mostly use clever tricks to achieve the results they get. Take speech recognition for example: your text-to-speech software transcribes nearly 100% correctly. Machine learning models can use huge datasets of audio, as well as commonly-spoken phrases to decide which words you’re most likely to say. The result is that mumbling, stuttering, or ambient noise is a bit more forgivable. On the contrary, transcribing each and every syllable is not nearly as easy, and in fact it’s a problem that has yet to be solved. That’s a shame, considering I was hoping to transcribe an audio sample into phones as part of my process and I somehow doubt I can do it without first getting a PhD.
This realization has led me to take a quick course on machine learning problem framing. It teaches the process of developing an hypothesis and developing a model to prove it, as well as resisting the temptation to shoehorn a problem into machine learning when a heuristic solution is as good or better. I did manage to find examples of using machine learning to solve some of the problems I wanted to (dating back 20+ years, even), but unfortunately they were each limited in scope and would be difficult to use to make a cohesive app. My goal isn’t a Frankenstein project.
In an effort to dig deeper, I’ve also done an introduction to Pandas tutorial, and started on a Tensorflow tutorial. These are surface-level in and of themselves, but help in understanding the higher-level frameworks. My hope is that understanding the basics will allow me to create a model that has an exciting application. In the meantime, I can implement the prerequisite features in software: audio recording and signal processing.
I’m going to dive into more specific problems as the semester goes on and I get more comfortable with the topics. I’ve already come up with a list of ideas and find myself wanting to write posts on small things like Android project flavors and build configuration. Posting thoughts and lessons in a public place has been great for accountability, and my goal is to know these technologies inside and out 4 months from now.
This blog is the first in a series of posts that will be covering software craftsmanship patterns I find compelling from Apprenticeship Patterns by Oshineye, Hoover. With these posts I aim to summarize the pattern and explain its relevance to me and software development as a whole.
In short, the “Expose Your Ignorance” pattern is aimed at dealing with a fundamental issue with people living in industrialized society. Software developers are under extreme pressure from managers and team members to know how to use many technologies. Especially in the case where those relying on you are under the impression that you understand how to do something, it can be extremely hard to make it clear that you actually don’t know how to do that something yet. Acknowledging the fact that there is a push to reassure everyone that you know everything and going directly against this is essential to learning as quickly as possible. This is the gist of “exposing your ignorance”.
I constantly feel the pressure to reassure my colleagues that I understand whatever it is we are talking about. I’ve always felt like doing otherwise would make me seem incompetent when in reality it is a sign of maturity. Immediately after reading this pattern I feel as though it made a fundamental shift in my approach to problems. It makes complete sense that mastering this pattern would yield great benefits throughout my career. “The most obvious way to expose your ignorance is to ask questions”(Oshineye,Hoover). Being able to ask questions whenever I am unsure of something can greatly abridge the time it takes me to learn a given skill. Also, in a world where we have near infinite knowledge at out fingertips at all times, I feel that a desire to learn is a much greater skill to possess than “knowing” a lot.
I find it very interesting that the authors make a distinction between software craftsman and experts. I agree that not being able to ask questions can shoehorn a developer into becoming really good at one skill, yet never branching out into others. I personally feel like being an expert rather than a craftsman can make a career in software development grow stale. Being able to nurture a desire to learn is important not only in the context of a software development career, but in everyday life as well. “Expose your ignorance” truly is a pattern that I feel will improve my career as a software developer.
From the blog CS@Worcester – Your Friendly Neighborhood Programming Blog by John Pacheco and used with permission of the author. All other rights reserved by the author.
This apprenticeship pattern concerns something that most people are afraid to do. Nobody wants to look ignorant in their profession, because we are expected to be competent and knowledgeable and that is what we are paid for.
The main idea is simple: don’t pretend to know something you don’t. This leads to headaches in many ways, but most importantly it will make it more difficult to learn what you need to learn. In software there is an endless supply of new technology to learn and throughout a software career, there will be countless projects that use something you don’t understand. Admitting this fact and asking others for help is the quickest way to learn it. At the same time, you will build trust with your team and show that you know how to learn.
We are trained to look competent from a young age. We need good grades to get into better classes, a better college, the best job possible. Getting a poor grade reflects lack of preparation rather than exposing ignorance, so it’s natural to think that we will be seen as unprepared if we show ignorance in our work. If this fear is realized, it is likely a problem with the culture.
The most important idea in this pattern is showing others that learning is part of the software process. Speaking from experience, I’ve never judged a coworker or classmate for something they didn’t know. Each of us has our expertise, and if I don’t have time to teach something, I can at least be there for support if they need it. What would become an issue, is when someone says they can get something done and only much later admit that they can’t, when it’s too late to get them up to speed.
Likewise, people have always been willing to help in the times I’ve admitted not knowing. More often than not, the response has been mutual frustration. I’ve saved myself a lot of worry by admitting confusion and hearing from tenured employees that “it’s just confusing, I don’t really understand it either”. The result is a collaborative effort where both people come out knowing more, and having a better rapport in the future.
This pattern is an excellent reminder that we’ll never know it all, and that pretending to is not a long-term solution. The suggested action is to write down five things that you don’t understand about your work, and showing it where others can see it. This seems like a good tactic, and I plan to do this on a whiteboard at work. Coworkers who know better than I will hopefully guide me in the right direction.
As I picked through the list of Apprenticeship Patterns one of the earlier ones jumped out to me, as it seemed fairly obvious from the name what it was. Upon reading the description I was correct in this assumption and further I had experience with this particular pattern – even if outside of an apprenticeship. That description being a “toy system that [is] similar in toolset, but not in scope to the systems you build at work”. If you were to insert “school” instead of “work”, then I have built breakable toys for the same reason the book describes: to try and fail in private so that your successes can be applied to a real project using the same technologies, but your failures do not come at the expense of said project.
I have a sense already that many of the patterns I pick this semester will be those that I either have experience with or involve skills I feel insecure about. This being a pattern I feel familiar with I hoped to see if I was applying it correctly, and I wasn’t, at least not completely. First, the book stresses that a breakable toy should be like any real toy, fun. I think this is at least one hang up I have had with my own toys is that I try too hard to make them into potentially repurposable that I can use in whatever project I am training for. Instead, I think moving forward I will try first to make something fun, but overengineer it like the book says, such that I can gain as much experience possible from some silly little program.
Additionally, the book mentions making a little wiki as your toy, and this I had never thought of. Initially, I had read this as meaning thoroughly documenting the toy you are building. It makes perfect sense and follows logically one of the best points that has been made to me about learning, which is that the best way to do so is to teach. However, upon subsequent readings I realized they meant developing a wiki with your selected tools. While this certainly would help foster an understanding of yours selected tools, it would clash with the previous goal of being fun, at least in my mind. Instead, despite it being a misunderstanding, I think much could be gained from documenting one’s progress on a breakable toy. Considering I have a spike project to work on currently, I think I will apply these lessons as I begin.
If you are close to graduation as a Computer Scientist or Software Developer, the market for you will be huge. There are unlimited opportunities in the Tech field but should really be prepared for that. How do you see yourself in the professional world? Where do you see your starting point, and what are your future goals? An inexperienced Software developer, you have to be an apprentice, and following the long way of this journey, you will be a master, unless something goes wrong – like really wrong.
Reading “Apprenticeship Patterns” by Adewale Oshineve and Dave Hoover, will give you the first jump on the “Software Craftsmanship” world.
The term Software Craftsmanship is used to illustrate the skills you need to be successful in this journey. Being a Software Craftsman, you don’t need to have coding skills, you need creativity, you need to build your crafts, design your ideas, solve the problems avoiding complexity. Sounds fun, right? Yes, it is actually fun if you enjoy it, and if you know how to start from point zero. Imagine if you are a baby: you need to learn how to walk before traveling the world. You need to learn how to talk and read before being a scientist. So, you must be an Apprentice and follow the pathway that is important for you. One step at a time, learning from your masters and applying your skills will make you jump to the next phases. However, if you need to maintain your skills you don’t need just to practice them, you should also pass them to the other people.
At this point, you will not be an apprentice anymore, you will be a journeyman! Being a journeyman does not mean that you do not need to learn anymore, you should still follow your mentors, they will still be your masters who open new doors of your mind. You will still be focused on your craft, your ability to develop your skills, to advance the complexity of your designs. As a Journeyman, you should have created your portfolio, which represents your experiences, your knowledge and your ability to be a craftsman.
Next step, you will be a master. As a master, you will be an apprentice: you will keep learning and develop your skills, you will be a journeyman: you will keep building your portfolio and expand your craftsman ability, and Master: you have to move the industry forward and pass your knowledge to the new apprentices. Being a master means that you have all the needed skills and experiences to be a true craftsman. You will have the ability to design, architect and construct your crafts.
As you go through this journey you will need to make important choices. You should always need to be careful about what you choose, money or experience. Money can give a good life, financially, but skills and experience give you more opportunity and open more doors for your future. Ready to start your journey? Good luck…
Writing software is fun. Mostly.
When I look back on the projects I’ve made, a couple big ones stick out which were mostly not fun. For example, I made the mistake of trying to build an Android app before I fully understood what a class is. Design patterns were not even something I had considered. The consequence was a fairly simple app with code that was supremely complicated and confusing.
For my next project, I tried to do better with the lessons I had learned. I continuously had errors that I didn’t understand; errors that were seemingly unrelated to the changes I had made. After a couple weeks of struggle I deleted all my files and uninstalled Android Studio. The frustration was so bad it made me want to quit programming. The frustration could have been prevented.
This is where tests, and specifically Test-Driven Development (TDD) could have saved me.
James Grenning has a blog post discussing how he feels about TDD, after years of writing software without it. TDD forces you to think through what you want your code to do. If you can’t test your code it’s likely a sign of bad design, so TDD indirectly leads to a better software architecture. Tests describe what the code is supposed to do, and the tests will always be there. If the code stops doing it in the future the tests will fail, acting as a permanent, enforced documentation. This leads Grenning to bring up the concept of regression tests, which confirm that your new changes don’t modify legacy behavior. The suite of regression tests that you slowly build over time will make sure nothing is inadvertently broken. But as you write new tests, you’re also getting instant feedback that your new code is performing to specification.
My life as a programmer is much better with TDD.
TDD brings you back to the programming exercises you did when you first started learning. It is satisfying as it is to struggle through a problem and make your project do what you want. But it is so much more satisfying to see a big green bar that tells you everything is working, including everything you’ve done since the beginning of the project. Then you can play with your new features manually if you so desire.
There are some downsides to TDD. More code means more time and more to maintain. Sometimes you’ll have to change tests because what your code is doing also changes. Furthermore, TDD is an art in itself and must be learned, meaning you may need to break old habits of bad design to write code that is testable. I’m inclined to agree with Grenning that debugging a complex system is much more time consuming that these downsides.
It only took a couple weeks of clear thinking to realize I had overreacted when I uninstalled Android Studio. I learned to have a lot more patience and take the time to do things the proper way. I still forgo testing and TDD for small, personal projects, but the benefits of TDD greatly outweigh the downsides for any important project.
YAGNI stands for “You Aren’t Gonna Need It”. This is an acronym I’ve only taken to heart recently, despite reading about design principles on and off over the past few years. I have learned enough from my mistakes in the early days of programming to know that planning pays off, and what could be better planning than adding code now to help yourself add things in the future? Two words: clean code.
This summer, I was tasked with designing and implementing a desktop application from scratch, as the only developer. The specification was vague (essentially, “these are the user inputs, this is the output, and leave room to add more inputs and outputs later”) and it required research into topics that have nothing to do with software, that I had never seen before. This caused me to create unnecessary abstractions and extra features in many places, just in case. In the end, I refactored quite a bit once I understood more about what was required and realized what wasn’t needed. The extensibility that I actually needed worked out great. Everything else got in the way.
A blog post on YAGNI by Martin Fowler does a great job of describing what I did wrong, and I chose it in order to learn how I could have improved what I did. His summary of YAGNI is that features you expect to need should not be built. Features should be built only when you actually need them, because it’s very likely that “you aren’t gonna need it”.
Fowler goes on the describe the main argument YAGNI makes, which is that you might be wrong about presumed features. When you’re wrong about features, you accrue four costs: the cost of building a presumptive feature, the cost of delaying other features, the cost of carrying the presumptive feature (making it harder to modify other code), and the cost of repairing the presumptive feature (because even unused features must be maintained).
One major point that Fowler stresses is that this does not apply to efforts to make code extensible, unless it adds unneeded complexity. There is a difference between adding code that is easy to refactor in the future, and adding unused code. The former follows other design principles. The latter adds clutter and creates confusion. And who needs more of that?
Could I have done better with the aforementioned project? I think so. There were a couple major overhauls that would have been a nightmare without some extensibility baked in, but most of that code didn’t add unnecessary complexity and is therefore in line with YAGNI. I also have to consider that it was a single-person project done in 3 months, so it is likely that the negative side-effects were kept at a minimum. It’s also impossible to determine how much time I spent searching through unnecessary code, so a little more YAGNI could have sped things up. In the future, I’ll be considering this important design principle.
Many times, people go into projects without much planning
before-hand which can cause many problems to arise. UML class diagrams can come
to be your saving grace. With these diagrams you are able to plan out how the code
will be set up down in a neat organized diagram. In these diagrams, the top section
depicts the name of the class, the middle section depicts the attributes and
the bottom portion is what lists the methods of the class. The top section will
be bolded to indicate that it is the class name. This top section however can
say whether or not the class is abstract, concrete or an interface. If the name
is simply just bolded, the class is concrete. If the title is italicized, then
the class is abstract. If the class is an interface, the top section will have
the class name bolded and <<Interface>> listed above the name. In these middle sections you are able to
specify a lot about the attributes of the class. Any variable will be listed
with a minus sign beforehand and the data type following. If any of these
variables are static, then they must be underlined. This allows for someone to
seamlessly set-up the class without having to worry about including the correct
variables and data types. As stated before, the bottom section will contain the
methods of this class. These methods will contain the name of the parameter (if
applicable) and the data type of that method. If the method returns a data
type, this will be listed after the parameters. UML diagrams don’t stop there
though. What I was describing was one box/class, while UML diagrams can contain
many, with indicators to show the relationships between them. Arrows are used
to show relations between classes. An arrow going from one class to another
with a hollow white tip stands for inheritance. When an arrow is going from one
class to another with a dotted line, that represents implementation. A solid
black arrow means there is a reference from one of those classes to another. By
using UML diagrams, you are able to set up one’s entire program before writing
any actual code. This allows for anyone else to be able to read and understand
the code by simply going through the diagram. UML diagrams gives the coder the
ability to write clean flowing code. Below is an article which goes in depth
more with UML diagrams and also gives examples.