The Renegade Coder https://therenegadecoder.com Code First. Ask Questions Later. Wed, 24 Apr 2019 21:29:29 +0000 en-US hourly 1 https://wordpress.org/?v=5.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 Boeing’s Mistakes Highlight an Industry-Wide Problem https://therenegadecoder.com/blog/boeings-mistakes-highlight-an-industry-wide-problem/ https://therenegadecoder.com/blog/boeings-mistakes-highlight-an-industry-wide-problem/#respond Mon, 20 May 2019 14:00:44 +0000 https://therenegadecoder.com/?p=15804

Apparently, Boeing engineers are blowing whistles on major culture issues. It reminds me of my good ol' engineering days.

The post Boeing’s Mistakes Highlight an Industry-Wide Problem appeared first on The Renegade Coder.

]]>

Apparently, Boeing engineers are blowing whistles on major culture issues. It reminds me of my good ol' engineering days.

Looks like you're not logged in to view this content. If you have an account, feel free to log in below. Otherwise, head over to the memberships page and sign up for a tier.

The post Boeing’s Mistakes Highlight an Industry-Wide Problem appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/boeings-mistakes-highlight-an-industry-wide-problem/feed/ 0 15804
How to Teach Arrays in Computer Science https://therenegadecoder.com/teach/how-to-teach-arrays-in-computer-science/ https://therenegadecoder.com/teach/how-to-teach-arrays-in-computer-science/#respond Fri, 17 May 2019 14:00:36 +0000 https://therenegadecoder.com/?p=12885

While I've been writing tutorials for students, I thought: what if I wrote tutorials for other teachers. Today, let's learn how to teach arrays.

The post How to Teach Arrays in Computer Science appeared first on The Renegade Coder.

]]>

It may seem odd that I’m trying to teach arrays when I’ve already written an article about the data structure. But, articles are only so useful at conveying a concept. In this article, we’ll cover a few methods for conveying the concept in a classroom setting. If all goes well, I might make this into a series!

Table of Contents

What Are Arrays?

Before we dive in, I’d like to preface this article by stating that the approach in this article is largely language-agnostic. In other words, I won’t focus on any specific languages, but I will draw from my Java, C/C++, C#, and Python experience. As a result, there may be some concepts used that aren’t necessarily language-agnostic (i.e. indexing from zero, strings, etc.). Regardless, I think there are plenty of lessons to be learned by having concrete examples.

Naturally, my target audience with this article is fellow teachers who are looking for some new methods to teach the same old concepts. In addition, I’m looking to use this article as a way to document some of the things I’ve learned over the years. As a result, you can expect this article to grow and develop over time.

So, what are arrays? Well, I’m assuming you already know. If not, maybe you should check out my article on Arrays, but to summarize:

An array is a collection of data. More specifically, an array is a fixed-size chunk of memory that is split into cells for data storage. The size of the data type determines the size of each cell and the overall size of the array.

In C-like languages, arrays are defined as follows:

int[] numbers = new int[10];

In this example, we’ve defined an integer array of size 10. In other words, we can store at most 10 integers. Naturally, we can make arrays of any type and any size. However, those parameters of the array are fixed after declaration.

Alright, that’s enough review for now! Let’s continue!

Learning Objectives

When teaching arrays, we should have a handful of goals we want to reach by the end of the lesson. In no particular order, here are a few of mine (using Java as an example).

Students should be able to:

  • Understand and use array-related terminology:
    • Array
    • Element
    • Index
  • Read and write valid array syntax:
    • Declare: int[] arr;
    • Define: arr = new int[10];
    • Set: arr[3] = 5;
    • Get: int x = arr[2]
  • Accomplish usual array tasks:
    • Populate
    • Traverse
    • Search
    • Sort
    • Copy

Depending on the lesson, we may want to expand or narrow the scope of this list. Regardless, this is a great start!

Challenges

When it comes to learning arrays, students may run into a few challenges. In this section, I’ll share some of the challenges I’ve noticed, and how I try to address them.

No Data Structures Intuition

By the time arrays are introduced, students usually have no intuition around data structures. If they want to store some values, they often opt for as many variables as it takes to get the job done.

To address this knowledge gap, I like to relate arrays to something they’ve used quite a bit already: strings. After all, strings are just character arrays with extra functionality.

One transferable skill from strings is indexing. If students understand how to retrieve characters from a string by index, they should be comfortable indexing an array. Likewise, strings often start indexing at zero, so students familiar with strings should be able to draw the connection.

Regardless, this may be the first time a student is dealing with the concept of a data structure, so it’s important to relate the idea to collections they might know from everyday life.

No Indexing Intuition

For some students, arrays might be the first time they’ve ever had to start counting from zero. For most students, indexing from zero is counterintuitive. After all, we typically start counting from one in everyday life. Of course, starting from zero isn’t exactly a foreign concept. After all, we usually start from zero with continuous data like timelines, so there are plenty of opportunities for real world parallels.

As mentioned already, strings can be a great place to start if you’ve already introduced them. In many programming languages, strings are character arrays, so the parallels should be clean cut. Just be aware that strings are often immutable, and arrays are typically not.

No Reference Type Intuition

If arrays are the first time a student is exposed to objects, they’re bound to run into a few problems. For instance, this may be their first time dealing with references, so it’s important to demonstrate that copying is a nontrivial task.

Also, as mentioned previously, students may have used strings before. Unfortunately, the parallels between strings and arrays sort of break down when talking about reference types. In many languages, strings are immutable, so you can’t actually make changes to them like you can to an array. Be aware of this mental leap if you choose to use strings in your examples.

Methods

Given the learning objects and challenges, how do we go about actually teaching arrays? In this section, I’ll cover some of my favorite methods with examples.

Teaching Through Related Principles

As mentioned several times already, there’s a good chance that students already have some familiarity with a data type that closely mimics arrays: strings. After all, if your course starts with Hello World, then you’ve already exposed your students to strings.

I like to use strings because a lot of languages model them using arrays. In languages like Java, it’s not a stretch to go from str.charAt(0) to str[0]. In other languages like Python (which uses something closer to an array list), the syntax is exactly the same. As a result, there’s a good chance you’ve already taught arrays.

Of course, there are usually a few loose ends you need to tie up. For example, initialization is usually a bit different. Be certain to share that arrays may have a different initialization syntax than strings:

String str = "Hello";

// vs
char[] str = {'H', 'e', 'l', 'l', 'o'};

// vs
char[] str = new char[5];
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';

Eventually, you’ll need to isolate the concept of arrays from strings after students have transferred some of their knowledge. I like to use the challenge of copying arrays as a segue into more interesting topics like nested arrays and array lists.

Teaching Through Real World Examples

While strings are a great tool for teaching arrays, we’re not really eliminating the problem of teaching arrays. After all, concepts like indexing have to be taught at some point. Enter: real world examples.

When teaching arrays, I like to draw parallels between concepts like paper lists and spreadsheets. With paper lists and spreadsheets, each item is usually assigned some number which we can relate to indices in an array.

As with many real world examples, the analogy usually breaks at some point. For instance, real world lists usually don’t have a limitation on how many items can be in them whereas arrays do.

As a result, I sometimes prefer to opt for a bookcase analogy. Each shelf is an array bound by the width of the shelf. Of course, books can be different sizes which breaks the fundamental definition of an array, but I find it can be a better analogy than a paper list.

Whatever analogy you choose, be aware of its limitations, and only use it as a way to bridge what your students already know with what they need to know.

Visual Aids

Finally, let’s get to the good stuff! After all, when I teach, I like to draw a lot of pictures, so let’s look at a few visual aids for arrays.

Memory Maps

One tool I’ve found useful over the last year is the memory map. If you’re not familiar with the idea, it’s basically an empty grid which you can use to demonstrate how objects might be stored in memory.

Memory Map Diagram

When you use a memory map for arrays, you can segment out a section of the memory map to demonstrate a contiguous block of memory. Then, you can fill various cells with numbers or characters to begin demonstrating the idea of arrays.

To me, the real power in memory maps is showing how pass-by-value works. In other words, you can show how a function might copy an array reference when passed as an argument.

Stack and Heap

If you want to get into the nitty gritty details, you may want to consider introducing the concepts of stack and heap. You don’t necessarily need to explain the concepts in depth considering your students’ lack of array knowledge, but I find visualizing the two sections of memory to be very helpful.

Stack and Heap Diagram

I like to draw a stack that just contains a call to the main method which creates an array. Then, I like to show that the address to the array gets stored on the stack while the array itself is placed in the heap. This usually further solidifies the idea of reference types.

Arrays

Yeah, it may seem silly, but sometimes the best way to explain a concept is to draw it directly. There are a lot of ways to draw an array, but I use two different kinds of diagrams typically: one uses the array syntax while the other likes like a one-dimensional grid.

Array Diagram

In either case, the idea should be clear. For instance, each cell has some index and stores some data. Then, you can use this visualization to demonstrate the various interactions you can have on an array like insertion and deletion.

In fact, I find the array visualization to be the best in terms of scalability. You can use it to show all sorts of actions like sorting, traversal, and population.

Activities

While analogies and visual aids are great for introducing computer science material, it’s critical that you actually provide something for the students to do to reinforce their understanding.

Labs

It’s typical for computer science curriculum to include a lab component where students explore a concept alongside the instructor. For arrays, that means running through tasks that force the student to interact with the data structure. Typical tasks might include:

  • Initialization: create an array
  • Population: fill the array with items
  • Traversal: perform an operation on every item in the array
  • Search: find an item in the array

Of course, there are more advanced tasks like:

  • Sorting: rearrange the items in the array according to some order
  • Copying: duplicate an array
  • Nesting: explore multi-dimensional arrays

And, I’m sure there are plenty of other activities you can do in lab. Just pick a few of the topics above and find a way to make it interesting. For example, it might be fun to do a Caesar cipher with arrays. Ask students to load up an array with some characters then shift them by some offset. Here are a couple of labs I’ve seen in the wild:

Ultimately, the goal in lab is to stimulate some reasoning about the topic. I usually like to employ the Socratic method in lab. Instead of answering questions directly, I’ll try to point the students in the right direction by asking them pointed questions. Of course, this can become a time crunch if you have a lab filled with 40 students like I did, so don’t be afraid to give away solutions.

Games

A lot of people may find games a little unprofessional for adults, but I find they can be great for injecting some excitement into the classroom. If students are having fun with the material, you know you’re doing something right. Just make sure it’s authentic and not too gimmicky.

For instance, I once held a jeopardy game for the class. Essentially, I had the students get into teams. Then, for each question, every group had 15 seconds to write their answer on the board. If the group got it, they got the points. The competitive nature of the game forced students to think quickly. As a result, when students clearly didn’t know an answer, I was able to pause and explain it.

Due to the nature of jeopardy, answers have to be short. Naturally, It can be difficult to come up with 25 interesting short answer questions just related to arrays, so you may want to seek other options. For instance, platforms like Top Hat and Kahoot! are great for generating quiz-like games. Students join in with their smart phones or laptops and face a series of questions. Naturally, this can turn into a bit of a competitive game among your students who all want to be the first to share the right answer.

In terms of content, definitions of terms like arrays, traversal, and index are all great. In addition, you can share code snippets and ask students for the result (i.e. list[i]). Whatever you choose to do, the students will appreciate the break in lecture.

Interactive Lessons

One thing I always try to do is make lectures interactive. Whether that means asking questions or organizing group projects, it doesn’t really matter. Interactivity is key here. An engaged class is a learning class, and that’s all the more important when working with challenging computer science topics.

Personally, I used Top Hat to periodically quiz students throughout class. This helped me gauge understanding without having to constantly ask “does that make sense?” For arrays, I might ask basic indexing questions to ensure students know that arrays start from zero (or whatever the convention is in your language of choice).

I also like to give students a break from lecture by giving them a coding problem to solve for a few minutes in groups. For example, I might ask the class to break up into groups and write a code snippet which can compute the average of the numbers in an array. After a few minutes, I’ll let the students share their work, and I might even share an example of my own. Ultimately, I like to push the idea that there are a lot of ways to solve the same problem.

Homework

What you send your students home with is just as important as what you teach in class. Make sure you’re intentional with your homework assignments, and you’re not just creating busy work.

Quizzes

A lot of classes I’ve been in have had some form of online quizzes to ensure students are keeping up with the work. I recommend keeping the point value low on quizzes, so students don’t feel pressured when they don’t understand something. After all, these quizzes are for you, the instructor, not the students. It’s your job to assess the growth of your students, and quizzes can be a nice way of accomplishing that.

In terms of array-related quizzes, I recommend covering high-level concepts only. For instance, it’s helpful to show code snippets and ask students to tell you what they do:

x = [1, 4, 6]
print(x[1]) # What does this print?

These sort of comprehension questions can help you gauge your students’ understanding of arrays.

In terms of format, you can easily issue quizzes outside class as homework. Alternatively, you may leverage quizzes as in class checkpoints. Either way, I think there is some value in tracking progress regularly.

Projects

As with any well-rounded computer science curriculum, I think it’s a good idea to send your students home with a project or two. Ideally, projects should be harder than the material you go through in class and in lab. That way, students have a chance to really fight through problems on their own or in small teams.

When I took an intro programming class, we were asked to make a game. In particular, we made something similar to Bejeweled where there is a grid of colors that you can match. The grid, of course, is made of a set of nested button arrays which relate to columns and rows of the game board. Naturally, there are a lot of these kinds of grid-based games. For instance, you might ask students to implement a simple version of 2048 or even the Game of Life.

If games seem too challenging, you can always opt for any number of array manipulation projects: sorting, searching, etc. Alternatively, you could go the data science route. For instance, you could ask students to fill an array with numbers and perform statistics computations on the collection: max, min, average, standard deviation, median, mode, etc.

Depending on your students’ experience level, you may want to provide them with a template of methods to fill out. Alternatively, you could provide an API and ask the students to reproduce the functionality in code.

In either case, be careful with your deadlines. In my opinion, students should be given a couple weeks to complete projects. The extra time should make them feel less rushed, so you get better results. Also, longer timelines forces students to focus on their time management skills. Most students will wait until the last minute anyway, but people like me will appreciate the breathing room.

Problem Sets

While quizzes are great for checkups and projects are great for practice, problem sets are great for theory. In other words, create problem sets when you want students to stretch their understanding.

In terms of arrays, problem sets should include questions that push the boundaries on what students already know. For instance, it might be interesting to ask students how they would implement an array list without telling them about array lists. This forces students to think about how to handle the case where an array is at capacity and a user tries to add another element. It also gets them to touch on topics like copying.

Alternatively, problem sets can be used to reinforce jargon. I wouldn’t necessarily have students copy and paste definitions, but it may be helpful to have them give definitions in their own words. For example, you could have them explain to you what an array is and how it is used.

Personally, I like compare and contrast questions the most. Unfortunately, students are probably being exposed to data structures for the first time, so arrays stand alone. However, it may be a good opportunity to ask about the differences between primitive types and reference types (language-dependent of course).

As students get deeper in their computer science curriculum, I find that professors tend to go the problem set route since topics are more theoretical. Regardless, problem sets can be a good chance for students to really explain their thought process.

Feedback

As always, I’m aware I’m not the only computer science educator in the world. If you’ve taught arrays in the past, what are some of your favorite ways of conveying the material? Feel free to share your thoughts.

Otherwise, thanks for stopping by! I appreciate the support, and I hope you’ll continue to stick around.

The post How to Teach Arrays in Computer Science appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/teach/how-to-teach-arrays-in-computer-science/feed/ 0 12885
Why I No Longer Enjoy Online Gaming https://therenegadecoder.com/blog/why-i-no-longer-enjoy-online-gaming/ https://therenegadecoder.com/blog/why-i-no-longer-enjoy-online-gaming/#respond Mon, 13 May 2019 14:00:16 +0000 https://therenegadecoder.com/?p=15635

After 15 or so years of online gaming, I've decided to start cutting back. Here's why.

The post Why I No Longer Enjoy Online Gaming appeared first on The Renegade Coder.

]]>

After 15 or so years of online gaming, I've decided to start cutting back. Here's why.

Looks like you're not logged in to view this content. If you have an account, feel free to log in below. Otherwise, head over to the memberships page and sign up for a tier.

The post Why I No Longer Enjoy Online Gaming appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/why-i-no-longer-enjoy-online-gaming/feed/ 0 15635
The Guide to Causing Mass Panic https://therenegadecoder.com/blog/the-guide-to-causing-mass-panic/ https://therenegadecoder.com/blog/the-guide-to-causing-mass-panic/#respond Fri, 10 May 2019 14:00:41 +0000 https://therenegadecoder.com/?p=15602

Awhile back, I published an article about an event that caused mass panic on social media and have since made it premium content. That is this article.

The post The Guide to Causing Mass Panic appeared first on The Renegade Coder.

]]>

Awhile back, I published an article about an event that caused mass panic on social media and have since made it premium content. That is this article.

Looks like you're not logged in to view this content. If you have an account, feel free to log in below. Otherwise, head over to the memberships page and sign up for a tier.

The post The Guide to Causing Mass Panic appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/the-guide-to-causing-mass-panic/feed/ 0 15602
Be Careful When Copying Mutable Data Types https://therenegadecoder.com/code/be-careful-when-copying-mutable-data-types/ https://therenegadecoder.com/code/be-careful-when-copying-mutable-data-types/#respond Mon, 06 May 2019 14:00:07 +0000 https://therenegadecoder.com/?p=15438

As with many posts in this series, I'm interested in examining some of the pitfalls when learning to code. Today, we'll cover the pitfalls when copying mutable data types.

The post Be Careful When Copying Mutable Data Types appeared first on The Renegade Coder.

]]>

Recently, I was working on an article about list comprehensions in Python when I thought it would be helpful to talk a little bit about making copies of variables. In particular, I want to take a moment address some of the risks when copying mutable data types.

Table of Contents

Immutability

Before we talk about copying variables, it’s important discuss an important programming language feature called immutability. Immutability describes a variable which cannot be changed. In other words, immutable variables are constants.

More specifically, immutability implies that a variable cannot be mutated. For example, an immutable string cannot have any characters changed or removed without creating a completely new string in the process. We often see this when working with numbers in a language like Java or Python:

num = 5
copy = num

Naturally, we would expect that anything that happens to copy has no effect on num. That’s because numbers are typically immutable. In other words, the 5 that is stored in num has an identity that is unique from the 5 that is stored in copy.

Unfortunately, in most programming languages, immutability has very limited support. As a result, variables beyond numbers and strings are typically mutable which means the code snippet above will fail to create a copy. Instead, you’ll get what’s called “spooky action at a distance” in quantum entanglement. In other words, whatever you do to one variable will happen to the other variable.

The Basics of Copying

Since most languages lack support for immutability, we’re stuck dealing with the consequences when creating copies. In particular, we have to create new variables with all the same properties of the variable we’d like to copy by hand. In the following subsections, we’ll look at how this plays out.

Copying a List in Python

If we wanted to copy a list in Python, we might try the following:

my_list = [1, 2, 3]
my_copy = my_list

If we poke around, we’ll notice that both lists are in fact the same. What a big success, right? Maybe we should take another look:

my_copy[1] = 7
print(my_list)  # Prints [1, 7, 3]... uh oh!

As we can see, lists in Python are mutable. When we created a “copy,” we actually copied the reference—not the contents of the list.

To create a proper copy, we need to iterate over the list and add each element to a new list:

my_copy = [item for item in my_list]

Here, we used a list comprehension to create a copy of the original list. Now when we manipulate the new list, we don’t have to worry about corrupting the old list. But, is this enough?

Copying Nested Lists in Python

As it turns out, a list comprehension isn’t guaranteed to perform a proper copy. For example:

my_list = [[1, 2], [2, 7]]
my_shallow_copy = [item for item in my_list]

Here, we’ve created a shallow copy of my_list. While the new list has a unique identity from the original list, the contents of both lists are the same. In other words, the following is safe:

my_shallow_copy.append([5, -4])
print(my_list)  # Prints [[1, 2], [2, 7]]

However, changing any of the nested elements will result in corruption of both lists:

my_shallow_copy[0][1] = -4
print(my_list) # prints [[1, -4], [2, 7]]... uh oh!

If we want perform a deep copy in this case, we have to copy the nested lists as well:

my_deep_copy = [[item for item in sub_list] for sub_list in my_list]

Naturally, this leads us to writing a recursive function that can handle an n-dimensional matrix:

def deep_copy(item):
  if type(item) is list:
    return [deep_copy(sub_list) for sub_list in item]
  else:
    return item

Of course, even this deep copy function can only go so far. What if our lists contain mutable objects?

Copying Mutable Objects in Python

At this point, we’re fairly comfortable with copying immutable data types like numbers and strings as well as mutable data types like lists, but what if the data types we’re dealing with are something else? For example, what if we make our own class as follows:

class Votes:
  def __init__(self):
    self.pro = list()
    self.anti = list()

Here, we’ve created some class that represents a set of votes which maintains two lists: pro (for) and anti (against). We can populate those lists with unique IDs that represent voters:

town_votes = Votes()
town_votes.pro.append("109437139")
town_votes.pro.append("476524275")
town_votes.pro.append("794314532")
town_votes.anti.append("420901790")

Great, now we can do fun things like count the votes for and against:

len(town_votes.pro)  # 3
len(town_votes.anti)  # 1

Now, let’s say we have several people counting the votes, so we can make sure we got it right. For security purposes, we want to create a deep copy of the town_votes objects, so corrupt individuals don’t ruin the counts for everyone. If they try, they should fail during the final check.

Of course, how do we copy our town_votes object? For example, would something like this work:

duplicate = town_votes

Of course not. We’ve only copied the reference which results in the same problem we had with lists. But, what if we make a new Votes object and duplicate its references:

duplicate = Votes()
duplicate.pro = town_votes.pro
duplicate.anti = town_votes.anti

Sure, we now have a new Votes object, but there’s still a problem: the pro and anti lists are the same. In other words, we’ve only created a shallow copy of our Votes object. Luckily, we know a thing or two about cloning lists:

duplicates.pro = [id for id in town_votes.pro]
duplicates.anti = [id for id in town_votes.anti]

Now, we have a deep copy of our town_votes object. If someone were to come along and tamper with the copy, we’d still be okay.

Copying Constructors

What we just managed to accomplish with the Votes object is known as a deep copy. Naturally, the process scales up quickly depending on how many references our object is storing. What can make matters worse is if those references store references. To deal with this, it’s not uncommon for libraries to implement what is known as a copy constructor:

def __init__(self, to_copy=None):
  if to_copy:
    self.pro = [id for id in to_copy.pro]
    self.anti = [id for id in to_copy.anti]
  else:
    self.pro = list()
    self.anti = list()

Then, if we ever want a deep copy of our Votes object, we’ll provide it as the input to the constructor. And, if our votes lists contained references (like hypothetical Voter objects), we could call their copy constructor directly from the list comprehension:

def __init__(self, to_copy=None):
  if to_copy:
    self.pro = [Voter(id) for id in to_copy.pro]
    self.anti = [Voter(id) for id in to_copy.anti]
  else:
    self.pro = list()
    self.anti = list()

Of course, there are challenges when performing a deep copy. Perhaps the most dangerous are circular references where one object points to another and the other points back. During copying, both objects would need to construct each other in an infinite loop. To deal with that, you usually need to maintain some sort of reference lookup table to see if you’ve ever duplicated that object in the past.

In any case, Python does provide copying libraries that can handle all this fun stuff for you within reason. I won’t go into that here because I wasn’t planning to write a Python article, but you’re welcome to dig into the documentation yourself.

Attack of the Clones

At this point, I hope you’re more comfortable with concepts like immutability and cloning. These concepts apply to just about every popular language used today like C, C++, JavaScript, and Java. You’d be hard pressed to find a language which implements total immutability, but there are a few that exist. I believe most functional languages try to avoid the notion of state, so you might be able to avoid this cloning issue using languages like Haskell.

While you’re here, I recommend checking some of the following articles:

And, if you’re feeling extra generous, check out the membership page for subscription information. Every little bit helps!

The post Be Careful When Copying Mutable Data Types appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/be-careful-when-copying-mutable-data-types/feed/ 0 15438
How to Write a List Comprehension in Python https://therenegadecoder.com/code/how-to-write-a-list-comprehension-in-python/ https://therenegadecoder.com/code/how-to-write-a-list-comprehension-in-python/#respond Fri, 03 May 2019 14:00:58 +0000 https://therenegadecoder.com/?p=15408

After covering so many common problems, I thought it would be fun just to explore a chunk of syntax known as the list comprehension in Python.

The post How to Write a List Comprehension in Python appeared first on The Renegade Coder.

]]>

Welcome back to yet another post in the How to Python series. This time I’m looking to step back a little bit to talk about one of Python’s builtin features called the list comprehension. While we’ve used them a few times in the series, I never thought to really explain them until now.

Table of Contents

Problem Introduction

Unlike other articles in this series, there’s not exactly a concrete problem we’re trying to solve in this article. Instead, the goal is to understand the list comprehension syntax:

nums = [2, 6, 10, -4]
negative_nums = [x for x in nums if x < 0]

What is this bizarre syntax, and how does it work? That’s the goal of the article today. In particular, we’ll look at a few scenarios where a list comprehension is useful such as:

  • Duplicating a list
  • Modifying a list
  • Filtering a list
  • Filtering and modifying a list
  • Generate all pairs from two lists
  • Duplicating nested lists

If you know of anything else we can do with a list comprehension, let me know!

Solutions

Before we can dive into the solutions, let’s talk about the syntax a bit. Here’s my best attempt at illustrating the concept:

output = [expression(item) for item in some_list]

At the most basic level, we can construct a list comprehension that iterates over each item in some list, performs some expression on that item, and places that new item in an output list. Or as a loop:

output = []
for item in some_list:
  output.append(expression(item))

Of course, we can do a lot more than just create a list from some other list with a list comprehension. In the following subsections, we’ll take a look at a few examples.

Duplicate a List

Perhaps the simplest use of a list comprehension is duplicating another list:

my_list = [2, 5, -4, 6]
output = [item for item in my_list]  # [2, 5, -4, 6]

In this case, output will be equivalent to my_list. For completeness, here’s the same solution as a loop:

my_list = [2, 5, -4, 6]
output = []
for item in my_list:
  output.append(item)

As we can see, the list comprehension is significantly more concise. In either case, we will only perform a shallow copy—meaning items in the new list may point to the same items in the old list—so it’s a good idea to only use this syntax for copying lists of immutable values like numbers.

Modify a List*

Now that we know how to duplicate a list, let’s try modifying the items before we add them to the output list:

my_list = [2, 5, -4, 6]
output = [2 * item for item in my_list]  # [4, 10, -8, 12]

Instead of copying the original list directly, we modified each item by multiplying it by two before storing it in the new list. As a result, we end up with a list where each term is twice as big as it was in the original list. Here’s the same concept using a loop:

my_list = [2, 5, -4, 6]
output = []
for item in my_list:
  output.append(item * 2)

To be clear, as the asterisk probably hints, we didn’t actually change the original list. Instead, we created a completely new list with the items doubled.

If my_list contained objects or some other mutable data type like a list, there would be nothing stopping us from modifying them. Of course, that’s considered bad practice, so I neglected to share an example on the off chance that someone haphazardly copies it into a production system.

Filter a List

While duplicating and modifying lists is fun, sometimes it’s helpful to be able to filter a list:

my_list = [2, 5, -4, 6]
output = [item for item in my_list if item < 0]  # [-4]

In this case, we’ve added a new expression to the rightmost portion of the list comprehension that reads: if item < 0. Of course, the loop equivalent might look something like the following:

my_list = [2, 5, -4, 6]
output = []
for item in my_list:
  if item < 0:
    output.append(item)

In other words, for each item in the list, only consider it if it’s less than zero. If it is, dump it to the new list. As a result, we end up with a list that only contains negative values.

Filter and Modify a List

Naturally, we can both modify and filter a list at the same time by combining the syntax:

my_list = [2, 5, -4, 6]
output = [2 * item for item in my_list if item < 0]  # [-8]

In this case, we’ve decided to double all negative values before dumping the results to a list. Once again, the same syntax as a loop might look something like:

my_list = [2, 5, -4, 6]
output = []
for item in my_list:
  if item < 0:
    output.append(item * 2)

As a result, the output list only contains -8. Once again, it’s important to mention that we didn’t actually modify the original list.

Generate All Pairs from Two Lists

Now, we’re starting to get into some of the more advanced features of list comprehensions. In particular, we’re looking to generate pairs of values between two lists:

# [(1, 2), (1, 4), (1, 6), (3, 2), (3, 4), (3, 6), (5, 2), (5, 4), (5, 6)]
output = [(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]

Here, we’ve created a list that contains all combinations of pairs from two lists. As usual, we can implement the same thing with the following set of loops:

output = []
for a in (1, 3, 5):
  for b in (2, 4, 6):
    output.append((a, b))

If we wanted to make things more interesting, we could apply some filtering:

# [(3, 2), (5, 2), (5, 4)]
output = [(a, b) for a in (1, 3, 5) for b in (2, 4, 6) if a > b]

In this case, we only generate a pair if the number from the first list is larger than the number from the second list.

Duplicate Nested Lists

With the shallow copy example mentioned earlier, we’re not able to duplicate nested lists such as two-dimensional matrices. To do that, we can leverage nested list comprehensions:

my_list = [[1, 2], [3, 4]]
output = [[item for item in sub_list] for sub_list in my_list]
print(output) # Prints [[1, 2], [3, 4]]

Instead of performing a surface-level copy, we retrieve each list and copy them using the same comprehension from before. As you can probably imagine, we could abstract this concept into a recursive function which performs a list comprehension on every dimension of the matrix:

def deep_copy(to_copy):
  if type(to_copy) is list:
    return [deep_copy(item) for item in to_copy]
  else:
    return to_copy

How cool is that? Of course, if you have anything other than numbers or strings at the deepest levels of your matrix, you’ll have to handle the rest of the cloning process yourself.

A Little Recap

As always, here is a giant dump of all the examples covered in this article with comments briefly explaining each snippet. Feel free to grab what you need and go!

# Define a generic 1D list of constants
my_list = [2, 5, -4, 6]

# Duplicate a 1D list of constants
[item for item in my_list]

# Duplicate and scale a 1D list of constants
[2 * item for item in my_list]

# Duplicate and filter out non-negatives from 1D list of constants
[item for item in my_list if item < 0]

# Duplicate, filter, and scale a 1D list of constants
[2 * item for item in my_list if item < 0]

# Generate all possible pairs from two lists
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]

# Redefine list of contents to be 2D
my_list = [[1, 2], [3, 4]]

# Duplicate a 2D list
[[item for item in sub_list] for sub_list in my_list]

# Duplicate an n-dimensional list
def deep_copy(to_copy):
  if type(to_copy) is list:
    return [deep_copy(item) for item in to_copy]
  else:
    return to_copy

I hope you had as much fun reading through this article on list comprehensions as I did writing it. I think at this point in the series I’m going to start exploring basic concepts like this and stretching them to their limits. Do you have a Python concept that you’d like explored? Let me know!

In the meantime, why not check out some of these other awesome Python articles:

And, if you’re feeling extra generous, make your way over to the members page and take a look at your options. You’re welcome to try before you buy. That’s why there’s a free option. At any rate, thanks again for the support. Come back soon!

The post How to Write a List Comprehension in Python appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/how-to-write-a-list-comprehension-in-python/feed/ 0 15408
The Problem with Working in Teams https://therenegadecoder.com/blog/the-problem-with-working-in-teams/ https://therenegadecoder.com/blog/the-problem-with-working-in-teams/#respond Mon, 29 Apr 2019 14:00:18 +0000 https://therenegadecoder.com/?p=14669

In this rant, I discuss my history of working in teams in both academia and industry and how it's been mostly unpleasant.

The post The Problem with Working in Teams appeared first on The Renegade Coder.

]]>

In this rant, I discuss my history of working in teams in both academia and industry and how it's been mostly unpleasant.

Looks like you're not logged in to view this content. If you have an account, feel free to log in below. Otherwise, head over to the memberships page and sign up for a tier.

The post The Problem with Working in Teams appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/the-problem-with-working-in-teams/feed/ 0 14669
Is the Work Finally Paying Off? https://therenegadecoder.com/meta/is-the-work-finally-paying-off/ https://therenegadecoder.com/meta/is-the-work-finally-paying-off/#respond Fri, 26 Apr 2019 14:00:33 +0000 https://therenegadecoder.com/?p=15358

After over two years of grinding at The Renegade Coder, let's find out if all this work is paying off.

The post Is the Work Finally Paying Off? appeared first on The Renegade Coder.

]]>

Not too long ago, I was celebrating some major milestones. And while those were great, I started to wonder whether or not the work was finally paying off. In this article, I’ll take a look at what I think success is and whether or not I measure up.

Table of Contents

Backstory

It’s April 26th, 2019, and I’m reminded of the fact that I bought The Renegade Coder domain just over two years ago (April 20th, 2017). At the time, I was sitting in an engineering class at General Electric at 8AM when I decided to pull the trigger on The Renegade Coder domain. The reason? I was absolutely sick of working on a blog (Cybrotronics) with one of my best friends.

I won’t go into the details because I think my first article on this site does an excellent job of capturing my anger at the time. That said, I will remind everyone of the text that sent me over the top:

Jeremy, please don’t call me Mickey on the site. I honestly hate that nickname and want to move forward past it. Please just say Matt from now on with anything website related. I would like to be called that in general but I doubt you guys will change your way

Apr 20, 2017, 3:58 AM

To which I responded:

What’s it matter? No one puts an effort in the site. So no one will ever see it.
But I’m glad something finally got your attention hah
I’m over this bullshit.
You left the group.

Apr 20, 2017, 7:14 AM

And it was at that point that I became The Renegade Coder.

Goals

Flash forward to today, and you’ll see a dramatically different site. With over 250 articles written, a handful of open source projects in the works, and some generous community support, I’ve started to ask myself: is the work finally paying off?

Of course, that depends. What is my measure of success, and am I meeting those goals? Let’s talk about it.

Metrics

At the surface level, I’m always going to be chasing metrics like views, visitors, and revenue. After all, those metrics directly affect one of my main goals of becoming financially independent. So, how close am I to that goal?

Earlier this month, I released an article celebrating a few milestones like 100,000 lifetime views, 1,000 daily views, and 250 articles. Oddly enough, my website has blown up since then. In fact, on April 4th, I nearly cracked 2,000 daily views. We’re talking about doubling my viewership almost twice in the span of two months. That’s insane.

Naturally, the 100,000 lifetime views milestone is already starting to seem silly considering I’ve nearly doubled it in the span of two months. We’re talking about a number that I spent two years accumulating, and now it’s just another day at the office.

Of course, views are great, but there’s still a problem. I can’t convert visitors into members. As of today, I have 47 members of which just two are paid: one of my best friends and my mom. Sure, the $10/month is awesome, but I would have liked to convert a few more of those viewers along the way.

On the flip side, the ad revenue is finally becoming respectable. In fact, March returned a healthy $22, and now I’m averaging about $1/day. Hopefully by this time next month, I’ll have my first WordAds paycheck. Then, I should start seeing them more often—like every few months.

Unfortunately, I’m still worried the views will suddenly dry up. After all, I’m incredibly dependent on organic traffic, and one article in particular is carrying the bulk of my views. Hopefully, I can start building up a diverse portfolio of backlinks and members to protect against search engine updates. I’d hate to continue to be this dependent of organic traffic in the future.

Significance

That said, at a deeper level, I want to feel like I’m doing something significant. In other words, I want my work to feel like it’s worth it, and that’s a hard thing to gauge. Sure, I get some feedback, but I’m generally not that great with it. Compliments just make me feel awkward and critiques usually piss me off, and neither have really helped me feel significant.

I will say that I really like it when other bloggers write about my site. I’ve only had the pleasure of The Renegade Coder being linked on a handful of websites, but it makes me feel good when I start to get traffic from that source as a result. It’s like “wow, someone went out of their way to write about my work, and it wasn’t just a comment,” and that feels awesome.

If it’s worth anything, I’m starting to feel like a virus—in a good way. As my posts grow in popularity, people link to them which increases their popularity. It’s like a positive feedback loop that makes me feel like maybe my work is worth it.

Of course, I think I’ll always have this internal drive to become self-employed, so I’m going to continue writing no matter what. Sorry, haters!

Time

Despite feeling more significant, one thing hasn’t really improved since I started: time. In fact, I’d argue that I work harder and longer than I did before: both on the site and in my day-to-day life. As someone who saw this website as an opportunity to earn some passive income, I’m not exactly happy with where I’ve ended up.

In any given week, I’ve promised myself that I’ll post twice. Currently, the schedule is 10AM on Mondays and Fridays. Naturally, you can imagine it takes a lot of time to put together one post a week—let alone two. Fortunately, writing comes a lot easier to me now than before. Instead of spending tons of time trying to find the right wording, I’ve grown into my own style which allows me to write exactly what I’m thinking.

Regardless, I’d love to have a life outside of school and The Renegade Coder. Hell, I used to play video games, and I rarely do that anymore. My hope is that once the money starts coming in, I can start backing away from obligations that don’t bring a ton of value into my life. Of course, I’m sure everyone says that. After all, I’m two years in and still waiting for that money.

Joy

Now, to be fair, writing has brought me a lot of joy. In fact, I’d argue that it’s currently my main source of joy outside of family and friends. Unfortunately, that means a lot of my mental health rides on the success of every single post. Naturally, the quickest way to really ruin my day is to make some snarky comment about one of my articles. For example, someone didn’t like my example of an assignment grading program:

P.S. What is wrong with you Americans? Don’t you care for the alphabet? What happened to ‘E’?

Likewise, some people just like to try to read my mind instead of reading what’s actually written:

How is this a problem? Code with lots of branches is a design smell; don’t do that. Also, consider using the switch statement, which is getting more powerful with recent java releases. Or better, switch to Kotlin which has a nice when statement that is a bit more sane than switch or if else garbage.

There’s also the folks who can’t put two and two together:

The tweet mentions ‘JS’, not Java as far as I can tell?

And even the people who think they have it all figured out:

My friend, if you want to see and do macro programming right, you need to get yourself a Lisp.

Of course, I’ve received much worse—in fact, I’ve considered creating a wall of shame for such comments—but even these relatively light-hearted critiques can sap the joy out of my day rather quickly. As a result, I’ve grown a rather thick skin despite my best attempts otherwise.

Reflection

If I had to gauge my success up to this point, I’d say I’ve been doing quite well. Who else can say they’re making $30/month from work they did months ago? Who else can say they’ve written over 250 articles in two years? Who else can say they have open source projects with over 100 stars? When I look at it that way, I feel great. Let’s see how I’m feeling a year from now.

Until then, here are couple posts I think you’d enjoy if you liked this post:

Thanks again for the support! If you’d like to help me hit some of my goals outlined in this post, consider subscribing.

The post Is the Work Finally Paying Off? appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/meta/is-the-work-finally-paying-off/feed/ 0 15358
Hello World in Goby https://therenegadecoder.com/code/hello-world-in-goby/ https://therenegadecoder.com/code/hello-world-in-goby/#respond Mon, 22 Apr 2019 14:00:47 +0000 https://therenegadecoder.com/?p=15111

Looks like I'm back at it again with another installment of the Hello World series. This time we're tackling Hello World in Goby.

The post Hello World in Goby appeared first on The Renegade Coder.

]]>

In this article, we’re tackling Hello World in Goby, a Ruby-like language written in Go. For the most up-to-date version of this article, check out the official documentation.

Table of Contents

Goby Background

According to the GitHub project, Goby, formerly known as Rooby, is a Ruby-like language written in Go. The goal of the language is to provide a small environment for building microservices and API servers.

Beyond that, the project didn’t have much to offer in terms of use cases or samples. That said, the official website does give a few examples of language features including:

  • Concurrency Support
  • Builtin Multi-threaded Server
  • Plugin System

For anyone who would like to give the language a try, Goby can be installed and ran in REPL mode with the following commands:

brew tap goby-lang/goby
brew install goby
goby -i

Alternatively, you can try running all the sample code snippets using the samplerunner script included in the repo:

./samplerunner.sh run -l goby

In the following sections, we’ll cover the solution and how to run it.

How to Implement the Solution

As seen many times in this collection, Hello World in Goby is actually really simple. In total, it’s one line of code which looks a lot like Ruby:

puts("Hello, World!")

Alternatively, we can leave out the parentheses:

puts "Hello, World!"

In either case, puts writes the “Hello, World!” string to the user on standard output. That’s it!

How to Run Solution

To run this solution, we can take advantage of the samplerunner script included in the Sample Programs repo. If our system is setup correctly, the following command should get the job done:

./samplerunner.sh run -s hello-world.gb

Alternatively, we may want to get a copy of the Goby interpreter. According to the documentation, there are a few ways to do that, but we won’t dig into that now.

Unlike many other languages in this collection, Goby does not have an online interpreter at this time.

Sample Programs in Every Language

It’s been a long time since I published one of these articles. In fact, I wasn’t planning on doing it again with the sample-programs subdomain up and running. However, I ultimately decided that it was best if I could both support that website and this one simultaneously. As a result, I’ve begun cross-posting new sample-programs articles here.

Honestly, I’m pretty excited for the change. I can continue writing fun technical content on the other site while adding a personal flair here. Also, when I post here, the new content goes out to all my subscribers, so I expand my reach. It would be silly not to!

As always, if you like this series or you just want to show your support, find your way over to my membership page where you can subscribe.

The post Hello World in Goby appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/code/hello-world-in-goby/feed/ 0 15111
The Worst Professor Ever https://therenegadecoder.com/blog/the-worst-professor-ever/ https://therenegadecoder.com/blog/the-worst-professor-ever/#respond Fri, 19 Apr 2019 14:00:08 +0000 https://therenegadecoder.com/?p=15080

Sometimes you just have to get something off your chest. Today, I'd like to share the story of the worst professor ever.

The post The Worst Professor Ever appeared first on The Renegade Coder.

]]>

Sometimes you just have to get something off your chest. Today, I'd like to share the story of the worst professor ever.

Looks like you're not logged in to view this content. If you have an account, feel free to log in below. Otherwise, head over to the memberships page and sign up for a tier.

The post The Worst Professor Ever appeared first on The Renegade Coder.

]]>
https://therenegadecoder.com/blog/the-worst-professor-ever/feed/ 0 15080