Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Tuesday, February 9, 2021

Coding Challenges and Job Searching

I know I missed posting last weekend and for good reason. Not only was it a busy weekend at the house I'm living at, but I also was stressed preparing for my first coding challenge that one of the companies I applied with asked me to complete.

I'm admittedly somewhat self-taught when it comes to computer science concepts. I have a limited background in algorithms. What object oriented programming I know is mostly what I've picked up learning Python, which allows for, but doesn't require, an object oriented paradigm. I'm familiar with big O notation from my math studies, but still have difficulty knowing what the time complexity of various common functions and operations is.

Needless to say, I quickly realized that I was unprepared for the typical algorithmic coding challenges companies use as part of their interviewing and hiring process. The challenge I completed was administered through a platform called CodeSignal. Once I signed up for an account, I started working through some of their arcade and interview prep problems. In addition to providing practice, it also allowed me to become familiar with their in-browser IDE (integrated development environment) and allowed me to test out a few programming languages I might use. I was initially torn between using either Python or MATLAB (I don't feel comfortable enough with perl to attempt a timed test). Since MATLAB is proprietary software, it isn't supported on CodeSignal's platform. Octave, an open-source language similar to MATLAB, is, but I am not familiar with or comfortable navigating the differences between the two. Plus, it's been a while since I've used MATLAB, so I'm a bit rusty. Ultimately, I chose to proceed with Python.

I didn't do horribly on the coding challenge, but neither did I do super well. This will likely not be the last challenge I'm asked to complete, so I have decided that going forward I will try to complete one practice problem a day. This was initially a goal I was intending to pursue with Leetcode, but I've settled on using CodeSignal for now. This has a few advantages. First, you must either spend some hard earned coins, gained through completion of exercises, or successfully solve the problem in order to view hints or other users' solutions. This removes the temptation to look at the solution the moment you become stuck. Second, the organization of problem sets on CodeSignal makes it easy to progress from simpler problems through to more challenging ones.

One recommendation I have for anyone seeking to expand their coding abilities this way is to do the problem, and if you get royally stuck, do a quick Google search and read through a few forum threads or search the language's documentation to discover some unknown-to-you function, package, or syntax that may be helpful. Once you've solved the problem in its entirety, look at a few of the solutions for your chosen language and look up pieces of code that are unfamiliar to you. I've been doing this and have learned new things I wouldn't have discovered otherwise. For example, I learned this past week about list (and dictionary) comprehension in Python. This technique is a way of constructing lists (or dictionaries) more quickly than using something like a straight-forward for loop, which constructs entries one by one. I've been able to implement it in other problems I've worked on and it's helped to speed up the execution of my code.

One last thing I wanted to briefly touch on this week: job searching. I know I mentioned a while back that I'm looking for my first professional job. One thing I've discovered is that colleges by and large don't do a good job of preparing students to job search. I think the expectation is that you go to a school job fair, you get a job. Eazy-peazy. In reality, it's not that simple. I've spend the better part of my job search fumbling my way around job boards and reading job posting that make me feel depressed about not having any experience. This is a topic I hope to elaborate on in the future, but for now, I just wanted to mention that if you are feeling lost in your search for a job, you are not alone. I've watched enough videos and read enough forum posts to know that no one really knows what they are doing, but they hope that they get noticed by the right recruiter or hiring manager. I think sometimes there is this misconception that once you become an adult, you know how to do adult things, like getting a job. That couldn't be further from the true: we are all pretending and hoping that those around us believe we know what we are doing until we've got it figured out.

Monday, January 25, 2021

Regexes and Sizers

 As I mentioned a few weeks ago, I've been learning Perl using the infamous llama book.  My first introduction to Perl was by a friend of mine when I was working on a class project using MATLAB (which was a mistake, but that's a story for another time).  I didn't try picking it up at that time, but it's been on my list of languages to learn since then.  

There are few things I've learned that Perl is good for: it's really good at processing text and it's goal is to allow for quick and dirty programming.  This means it doesn't take a lot of time or typing to write short little snippets of code that are pretty powerful.  Even though I'm a tad more than half-way through the llama book, I still feel like a noob because some of the syntax feels so obtuse, particularly when it comes to regular expressions.

Several of the more recent chapters I've gone though give an intro to regular expressions and it's the first time I've really had any exposure to said concept.  So what are regular expressions (or regexes) anyway and why are they useful?  They are a way of matching parts of text (in geek-speak: matching patterns in strings) and their existence and robustness in Perl is why it's a great language for text processing. Anytime you have to do some sort of searching there's probably some regexes (although maybe not in Perl) being utilized in the background.

Regexes are going to be useful for me in one of the later coding projects I have planned, but they may also come in handy in my current project.  The llama book alluded to the fact that Perl supports some Python-style regexes, so I know such objects (because everything in Python is an object) exist in Python.  In the coming weeks I'll need to look into their syntax and usage in Python as I look to adding search functionality into my catalog application.

And speaking of my music catalog app, I'm in the middle of prototyping, but I'm no where near as finished with this step as I had hoped to be.  I definitely underestimated how long it would take me to implement the layouts I had sketched in my design step.  This is mainly because I start doing something I think is simple and then quickly run into problems because it's a bit more complex than I anticipated. One of the coding issues I've had is using sizers to create the layout of buttons, text fields, and other visual elements in windows.  I now understand that if you're using horizontal sizers, their inputs (flags) determine how the elements are placed vertically and vice versa.  And sizers embedded inside other sizers also influence how elements are placed, so you've got to be extra careful with the flags you've used on various levels of sizers.  I've only completed two, simple layouts as of yet, but it took me the better part of a day to figure out enough to successfully do even that.  So instead of focusing on building one dialog window or panel at the time, I started by just making skeletons of many of these elements so when it comes time to coding the layouts, I can focus more on playing with the sizers themselves.

The other issue that roadblocked me earlier in the week was figuring out how to break up my code so it wasn't all in one long, hard-to-read file.  I was operating under the assumption that this should be part of the design phase, but a friend of mine advised me otherwise.  He said that at least initially (especially when you don't have very many projects under your belt), you don't always have a good feel for the architecture of your code. As such, it may change several times in the early phases as you figure out the best place for classes and methods in the structure of your code.  He recommended writing it all in one file at first and make clear section breaks to group pieces of code together.  This has a few advantages.  First, as you work, you can rearrange things as many times as you'd like as you begin to figure out where stuff should go.  Second, because everything is still in one file, it's easier to test your code and not accidentally break it since you don't have to worry about dependencies. Then, once you've gotten several hundred lines of code written, you can break it up into different files and make sure all the dependencies work before continuing along your merry way.  I imagine I'll get to this point before the end of next week, but we'll see how well the layouts go.

Now that I've actually begun coding for my project, I've started practicing using Git. I read several threads this week trying learn how often I should be committing changes to my repository (repo).  Different people have slightly different suggestions, but I've settled on doing a commit anytime I've added a thing that works.  So this week, that's been any time I've added code for a new dialog window and successfully tied its opening to a button or menu item click (in code-speak, that's binding a method to open said window once an event is triggered by the user clicking on something).  I do all these commits locally and then when I'm finished for the day, I push everything to the remote repo on my GitHub.  Right now this repo is private, but I will probably make it public once I release my app (which will hopefully be later this year).  I should also mention I'm doing this all on a different branch than the master.  I figured this is probably a good habit to get into for two reasons.  In the event I work on projects with other people, it's good to work on your own independent branch so as to minimize conflicts in code several people may be working on.  Working on a separate branch is also a good thing to do once an application is released into the wild, as it will mean changes only get made to the code once a new version is ready to be released to users, and that is something I may need to contend with in the future.

Saturday, January 16, 2021

Dynamic Programming with Python and More!

Last week I alluded to the fact that I've been working to improve and increase my Python skills using resources I've found online. One of those resources has been using Leetcode. I was initially inspired by an article, which I can't seem to find, that had a handful of recommended Leetcode exercises to try as part of preparation for a technical interview. While I haven't been working on any recently, I was finding that, by attempting them in Python and reading the comments on the exercise when I got stuck, I was expanding my knowledge of both Python and algorithms. In the coming weeks I hope to start working on more Leetcode problems.

freeCodeCamp is another resource that I highly recommend.  I think initially they started with courses in web development, covering HTML5, CSS, Java, and Javascript, among other things.  They've greatly expanded their resources in the time since I've discovered them.  I'm signed up for their weekly email digest and it includes links to five different articles and videos covering a variety of topics.  Their main YouTube channel now has a bunch of full-length courses.  One such course covers two dynamic programming techniques:  memoization and tabulation.  So far I've only finished the exercises in the memoization part of course and it has taken a bit of effort to translate from the Javascript code that is presented in the course to Python.

So what is dynamic programming?  In short, it is a way of optimizing recursive problems.  In the case of memoization, it allows a recursive program to remember values it learned in previous steps so that it doesn't have to find them again.  This method allows a programmer to reduce what is known as the time complexity of a problem, allowing larger initial inputs to run through the recursion faster.  And faster is better: everyone would prefer to sit waiting at a computer screen for less than a minute instead of an hour.

In Python, memoization can be a little tricky to implement, as I discovered.  The technique requires a memo dictionary to be added as an optional input to the recursive method.  The problem I encountered seems to have to do with how Python initializes keyword parameters, which didn't cause issues in the first few exercises of the course, but started interfering with later results.  After doing some googling, I discovered a work-around, which might not be the cleanest way of doing it, but it worked for me.  Instead of adding a keyword parameter that was an empty dictionary upon initialization, I set it to be a Nonetype.  Then, the first thing I checked for in the method was if it had a value of None. If it did, I created a empty dictionary; if not, I left it alone.

I have yet to finish the tabulation portion of the dynamic programming video course, but I'll keep you posted if I learn anything interesting. There are a few other videos on freeCodeCamp's channel covering algorithms that I would like to go through as well.  In the meantime, I've also started working on one of my Python projects.

This first project is a bit of a pet project that I've been wanting to do for a long time, and my learning goals for it have evolved over the years. Initially, I was just going to learn a database program, specifically Microsoft Assess, to build a searchable catalog for my own personal music library. I knew of an organist that had a note card catalog that he used to quickly search through his music. After giving it some thought, I decided I wanted a little more functionality than what note cards give, so I thought an electronic format might better serve my needs. I never got any further than that (being in grad school and all). Now, with my explorations in programming, I've decided I might as well go whole hog and write my own user interface.  (Did you know you can create GUIs in Python?  Neither did I.  Now we know!)  The added benefit of this is that I can distribute my program to my fellow church musicians for them to use as well.

Right now, I'm trying to finish up the design phase. I've laid out a top-down design chart with the functionality my program needs to have. There's a list of the information I need to include for each record. I have a couple of logic flowcharts describing what needs to happen for some of the functionality to work. Now I just need to finish sketching what various parts of the GUI should look like. This coming week I hope to have a GUI prototype finished so I can get feedback on the design from some friends of mine. How do I plan to build the GUI? As hinted above, I'm going to be using a toolkit (wxPython) to build it out. I already completed a toy application earlier this week to get a feel for how things are constructed.

Next week, in addition to my application's progress, I will share a little bit about what I'm picking up in perl.  Until then, I'll keep on coding!

Saturday, January 9, 2021

My Coding Journey

I've been out of school for about a year and a half now, and I'm still struggling with the whole job hunt business. After looking at an untold number of jobs postings, at this point I see how valuable coding skills are in a wide variety of fields. I also happen to enjoy learning about programming and trying my hand at what I pick up. Since I don't have a formal computer science background, I'm trying to learn as I go and hope the skills I'm picking up will be valuable in my job search.

I have also recently seen other people, through various platforms, talk about their own coding journeys. One thing I've gathered is that a lot of software engineers and developers are self-taught and came from a wide variety of backgrounds. For my own sake, to both document my journey and to process and retain what I'm learning, I thought I'd share a weekly digest of I'm discovering.

This week, being week number one, is going to be a brief overview of where I'm coming from. Next week, I'll cover some of the highlights of knowledge I've acquired in more recent months. From there, hopefully I can go into detail about the things I'm learning week by week.

The first exposure to programming that I can recall was in high school. I don't remember what class it was for, but I remember one of my teachers was offering extra credit if we could write a little calculator program to compute solutions to the quadratic equation. I had a friend at church who taught me how to do it. With the TI-89 I had at the time, it only took a few lines to create a little function that would take a quadratic equation as input and spit out two solutions for the given variable.

My next real coding experience came when I took an intro programming class in early college. The class was taught in C. I enjoyed the challenge of trying to write programming labs and the exhilaration of finally working out all of the bugs. I think I enjoy it for the same reason I enjoy math: there is nothing like that feeling of satisfaction when you've solved a problem after having struggled with it. So even though I enjoyed the class, I wasn't convinced I wanted to change my major to CS and spend the rest of my life behind a computer.

In my early years of college, I also had exposure to MATLAB and Maple. Aside from one math lab class, I never used Maple again.  In the same way, I didn't ever program in C after the lone programming class I took. MATLAB became a staple of programming for me, perhaps to a fault, as it was just about all I used in grad school.  

I transferred schools part way through college, and my second undergrad institute was where I had my first experience using LaTeX. LaTeX is another tool, alongside MATLAB, that became indispensable to me in grad school. It's still something I use occasionally, as I find it to be superior to word processors for writing and formatting certain documents.

While in grad school, I tried at one point to pick up some Mathematica. It can be a powerful teaching tool, but since I wasn't planning on teaching after graduating and I didn't really need it for any of my own coursework and research, I ended up not spending a lot of time on it. In part it's because I found it rather obtuse. It's also heavily symbolic, which works great for some things, but I really just didn't like using it.

It took me long enough to realize, but finally at the end of grad school, I knew I needed to expand my coding horizons, especially since I knew it would make me more marketable. I started with Python. Python can be used for a variety of applications, and I figured the best starting place for me would be through data science. I signed-up for edX and worked my way through a Python for data science course taught by a fellow from MIT. Since my completion of the class, I've tried to continue to expand my knowledge through coding exercises on Leetcode and by working through additional material I find out on the interwebs. More on this next week.

I've dabbled in a few other things along the way. For the internship I had one summer in grad school, I had to pick up some Visual Basic, which I haven't used since. I tried a bit of HTML5 and CSS at some point and later started an edX course on basic SQL. Neither of these things are things I stuck with. I was thinking about doing some mobile app development. Dart and flutter were going to be my weapons of choice. I might yet endeavor this pursuit.

Git and perl are two things I have been working on. I really wish I would have learned some basic Git early in grad school. It will come in handy as I start a few personal coding projects. Perl is currently what I'm focusing most of my energy on. Of course, I feel like I would be doing it wrong if I wasn't using the llama book. If you're looking for an entertaining technical read, the llama book is it. It's also not bad as a learning tool.

Taking a look back on my coding journey up to this point in time, I notice I have a lot of aspirations, languages and skills I think it would be neat to learn, but the depth of my knowledge is still very much lacking. One of my goals this year is to change that. A tangible measure of my progress will be the completion of, or at least actual progress on, some personal projects. Stay tuned in the coming weeks for discussions on Python and perl topics and descriptions of two projects I will be kicking off with.