Categories
Podcasts Process Programming Tampa Bay

If you’re part of a software team, you should be watching “Arguing Agile!”

Photo: Still frame from an “Arguing Agile” featuring Brian Orlando and Om Patel with guest Stormy Dickson.

If you work on a team that produces software, and especially if it’s supposed to be an agile team, do yourself a favor and check out Arguing Agile, the YouTube channel and podcast produced and presented by Tampa Bay’s own Brian Orlando and Om Patel.

They’ve been really hard at work on this project, gathering interesting guests to talk about important topics in software development, from leadership, career progression, and knowing when it’s time to quit, to handling conflict and dealing with gatekeeping, to estimations and acceptance criteria, and so many other topics!

Here’s the latest set of videos/podcasts from Arguing Agile:

And just for kicks, here are the episodes featuring The Missus and me!

Categories
Career Programming

My “How to solve coding interview” articles so far…

Meme: Coding alone (picture of not-too-bright Spider-Man villain The Rhino with stupid smirk) vs. Coding in an interview (exact same picture of not-too-bright Spider-Man villain The Rhino with stupid smirk).

Are you trying to pivot into a programming job? Are you part of the Great Resignation and looking for your next coding gig? Are you learning coding and looking for examples of how to solve programming problems?

If you answered “yes” to any of these questions, you might want to check out my series of articles on this blog in which I show you how to solve coding problems that tech companies have been known to ask in interviews.

Here’s what I’ve written so far:

Categories
Humor Programming

Truth.

Meme: Twitter tech community (mother holding child above the water in a swimming pool) / Web development (child being held up by mother) / Mobile development (child drowning in pool, ignored by mother) / Algorithms and data structures (skeleton in chair at bottom of pool).
Categories
Current Events Florida Programming Tampa Bay What I’m Up To

StartupBus Florida 2022 was a success!

The riders of StartupBus Florida 2022. From left to right: Cary, Evan, Justin, Josh, VJ, Julie, Marley, Ray, Charlotte, Joey, Mandy, Sasha, and Chevy.
StartupBus Florida 2022!
Tap to view at full size.

This article is a work in progress — I’m making it available to readers as I write it!

On Wednesday July 27, 2022, 13 people boarded a bus at The Sail on the Riverwalk in downtown Tampa bound for Austin, Texas to participate in a contest unlike any other: StartupBus 2022. I was one of those 13 people, and this is what happened on (and off) that bus.

StartupBus is the Mother of All Hackathons. The first part of the event is a three-day bus ride where buspreneurs (contestants), with help from conductors (coaches), conceive a technology startup, its software, and marketing and business plans. There are a number of buses that start in different places — in 2022, the buses left from California, Mexico City, Cincinnati, and Tampa — and they spend three days making their toward Austin, where their buspreneurs present their startups at the qualifying, semi-final, and final rounds of judging. It’s a road trip, entrepreneurship crash course, competition, and adventure all in one.

Day 1: On the bus from Tampa to Gainesville and Tallahassee

Boarding the bus

At 6:00 a.m., I arrived at The Sail, the designated pickup loacation. It’s a pavilion located downtown, on the Tampa Riverwalk, just a stone’s throw away from the Tampa Convention Center. The buspreneurs were told that the bus would depart at 7, so I expected to be the first one there. Instead, Mandy was there, and so were a handful of buspreneurs. This was a good sign.

The bus should’ve been there too, but it wasn’t. None of our bus contacts were responding to messages or Mandy’s phone calls.

“Let’s just chalk this up to Murphy’s Law and declare 6:45 as ‘panic o’clock,’” I suggested.

Fortunately, she made contact with the bus people at around panic o’clock, and they told us that they were on their way. That gave us a little more time to chat and get to know each other a little more:

Wednesday, 7:16 a.m.: VJ, Ray, Marley, Chevy, and Justin. In the background: Cary.
Tap to view at full size.

The slight delay gave us a chance to load up on coffee and a little breakfast food. We started boarding the bus soon afterward:

Wednesday, 7:22 a.m. The buspreneurs get set to board the bus.
Tap to view at full size.

Here’s a shot showing Josh’s photobombing prowess:

Wednesday, 7:22 a.m. Me in the foreground, VJ and Josh in the background.
Tap to view at full size.

…and shortly after 7:30, our bus started making its way toward the highway.

The secret route

While the buspreneurs knew that the bus would start in Tampa on Wednesday morning and arrive in Austin sometime on Friday evening, they didn’t know what route we’d take or what stops we’d make.

The simplest route from Tampa to Austin takes I-75 north to I-10, and then takes I-10 west, a route 1,200 miles (a little over 1900 km) long. If you were to drive that distance at a consistent 70 miles an hour with no stops at all, you could make the trip in a little over 17 hours. Add stops for activities (more about these later), meals, sleep (at hotels or Airbnbs — we weren’t going to sleep on the bus), and bio breaks, and the trip easily expands to fill three days. At least one of the buspreneurs did some map consulting and guessed our route and where we might end up stopping.

Here’s a map of the route we took:

The route we took from Tampa to Austin.
Tap to view at full size.

Opening ceremonies

Shortly after everyone had settled in on the bus, it was time to get started with the opening ceremonies. The buspreneurs were already familiar with us conductors, so we got on with the task of having the mentors say something to inspire them. First Cary…

Wednesday, 7:42 a.m. Cary addresses the troops.
Tap to view at full size.

…then Josh:

Wednesday, 7:43 a.m.
Tap to view at full size.
Wednesday, 7:43 a.m. The troops watch the opening address.
Tap to view at full size.

With the introductory speeches out of the way, the next step was to have the buspreneurs introduce themselves and propose a startup idea.

Wednesday, 7:47 a.m. Chevy proposes “Tinder for puppy playdates.”
Tap to view at full size.
Wednesday, 7:49 a.m. VJ proposes an electronic replacement for a first responder standard operating procedure manual.
Tap to view at full size.

The buspreneurs got to refine their startup pitches in an online meetup with one of Tampa Bay’s Toastmasters groups, who listened and provided valuable feedback.

After the meetup, the buspreneurs started talking amongst themselves to figure out which startups they should create. Remember, they had only three days to create them!

Wednesday, 9:06 a.m.
Tap to view at full size.
Wednesday, 9:47 a.m.
Tap to view at full size.
Wednesday, 9:47 a.m.
Tap to view at full size.

In the meantime, I got into an extensive conversation with Cary about his life and work, and we discovered that we had both lived in Toronto. Small world!

University of Florida Innovation Hub

At about 10:00 a.m., we arrived in Gainesville, where we paid a visit to the University of Florida’s business incubator, UF Innovate | Accelerate @ The Hub.

Wednesday, 10:18 a.m.
Tap to view at full size.

Wednesday, 10:18 a.m.
Tap to view at full size.
Wednesday, 10:21 a.m.
Tap to view at full size.
Wednesday, 10:21 a.m.
Tap to view at full size.
Wednesday, 10:31 a.m.
Tap to view at full size.
Wednesday, 10:31 a.m.
Tap to view at full size.
Wednesday, 10:35 a.m.
Tap to view at full size.
Wednesday, 10:43 a.m.
Tap to view at full size.
Wednesday, 10:43 a.m.
Tap to view at full size.
Wednesday, 11:41 a.m.
Tap to view at full size.
Wednesday, 11:57 a.m.
Tap to view at full size.

Back on the bus

Wednesday, 12:06 p.m.
Wednesday, 12:14 p.m.
Wednesday, 12:23 p.m.
Wednesday, 2:07 p.m.
Wednesday, 3:20 p.m.
Wednesday, 3:46 p.m.
Wednesday, 3:59 p.m.
Wednesday, 4:17 p.m.

Domi Station, Tallahassee

Day 2: New Orleans

The wiper hack

Stayges

Next Responder

Afterparty on the roof

A night out in New Orleans

Day 3: Austin

Making our way to Texas

Buc-ee’s!

Home stretch

Arrival at the “TikTok Mansion”

Day 4: Qualifying round

Breakfast and getting ready

Capital Factory and the qualifying rounds

Brent Britton and CoreX

Day 2: Semifinals and finals

Categories
Humor Programming

Don’t interrupt a programmer at work…

…because this could happen:

Comic showing what happens when you interrupt a programmer in the “flow state.”
Creative Commons comic by Jason Heeris. Tap to view the original.
Categories
Programming

Getting my (rubber) ducks in a row

Photo: Acer Nitro 5 laptop computer with monitor and many rubber ducks.
Tap to view at full size.

In programming, there’s a term called rubber duck debugging. It’s a problem-solving technique where you describe the problem you’re facing in as simple a way as possible to an inanimate object, such as a rubber duck. 

It’s turned out to be a good way to solve many programming problems. When you describe how something should work and then look at the system and see how it isn’t working, it often becomes easy to spot where the issue is.

You could perform the exact same thing with a person — in fact, it’s one of the things that pair programmers are supposed to do — but when another person isn’t available, a rubber duck can come in pretty handy. So I’ve started a collection.

The newest addition is the Einstein duck, located below the big monitor on the left. I supposed I could’ve ordered it from Amazon, but I bought it at the gift shop the History of Science Museum when I visited Oxford last month.

See also…

Categories
Career Programming

How to solve coding interview questions: Linked lists, part 3

The linked list exercises continue! In case you missed them, be sure to check out part 1 and part 2 of this linked list series before moving forward…

Adding an item to the start of a linked list

In this article, the first new feature we’ll implement is the ability to add new items to the start of the list. It’s similar to adding an item to the end of a list, which is why I reviewed it above.

The diagram below shows the first two nodes of a linked list. Recall that a linked list’s head points to its first node and that every node points to the next one:

Here’s how you add a new node to the start of the list. The new node becomes the first node, and the former first node becomes the second node:

Here are the steps:

  • Create a new node. In our implementation, newly-created nodes have a next property that points to null, nil, or None by default.
  • If the list is empty (i.e. head points to null, nil, or None), adding it to the list is the same thing as adding it to the start of the list. Point head to the new node and you’re done.
  • If the list is not empty, you need to do just a little more work.
    • Point the new node’s next property to head. This makes the current first node the one that comes after the new node.
    • Point head at the new node. This makes the new node the first one in the list.

Here’s how I implemented this in Python…

# Python

def add_first(self, value):
    new_node = Node(value)

    # If the list is empty,
    # point `head` to the newly-added node
    # and exit.
    if self.head is None:
        self.head = new_node
        return

    # If the list isn’t empty,
    # make the current first node the second node
    # and make the new node the first node.
    new_node.next = self.head
    self.head = new_node

…and here’s my JavaScript implementation:

# JavaScript

addFirst(value) {
    let newNode = new Node(value)
    
    // If the list is empty,
    // point `head` to the newly-added node
    // and exit.
    if (this.head === null) {
        this.head = newNode
        return
    }
    
    // If the list isn’t empty,
    // make the current first node the second node
    // and make the new node the first node.
    newNode = this.head
    this.head = newNode
}

Inserting a new item at a specified position in the list

So far, we’ve implemented methods to:

  • Add a new item to the start of the list, and
  • Add a new item to the end of the list.

Let’s do something a little more complicated: adding a new item at a specified position in the list. The position is specified using a number, where 0 denotes the first position in the list.

Here’s how you add a new node at a specified position in the list.

Here are the steps:

  • The function has two parameters:
    1. index: The index where a new node should be inserted into the list, with 0 denoting the first item.
    2. value: The value that should be stored in the new node.
  • Create a new node, new_node, and put value into it.
  • Use a variable, current_index, to keep track of the index of the node we’re currently looking at as we traverse the list. It should initially be set to 0.
  • Use another variable, current_node, which will hold a reference to the node we’re currently looking at. It should initially be set to head, which means that we’ll start at the first item in the list.
  • Repeat the following as long as current_node is not referencing null, nil, or None:
    • We’re looking for the node in the position immediately before the position where we want to insert the new node. If current_index is one less than index:
      • Point the new node at the current node’s next node.
      • Point the current node at the new node.
      • Return true, meaning that we successfully inserted a new item into the list
    • If we’re here, it means that we haven’t yet reached the node immediately before the insertion point. Move to the next node and increment current_index.
  • If we’re here, it means that we’ve gone past the last item in the list. Return false, meaning we didn’t insert a new item into the list.

Here’s how I implemented this in Python…

# Python

def insert_element_at(self, index, value):
    new_node = Node(value)
    current_index = 0
    current_node = self.head

    # Traverse the list, keeping count of 
    # the nodes that you visit,
    # until you’ve reached the specified node.  
    while current_node:
        if current_index == index - 1:
            # We’re at the node before the insertion point!
            # Make the new node point to the next node
            # and the current node point to the new node.
            new_node.next = current_node.next
            current_node.next = new_node
            return True
        
        # We’re not there yet...
        current_node = current_node.next
        current_index += 1
        
    # If you’re here, the given index is larger
    # than the number of elements in the list.
    return False

…and here’s my JavaScript implementation:

// JavaScript

insertElementAt(index, value) {
    let newNode = new Node(value)
    let currentIndex = 0
    let currentNode = this.head
    
    // Traverse the list, keeping count of 
    // the nodes that you visit,
    // until you’ve reached the specified node.     
    while (currentNode) {
        if (currentIndex === index - 1) {
            // We’re at the node before the insertion point!
            // Make the new node point to the next node
            // and the current node point to the new node.
            newNode.next = currentNode.next
            currentNode.next = newNode
            return true
        }
        
        // We’re not there yet...
        currentNode = currentNode.next
        currentIndex++
    }
    
    // If you’re here, the given index is larger
    // than the number of elements in the list.
    return false        
}

Deleting an item from a specified position in the list

Now that we can add a new item at a specified position in the list, let’s implement its opposite: deleting an item from a specified position in the list. Once again, the position is specified using a number, where 0 denotes the first position in the list.

Here’s how you delete a new node from a specified position in the list:

Here are the steps:

  • The function has a single parameter, index: the index of the node to be deleted, with 0 denoting the first item in the list.
  • Use a variable, current_index, to keep track of the index of the node we’re currently looking at as we traverse the list. It should initially be set to 0.
  • Use another variable, current_node, which will hold a reference to the node we’re currently looking at. It should initially be set to head, which means that we’ll start at the first item in the list.
  • Repeat the following as long as current_node is not referencing null, nil, or None:
    • We’re looking for the node in the position immediately before the position of the node we want to delete. If current_index is one less than index:
      • Point the current node to the next node’s next node, which removes the next node from the list.
      • Set both the next node’s data and next properties to null, nil, or None. At this point, this node is no longer in the list and is an “island” — no object points to it, and it doesn’t point to any objects. It will eventually be garbage collected.
      • Return true, meaning that we successfully deleted the item from the list
    • If we’re here, it means that we haven’t yet reached the node immediately before the deletion point. Move to the next node and increment current_index.
  • If we’re here, it means that we’ve gone past the last item in the list. Return false, meaning we didn’t delete the item from the list.

Here’s how I implemented this in Python…

# Python

def delete_element_at(self, index):
    current_index = 0
    current_node = self.head

    # Traverse the list, keeping count of 
    # the nodes that you visit,
    # until you’ve reached the specified node.  
    while current_node:
        if current_index == index - 1:
            # We’re at the node before the node to be deleted!
            # Make the current node point to the next node’s next node
            # and set the next node’s `data` and `next` properties
            # to `None`.
            delete_node = current_node.next
            current_node.next = delete_node.next
            delete_node.data = None
            delete_node.next = None
            return True
        
        # We’re not there yet...
        current_node = current_node.next
        current_index += 1
        
    # If you’re here, the given index is larger
    # than the number of elements in the list.
    return False

…and here’s my JavaScript implementation:

// JavaScript

deleteElementAt(index) {
    let currentIndex = 0
    let currentNode = this.head
    
    // Traverse the list, keeping count of 
    // the nodes that you visit,
    // until you’ve reached the specified node.  
    while (currentNode) {
        if (currentIndex === index - 1) {
            // We’re at the node before the node to be deleted!
            // Make the current node point to the next node’s next node
            // and set the next node’s `data` and `next` properties
            // to `null`.
            const deleteNode = currentNode.next
            currentNode.next = deleteNode.next
            deleteNode.data = null
            deleteNode.next = null
            return true
        }
        
        // We’re not there yet...
        currentNode = currentNode.next
        currentIndex++
    }
    
    // If you’re here, the given index is larger
    // than the number of elements in the list.
    return false  
}

The classes so far

Let’s take a look at the complete Node and LinkedList classes so far, in both Python and JavaScript.

Python

# Python

class Node:
    
    def __init__(self, data):
        self.data = data
        self.next = None
        
    def __str__(self):
        return f"{self.data}"


class LinkedList:
    
    def __init__(self):
        self.head = None
        
    def __str__(self):
        if self.head is None:
            return('Empty list.')
        
        result = ""
        current_node = self.head
        while current_node:
            result += f'{current_node}\n'
            current_node = current_node.next
            
        return result.strip()
    
    def add_last(self, value):
        new_node = Node(value)

        # If the list is empty,
        # point `head` to the newly-added node
        # and exit.
        if self.head is None:
            self.head = new_node
            return
        
        # If the list isn’t empty,
        # traverse the list by going to each node’s
        # `next` node until there isn’t a `next` node...
        current_node = self.head
        while current_node.next:
            current_node = current_node.next
        
        # If you’re here, `current_node` is
        # the last node in the list.
        # Point `current_node` at
        # the newly-added node.
        current_node.next = new_node
        
    def __len__(self):
        count = 0
        current_node = self.head
        
        # Traverse the list, keeping count of 
        # the nodes that you visit,
        # until you’ve gone past the last node.
        while current_node:
            current_node = current_node.next
            count += 1
            
        return count        
        
    def get_element_at(self, index):
        current_index = 0
        current_node = self.head
        
        # Traverse the list, keeping count of 
        # the nodes that you visit,
        # until you’ve reached the specified node.        
        while current_node:
            if current_index == index:
                # We’re at the node at the given index!
                return current_node.data
            
            # We’re not there yet...
            current_node = current_node.next
            current_index += 1
    
        # If you’re here, the given index is larger
        # than the number of elements in the list.
        return None
    
    def set_element_at(self, index, value):
        current_index = 0
        current_node = self.head
        
        # Traverse the list, keeping count of 
        # the nodes that you visit,
        # until you’ve reached the specified node.  
        while current_node:
            if current_index == index:
                # We’re at the node at the given index!
                current_node.data = value
                return True
            
            # We’re not there yet...
            current_node = current_node.next
            current_index += 1
            
        # If you’re here, the given index is larger
        # than the number of elements in the list.
        return False
        
    def add_first(self, value):
        new_node = Node(value)

        # If the list is empty,
        # point `head` to the newly-added node
        # and exit.
        if self.head is None:
            self.head = new_node
            return
        
        # If the list isn’t empty,
        # make the current first node the second node
        # and make the new node the first node.
        new_node.next = self.head
        self.head = new_node
        
    def insert_element_at(self, index, value):
        new_node = Node(value)
        current_index = 0
        current_node = self.head
        
        # Traverse the list, keeping count of 
        # the nodes that you visit,
        # until you’ve reached the specified node.  
        while current_node:
            if current_index == index - 1:
                # We’re at the node before the insertion point!
                # Make the new node point to the next node
                # and the current node point to the new node.
                new_node.next = current_node.next
                current_node.next = new_node
                return True
            
            # We’re not there yet...
            current_node = current_node.next
            current_index += 1
            
        # If you’re here, the given index is larger
        # than the number of elements in the list.
        return False
        
    def delete_element_at(self, index):
        current_index = 0
        current_node = self.head
        
        # Traverse the list, keeping count of 
        # the nodes that you visit,
        # until you’ve reached the specified node.  
        while current_node:
            if current_index == index - 1:
                # We’re at the node before the node to be deleted!
                # Make the current node point to the next node’s next node
                # and set the next node’s `data` and `next` properties
                # to `None`.
                delete_node = current_node.next
                current_node.next = delete_node.next
                delete_node.data = None
                delete_node.next = None
                return True
            
            # We’re not there yet...
            current_node = current_node.next
            current_index += 1
            
        # If you’re here, the given index is larger
        # than the number of elements in the list.
        return False

JavaScript

// JavaScript

class Node {
    
    constructor(data) {
        this.data = data
        this.next = null
    }
    
    toString() {
        return this.data.toString()
    }
    
}


class LinkedList {
    
    constructor() {
        this.head = null
    }
    
    toString() {
        if (!this.head) {
            return('Empty list.')
        }
        
        let output = ""
        let currentNode = this.head

        while (currentNode) {
            output += `${currentNode.data.toString()}\n`
            currentNode = currentNode.next
        }
        
        return output.trim()
    }
    
    addLast(value) {
        let newNode = new Node(value)
        
        // If the list is empty,
        // point `head` to the newly-added node
        // and exit.
        if (this.head === null) {
            this.head = newNode
            return
        }
        
        // If the list isn’t empty,
        // traverse the list by going to each node’s
        // `next` node until there isn’t a `next` node...
        let currentNode = this.head
        while (currentNode.next) {
            currentNode = currentNode.next
        }
        
        // If you’re here, `currentNode` is
        // the last node in the list.
        // Point `currentNode` at
        // the newly-added node.
        currentNode.next = newNode
    }
    
    getCount() {
        let count = 0
        let currentNode = this.head
        
        // Traverse the list, keeping count of 
        // the nodes that you visit,
        // until you’ve gone past the last node.
        while (currentNode) {
            currentNode = currentNode.next
            count++
        }
        
        return count
    }
    
    getElementAt(index) {
        let currentIndex = 0
        let currentNode = this.head
        
        // Traverse the list, keeping count of 
        // the nodes that you visit,
        // until you’ve reached the specified node.     
        while (currentNode) {
            if (currentIndex === index) {
                // We’re at the node at the given index!
                return currentNode.data
            }
            
            // We’re not there yet...
            currentNode = currentNode.next
            currentIndex++
        }
        
        // If you’re here, the given index is larger
        // than the number of elements in the list.
        return null
    }
    
    setElementAt(index, value) {
        let currentIndex = 0
        let currentNode = this.head
        
        // Traverse the list, keeping count of 
        // the nodes that you visit,
        // until you’ve reached the specified node.     
        while (currentNode) {
            if (currentIndex === index) {
                // We’re at the node at the given index!
                currentNode.data = value
                return true
            }
            
            // We’re not there yet...
            currentNode = currentNode.next
            currentIndex++
        }
        
        // If you’re here, the given index is larger
        // than the number of elements in the list.
        return false
    }
    
    addFirst(value) {
        let newNode = new Node(value)
        
        // If the list is empty,
        // point `head` to the newly-added node
        // and exit.
        if (this.head === null) {
            this.head = newNode
            return
        }
        
        // If the list isn’t empty,
        // make the current first node the second node
        // and make the new node the first node.
        newNode = this.head
        this.head = newNode
    }
    
    insertElementAt(index, value) {
        let newNode = new Node(value)
        let currentIndex = 0
        let currentNode = this.head
        
        // Traverse the list, keeping count of 
        // the nodes that you visit,
        // until you’ve reached the specified node.     
        while (currentNode) {
            if (currentIndex === index - 1) {
                // We’re at the node before the insertion point!
                // Make the new node point to the next node
                // and the current node point to the new node.
                newNode.next = currentNode.next
                currentNode.next = newNode
                return true
            }
            
            // We’re not there yet...
            currentNode = currentNode.next
            currentIndex++
        }
        
        // If you’re here, the given index is larger
        // than the number of elements in the list.
        return false        
    }
    
    deleteElementAt(index) {
        let currentIndex = 0
        let currentNode = this.head
        
        // Traverse the list, keeping count of 
        // the nodes that you visit,
        // until you’ve reached the specified node.  
        while (currentNode) {
            if (currentIndex === index - 1) {
                // We’re at the node before the node to be deleted!
                // Make the current node point to the next node’s next node
                // and set the next node’s `data` and `next` properties
                // to `null`.
                const deleteNode = currentNode.next
                currentNode.next = deleteNode.next
                deleteNode.data = null
                deleteNode.next = null
                return true
            }
            
            // We’re not there yet...
            currentNode = currentNode.next
            currentIndex++
        }
        
        // If you’re here, the given index is larger
        // than the number of elements in the list.
        return false  
    }
    
}

Coming up next

It’s time to reverse that list!

Previously in this series