The Renegade Coder https://therenegadecoder.com Code First. Ask Questions Later. Sat, 15 Feb 2020 04:43:37 +0000 en-US hourly 1 https://wordpress.org/?v=5.3.2 https://i0.wp.com/therenegadecoder.com/wp-content/uploads/2017/05/the-renegade-coder-icon-cropped.png?fit=32%2C32&ssl=1 The Renegade Coder https://therenegadecoder.com 32 32 127809749 The Remainder Operator Works on Doubles in Java https://therenegadecoder.com/code/the-remainder-operator-works-on-doubles-in-java/ https://therenegadecoder.com/code/the-remainder-operator-works-on-doubles-in-java/#respond Mon, 17 Feb 2020 15:00:00 +0000 https://therenegadecoder.com/?p=22050

The remainder operator is a staple in Java, but did you know it works on doubles as well? Now, you know!

The post The Remainder Operator Works on Doubles in Java appeared first on The Renegade Coder.

]]>

I’ve been teaching at OSU for nearly two years, and it always astounds me how much I learn from my students. For instance, in the past, I’ve had students write strange pieces of code that I didn’t understand. At this point, even after 300+ blog posts, several YouTube videos, and even collecting code snippets from over 100 languages, you’d think I’d seen it all. Well, recently, I saw a student using the remainder operator (%) on doubles, and I haven’t really been the same since.

Table of Contents

Remainder vs. Modulus Operator

Before I get into the story, I wanted to come along and make a distinction between the remainder operator and the modulus operator. In Java, there is no modulus operator. Instead, % is the remainder operator. For positive numbers, they are functionally equivalent. However, once we start playing with negative numbers, we’ll see a surprising difference.

I’ve talked about this difference a bit already in an article about RSA encryption. That said, I found another great source which compares the “modulo” operator in various languages including Java, Python, PHP, and C.

To summarize, the remainder operator works exactly as we’d expect it to function with positive numbers. For example, if we take 3 % 5, we’d get 3 because 5 doesn’t go into 3 at all. If we start playing around with negative numbers, the results are similar. For instance, if we take 3 % -5, we’d still get three because that’s all that is left over.

Meanwhile, if we flip the script and make the dividend negative—after all, remainder is a byproduct of division—we’d start to see negative remainders. For example, -3 % 5 returns -3. Likewise, -3 % -5 returns -3.

Notice how in all these examples we get the same results with some variation on the sign. In other words, with the remainder operator, we aren’t too concerned with signs. All we want to know is how many times one number goes into another number. Then, we peek at the dividend to determine the sign.

On the flip side, the modulo operator has quite a bit more nuance. For starters, the operand on the right side determines the range of possible return values. If that value is positive, the result will be positive. That’s a bit different from our remainder operator.

Meanwhile, the left operand determines the direction we cycle through the range of possible values. Naturally, this lines up perfectly with the remainder operator when both values have the same sign. Unfortunately, they’re completely different in any other circumstance:

ExpressionJava (Remainder)Python (MOD)
3 % 533
3 % -53-2
-3 % 5-32
-3 % -5-3-3

If you’re interested in learning more about modular arithmetic, another student inspired me to write an article on the game Rock Paper Scissors using modular arithmetic.

Remainder Operator on Doubles

When we think about the remainder operator, we often assume that it works exclusively with integers—at least up until recently that was my understanding. As it turns out, the remainder operator actually works on floating point numbers, and it makes sense.

Inspiration

Earlier this month, I was working with a student on a lab which asked them to write a coin change program. Specifically, this program was supposed to accept a number of cents from the user and output the denominations in American currency (e.g. dollars, half dollars, quarters, dimes, nickels, and pennies).

If you’re thinking about how you would solve this problem, I’ll give you a hint: you can take a greedy approach. In other words, pick the largest coin first and compute how many of them divide into your current number of cents. If you do it right, you don’t even need an control flow. However, you can clean up your code a bit with an array and a loop. Since I’m too lazy to write up a solution in Java, here’s what it might look like in Python:

cents = 150
dollars = cents // 100
cents %= 100
half_dollars = cents // 50
cents %= 50
quarters = cents // 25
cents %= 25
dimes = cents // 10
cents %= 10
nickels = cents // 5
cents %= 5
pennies = cents
print(f'{dollars}, {half_dollars}, {quarters}, {dimes}, {nickels}, {pennies}')

At any rate, I had a student who interpreted cents as dollars and cents. In other words, they let their user enter dollar amounts like $1.50 rather than 150 cents. To be fair, that isn’t a huge deal. All we have to do is multiply the dollar amount by 100 and add the leftover cents to get an integer.

However, that’s not what this student did. Instead, they treated each denomination as a double (i.e. a real number). Then, they proceeded to use the remainder operator without any consequences. Simply put, I was dumbfounded. After all, how could that possibly work? You only calculate a remainder on long division, right? Otherwise, you’re left with a decimal and nothing left over—or so I thought.

Using Doubles

If we were to rewrite the program above using dollars and cents, we might have something that looks like the following:

cents = 1.50
dollars = cents // 1
cents %= 1
half_dollars = cents // .50
cents %= .50
quarters = cents // .25
cents %= .25
dimes = cents // .10
cents %= .1
nickels = cents // .05
cents %= .05
pennies = cents // .01
print(f'{dollars}, {half_dollars}, {quarters}, {dimes}, {nickels}, {pennies}')

And if we run this, we’ll get exactly the same result as before: one dollar and one half dollar. How is that possible?

As it turns out, calculating the remainder using decimals is perfectly valid. All we need to do is compute how many times our dividend goes completely into our divisor. For example, .77 % .25 would “ideally” yield .02 because that’s as close as we can get to .77 without going over.

Caveats

After finding out that it’s possible to take the remainder of a decimal, I immediately wondered why I hadn’t known about it sooner. Of course, a quick Google search shows you all sorts of erroneous behavior that can arise.

For instance, in the previous example, I claimed that .02 would be the remainder of .77 and .25, and it would be, kinda. See, in most programming languages, the default floating point values have a certain precision that is dictated by the underlying binary architecture. In other words, there are decimal numbers that cannot be represented in binary. One of those numbers just so happens to be the result of our expression above:

>>> .77 % .25
0.020000000000000018

When working with real numbers, we run into these sort of issues all the time. After all, there are a surprising number of decimal values that cannot be represented in binary. As a result, we end up with scenarios where rounding errors can cause our change algorithm to fail. To prove that, I rewrote the solution above to compute change for the first 200 cents:

for i in range(200):
    cents = (i // 100) + (i / 100) % 1
    expected = cents
    dollars = cents // 1
    cents %= 1
    half_dollars = cents // .50
    cents %= .50
    quarters = cents // .25
    cents %= .25
    dimes = cents // .10
    cents %= .1
    nickels = cents // .05
    cents %= .05
    pennies = cents // .01
    actual = dollars + half_dollars * .50 + quarters * .25 + dimes * .10 + nickels * .05 + pennies * .01
    print(f'{expected}: {actual}')

For your sanity, I won’t dump the results, but I will share a few dollar amounts where this algorithm fails:

  • $0.06 (fails when computing nickels: .06 % .05)
  • $0.08 (fails when computing pennies: .03 % .01)
  • $0.09 (fails when computing nickels: .09 % .05)
  • $0.11 (fails when computing dimes: .11 % .1)
  • $0.12 (fails when computing dimes: .12 % .1)
  • $0.13 (same issue as $0.08)
  • $0.15 (fails when computing dimes: .15 % .1)
  • $0.16 (same issue as $0.06)

Already, we’re starting to see an alarming portion of these calculations fall prey to rounding errors. In the first 16 cents alone, we fail to produce accurate change 50% of the time (ignoring 0). That’s not great!

In addition, many of the errors begin to repeat themselves. In other words, I suspect that this issue gets worse with more cents as there are more chances for rounding errors along the way. Of course, I went ahead and modified the program once again to actually measure the error rate:

errors = 0
for i in range(1000000):
    cents = (i // 100) + (i / 100) % 1
    expected = cents
    dollars = cents // 1
    cents %= 1
    half_dollars = cents // .50
    cents %= .50
    quarters = cents // .25
    cents %= .25
    dimes = cents // .10
    cents %= .1
    nickels = cents // .05
    cents %= .05
    pennies = cents // .01
    actual = dollars + half_dollars * .50 + quarters * .25 + dimes * .10 + nickels * .05 + pennies * .01
    errors += 0 if expected == actual else 1
print(f"{(errors/1000000) * 100}% ERROR")

Now, I should preface that this code snippet compares real numbers using == which is generally considered bad practice. As a result, it’s possible we count a few “correct” solutions as incorrect. That said, I think this is a good enough estimate for now.

When I ran it, I found that 53.850699999999996% of all change calculations were incorrect. Ironically, even my error calculation had a rounding issue.

Should You Use the Remainder Operator on Doubles?

At this point, we have to wonder if it makes sense to use the remainder operator on doubles in Java. After all, if rounding errors are such an issue, who could ever trust the results?

Personally, my gut would say avoid this operation at all costs. That said, I did some digging, and there are a few ways around this issue. For instance, we could try performing arithmetic in another base using a class which represents floating point values as a string of integers (like the Decimal class in Python or the BigDecimal class in Java).

Of course, these sort of classes have their own performance issues, and there’s no way to get away from rounding errors in base 10. After all, base 10 can’t represent values like one third. That said, you’ll have a lot more success with the remainder operator.

At the end of the day, however, I haven’t personally run into this scenario, and I doubt you will either. Of course, if you’re here, it’s likely because you ran into this exact issue. Unfortunately, I don’t have much of a solution for you.

At any rate, thanks for stopping by. If you found this article interesting, consider giving it a share. If you’d like more content like this to hit your inbox, head on over to my newsletter page and drop your email address. In addition, you can support The Renegade Coder by becoming a Patron, browsing the shop, or doing one of these weird things.

While you’re here, check out one of these related articles:

Otherwise, thanks for taking some time to check out my site! I appreciate it.

The post The Remainder Operator Works on Doubles in Java appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/the-remainder-operator-works-on-doubles-in-java/feed/ 0 22050
How to Compare Strings in Python: Equality and Identity https://therenegadecoder.com/code/how-to-compare-strings-in-python/ https://therenegadecoder.com/code/how-to-compare-strings-in-python/#respond Fri, 14 Feb 2020 15:00:00 +0000 https://therenegadecoder.com/?p=20721

In Python, if you want to compare strings, you need to understand the difference between equality and identity.

The post How to Compare Strings in Python: Equality and Identity appeared first on The Renegade Coder.

]]>

Once again, we’re back with another Python topic. Today, we’ll talk about how to compare strings in Python. Typically, I try to stay away from strings because they have a lot of complexity (e.g. different languages, implementations, etc.). That said, I decided to take a risk with this one. Hope you like it!

As a bit of a teaser, here’s what you can expect in this article. We’ll be looking at a few different comparison operators in Python including ==, <, <=, >=, and > as well as is. In addition, we’ll talk about how these operators can be used to compare strings and when to use them. If you want to know more, you’ll have to keep reading.

Table of Contents

Problem Description

Let’s imagine we’re building up a simple search engine. For example, we have a bunch of files with text in them, and we want to be able search through those documents for certain keywords. How would we do that?

At the core of this search engine, we’ll have to compare strings. For instance, if we search our system for something about the Pittsburgh Penguins (say, Sidney Crosby), we’ll have to look for documents that contain our keyword. Of course, how do we know whether or not we have a match?

Specifically, we want to know how we can compare two strings for equality. For example, is “Sidney Crosby” the same as “Sidney Crosby”? How about “sidney crosby”? Or even “SiDnEy CrOsBy”? In other words, what constitutes equality in Python?

Of course, equality isn’t the only way to compare strings. For example, how can we compare strings alphabetically/lexicographically? Does “Malkin” come before or after “Letang” in a list?

If any of these topics sound interesting, you’re in luck. We’ll cover all them and more in this article.

Solutions

In this section, we’ll take a look at a few different ways to compare strings. First, we’ll look at a brute force solution which involves looping over each character to check for matches. Then, we’ll introduce the comparison operators which abstract away the brute force solution. Finally, we’ll talk about identity.

Compare Strings by Brute Force

Since strings are iterables, there’s nothing really stopping us from writing a loop to compare each character:

penguins_87 = "Crosby"
penguins_71 = "Malkin"
is_same_player = True
for a, b in zip(penguins_87, penguins_71):
  if a != b:
    is_same_player = False
    break

In this example, we zip both strings and loop over each pair of characters until we don’t find a match. If we break before we’re finished, we know we don’t have a match. Otherwise, our strings are “identical.”

While this gets the job done for some strings, it might fail in certain scenarios. For example, what happens if one of the strings is longer than the other?

penguins_87 = "Crosby"
penguins_71 = "Malkin"
penguins_59 = "Guentzel"

As it turns out, zip() will actually truncate the longer string. To deal with that, we might consider doing a length check first:

penguins_87 = "Crosby"
penguins_71 = "Malkin"
penguins_59 = "Guentzel"
is_same_player = len(penguins_87) == len(penguins_59)
if is_same_player:
  for a, b in zip(penguins_87, penguins_59):
    if a != b:
      is_same_player = False
      break

Of course, even with the extra check, this solution is a bit overkill and likely error prone. In addition, this solution only works for equality. How do we check if a string is “less” than another lexicographically? Luckily, there are other solutions below.

Compare Strings by Comparison Operators

Fun fact: we don’t have to write our own string equality code to compare strings. As it turns out, there are several core operators that work with strings right out of the box: ==, <, <=, >=, >.

Using our Penguins players from above, we can try comparing them directly:

penguins_87 = "Crosby"
penguins_71 = "Malkin"
penguins_59 = "Guentzel"

penguins_87 == penguins_87  # True
penguins_87 == penguins_71  # False
penguins_87 >= penguins_71  # False
penguins_59 <= penguins_71  # True

Now, it’s important to note that these comparison operators work with the underlying ASCII representation of each character. As a result, seemingly equivalent strings might not appear to be the same:

penguins_87 = "Crosby"
penguins_87_small = "crosby"

penguins_87 == penguins_87_small  # False

When we compare “Crosby” and “crosby”, we get False because “c” and “C” aren’t equivalent:

ord('c')  # 99
ord('C')  # 67

Naturally, this can lead to some strange behavior. For example, we might say “crosby” is less than “Malkin” because “crosby” comes before “Malkin” alphabetically. Unfortunately, that’s not how Python interprets that expression:

penguins_87_small = "crosby"
penguins_71 = "Malkin"

penguins_87_small < penguins_71  # False

In other words, while these comparison operators are convenient, they don’t actually perform a case-insensitive comparison. Luckily, there are all sorts of tricks we can employ like converting both strings to uppercase or lowercase:

penguins_87_small = "crosby"
penguins_71 = "Malkin"

penguins_87_small.lower() < penguins_71.lower()
penguins_87_small.upper() < penguins_71.upper()

Since strings in Python are immutable like most languages, these methods don’t actually manipulate the underlying strings. Instead, the return new ones.

All that said, strings are inherently complex. I say that has a bit of a warning because there are bound to be edge cases where the solutions in this article don’t work as expected. After all, we’ve only scratched the surface with ASCII characters. Try playing around with some strings that don’t include English characters (e.g. 🤐, 汉, etc.). You may be surprised by the results.

Compare Strings by Identity

Before we move on, I felt like it was important to mention another way of comparing strings: identity. In Python, == isn’t the only way to compare things; we can also use is. Take a look:

penguins_87 = "Crosby"
penguins_71 = "Malkin"
penguins_59 = "Guentzel"

penguins_87 is penguins_87  # True
penguins_87 is penguins_71  # False

Here, it’s tough to see any sort of difference between this solution and the previous one. After all, the output is the same. That said, there is a fundamental difference here. With equality (==), we compare the strings by their contents (i.e. letter by letter). With identity (is), we compare the strings by their location in memory (i.e address/reference).

To see this in action, let’s create a few equivalent strings:

penguins_87 = "Crosby"
penguins_87_copy = "Crosby"
penguins_87_clone = "Cros" + "by"
penguins_8 = "Cros"
penguins_7 = "by"
penguins_87_dupe = penguins_8 + penguins_7

id(penguins_87)        # 65564544
id(penguins_87_copy)   # 65564544
id(penguins_87_clone)  # 65564544
id(penguins_87_dupe)   # 65639392 Uh Oh!

In the first three examples, the Python interpreter was able to tell that the constructed strings were the same, so the interpreter didn’t bother making space for the two clones. Instead, it gave the latter two, penguins_87_copy and penguins_87_clone, the same ID. As a result, if we compare any of the first three strings with either == or is, we’ll get the same result:

penguins_87 == penguins_87_copy == penguins_87_clone  # True
penguins_87 is penguins_87_copy is penguins_87_clone  # True

When we get to the last string, penguins_87_dupe, we run into a bit of an issue. As far as I can tell, the interpreter isn’t able to know what the value of the expression is until runtime. As a result, it creates a new location for the resulting string—despite the fact that “Crosby” already exists. If we modify our comparison chains from above, we’ll see a different result:

penguins_87 == penguins_87_copy == penguins_87_clone == penguins_87_dupe # True
penguins_87 is penguins_87_copy is penguins_87_clone is penguins_87_dupe # False

The main takeaway here is to only use == when comparing strings for equality (an any object for that matter). After all, there’s no guarantee that the Python interpreter is going to properly identify equivalent strings and give them the same ID. That said, if you need to compare two strings for identity, this is the way to go.

Challenge

Normally, I would check each solution for performance, but they’re not all that similar. Instead, I figured we could jump right to the challenge.

Now that we know how to compare strings in Python, I figured we could try using that knowledge to write a simple string sorting algorithm. For this challenge, you can assume ASCII strings and case sensitivity. However, you’re free to optimize your solutions as needed. All I care about is the use of the operators discussed in this article.

If you need a sample list to get started, here’s the current forward roster for the Pittsburgh Penguins (reverse sorted alphabetically):

penguins_2019_2020 = [
  'Tanev', 
  'Simon', 
  'Rust', 
  'McCann', 
  'Malkin', 
  'Lafferty', 
  'Kahun', 
  'Hornqvist', 
  'Guentzel', 
  'Galchenyuk', 
  'Di Pauli', 
  'Crosby', 
  'Blueger', 
  'Blandisi', 
  'Bjugstad', 
  'Aston-Reese'
]

When you’re finished, drop your solution in the comments below. Then, head on over to my article titled How to Sort a List of Strings in Python to see a few clever solutions.

A Little Recap

And with that, we’re all done. Check out all the solutions here:

penguins_87 = "Crosby"
penguins_71 = "Malkin"
penguins_59 = "Guentzel"

# Brute force comparison (equality only)
is_same_player = len(penguins_87) == len(penguins_59)
if is_same_player:
  for a, b in zip(penguins_87, penguins_59):
    if a != b:
      is_same_player = False
      break

# Direct comparison
penguins_87 == penguins_59  # False
penguins_87 > penguins_59  # False
penguins_71 <= penguins_71  # True

# Identity checking
penguins_87 is penguins_87  # True
penguins_71 is penguins_87  # False

If you liked this article, consider showing your support by hopping on the mailing list, becoming a patron, or browsing the shop. Otherwise, check out some of these related articles:

Likewise, here are a few resources you might benefit from on Amazon (ad):

If nothing else, thanks for taking some time to check out this article. See you next time!

The post How to Compare Strings in Python: Equality and Identity appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/how-to-compare-strings-in-python/feed/ 0 20721
How to Clean up WordPress Tags https://therenegadecoder.com/meta/how-to-clean-up-wordpress-tags/ https://therenegadecoder.com/meta/how-to-clean-up-wordpress-tags/#respond Mon, 10 Feb 2020 15:00:00 +0000 https://therenegadecoder.com/?p=21490

At some point, we all have to perform a little website maintenance. How about today we talk about how to clean up WordPress tags.

The post How to Clean up WordPress Tags appeared first on The Renegade Coder.

]]>

To kick off the new year, I decided to do some website maintenance. In particular, I finally decided to tackle the mess that was my tagging system. Now, instead of rocking 400+ tags, I have just 53 of them. Let’s talk about what I learn and how you can clean up WordPress tags too.

Table of Contents

What Are WordPress Tags?

In the WordPress, there are various ways of organizing content. For instance, there are categories which can be used to set up a hierarchy of content. Let’s say we started a pop culture blog, and we decided that our three main topics would be music, movies, and podcasts. Those three topics would become our website’s categories.

If we had enough content, we might even break those categories into subcategories. For example, perhaps we could break up movies into genres (e.g. horror, comedy, drama, etc.). These new categories would nest under the core category, movies. Then, we might include these categories along our main navigation bar. If a user were to hover over movies, they’d also see our three subcategories.

Outside of navigation, categories may also show up in the post URL. In my case, I used categories as an indicator in the URL of what kind of content you’ll be reading. For example, this post is filed under meta because it focuses primarily on maintenance of my website—even though I’m structuring this article like a how-to guide.

All of this information about categories is important because it contrasts significantly with another content organization technique known as tagging. Unlike with categories, multiple tags can be used to link together similar types of content. For example, our pop culture blog might have the following two articles:

  • Rihanna Knocks it out of the Park in Ocean’s 8
  • Top 10 Rihanna Songs of the Decade

One of these articles would be categorized under movies while the other would be categorized under music. That said, there’s clearly a thread linking these two articles together: Rihanna. If we want our users to be able to enjoy all content related to Rihanna, we need some way to group that content. This is where tags come in.

How to Use WordPress Tags

If we keep going with the scenario from above, we should probably create a tag to string together all the Rihanna related content. To do that, we can go right into our editor for one of the articles, type “Rihanna”, and hit enter. That will create the tag and apply it to that post only:

Adding Tag to WordPress Article

If we want to add that tag to all Rihanna related content, we’ll have to take advantage of the bulk edit feature under “All Posts”:

Bulk Editing Tags in WordPress

With this window, we can add our tag to the “Tags” box and click “Update”.

Naturally, we can to do this for any tag we like. On a pop culture blog, we might have tags for various celebrities and artists like Justin Bieber, Lady Gaga, and more. Likewise, we might have tags for studios, record labels, directors, movies, Netflix series, etc.

If we don’t plan out our content, we may find ourselves adding these sort of tags any time we make an article. For example, maybe we write an article about the latest Godzilla movie and give it the following tags:

  • Millie Bobby Brown
  • Godzilla
  • Kyle Chandler
  • English
  • Warner Bros. Pictures

To us, all these tags make sense because they serve as metadata for our content. In other words, users might be interested in other movies in English, so we figured it was important to include that tag. In fact, we can use this sort of argument for all our tags.

The Downside of Using WordPress Tags

Unfortunately, the sporadic tagging argument doesn’t really hold up. In reality, if we just tag every article with our main keywords, we’re likely to watch our list of tags explode. For instance, let’s say we add five tags to every article for 100 articles. At best, we collect 5 tags—albeit mostly useless. At worst, we’re sitting on 500 unique tags—also useless.

While the sheer number of tags is an issue, there are other issues as well. For example, let’s say we only have 20 tags, but 15 of them are unique. In other words, those tags only link to one article each. What sort of value is that serving our users? Some might say none. I’d argue it’s actually worse than having no tags at all. After all, how annoying would it be to stumble upon a tag that doesn’t bring us to at least one other post?

Beyond the maintenance and usability issues, there are actually other tagging related issues. For instance, tags can be redundant, overlap, or share similar scope. If we have two tags, “Film” and “Films”, how do we know which one to use? How do we know which way to interpret the tag “Film”? Is it like camera film or a movie? What about tags that are synonyms like “Film” and “Movie”?

Finally, there’s one major issue with tags that I alluded to already: they create tag archive pages. Just like categories, every new tag generates a new archive page which can be used to share all articles with the same tag. If we have 500 tags and only 100 articles, we have nearly five times as many pages with almost no value. That’s a bad recipe for success.

WordPress Tagging Strategies

Clearly, all sorts of issues can come up when tagging, and it can be hard to manage this issue once it spirals out of control. That’s why it’s important to have a basic tagging strategy. In this section, we’ll take a look at a few things we can do to manage our tags better.

Get Rid of Tags Altogether

One tagging strategy that is becoming increasingly common in the WordPress space is to eliminate tags altogether. Since they’re such a pain to begin with, why even bother? After all, what’s the real benefit of tagging?

For most people, this is probably the way to go. Instead of managing tags, just don’t use them at all. That way, there are no tag archive pages to manage, and there’s no potential negative hit to SEO.

Of course, if we choose not to use tags, we lose out on the potential benefit that tag archives could have on our users. For example, let’s say our users want to learn more about Rihanna. Without a tag page, we’d have to be more deliberate in our internal linking strategy. In other words, we’d have to make sure to link new Rihanna content in older articles which can be a tiring but rewarding process. Instead, we might opt for tags.

Track Keywords in a Spreadsheet

One of the challenges with tagging is that you can’t just start tagging without a plan. In other words, it’s a good idea to take an inventory of your content and track keywords in a spreadsheet. That way, you can get an idea of what articles are related. Then, you can come up with tags.

To continue with our pop culture blog example, I might list out every blog post in a spreadsheet. For instance, we already mentioned the two Rihanna related articles:

  • Rihanna Knocks it out of the Park in Ocean’s 8
  • Top 10 Rihanna Songs of the Decade

Place these in separate rows and add a few columns for metadata:

TitleCategoryKeywords
Rihanna Knocks it out of the Park in Ocean’s 8MoviesRihanna, Comedy
Top 10 Rihanna Songs of the DecadeMusicRihanna, Pop

Then, we might write a small function which totals each keyword and places the results in a separate table:

KeywordFrequency
Rihanna2
Comedy1
Pop1

From this table, we can start to see what could make for a good tag. With a blog this small, we might not want to create any. However, as we build up our catalog, we can start to see trends in our content. If we find the right niche, the tags should pretty much write themselves.

Plan Out Niche

Instead of letting tags come out organically, we might try planning out our niche first. In other words, we could decide our first 30 articles based on our vision of the future site. Then, we can anticipate what some our tags will be.

Again, using our pop culture blog example, we might decide that we want to focus on Eminem related content. If that’s the case, we can start picking our keywords before we write. Naturally, those keywords can flow right into tags.

In this case, it’s probably still a good idea to draft a spreadsheet in the same form as above—even if the content is tentative. At least that way, we know we aren’t constructing tags in vain.

WordPress Tag Cleaning Strategies

Note: Before you go through this process, understand that it’s not necessarily linear. For example, you may find duplicate tags in the process of merging smaller tags into more general topics. As a result, you should think about doing several passes of your tags for each of the following steps. Eventually, you’ll be able to reduce your overall tag count to something manageable.

Unfortunately, most of you are probably here because you didn’t do any planning. Luckily for you, I was in this exact situation at the start of the year. In fact, I probably had over to 400 tags with about half of them unique.

Assess the Situation

If you don’t believe me, here’s my coverage according to Google Search Console:

Google Search Console All URLs for The Renegade Coder

Essentially, this is a graph of every known page on my website over the past three months. As you can see, Google has indexed roughly 958 pages on a blog with only about 330 articles. As of January first, there were 675 pages indexed that were also submitted in my sitemap:

Google Search Console Submitted and Indexed URLs for The Renegade Coder

If you take a look at what content is being indexed, you’ll see a huge list of URLs. With a quick Google search, I was able to write the following Excel formula which computes the number of URLs that include “/tag/”:

=COUNTIF(A:A, "*/tag/*")

According the formula, there were 261 pages. Naturally, I had to run the same formula on the indexed URLs that weren’t submitted. In that case, the formula returned 109. Naturally, I decided to run the same formula on the list of URLs that weren’t indexed. That returned 335!

At that point, I realized my mistake. Apparently, all pages (including tag pages) have RSS feeds. Naturally, these feeds are not submitted or indexed, so I had to find a way to exclude them from my count. To do that, I ran a similar formula that didn’t count anything including “/feed/”:

=COUNTIFS(A:A, "*/tag/*", A:A, "<>*/feed/*")

My thought behind this formula was to count everything that including “/tag/” and ignore everything that included “/feed/”. As a result, it returned 96. If we add the three totals together, we get something like 466 which seems right.

Naturally, you don’t have to go through this much work to figure out how many tags you have. You can go straight to the tags page and check for yourself. In my case, I started writing this piece after I had already finished, so my tag page looks like this:

WordPress Tag Page 2020

At any rate, let’s talk about how we can actually go about achieving this kind of reduction.

Consolidate Duplicate Tags

One way we can begin to reduce our number of tags is to consolidate duplicate tags. In other words, we need a way to identify tags that are similar and merge them.

On the first pass, we might try sorting the tags alphabetically. That way, we can catch plural and singular forms of the same term. In addition, we might be able to catch some misspellings or synonyms. When we do, we need to find each article with the incorrect tag and replace that tag with the correct one.

To do this, we can take advantage of the bulk edit tool. First, we’ll identify a tag that we want to replace, go to posts, and search for that tag. Then, we’ll select all articles with that tag and bulk add the correct tag. At that point, it’s just a matter of deleting the incorrect tag.

Feel free to follow this process for a little while. As you grow more acquainted with your massive catalog of tags, you’ll find that it becomes easier to spot duplicates.

Remove Junk Tags

After passing over our tags a few times, we should be able to easily identify tags that are useless. For example, there are probably dozens of tags that were created for one-off topics. We can delete them outright.

Before we get too delete happy, it might be a good idea at this point to take a look at the articles with junk tags. Are these old articles that aren’t really relevant to our readers, or are they still related to the rest of our content? If the answer is the latter, then we should probably apply appropriate tags while removing the junk ones.

As this junk removal process continues, we should begin to see our network of connected posts grow. In other words, each junk tag that gets removed is replaced by zero or more proper tags. As a result, old content finds its way in front of new eyes through appropriate tagging.

Over time, we’ll get more comfortable with the existing tags. This will set us up well for the next step.

Merge Specific Tags Into More General Topics

For me, the process of removing junk and duplicate tags was great, but it wasn’t helping me deal with my main issue: most of my tags were still extremely valid. For instance, I had tags for just about every piece of the software development life cycle (e.g. pull requests, continuous integration, deployment, version control, etc.).

Unfortunately, these tags were so narrow that there may only have been two or three posts that even mentioned the topic. As a result, I decided to merge many of them into my more general Software Development tag.

For our pop culture blog example, that means going through our tags and determining what the general themes and ideas are. For instance, if our blog focuses on Rihanna, we might have tags down to song titles (e.g. Umbrella, Shut Up and Drive, etc.). Clearly, we could abstract them a bit into album titles. Then, if we end up writing 10+ articles on Umbrella, we could reintroduce the tag.

As this merging process continues, we’ll start to notice more overall trends for the site. These trends are important for understanding the identity of our own site. In the end, it becomes a cool meta-analysis of our own writing.

Reap the Benefits of Fewer Tags

For me, one of the biggest benefits of going through this process is knowing all of my tags. As a result, I can use them to inspire my next article. For instance, one of my lowest count tags is Operators. As a result, I might try to create more content in that area. If I can’t come up with anything, I might delete that tag altogether.

In addition, knowing all my tags helps me figure out where future articles fit in my website structure. For example, an article teaching readers how to create a git repo falls right into my Version Control and Open Source Software tags.

Finally, I think knowing all my tags has helped me go through old articles for tagging purposes. In other words, I’m able to bring older content back into the mix by associating it with dozens of related articles. In the past, that article might not have many related posts in its network. Now, it leads people to boatloads of fresh content.

Bonus Tip: Give Descriptions to Your Tags

If your WordPress theme supports tag descriptions, I recommend adding them. While tag archives alone can helpful for directing readers around your site, the descriptions can be a great opportunity to explain the tag or even direct the reader to the most important content in that archive.

Personally, I use the descriptions to help give myself bounds for the tag, but that doesn’t stop me from also using them as calls to action. For example, here is my current description for the Hello World tag:

Hello World is a common program used to introduce language syntax. Naturally, the goal of the program is to print the “Hello, World!” string to the user. Articles with this tag demonstrate just that.


If you’re looking for somewhere to start, check out one of these articles:


Hello World in Every Language

Hello World in Python

Hello World in Java


If you just want to see some sample Hello World code, I have an entire GitHub repository dedicated to that sort of thing.

Naturally, this sort of description can set your archive page apart and perhaps even encourage Google to index it. After all, I’d love for my Python archive to show up for people looking for Python resources.

More realistically, however, I think this description just helps the page seem more valuable to Google. I don’t necessarily want it to rank well. I just don’t want it to contribute negatively to my site overall. After all, Google doesn’t like a high ratio of low quality pages.

How to Clean Up WordPress Tags Summary

At this point, that’s I’ve got. As a result, I figured I’d summarize some of the major points from this article, and let you get to work!

First, tags are a way of organizing content—similar to categories. However, instead of being hierarchical in nature, tags are meant to provide more of a network structure. After all, articles in different categories can still be connected by topics (e.g. a film article about Rihanna’s role in Ocean’s 8 and a music article about Rihanna’s song Umbrella).

Unlike categories, however, tags tend to get out of hand quickly. After all, what’s the appropriate scope for a tag? Luckily, there are some basic strategies for dealing for tags:

  • Don’t—forget ’em
  • Take note of existing articles and find connecting threads
  • Plan out niche and use general tags to indicate connecting threads

Of course, if you already have way too many tags like I did, consider using the following strategies:

  • Consolidate duplicate tags like synonyms (e.g. hat vs. cap), singulars and plurals (e.g. cat vs. cats), and misspellings (e.g. housing vs. hosing)
  • Remove junk tags like overly specific keywords from one-off articles (e.g. python list comprehensions)
  • Merge specific tags (e.g. flyers, ads, etc.) into more broad tags (e.g. marketing)

Eventually, you should get all your tags in order! Otherwise, feel free to share your own tips below in the comments.

If you enjoyed this piece, help me out by hopping on my mailing list, becoming a patron, or browsing the shop—every little bit helps! In addition, you can check out some of these related articles:

Otherwise, thanks for stopping by. I appreciate it!

The post How to Clean up WordPress Tags appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/meta/how-to-clean-up-wordpress-tags/feed/ 0 21490
Image Titler 1.5.2 Supports Logo Insertion https://therenegadecoder.com/meta/image-titler-1-5-2-supports-logo-insertion/ https://therenegadecoder.com/meta/image-titler-1-5-2-supports-logo-insertion/#respond Fri, 07 Feb 2020 15:00:00 +0000 https://therenegadecoder.com/?p=21879

It's been almost a year since I last updated the Image Titler tool, but now it supports logo insertion! Add your logo with just one option.

The post Image Titler 1.5.2 Supports Logo Insertion appeared first on The Renegade Coder.

]]>

During the first weekend of the semester, I got inspired to do some Python development. Out of the inspiration came the latest feature of the Image Titler took: logo insertion. In this article, we’ll take a look at what that means and how it was implemented.

Table of Contents

What Is Logo Insertion?

As far as names are concerned, logo insertion isn’t a formal term. It’s just what I’ve been calling the latest feature of the Image Titler script. Now, in addition to being able to add titles and borders to image, you can also insert your logo:

Notice how there’s now an image of my logo in the lower left corner. How cool is that?

Personally, I haven’t tried other logos, but I imagine you’ll get similar performance as long as it’s square. Otherwise, it’ll shrink one way or the other.

In any case, you can add a logo of your own with the following code:

pip install image-titler # in case you haven't already
image_titler -l "path/to/logo"

That will open up a prompt for you to select an image. Then, the tool will attempt to parse the file name (i.e. assumes - separators) and place it as a title on the image. Finally, the logo will be positioned in the lower left corner, and the image will be saved wherever you wrote this command.

How Does Logo Insertion Work?

Under the hood, we take advantage of the PIL library in Python. Essentially, we load two images: the background and the foreground. Then, we paste one onto the other:

def draw_logo(img: Image, logo_path: str):
    """
    Adds a logo to the image if a path is provided.

    :param img: an image to be modified
    :param logo_path: the path to a logo
    :return: nothing
    """
    if logo_path:
        logo = Image.open(logo_path, "r")
        logo.thumbnail(LOGO_SIZE)
        width, height = img.size
        img.paste(logo, (LOGO_PADDING, height - LOGO_SIZE[1] - LOGO_PADDING), logo)

As you can see, I wrote a draw_logo() function which takes a background image and a path to a logo. Then, if the logo path is present, we load the logo, convert it to a thumbnail of a particular size, and paste it onto the background image.

Here, the real magic is in the last line. In other words, we can the paste() function which takes a few inputs: the image file, its location, and a mask. In this case, we use the logo, and we calculate where to paste it using the height of the logo and the height of the background. Since we don’t want it perfectly in the corner, we add some padding.

If you’re interested in seeing the entire script, you can check it out here. Keep in mind that it’s a little rough around the edges, but it gets the job done. Feel free to fork it and modify it to your needs.

Any Other Changes?

While I was putting this feature together, I realized that there was this strange artifact showing up in my output images. Let me show you what I mean:

How to Write a Loop in Python Featured Image

Since I put the Image Titler tool together, I’d been generating images that look exactly like this one. If you don’t look to hard, there’s nothing to see. It’s just a regular featured image.

However, if you zoom in on the text, you’ll notice some strange artifacts. For instance, the red isn’t exactly solid—there are some darker shades mixed in. Overall, the image looks rather poor.

For awhile, I chalked this up to WordPress. After all, the previews that Image Titler generates are always extremely clean and clear. Unfortunately, that’s not the same quality you get when you save the image. Apparently, the save function does some compression which can actually be toggled off:

edited_image.save(storage_path, subsampling=0, quality=100)

Here, I set the quality to max and subsampling to zero. Now, images in v1.5.1 look exactly how I expect them to:

Of course, WordPress still does some minor distortion. If you want to compare the two raw images, try right clicking and selecting “open image in new tab.”

Outside of this change, I also updated the dimensions of the image in v1.5.2, so they conform more to my thumbnails:

Python Code Snippets for Everyday Problems Featured Image

Now, you’ll be able to see both the title and the logo on the archive pages of the website. How cool is that?!

Future Changes

At this point, I’m fairly satisfied with where the Image Titler tool is at. That said, there are a few outstanding issues I’d like to deal with at some point. In addition, I’m open to suggestions. Is there anything you’d like to see?

Otherwise, thanks for stopping by! If you’re interested in getting updates like this in your inbox, hop on my mailing list. I publish twice a week, and I always send both posts out in a Friday newsletter. In addition, you can support this project and others like it by becoming a patron or sponsor me directly on GitHub.

Here are a few related posts for your perusal:

Thanks for taking some time to check out this update! I appreciate the support.

The post Image Titler 1.5.2 Supports Logo Insertion appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/meta/image-titler-1-5-2-supports-logo-insertion/feed/ 0 21879
26 Songs That Made Me Who I Am Today https://therenegadecoder.com/blog/26-songs-that-made-me-who-i-am-today/ https://therenegadecoder.com/blog/26-songs-that-made-me-who-i-am-today/#respond Wed, 05 Feb 2020 15:00:00 +0000 https://therenegadecoder.com/?p=13102

For my 26th birthday, I put together a list of 26 songs that have shaped who I am today.

The post 26 Songs That Made Me Who I Am Today appeared first on The Renegade Coder.

]]>

Today is my 26th birthday, and like the last few years, I’ve decided to celebrate with a list of stuff! This time around I’m sharing 26 songs that have shaped my life up to this point.

Table of Contents

Spotify Playlist

To kick off the list, I figured I’d put together a Spotify playlist for you. Feel free to browse the list, take a listen, then jump down to the rationale for each choice below.

Master List

In no particular order, I present to you the list of 26 songs that have defined my life up to this point. Feel free to share some of your own favorites in the comments below!

1. The Devil in My Bloodstream – The Wonder Years

Up first in the list is a sad song by one of my all-time favorite bands, The Wonder Years, called The Devil in My Bloodstream. Naturally, this song comes off my favorite The Wonder Years album, The Greatest Generation, which came out in mid-2013 right after I finished my first year of college.

For me, that first year was rough. For instance, I ended up dropping my music major while trying to balance an overwhelming amount of work. In addition, I had to get used to making mistakes without a strong support network.

Thankfully, this album helped me get through that first summer. In fact, I even went to Warped to see a few songs of this album performed live. Unfortunately, it wasn’t until almost a year later that I actually got to see this song performed live.

By that point, one of my friends had basically ruined this song for me. That said, I’m still a huge fan.

2. Hide and Seek – Imogen Heap

While Hide and Seek is a bit of a meme song, it used to be one of favorite songs. In fact, I attribute this song to getting me into new genres of music like indie and pop punk. Of course, I have my first high school relationship to thank for finding out about this song (#MixTapes).

One of the things I really love about this song is that it completely lacks instrumentals. In other words, the song is made up of layers of vocals from a single vocalist using a vocoder. I realize in 2020 that vocoders are sort of a meme, but this song does it well.

If you’ve never actually heard this song outside of the memes, I recommend checking it out. It’s unironically good. After all, even Jason Derulo thought it was good enough to sample.

3. Mokena – Real Friends

Around the time I graduated college, Real Friends released an album called The Home Inside My Head which featured a song called Mokena, which happens to be a town near Chicago.

At the time, I was really struggling to figure out my life. For instance, I was living alone and working a job I hated. To be quite honest, Mokena got me through most of that singlehandedly. Even now, I like to drive at night while blasting this song.

For some reason, this song really clicked with me because I spent a lot of time driving to and from Cleveland (see 2nd verse). In addition, I don’t like my hometown which was where I was working at the time. As a result, this song felt like it was speaking directly to me, so I probably listened to it 1,000 times.

On a side note, listening to this song always makes me think about how much winter sucks. Bleh.

4. Home – Michael Bublé

When I was growing up, I somehow found out about Michael Bublé , and I was HOOKED. In fact, I even bought his Michael Bublé Meets Madison Square Garden movie, and I watched that movie several times. How else would I know that he would have been playing for the Canucks if he weren’t a musician?

At any rate, I’m not really sure why I like this particular song so much. After all, it came out in 2005, but somehow it helped me get through a lot of different tough spots in my life. For instance, it helped me get through college as well as a long distance relationship.

Even now, I get a lot of value out of this song. Of course, home isn’t really a place for me. It’s more like a feeling.

5. Marigold – Mallory Run

In early 2018, one of my childhood best friends released an album called Spin as a part of their band, Mallory Run. On that album, you’ll find a song called Marigold, and it’s incredible.

At that point in my life, I had just quit my job and gotten married. Over the next six months, I was trying to find any way possible to make some money while I waited to start grad school. During that time, Marigold really helped me feel like I wasn’t alone despite living with just my wife nearly 1000 miles away from family and friends.

If you’re looking for something raw and real, I absolutely recommend this song.

6. What a Catch, Donnie – Fall Out Boy

When I first discovered What a Catch, Donnie, I was probably in high school—although I don’t really remember. Of course, at the time, I found the song on Fall Out Boy’s greatest hits album, Believers Never Die, while the band was separated.

Honestly, I’m not sure why I was so obsessed with this song. I guess I just have a thing for key changes and callbacks to old songs. Also, this song is really fun to sing, and I love me some vocal harmonies.

Like many of the songs in this list, I like to listen to this song when I’m going through a tough time. Although, I’ve probably burnt it out because I’m not enjoying it that much at the moment.

7. King for a Day – Pierce the Veil

The first time I heard Pierce the Veil I was at Darien Lake (I believe) for Warped Tour. At the time, it was nearly the end of the day, and my buddies and I were tired. As a result, we decided to sit around and listen to Pierce the Veil which I actually enjoyed.

Besides A Day to Remember and Precinct Aflame, I hadn’t actually listened to any “hardcore” music. At that point in my life, I was hard locked into pop punk, so Pierce the Veil was a nice contrast to that.

Eventually, I became obsessed with songs like King for a Day, Bulls in the Bronx, and Caraphernalia. Over time, these songs became my angsty summer anthems in between bouts of Eminem.

8. ’67, Cherry Red – Aaron West and The Roaring Twenties

To be honest, I’m not sure when I got into Aaron West, but I’ve seen him now twice: once in 2014 in Cleveland and again in 2019 in Columbus. If you haven’t listened to him, do yourself a favor and do it.

As some backstory, Aaron West is a fictional character created by Soupy of the Wonder Years. If that seems kind of weird, I don’t blame you. For Soupy, I think this was a chance to challenge himself to write and perform a fictional narrative. Needless to say, this project is phenomenal.

For me, Aaron West was sort of an offshoot of The Wonder Year. That said, while the vocalist is the same, the music is a bit more folksy, and the instrumentation is a lot more interesting (e.g. trumpets, trombones, saxophones, banjos, etc.).

Of course, what sold me on Aaron West was seeing him live. Soupy literally plays the character as if it were him, and it’s incredible. If you didn’t know who he was, you’d probably think Aaron West was a real person. I sometimes wonder how many people think he’s real.

Now, Aaron West is sort of long distance driving music for me. For instance, I spent a lot of time listening to him on drives from Atlanta to Erie and Columbus to Jersey. There’s something about listening to these records top to bottom that you just wouldn’t do with any other record.

All that said, my favorite song by far is “’67, Cherry Red”. I just love a song where the lyrics hit hard, and the instrumentals hit harder.

9. Are You Ready for This? – Freshman 15

Would you believe me if I said I learned how to harmonize vocals thanks to Freshman 15? When I was in a high school, a buddy of mine—the singer from Mallory Run—tipped me off on Freshman, and I’ve been hooked ever since.

As I’ve mentioned already, I love pop punk, and I think Freshman 15 perfectly encapsulates the genre (i.e. heavy guitar, double bass, clean vocals, and angst). Of course, what I love about Freshman 15 is their obsession with vocal harmonies which is something you don’t get in a lot of popular music.

As for a favorite song, I don’t really have one. That said, the song I’ve probably sang the most is “Are You Ready for This?” which is a nice commentary on the music industry. It’s really a shame these guys aren’t around anymore.

10. If It Means a Lot to You – A Day to Remember

If you want to know which band got me into the music I like today (e.g. indie and pop punk), look no further than A Day to Remember. I think most people in the early 2010s treated ADTR like a gateway drug. If you listened to them, chances are they got you hooked on related music.

For me, ADTR opened the doors to bands like Modern Baseball, Real Friends, The Wonder Years, State Champs, Patent Pending, Freshmen 15, Have Heart, etc. The list literally doesn’t end.

Oddly enough, I’ve never seen ADTR live. Meanwhile, I’ve seen almost every band in the previous list live. In other words, ADTR never really stuck with me, but their music had a huge impact on what I listen to today.

Of their entire catalog, I’m partial to “If It Means a Lot to You” which is a sad acoustic song—and you know I love ’em sad. That said, I love “Sometimes You’re the Hammer, Sometimes You’re the Nail”, “It’s Complicated”, “U Should Have Could Me When U Had the Chance”, and “Monument”.

11. 25 to Life – Eminem

While I was going through my pop punk “phase”, one artist stood by me: Eminem. He and I go way back—like all the way back to the early 2000s. Back then, I was just an awkward preteen, but I was hooked on songs like “Cleanin’ Out My Closet”, “Sing for the Moment”, and “The Real Slim Shady”.

As I got older, Eminem’s style grew and developed. By the time I was in high school, he dropped Relapse. Then, by the time I could drive, he dropped Recovery. Suddenly, I found myself blasting that album around my small town.

At the time, “Love the Way You Lie” was insanely popular. Of course, while the radio wore that song to death, I burned out “25 to Life” in my dad’s Jeep. Honestly, I’m not sure why I love that song. I think part of it is the narrative story telling, but I also just love the anti-authority/anti-establishment takeaway. As someone who prefers to do things their own way, “25 to Life” speaks to me.

12. Moonlight Serenade – Glenn Miller

Up to this point, I’ve talked mostly about music I grew up with. After all, each artist in this list until now was making music while I was growing up.

That said, I don’t just listen to modern music, nor do I recommend it. There’s so much more out there to experience. For instance, I’ve been playing trombone since 2005 (which recently prompted me to make a little niche site called Trill Trombone), and that experience has exposed me to music from many different eras and cultures. In all that time, I managed to stumble up Jazz, my favorite type of music outside the modern era.

To be fair, I could list a lot of Jazz pieces that I love. For instance, I’m a big Maynard Ferguson fan, so I love “Birdland” and “Hey Jude”. Likewise, I love Gordon Goodwin, so naturally I could have included “Count Bubba”. In addition, I spent some time in college playing more abstract charts from folks like Bill Dobbins and Paul Ferguson.

Of all the Jazz I’ve listened to over the years, I keep coming back to the classics. In particular, I’ll listen to pretty much anything released by Glenn Miller—especially anything on the emotional end like “Moonlight Serenade”. There’s just something about it that always pulls me back in.

13. Wasting Time – Four Year Strong

Around the same time that I got into A Day to Remember and Freshman 15, I also got into Four Year Strong. Also like those bands, I stopped listening to them awhile back. That said, if certain songs come on, you know I’m throwing down.

Before Warped Tour ended, I went to the Blossom Center with one with my buddies, Robert. At the time, I hadn’t listened to Four Year Strong in forever, and they had released some music since then. That said, we decided to go check them out since they were one of the last bands of the day.

When we got there, they came out in holiday gear which was sort of silly and fun. Then, they played a few songs that I didn’t really know. As a result, Robert and I sat in the back boppin’ our heads with our arms crossed.

As the set went on, I started to wonder if they were going to play anything I knew. That’s when they pulled out “Wasting Time”. At that moment, I looked at Robert, gave him a nod, and began pushing my way to the center of pit like I was 18 again. For about 3 minutes, I threw down. Then, we went home.

I have no clue why I like this song so much, but memories like this give the song some sentimental value. Whenever I hear it, I get the urge to throw down.

14. A Part of Me – Neck Deep

During that part of my life when I was regularly attending Warped Tour, I got into Neck Deep. Of all the bands in this list, Neck Deep is probably my least favorite. That said, they had one song that I’ve listened to several hundred times called “A Part of Me”.

If you haven’t heard it, it’s a short song which features a male/female duet. In the first few verses of the song, the guy sings about the woman. Then, they drop everything but a guitar and a piano, and the man and the women exchange bars. Finally, they sing together.

What makes this song so good is the contrast between the singers. On one hand, the guy has an extremely rough voice which borders screaming. Meanwhile, the woman has extremely clean vocals—which I was obsessed with for a bit. Together, they make the perfect contrast.

Outside of this song, however, I never really got into Neck Deep. At this point, I’ve sort of worn the song out, but I had to include it for my own sake.

15. Two Good Things – Modern Baseball

One of the worst experiences I ever had in my life was living abroad in England. For about six months, I had to survive without making any real connections with the locals. By the end of the trip, I was deeply depressed, and I vowed to never make anyone feel like that in my home country.

To get through that experience, I leaned heavily on music. At the time, I was listening to a lot of The Wonder Years, State Champs, Real Friends, and Modern Baseball. By far, the song that got me through the trip was “Two Good Things” by Modern Baseball.

If you listen to the lyrics, you’ll find that they perfectly encapsulate exactly how I was feeling at the time. A few lyrics that come to mind include:

  • “Trying hard not to look like I’m trying that hard”
  • “Not feeling lonely, I just like being alone”
  • “Mathematically that can’t be more than one end of a candle”
  • “I’m stuck between two good things, but I just wanna get out”

Also, the whimsical nature of the song reminds me of my carefree attitude—at least on the outside.

16. Out of The Woods – Taylor Swift

While most of this list consists of pop punk music, my music tastes are quite a bit more complicated than that. For instance, I’m a huge Taylor Swift fan, and I’m not saying that ironically. For whatever reason, I’ve enjoyed almost everything shes released since I heard her on the radio in middle school.

Now, I should mention that I hate country music. Oddly enough, she served as a bit of a gateway to country music for me, but it never stuck with me. That said, I still love her older stuff which is probably more like country pop.

At any rate, I’ve been listening to Taylor Swift for ages, but the song that I’ve listened to the most is “Out of the Woods”—with “Love Story” as a close second. By no means should I like either song because they’re so repetitive, but I just can’t stop listening to them.

For “Out of the Woods” in particular, the song was a powerful motivator for me in college. Any time I felt like I wasn’t going to be able to get through something, I’d just binge this song. I realize this song is about a relationship, but I applied it to pretty much any context I could. After all, the chorus is about getting through the woods, so I figure it applies to any hardship.

17. NASA – Ariana Grande

Unlike the majority of Ariana stans, I didn’t start listening to her until she released “thank u, next”. For whatever reason, I picked up that album and began listening to it top to bottom. Like Aaron West, it makes for great driving music.

Funnily enough, if you check my top artist of 2019 on Spotify, it’s Ariana Grande. The obsession started in late 2018 when I binged that album for several hours on my trip to and from Jersey to visit my friend, Robert.

Of all the songs on that album, I’m most partial to “NASA” which is a song about needing space. Honestly, I don’t identify with the lyrics at all, but the song is so damn good. I’ve pretty much ran it into the ground at this point.

All that said, I expect Ari to be a big part of my life moving forward. Sometimes I just need this kind of music to offset the depressing shit I normally binge.

18/19. Remembering Sunday/Dear Maria, Count Me In – All Time Low

Around the same time I got into pop punk, I got into All Time Low. Honestly, I was pretty against mainstream music when I was younger, so I avoided them. Then, somehow they crept back into my life to help me practice vocal harmonies.

Of all their songs, I was a big fan of “Dear Maria, Count Me In” because it was an “easy” song for guitar, bass, and singing. In fact, I once spent an entire night practicing just this song on bass in my buddy’s basement.

Since then, I’ve sort of moved on from All Time Low, but I still see them as a guilty pleasure. In fact, my favorite song of theirs was “Remembering Sunday.” Weirdly enough, I didn’t care for the original recording; I preferred the “Live from Straight to DVD” version featuring Juliet Simms. Now, whenever I pick up a guitar, I try to play this song.

20. Someone Like You – Adele

Would you believe me if I said it took me a year to put this list together? By this point in the list, I was tired of searching my memory for old nuggets of gold. So, I deferred to my friend, Robert, who has made quite a few appearances in this list already.

Initially, I turned over my Spotify playlist, and I asked him what was missing. Within seconds he said “someone like you by adele?”:

How did I forget this song?! This was literally the only song I knew the chords for on piano, and I used to play it way too often. Of course, he actually knew how to play piano, so he often jazzed it up for me. Then, I’d sing vocal harmonies with him. Good times!

There was a period of my life where I shamelessly played this song on loop. Now, I’m realizing I’ve done that with quite a few songs. No wonder I burn out artists.

21. Take One Last Breath – Abandon All Ships

Speaking of songs I ruined! Say hello to “Take One Last Breath” by Abandon All Ships. If you’ve never heard this song, you’re not missing much. However, it has probably one of the sickest drum breaks I’ve heard, so I often listen to it just to air drum that section.

In college, this song was sort of a meme in my friend group. Whenever we would sit around on the weekend, we would play songs like this and joke around. After a few air drum solos, everyone would forget their silly homework assignments.

Outside of this song, I really don’t know anything about Abandon All Ships. Perhaps some of their other music is good. After all, I kind of like the techno/screamo mashup.

22. Part of Your World – The Little Mermaid

As mentioned previously, beyond pop punk, I love listening to musician’s music like jazz. Of course, my second favorite place to perform is a pit orchestra. For instance, I’ve performed for several musicals including Annie Get Your Gun, Titanic, and The Full Monty.

In general, I enjoy a good showtune whether that be from a broadway musical or a Disney movie. For instance, I think my favorite Disney movie is Coco. That said, a Disney song that has been with me my entire life is “Part of Your World” from The Little Mermaid.

Of all the Disney songs, I chose this one because of its strong theme of rebellion. As I get older, I get more rebellious, and I think this song was a strong foundation for that. Also, it’s just so much fun to sing.

23. Get It On – Chase

When I was in high school, I rehearsed in Jazz band every day for about 90 minutes. Back then, I had a ton of fun playing songs like “Over the Rainbow”, “Hey Jude”, “Freedom at Midnight”, and “Get It On”. Of all those songs, I was a huge fan of “Get It On” just because of the trumpet waterfall.

Recently, I rediscovered this song when I was putting this list together, and now I’m obsessed with it. When it comes to Jazz, you really can’t beat fusion. I just love a wild electric guitar over some blaring trumpets.

Of course, like some of these songs in this list, I don’t really care for the actual lyrics. I’m here for the music!

24. Forgot About Dre – Dr. Dre & Eminem

As we near the end of this list, we get to a few songs that I don’t really listen to anymore but had a profound impact on my youth development. One of those songs is “Forgot About Dre” by Dr. Dre and Eminem. I haven’t listened to this song in ages, but it’s so ingrained in my memory that I can still sing all the words perfectly (I know. I just tried).

As mentioned already, I’m a huge Eminem fan, and this song is just so fun to “sing.” In addition, the music video was a source of inside jokes with my friends for a long time (e.g. “I was upstairs listening to my Will Smith CD.”). As a result, I have long history with this song that involves nailing every word.

25. Shenandoah – Frank Ticheli

As a musician, I wouldn’t be doing myself justice if I didn’t share at least one concert band piece that I actually liked. In particular, I love anything emotional, so I had to go with Shenandoah by Frank Ticheli. I think I’ve played this song in at least three different bands, so band directors agree this piece is excellent.

Since I’ve played this so many times, I have to admit that there are a lot of memories attached to it. For instance, I played this once with my high school concert band. Then, I played it again the only time I got into District Band. Finally, I believe I even played this in college, so it’s been a big part of my life.

Generally, I don’t care for concert band music, so this piece is really special to me. While the melody alone is pretty solid, I love all the little details like all the echos and layering. If you get a chance, check it out!

26. Gypsy – Fleetwood Mac

Finally, I had to close this list out with a song that reminds me of home: “Gypsy” by Fleetwood Mac. If you swing by my parents’ house around 6 PM on a Friday, there’s a chance you’ll hear this song playing. That’s around the time my mom likes to throw on a list of my parents’ favorite tunes which includes many songs like “Run to the Hills” by Iron Maiden, “Cleanin’ Out My Closet” by Eminem, and “Friday I’m in Love” by The Cure.

Of all those songs I used to listen to every week, “Gypsy” by Fleetwood Mac stands out to me. After all, they’re the only group from their playlist that I’ve seen live. That’s right! I’ve seen Fleetwood Mac live in concert.

That said, I could have picked any of their charts. For instance, “Landslide” is excellent. Likewise, I love “Sara” and “Rhiannon”. That said, “Gypsy” takes the cake for me because it was just so good live. In particular, Stevie Nicks explained the backstory to this song, and I’ve been hooked ever since.

Without the story, the lyrics don’t really make sense. With the story, it’s like forming a connection with the artist. That’s why I love to see bands live. They always share little tidbits about their songs, and you get to feel slightly more connected to them (and consequently, my parents). How cool is that?

Honorable Mentions

Like any good list, there are items that just didn’t quite make it. In this section, I’ll list a few songs that didn’t make the main list and briefly explain why not.

  • I really wanted to restrict this list to standalone music that wasn’t linked to any form of media (e.g. games, anime, etc.). That said, anime and video game music has had a huge impact on my life. Here are a few songs I like:
    • Believe Me – Steins;Gate
    • You Can Become a Hero – Boku No Hero Academia
    • Cauis’s Theme – Final Fantasy 13-2
    • Impend – Halo 2
    • Glassy Skies – Tokyo Ghoul
  • In addition to “Gypsy”, there are tons of songs that I’ve listened to hundreds of times, but I don’t personally choose to listen to anymore. The songs below join the long list of songs that remind me of home.
    • Friday I’m in Love – The Cure
    • Enjoy the Silence – Depeche Mode
    • Run to the Hills – Iron Maiden
    • Duality – Slipknot
    • Happy – Mudvayne

As always, there’s probably another 100 songs I could add to this list, but what’s the point?

Let’s Celebrate

Today I’m 26, and The Renegade Coder is almost 3 years old. Help me celebrate these two events by spreading the word about my website. If you’d like to help even more, you’re welcome to hop on my mailing list, become a Patron, or browse my shop.

In addition, feel free to check out all my birthday posts up to this point:

To no surprise, I’m already plotting out my 27th birthday article. Right now, I’m planning on listing off my top 27 anime of all time. That said, if you have a better idea, let me know in the comments. Otherwise, thanks for stopping by!

The post 26 Songs That Made Me Who I Am Today appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/26-songs-that-made-me-who-i-am-today/feed/ 0 13102
How to Create a Git Repo From Scratch: Git Init, GitHub Desktop, and More https://therenegadecoder.com/code/how-to-create-a-git-repo-from-scratch/ https://therenegadecoder.com/code/how-to-create-a-git-repo-from-scratch/#respond Fri, 31 Jan 2020 15:00:00 +0000 https://therenegadecoder.com/?p=20832

Maybe you've cloned a few Git repos before, but how do you actually create your own. In this article, we'll look at a few techniques to get you up and running.

The post How to Create a Git Repo From Scratch: Git Init, GitHub Desktop, and More appeared first on The Renegade Coder.

]]>

Welcome to my new Git series. Since I use Git all the time, I figured I could start documenting some of my tips and tricks. For instance, today I want to talk about how to create a Git repo from scratch.

If you need an answer fast, try navigating to the folder you want to start a Git repo in and run the command git init. Alternatively, you can always leverage GUI-based tools like GitHub Desktop. If all else fails, keep reading!

Table of Contents

Problem Description

When I was first learning Git, I was very confused. After all, there’s a lot of terminology to grasp. For instance, what’s a repository? How about a branch? How are Git and GitHub different? What’s a merge conflict, and how do I fix one? These were all questions that kept me up at night.

That said, when I finally got around to learning the ropes, I often found myself Googling the same questions over and over. For instance, what’s the command to add a description to a commit? Likewise, what’s the command for switching branches? Ultimately, I caved and started using a graphical user interface (GUI) like GitHub Desktop.

Even after throwing in the towel, I still find myself asking questions like “How do you create a Git repo from scratch?” As a result, I figured I could do myself a favor by documenting the answer. In this article, we’ll learn a few ways to do exactly that. Then, in the future, we’ll start tackling other questions together.

Solution

Today, we’ll look at a few different ways to create a Git repository. First, we’ll look at a command line solution which takes advantage of the git init command. Then, we’ll explore a few tools that will abstract away the command line. Sound good? Let’s dive in!

Create a Git Repo Using the Command Line

One way to create a Git repo is to use the git init command in the appropriate folder:

cd /path/to/repo
git init

In this example, we open our command line and change to the directory that we want to convert to a git repository. Then, we run the git init command. Here’s what that might look like:

E:\>cd Projects

E:\Projects>cd git-project

E:\Projects\git-project>git init
Initialized empty Git repository in E:/Projects/git-project/.git/

E:\Projects\git-project>git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Now, I have an empty git repository on my machine. Just to be sure, I ran git status which let me know the current state of the repo.

At this point, we might try creating a file. In my case, I created a simple README and placed it in the root of my new repo:

# Project README

Check out this cool new project!

Now, when I run git status, I’ll get a different result:

E:\Projects\git-project>git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README.md

nothing added to commit but untracked files present (use "git add" to track)

If we follow the directions, we can add our README to the repo with git add README.md. Then, we can make our first commit:

E:\Projects\git-project>git add README.md

E:\Projects\git-project>git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   README.md


E:\Projects\git-project>git commit -m "Created README"
[master (root-commit) 0ee160c] Created README
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

And, there we have it—a brand new Git repo created from scratch!

Create a Git Repo Using GitHub Desktop

If you’d prefer to avoid the command line, there are tons of GUI-based tools you can use. For instance, I like to use GitHub Desktop since I host all my projects there. That said, you can use pretty much any IDE (e.g. Eclipse, PyCharm, VS Code, etc.) with a Git plugin.

When we open GitHub desktop, we’re greeted with a window that looks like this (could be different in the future):

GitHub Desktop Application Homepage

If we want to create a new repository, we can go to “File” and select “New repository”. Alternatively, we can press Ctrl + N. That pops up the following prompt:

GitHub Desktop Application Create Repository Prompt

Unlike Git, GitHub Desktop has a few more options for customization. For instance, we can create a repository with a name, a description, a README, a Git ignore, and a license. Naturally, we’ll keep this one simple:

GitHub Desktop Application Create Repository Completed Prompt

When that’s finished, we’re greeted with a window that looks like this:

GitHub Desktop Application New Repository

Say hello to our brand new Git repo! Now, we can make changes like any other repo.

Create a Git Repo Using the GitHub Website

If you’d prefer something completely centralized and web-based, look no further than GitHub’s website. If you have an account, it’s possible to create a repository right from the homepage:

GitHub Website Homepage

In the upper righthand corner, we’ll see a bell, a plus sign, and a profile picture. If we click the plus sign, we’ll be greeted with a few options:

GitHub Website Homepage Add New Repository

If we click the “New repository” option, we’ll be taken to a new page which begins the repository creation process:

GitHub Website Add New Repository Page

If this looks familiar, it’s because this is the same prompt GitHub desktop gives. In other words, we can fill it out the same way:

GitHub Website Add New Repository Completed Page

Once we hit “Create repository”, we’ll be greeted with the repository homepage:

GitHub Website New Project Homepage

At this point, we’ve created our repo, but it’s on GitHub’s servers instead of our computer. To get it on our computer, we’ll need to clone the repo. To do that, we can hit the “Clone or download” button:

GitHub Website New Project Clone Button

In a future article, we’ll talk about cloning repositories, so I won’t dwell on it here. That said, feel free to select “Open in Desktop” for ultimate convenience. That should open up the GitHub Desktop application which will prompt you to clone the project on your system. Otherwise, you might want to get familiar with the git clone command.

A Little Recap

With all that out of the way, here’s a quick recap of the solutions we saw today:

  • git init
  • GitHub Desktop
  • GitHub Website

If you have a preferred solution that wasn’t listed here, feel free to drop it in the comments. Otherwise, help support this website by joining the mailing list, becoming a patron, or browsing the shop.

If you want to stick around, here are some related articles:

Likewise, here are some Git resources from Amazon (ad):

If nothing else, thanks for stopping by! I appreciate it.

The post How to Create a Git Repo From Scratch: Git Init, GitHub Desktop, and More appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/how-to-create-a-git-repo-from-scratch/feed/ 0 20832
How to Write a Loop in Python: While and For https://therenegadecoder.com/code/how-to-write-a-loop-in-python/ https://therenegadecoder.com/code/how-to-write-a-loop-in-python/#respond Mon, 27 Jan 2020 15:00:00 +0000 https://therenegadecoder.com/?p=20715

If you're trying Python for the first time, it's a good idea to learn how to write a loop. Luckily, I've got you covered.

The post How to Write a Loop in Python: While and For appeared first on The Renegade Coder.

]]>

As this series grows, I often find myself revisiting the fundamentals. For instance, today we’ll be learning how to write a loop in Python. Luckily for you, there’s some bonus material on recursion as well.

In short, there are two core ways of writing a loop, while and for. If you’re looking for a tradition loop, opt for the while loop. Meanwhile, if you have some sequence or iterable to traverse, opt for the for loop. If you find a scenario which gets messy with a loop (e.g. tree traversal), don’t be afraid to fall back on recursion.

Table of Contents

Problem Description

When you first get into programming, you often go through a progression of different pieces of syntax. For instance, you might learn about printing and variables. Then, you might expand your knowledge into arithmetic and boolean expressions. If all goes well, you might even learn about conditionals.

As time goes on, you might ask yourself “but, what if I want to do something repeatedly?” Luckily, most imperative programming languages have a syntax for this called looping. Essentially, we repeat a task until we satisfy some condition.

Of course, if you’ve come from another programming language, you already know all about looping (or at least recursion). The trouble is getting used to the new syntax. Fortunately, we have several different solutions which we’ll take a look at in the next section.

Solutions

In this section, we’ll take a look at three different ways to write a loop in Python. First, we’ll look at recursion, a functional technique. Then, we’ll dive into the two iterative techniques, while and for.

Recursion

Before we dig into the various loop syntax in Python, I feel like it’s important to mention recursion as a concept. After all, we don’t actually need loops at all. We can get away from writing functions which reference themselves:

def recurse():
    recurse()

In this example, we’ve written a function called recurse() which calls itself. If we run it, however, we’ll get an error:

>>> recurse()
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    recurse()
  File "<pyshell#1>", line 2, in recurse
    recurse()
  File "<pyshell#1>", line 2, in recurse
    recurse()
  File "<pyshell#1>", line 2, in recurse
    recurse()
  [Previous line repeated 991 more times]
RecursionError: maximum recursion depth exceeded

Of course, this makes sense. After all, if a function calls itself, then it will call itself, then it will call itself, then it will call itself… alright, my head is spinning.

Luckily, this is pretty easy to fix. We just need to add a condition which only calls the function under certain conditions (e.g. while the input is greater than zero):

def recurse(i):
    if i > 0:
        recurse(i - 1)

Now, if we can this function with some number, we won’t crash:

>>> recurse(5)

But, what is this actually doing? Well, let’s try printing something:

def recurse(i):
    print(f'Input is {i}')
    if i > 0:
        recurse(i - 1)

Here, we used an f-string (learn more about those here) to show the input every time this function is called:

>>> recurse(5)
Input is 5
Input is 4
Input is 3
Input is 2
Input is 1
Input is 0

Check that out! We managed to create a function which executes 6 times when we enter a 5. As you can probably imagine, this mechanism can be used to do a lot of interesting things. If you’re interested in learning more about recursion, I’ve written an article all about it.

While Loop

With recursion out of the way, let’s talking about loops. In Python, there are two main looping mechanisms: while and for. Typically, courses cover while first because it’s simpler. If you’re familiar with if statements, a while loop looks almost exactly the same:

while condition:
    do_thing()

If the condition is true, the loop body executes just like an if statement. However, after the body executes, the condition is rechecked. If the condition is still true, we drop back into the loop body once again.

Naturally, we can write a loop which behaviors similarly to our recursion example. All we have to do is create a counter variable and count down on each iteration:

i = 5
while i >= 0:
    print(f'Input is {i}')
    i -= 1

In this example, we create a variable called i and give it a value of 5. Then, we kick off the loop by checking if i is greater than or equal to 0. Since it is, we drop into the loop where we print “Input is 5” and decrement i. Then, the process repeats. Of course, now i is 4 instead of 5. Overall time, i will decrement until it is -1, and the loop condition will fail.

In Python, while can be used to implement any indefinite loop. In other words, use a while loop when you don’t know how many iterations you’ll have ahead of time. For example, while loops are perfect for reading from files or prompting for input from a user. In the next section, we’ll take a look at an example of a definite loop.

For Loop

In many imperative languages like Java, C, and Python, there is more than one way to write a loop. For example, in Java, there are at least four different loop syntaxes that I’m aware of (e.g. while, for, for each, do while). Since Python tries to keep things simple, the number of loop syntaxes are limited. As far as I know, there are only two: for and while.

Now, for loops in Python aren’t like for loops in other languages. Instead of providing a space to track an index, they operate more like for each loops in other languages. In other words, we need something to iterate over like a list. Let’s try recreating our while loop from above:

indices = [5, 4, 3, 2, 1, 0]
for i in indices:
    print(f'Input is {i}')

To make this loop work, we had to create a list to iterate over. Clearly, this isn’t as convenient as the previous solution. Luckily, Python has a way generating these sort of iterables:

for i in range(5, -1, -1):
    print(f'Input is {i}')

Here, we’ve created a loop which will count down from 5 to 0 just like all our other loops. To do that, we used the range() function which generates a list-like structure from the inputs provided. In this case, 5 represents the inclusive starting value, the first -1 represents the exclusive ending value, and the second -1 represents the step (i.e. how many values to skip and in what direction).

In general, for loops are more useful for iterating over sequences like lists, strings, or generators. In other words, they don’t work exactly like for loops in other languages—not without using a special function like range().

Performance

At this point, I’m not sure it makes sense to compare the performance of these three constructs, but I already wrote three solutions that do the same thing. In other words, we’re just begging for a comparison. To kick things off, let’s store all three of our solutions in strings:

setup = """
i = 5
def recurse(i):
    # Removed print for sanity
    if i > 0:
        recurse(i - 1)
"""

recursion = """
recurse(5)
"""

while_loop = """
while i >= 0:
    # Removed print for sanity
    i -= 1
"""

for_loop = """
for i in range(5, -1, -1):
    pass  # Removed print for sanity
"""

Then, we can run out test as follows:

>>> import timeit
>>> min(timeit.repeat(setup=setup, stmt=recursion))
0.7848201999999986
>>> min(timeit.repeat(setup=setup, stmt=while_loop))
0.040824499999999375
>>> min(timeit.repeat(setup=setup, stmt=for_loop))
0.34835850000000335

One thing I found really interesting was the performance of the while loop. Then, I realized that my test was slightly inaccurate. Specifically, I had placed the i in setup, so it became zero after the first iteration. In other words, the while loop became a glorified if statement. When I updated my setup string, here were the results:

>>> setup = """
def recurse(i):
    # Removed print for sanity
    if i > 0:
        recurse(i - 1)
"""
>>> while_loop = """
i = 5
while i >= 0:
    # Removed print for sanity
    i -= 1
"""
>>> min(timeit.repeat(setup=setup, stmt=while_loop))
0.3415355000000204

Now, that’s almost identical to the for loop—which makes sense to me. That said, I was reading some performance discussions on StackOverflow, and the for loop should be faster overall. Naturally, I had to investigate, so I updated both solutions for large numbers:

>>> for_loop = """
for i in range(100, -1, -1):
    pass  # Removed print for sanity
"""
>>> min(timeit.repeat(setup=setup, stmt=for_loop))
1.2956954000001133
>>> while_loop = """
i = 100
while i >= 0:
    # Removed print for sanity
    i -= 1
"""
>>> min(timeit.repeat(setup=setup, stmt=while_loop))
4.765163399999892

Turns out that 100 was all I was willing to wait. Otherwise, this test may have taken all day. That said, even at a number this small, there’s an obvious difference in performance. Feel free to check out that discussion above for a further explanation of why.

Challenge

Now that we know how to write a loop, let’s try something interesting. Let’s imagine we have a list of lists (aka a matrix):

my_matrix = [
    [3, 5, 2, 4],
    [5, 9, 4, 2],
    [1, 8, 4, 3]
]

And, we want to total each row (inner list) and determine the average of all rows. Using the example above, we’d get the following row totals:

my_matrix = [
    [3, 5, 2, 4],  # 14
    [5, 9, 4, 2],  # 20
    [1, 8, 4, 3]   # 16
]

Then, we’d average the totals:

(14 + 20 + 16) / 3  # 16.666666666666668

When we’re done, we’d report the result to the user.

While this seems like a pretty straightforward task for us, how would we train the computer to do it? In other words, how would we use the various loop syntaxes to do this (hint: you’ll might want to nest two loops)?

If you come up with a solution, drop it down below in the comments. Naturally, I’ll throw my own solution down there to get us started.

A Little Recap

With all that out of the way, let’s revisit our solutions once again:

# Recursion
def recurse(i):
    print(f'Input is {i}')
    if i > 0:
        recurse(i - 1)
recurse(5)

# While loop
i = 5
while i >= 0:
    print(f'Input is {i}')
    i -= 1

# For loop
for i in range(5, -1, -1):
    print(f'Input is {i}')

If you liked this article, you might like joining the weekly mailing list, becoming a Patron, or browsing the shop. Right now, I have a Python 3 Beginner Cheat Sheet which includes the loop syntax from this article among other things. Check it out!

Otherwise, stick around and check out some of these related articles:

In addition, you might get some value out of the following products on Amazon (ad):

If none of that sounds interesting, no sweat! Thanks for checking out my work today.

The post How to Write a Loop in Python: While and For appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/how-to-write-a-loop-in-python/feed/ 0 20715
Want to Design Your Own Indie Game? Check Out These Programming Languages! https://therenegadecoder.com/blog/want-to-design-your-own-indie-game-check-out-these-programming-languages/ https://therenegadecoder.com/blog/want-to-design-your-own-indie-game-check-out-these-programming-languages/#respond Fri, 24 Jan 2020 15:00:00 +0000 https://therenegadecoder.com/?p=22026

Someone in the community thought it would be helpful to share this list of programming languages for game development. I figured you might enjoy it.

The post Want to Design Your Own Indie Game? Check Out These Programming Languages! appeared first on The Renegade Coder.

]]>

Online games were once all the rage–and for many, they still are. Previously, ‘Why I No Longer Enjoy Online Gaming’ covered a personal decision to veer away from online games like the game Overwatch. Without speaking for everyone, online gaming can be an exhausting pursuit, especially when you’ve dedicated the majority of your time to it and feel like your world revolves around it. While you can make friends, the online community can be extremely toxic, exclusive, and arbitrary.

Perhaps it may be time to consider going back to basics with single-player games, or even indie games by smaller developers or individuals. Many of the problems of online games stem from their development by huge corporations. Researchers at the University of York found how big developers include problematic elements like microtransactions and income-generating loot boxes in their games in an effort to make more money. This is what makes supporting up-and-coming games so refreshing, as most of them have been created for the sole intent of user enjoyment, you rarely see things done just for the sake of making money. A clever analogy in an HP article about the ‘13 Best Indie Games for PC’ describes this genre as the “garage bands” of programming due to their more off-beat mechanics and somewhat more compelling gameplay. These titles are programmed with pure passion, talents, and ideas, which makes them unique tokens created for likeminded individuals to enjoy.

If you’re interested in designing your own indie game, here are some programming languages to check out.

C++

While C++ may be difficult to learn, it is one of the most commonly used languages as it lets you have more control over the hardware and graphical processes that are essential in video game design. As it uses object-oriented language, internal structures are used to organize code into reusable blocks. Many consider this the language to learn since many others stem from it. The action-adventure game Starbound was developed with C++.

Java

The dynamism of the Java language makes it a preference for a lot of game programmers as it supports multithreading which uses less memory and maximizes CPU. Since it runs on a virtual machine, your game can be distributed easily as it’s compatible with different devices. Minecraft–one of the best-selling video games of all time–was originally created using Java by developer Markus Persson before selling it to Microsoft.

HTML5

HTML5 allows you to modify the appearance of webpages, structure, and present web content. Multimedia content can even be added without Flash or a third-party plug-in, and websites can be accessed without the Internet, making it a considerable option for game developers. It’s also meant to work across platforms. The classic game Bejeweled is written with HTML5.

JavaScript

JavaScript is one of the most popular scripting and programming languages in the world. It allows the creation of dynamically updated content, animation, and other multimedia properties. When used in tandem with Application Programming Interfaces, it lets developers implement difficult programs. The popular Angry Birds game runs on JavaScript.

Your choice of programming language rests heavily on your game design interests. Assess your options before you get started and create an indie game you can call your own!

The post Want to Design Your Own Indie Game? Check Out These Programming Languages! appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/want-to-design-your-own-indie-game-check-out-these-programming-languages/feed/ 0 22026
2019: Year in Review https://therenegadecoder.com/meta/2019-year-in-review/ https://therenegadecoder.com/meta/2019-year-in-review/#respond Mon, 20 Jan 2020 15:00:00 +0000 https://therenegadecoder.com/?p=20686

Wanna see how things went for The Renegade Coder in 2019? Well, I put together another yearly review capping out at 2500 words. Woo!

The post 2019: Year in Review appeared first on The Renegade Coder.

]]>

As The Renegade Coder heads into its 3rd birthday, I figured I’d wrap up 2019 with a little review. In it, you’ll find everything from my favorite articles to my traffic metrics. Come along!

Table of Contents

Accomplishments in 2019

Unlike last year, nothing major happened for me this year. Sure, I complained a lot, but I didn’t have any major developments. That said, I’m happy to share a few major things that happened to me:

Beyond all that, I was just living life. If you’re interested in learning more about my year, check out my blog. I ranted quite a bit!

Favorite Creations of 2019

In 2019, I started niching down to focus on my most popular content, Python articles. At the same time however, I also broadened to scope of the website to include teaching content. In addition, I started a YouTube channel. As a result, I figured this year I’d share my favorite creations—one for each month:

Also, I’d be happy to share my favorite YouTube videos, but I only made eight! If you’d like to see that collection grow, subscribe to my channel. Otherwise, feel free to share some of your favorites of the past year with me in the comments.

Projects in 2019

This year, I worked on a lot of fun projects. Since I have plenty to write about, I’ll share all my updates in the subsections below.

Sample Programs in Every Language

Unlike in previous years, the bulk of my contribution to this project came during Hacktoberfest. During that time, I merged A LOT of pull requests for code snippets, articles, and even some slick feature updates.

One of my favorite features that came out of this year is the addition of Glotter, a Docker-based blackbox testing library. Essentially, it allows us to pull up Docker images for each language and test all our code using a standard set of Python tests. Now, several of our languages and projects are fully tested. Read more about that here.

In addition, we hit several milestones with this project this year. For example, 100 of the code snippets/languages are now documented. In addition, we hit 25 projects. This ain’t no Hello World in Every Language anymore.

Overall, I’m excited to see this project grow, but I don’t plan to focus on it too much. As always, I’m sure Hacktoberfest will resurrect it again this year.

CSE 5521: Artificial Intelligence I

Last semester, I took a course on artificial intelligence which had a handful of projects in JavaScript. For instance, one project asked us to right a handful of search algorithms for the 8 puzzle. By the end of that project, I had implemented depth first search, breadth first search, iterative deepening, and A*.

Later in the semester, we had to write the minimax and alpha-beta pruning algorithms for tic-tac-toe. If done correctly, it’s impossible to beat the computer!

Finally, we had to write a few linear and nonlinear regression algorithms. For example, we had to implement linear least squares and gradient descent.

Overall, I actually enjoyed the course. For once, I understood some AI. Unfortunately, my education classes were a lot more fun, so I had a hard time focusing on as the semester went on. Hopefully, I can carry this knowledge over into AI II.

JuxtaMIDI

Recently, I published an article all about a tool I put together with a partner for a data visualization class. The goal of the tool was to generate a visualization of MIDI files, a type of music file.

While the tool is fairly nice looking, it doesn’t do a whole lot. Basically, it just plots the raw data from the MIDI files, so you can compare multiple files simultaneously. That said, I had a lot of fun making it, and I think it’s a fun tool for any tech folks also interested in music and data visualization.

If you’d like to learn more about the tool, I wrote a pretty lengthy article about it late last year.

Side Projects

Outside of code, I also worked on a few side projects this year. For instance, I started a YouTube channel which now features 8 videos. In addition, I created a portfolio site. Not sure how it’ll help me going forward, but it at least makes me look more legitimate. Finally, I started a niche site called Trill Trombone which features 18 articles.

At the moment, I don’t have much to report from these projects, but I am excited to see them grow in 2020. Hopefully, I’ll have something exciting to share by this time next year.

Metrics: 2017 – 2019

Now that I’m nearly three years into The Renegade Coder, I figured I’d start sharing some metrics in aggregate. In the following subsections, we’ll take a look at various statistics including page views, top posts, top traffic sources, and revenue. Without further ado, let’s dive in!

Months and Years

Below is a table that shows my page views for each month since I started The Renegade Coder:

JanfebMarAprMayJunJulAugSepOctNovDecTotal
2017 379 317 337 253 714 505 5162* 904 202 8773
2018 427 397 1141 1310 1364 780 1718 1921 5747 10,939 9936 13,871 49,551
2019 19,08116,26230,99545,35452,68326,66419,81619,93022,48717,77514,96011,834297,841

When I set out to create this website, I anticipated neverending growth. After all, even in the worst case, every post should get at least one view a year. In other words, more content means more viewership.

Unfortunately, that’s not really the case. As you can see, I had a very, very good year in terms of growth. In fact, my page views grew six-fold. However, that viewership peaked in May and has been on a major decline since then. As of December, I had less views than I did the previous December.

All-in-all, I’m not really concerned about this dip in views. As we’ll see later, I basically had a one-hit-wonder which finally stopped bringing in organic traffic. Meanwhile, several other posts were growing, so I feel like my views will be more diverse in the coming year. That said, it’s going to be tough to hit 300,000 with my current rate. We’ll see what we can do!

Also, it’s worth noting that I’ve been doing a bit of syndication. For instance, I often repost my coding related articles to dev.to with the canonical URL, so views there aren’t counted here. In addition, I’ve worked out a deal with Java Code Geeks where my reposted their regularly. Perhaps that’s hurting my view counts. Who knows!

Averages Per Day

If you’re not a fan of raw data, here’s the same chart but with daily averages:

JanFebMarAprMayJunjulaugsepoctnovdecoverall
201734101182317167*30734
20181414374444265562192353331447136
20196165811.0K1.5K1.7K889639643750573499382815

As you can see, we’re on a downward trend at the moment. My current plan for growth over the next few months is to get back to what got me views in the first place: Python content. Right now, I have four Python articles planned for January. Chances are I’ll have seven by the end of this month.

Then, I plan to start cranking out YouTube videos for all the Python content. If that becomes my brand, so be it! I really enjoy writing and speaking about the language.

Top Posts and Pages

In 2019, one of my articles climbed to the top of Google where it saw outrageous success. In the span of a year, How to Check if a File Exists in Python amassed nearly 150,000 views. That said, it was nice to have a few other articles pulling their weight as well.

201720182019
#1Home (2,908 views)How to Check if a File Exists in Python (27,245 views)How to Check if a File Exists in Python (148,399 views)
#2Archives (2,093 views)How to Sum Elements of Two Lists in Python (5,402 views)How to Check if a List is Empty in Python (65,644 views)
#3About (430 views)How to Convert Two Lists into a Dictionary in Python (2,697 views)How to Sum Elements of Two Lists in Python (14,047 views)
#4World Domination Checklist (282 views)How to Invert a Dictionary in Python (1,944 views)How to Invert a Dictionary in Python (13,326 views)
#5Computer Science Email Tutoring Now Offered (197 views)Archives (1,525 views)How to Convert Two Lists Into a Dictionary in Python (10,069 views)

As mentioned already, Python seems to be working out for me. As a result, I’m going to become a fire hose for Python content over the next few months. If I see any sort of success like this, I’ll be content!

Top Sources of Traffic

In 2019, I was driven almost entirely by traffic from Google. If anyone has any tips for me to diversify my traffic, let me know!

201720182019
#1Google (2,271 views)
Google (38,925 views)
Google (259K views)
#2Facebook (418 views)GitHub (809 views)DuckDuckGo (4,809 views)
#3Twitter (64 views)
Bing (451 views)Bing (4,775 views)
#4LinkedIn (30 views)Google+ (266 views)WordPress Android App (1,289 views)
#5StumbleUpon (20 views)WordPress Reader (247 views)
GitHub (967 views)
#6Yahoo (14 views)Twitter (246 views)Yahoo Search (777 views)
#7Bing (12 views)DuckDuckGo (215 views)Ecosia (522 views)
#8GitHub (9 views)
Facebook (193 views)Twitter (289 views)
#9WordPress Reader (8 views)Instagram (86 views)Quant (160 views)
#10DuckDuckGo (3 views)Yahoo (85 views)Yandex (144 views)

One thing I found interesting is how many developers use DuckDuckGo. Somehow, it managed to come in at second in terms of traffic sources with nearly 5,000 page views. That beats nearly everything but Google from the previous year. Also, I’m glad so many people want to save the planet with Ecosia.

Top Countries

Once again, I took a look at where my traffic was coming from in terms of geography. According to the report, I get an overwhelming amount of traffic from my home country. That said, it’s only about a third of the total traffic for the year. In other words, two thirds of my traffic comes from other places! How cool is that?

201720182019
#1
United States of America (4,037 views)United States of America (20,949 views)United States of America (115,649 views)
#2South Korea (578 views)India (6,230 views)India (33,496 views)
#3France (542 views)United Kingdom (2,581 views)United Kingdom (14,206 views)
#4Russia (221 views)Canada (1,716 views)Germany (13,664 views)
#5
Germany (220 views)Germany (1,517 views)Canada (11,003 views)
#6
Philippines (189 views)France (1,066 views)France (8,636 views)
#7Canada (183 views)Australia (807 views)Brazil (6,097 views)
#8India (173 views)Israel (718 views)Australia (5,445 views)
#9Japan (150 views)Brazil (685 views)Netherlands (4,847 views)
#10Cambodia (145 views)Netherlands (611 views)Spain (4,237 views)

Since 2018, it looks like I’ve lost my Israeli viewership but picked up some Spanish. That’s cool! I’ll be curious to see how this shakes out next year.

Content Length

One metric that I thought would be fun to share is how long my content is on average.

YearTotal PostsTotal WordsAverage Words Per post
2016610,0331,672
20177078,8121,126
2018150185,4241,220
2019105172,1641,640

As you can see, 2019 was the year for long form content. In other words, I was trying to shoot for 1000+ word articles, and I overshot that goal by 60% on average. Although, I’m not really surprise; this review alone is enormous.

Also, notice how this chart contains 2016. While The Renegade Coder didn’t exist until 2017, I actually transferred some content from a previous WordPress blog. You can find out the details in my first post.

Total Revenue

As you may recall, last year my ad revenue was growing rapidly. However, in the summer, my page views started to drop. Without page views, you can’t really generate ad revenue, so I decided to investigate.

Obviously, I couldn’t be sure why I was losing Google ranking, so I decided to take an educated guess: perhaps my site was just too slow. As a result, I decided to perform an overhaul which resulted in a trashing of the ads. In other words, I no longer generate ad revenue. That’s why you’ll see a dip in revenue below:

JanfebMarAprMayJunJulaugsepOCtNOVDECtotal
2018$0.00$0.34$1.68$1.68 $1.49$1.05$1.94 $0.56 $5.87 $9.28 $12.19 $15.56$49.96
2019$12.84$8.93$21.71$28.18$30.53$17.00$10.67$9.78$4.99$0.00$0.00$0.00$144.63

Unfortunately, WordAds doesn’t pay out until you’ve made $100, and have $72 holding on. Perhaps if I get enough page views again, I’ll turn these on briefly to collect my check.

At any rate, I’ve found other ways to make an income. For instance, I started a Patreon again. In addition, I created yet another shop. Unfortunately, one has been quite a bit more successful than the other. Here are my earnings from Patreon since July:

julaugsepoctnovdecTotal
2019$8.30$22.72$22.72$22.72$22.72$22.72$121.90

If you recall, I also had a membership site which I converted to Patreon. Here’s the income from that:

janfebmaraprmayjunjulTotal
2019$4.55$4.55 $9.10$9.10$9.10$9.10$4.55$50.05

Finally, I made another $4.55 from my store.

If you add all this up, you’ll find that I made about $297.26 in 2019—at least according to QuickBooks. For someone operating a blog as a hobby, that’s not bad. For someone who puts as much time into this as I do, that’s terrible. After all, we’re just looking at revenue. I spent about $545 in 2019 on website related costs like hosting and plugins, so I ended up a net negative.

You can learn more about my money making journey in my articles titled “Is the Work Finally Paying Off?” and “My First Ad Revenue Paycheck“. Here’s to better earnings in 2020!

A Look Into 2020

At this point, I haven’t really made any plans for 2020. Right now, grad school is kicking my ass, and I’ve been on the verge of complete burnout for months now. As a result, I’m tempted to take a little break. That said, I’m afraid that a break could mean stalling out the growth of my project. Then, I’ll never be free!

As far as I know, I’m planning to focus on writing Python articles for the next few months. In addition, I thought it would be fun to start writing Git related content. After all, I think version control is extremely important, and I forget that people don’t know about it.

Finally, I want to hit 25 YouTube videos by the end of the year. Right now, I have 8, so that means I’ll need to make 17 more to hit my target. That’s a pace of just over 1 a month which I think is attainable. However, I have to remember that I publish two articles a week, so it might still be a lofty goal. It all depends on what my summer looks like.

At any rate, that’s all I’ve got! If you liked this review, check out last year’s review. It basically covers all the same information here, but it’s interesting to see where my head was at this time last year. Otherwise, thanks for stopping by! Here’s to another year of grinding.

The post 2019: Year in Review appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/meta/2019-year-in-review/feed/ 0 20686
How to Comment Code in Python: Inline, Multiline, and Docstring https://therenegadecoder.com/code/how-to-comment-code-in-python/ https://therenegadecoder.com/code/how-to-comment-code-in-python/#respond Fri, 17 Jan 2020 15:00:00 +0000 https://therenegadecoder.com/?p=20719

How do you comment code in Python? Turns out there are three different ways, each with their own advantages and disadvantages.

The post How to Comment Code in Python: Inline, Multiline, and Docstring appeared first on The Renegade Coder.

]]>

As we kick off 2020, I wanted to start getting back to some of my favorite content: Python “how to” content. Today, we’ll be looking at how to comment code in Python—a skill we should all have.

To summarize, there are three main ways to make comments in Python. To make inline comments, use the hash mark, #. To make multiline comments, use a hash mark on every line. Alternatively, use triple quotes, """. These kick off a multiline string which can be used to simulate comments. For more details, check out the options below.

Table of Contents

Problem Description

One thing I’ve done throughout this series is create content that targets a specific issue and address it with a few solutions. Of course, many of those solutions require some fundamental understanding of how Python works. In other words, at no point have I actually written any of those fundamental articles. Well, I suppose it’s better late than never.

Today, I want to look at a few ways of commenting code in Python. For those that don’t know, comments are ways of documenting code directly. Specifically, a comment is text that has no semantic affect on your programs. In other words, comments don’t do anything but provide context for the reader.

As an example, we might want to write some mathematical expression like the Pythagorean Theorem:

a_squared = 3**2
b_squared = 4**2
c_squared = a_squared + b_squared

Clearly, this expression resembles the Pythagorean Theorem based on variable name choices alone. However, not everyone will be able to tell at first glance. In other words, we might want to add a comment that tells the reader what the purpose of this expression is. For example, we might say “uses the Pythagorean Theorem to compute c^2.” How do we go about doing that? Luckily, this article will give us a few options.

Solutions

In this portion of the article, we’ll take a look at a few different ways to write comments in Python. Keep in mind that this isn’t really an article on commenting styles or even a commentary on how to write comments. Instead, we’ll just be sharing the syntax. It’s up to you to figure out how you want to use the tools provided.

Inline Comments

In Python, you can create a comment using the hash mark, #. As soon as this mark appears, everything following it until the end of the line is considered a comment:

# Uses the Pythagorean Theorem to compute c^2
a_squared = 3**2
b_squared = 4**2
c_squared = a_squared + b_squared

Since comments don’t start until the hash mark appears, we can comment the ends of lines as well:

# Uses the Pythagorean Theorem to compute c^2
a_squared = 3**2  # Computes a^2
b_squared = 4**2  # Computes b^2
c_squared = a_squared + b_squared  # Computes c^2

Normally, I’m of the belief that your code should be primarily self-documenting. That said, an inline comment here and there can be helpful for future readers—including yourself.

Block Comments Using Inline Comments

Fun fact: Python doesn’t have block comments. In other words, there is no built-in syntax for handling multiline comments. As a result, PEP 8 recommends using repeated inline comments for block comments:

# Uses the Pythagorean Theorem to compute c^2.
# First, we compute a^2 and b^2. Then, the 
# expression is constructed as a^2 + b^2 and 
# assigned to c^2.
a_squared = 3**2  # Computes a^2
b_squared = 4**2  # Computes b^2
c_squared = a_squared + b_squared  # Computes c^2

Again, these comments are probably excessive; their role is to provide an example of a block comment.

Block Comments Using Multiline Strings

With all that said, it’s possible to simulate block comments with multiline strings:

"""
Uses the Pythagorean Theorem to compute c^2.
First, we compute a^2 and b^2. Then, the 
expression is constructed as a^2 + b^2 and 
assigned to c^2.
"""
a_squared = 3**2  # Computes a^2
b_squared = 4**2  # Computes b^2
c_squared = a_squared + b_squared  # Computes c^2

Now, that looks a little cleaner to me. In addition, it’s a bit easier to manage in source code in my opinion.

That said, keep in mind that this isn’t a true comment. We’ve instead created a string constant which isn’t assigned to a variable. In practice, this isn’t really an issue as the strings will get optimized out in the bytecode.

Another word of caution: sometimes this style of comment can be interpreted as a docstring. For example, if we insert this comment just below a function header, we’ll have created a docstring for documentation purposes:

def pythagorean_theorem(a, b):
  """
  Computes the length of the squared third leg of a right triangle.
  """
  a_squared = a**2
  b_squared = b**2
  c_squared = a_squared + b_squared
  return c_squared

In this example, our multiline comment is actually a docstring which we can use to document the method:

def pythagorean_theorem(a, b):
  """
  Computes the length of the squared third leg of a right triangle.
  :param a: the length of the first leg of the triangle
  :param b: the length of the second leg of the triangle
  :return: a^2 + b^2
  """
  a_squared = a**2
  b_squared = b**2
  c_squared = a_squared + b_squared
  return c_squared

Then, this docstring becomes a runtime attribute of the function. In other words, we can inspect that attribute as follows:

print(pythagorean_theorem.__doc__)

As you can see, docstrings aren’t like comments in the sense that docstrings still exist at runtime—regular comments do not. Many IDEs and other tools can then extract these docstrings for documentation purposes. How cool is that?

Challenge

At this point, I’d usually measure performance, but I didn’t feel like that would be applicable. Instead, let’s jump straight to the challenge!

Now that we know three different ways to comment code in Python, let’s talk about good commenting practices. In the comments below, share at least one tip you recommend when it comes to commenting code. Feel free to share anything from commenting styles to commenting etiquette. Bonus points for anything that’s Python specific.

As always, I’ll share my own tip below as well! If possible, I’d love to get a little discussion going. Depending on how it goes, I might compile the results in another article.

A Little Recap

And with that, we’re all done. As always, here’s a little recap of our three ways to comment Python code:

# Here is an inline comment in Python

# Here
# is
# a
# multiline
# comment
# in
# Python

"""
Here is another multiline comment in Python.
This is sometimes interpretted as a docstring,
so be careful where you put these.
"""

If you liked this article, and you want to see more like it, hop on my mailing list. Alternatively, you can contribute even more by becoming a patron and getting your name on the Wall of Fame. Finally, I’d love it if you ran over to YouTube and subscribed to my channel.

Since you’re here, you might benefit from my Python 3 Beginner Cheat Sheet. It’s basically a two-page document of Python syntax including if statements, loops, and expressions. If you’re looking to learn more about Python expressions, I also have a fun lab you can try out.

Beyond that, you can always check out some of these related articles:

Otherwise, thanks for stopping by! I appreciate it.

The post How to Comment Code in Python: Inline, Multiline, and Docstring appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/how-to-comment-code-in-python/feed/ 0 20719