A Few Cool Technologies (2014-11-15)

I wanted to point out a few cool technologies that I’ve come across lately. I decided to put a date on the title, because I imagine I’ll do this fairly regularly as I come across cool stuff.

The first couple tools (Docker and OpenShift) are for both admins and developers. The last one (Code School) is more directly relevant to developers–specifically folks who are looking to learn something new.

Docker

I know I’m a little late to the game on this one, but I’ve been living primarily in the Windows ecosystem over the last year or so. I didn’t hear about Docker until Microsoft announced that they’re incorporating the platform into Azure. And it’s a smart move! Docker isn’t the only technology of its kind, but it’s the one that everyone is talking about, and it’s clearly going to get credit for being the game-changer.

I’m going to assume that you know what a virtual machine is and have some idea how useful they are. But the downside of virtual machines (VM) is that, in terms of system resource usage, they can be expensive to distribute, maintain, and use. A VM makes a lot of sense if you need to split a server into multiple virtual servers, but if you only need it to run one legacy application, it’s pretty cumbersome.

Emerging as an alternative to VMs for one-off applications (among other uses) is something called a “container,” which basically allows an application to bring its own little environment with it. One way to think about it is that a virtual machine is kind of like building a guest house on your property for a family of five to use. Other than relying on the same utilities running to the property, you won’t interact a whole lot. Docker is more like having a guest in the spare bedroom. For the most part, they’ll keep to themselves, and if they like Jif better than Skippy, they’ll bring their own peanut butter. But they’re still in the same house and sharing a lot of the same resources.

If you do development, testing, or are in charge of moving applications from one environment to another in a Linux or Windows environment, Docker should be on your radar. There’s a pretty sweet slide show here. And here’s a hands-on.

OpenShift

Akin to Docker is Red Hat’s OpenShift, which is actually going to be incorporating Docker into its next version. OpenShift is a Platform as a Service (PaaS) product like Heroku or the Google App Engine. I’m not going to go into much detail here, because I’m going to point you to a great deep dive passed along to me by Scott McCarty, a Red Hat Solutions Architect. (Yes, I drank the Kool-Aid. But so will you.)  I’m also going to let Red Hat do the talking on what PaaS is in their words.

But in short, PaaS takes a lot of the administrative work of distributing a cloud application off of your plate. Want to set up a new WordPress site to your cloud but wish you could get straight to coding or deploying existing code and bypass the infrastructure and platform setup? Well, OpenShift has something they advertise as One-Click Deployment for WordPress. And it’s pretty much as simple as it sounds. You’ll have configuration to do, of course, but you’d have to do that anyway. It’s got a growing list of software already supported, but it’s also extensible. You don’t have to wait on Red Hat to get up to speed and add Hadoop, for example. If you’ve got the chops, you can take the initiative and add it to the mix yourself.

Code School

Finally, I wanted to give a shout out to Code School. I was recently told to start getting up to speed on Angular.js, and my manager recommended a Code School tutorial. I’m used to text-based tutorials with code samples that you just kind of copy and paste, then maybe tweak to see what happens–at least when it comes to the free stuff. Code School, however, took me by surprise. These folks are producing some pretty amazing screencast content, and whether you are just getting started as a code, want to add new arrows to your quiver, or just get a better idea of what the heck CoffeeScript or Ember.js might be, I’d recommend checking out their course offering. They have everything from basic HTML and CSS to R to mobile-first web design.

Most of it is geared toward front-end web development, so if you’re trying to do bare metal programming on your Raspberry Pi, this probably isn’t for you.

The coolest thing is that after each morsel, they have challenges. Yes, it’s gamified and you can earn points for completing challenges. If you’re into that, all the better. But gamified or not, it actually forces you to apply each piece as you learn it and makes you get it right before you can proceed. Sometimes you can just copy what you saw in the video exactly, and that’s good for making sure you’re paying attention to the important parts at least. But as you progress, they throw little changes into the challenge code that wasn’t in the video, forcing you to actually think about and gain an understanding of the relationships among the different components to be able to get them working together properly.

It’s also fun. Angular.js actually has a theme song. Where else are you gonna get that with your code?

Love and kisses,

Tyler

 

Interesting Intervew w/ Michael Tiemann

So I didn’t know who Michael Tiemann was until listening to this interview on Hacker Public Radio, but apparently he’s been one of the most major forces in Open Source over the last couple of decades. He’s incredibly well spoken, knows what he’s about, and the interviewer does a good job of guiding the discussion. Tiemann is also no edge-case hacker who just loves Open Source. He’s the VP of Open Source Affairs at Red Hat, Inc.

I thought my OTRS readers might be especially interested in the interview and in the philosophies presented. Check it out.

 

http://hackerpublicradio.org/eps.php?id=1622

 

PS: I don’t necessarily recommend Hacker Public Radio by default. There are some stellar episodes, for sure, but it’s not like standard commercial podcasts you might be used to where there is consistent subject matter or a consistent host you can form a bond with. All I can say is that I get something out of Hacker Public Radio and you don’t have to be a “hacker” to appreciate every episode (sometimes they’re just talking about how to use free software like LibreOffice Calc effectively). So if you’re shopping around for a new podcast, consider giving it a shot.

Quick Note On My Absence

Hi folks. I’m sure no one is watching this blog religiously, but it’s gained more popularity than I ever would have expected–and quickly–so I thought I should post a quick note about why I haven’t been posting lately. First, I did a lot of traveling over the summer and relaxed my commitment to the blog. It was just too much to keep up with. I had plans to start a series on OTRS ITSM this fall, but I at the end of the summer I had a very nice surprise. I was accepted to Georgia Tech’s Online Master of Science in Computer Science program!

I started out taking a single course, hoping that would allow me to ease back into the student mindset and hopefully leave me time to continue with some of my other side projects. However, I’ve found that working full time and taking just one course is usually enough to fill up my time. I’ve gotten much better at managing my time, so I hope to return to the blog soon. I will probably include some posts about what I’m learning in the program, as well. OTRS ITSM is still on my radar. It will just be behind my anticipated schedule.

Thanks everyone for reading and for your kind comments. I look forward to providing more help to you as soon as I can!

Anatomy of a Stackoverflow Discussion, Part II

Introduction

There’s a reason I named this blog the way I did. The first post is a good example of how a dummy does it. Turns out I did the opposite of what the asker needed. He wanted to find non-matching pairs, and I gave him matching pairs. So I don’t reexplain from scratch here, but I’m going to give an updated macro and explain the differences.

Scope of Application

This post references Microsoft Excel 2013 running on a Windows 8.1 machine. I’ll also be referencing Stackoverflow as experienced through Firefox 28.0 running in Sandboxie 4.08.

User Requirements

This one’s on me. I read the question once, started looking at the sample data, then forgot what the ultimate goal was because I was caught up in the minutiae of making things work. Granted, this was a casual response to an online question, but this is about par for the course in programming. Sometimes the requirements change, many times they were ill-defined in the first place, you have to constantly be on the lookout for scope creep, and other times, it turns out that I’m just kind of a dummy. So here’s a macro that does what the user actually asked for:

Sub TakeThree()

Dim rowCount1 As Long
Dim rowCount2 As Long

rowCount1 = ThisWorkbook.Sheets(1).Range("B20").SpecialCells(xlCellTypeLastCell).Row
rowCount2 = ThisWorkbook.Sheets(2).Range("C2").SpecialCells(xlCellTypeLastCell).Row

Dim rng1 As Range
Dim rng2 As Range

Set rng1 = ThisWorkbook.Sheets(1).Range("B20:B" & rowCount1)
Set rng2 = ThisWorkbook.Sheets(2).Range("C2:C" & rowCount2)

Dim currentRow As Long
currentRow = 2

For Each cell In rng1.Cells
For Each cell2 In rng2.Cells
If cell2.Value = cell.Value And cell2.Offset(0, -1).Value = cell.Offset(0, 5).Value And cell2.Offset(0, -2).Value = cell.Offset(0, 2).Value Then
GoTo NextIteration
End If
Next cell2
ThisWorkbook.Sheets(1).Rows(cell.Row).Copy Destination:=ThisWorkbook.Sheets(3).Range("A" & currentRow)
currentRow = currentRow + 1
NextIteration:
Next cell

End Sub

What’s the Difference?

We really haven’t changed much. We just moved the lines that copy and paste the row from sheet 1 and the currentRow increment outside of the loop through sheet 2. Why does that make it work? As I’ve said before (I think), the biggest part of coding isn’t so much about knowing how to read and write the language, it’s knowing how to work the logic.

Let’s frame the requirements one more time to help us understand how we got here. The asker wanted to compare data in 3 cells on sheet 1 to data in 3 cells on sheet 2. If the cells on sheet 1 do not match any of the corresponding cells in sheet 2, they should be copied to sheet 3. To be sure that each set of 3 cells from sheet 1 doesn’t match any of the corresponding cells in sheet 2, our only course of action is to compare each set of cells on sheet 1 to every set of cells on sheet 2–unless we get a match. As soon as the cells on sheet 1 match some cells on sheet 2, we don’t have to keep going with the comparison and can move to the next set of cells on sheet 1. But unless we get a match, we can’t copy anything from sheet 1 to sheet 3 until we’re sure we’ve exhausted every option.

So now look at what the loops are doing. The first one, “For Each cell in rng1.Cells,” is going to loop through every cell in sheet 1, as we discussed. It immediately starts another loop that will check the values at this spot in sheet 1 against a set of cells in sheet 2. If the cells from sheet 2 match the cells from sheet 1, the code jumps to the next iteration–completely bypassing the step that copies a row from sheet 1 to sheet 3.  However, if the code gets through every single set of cells in sheet 2 without finding a match, then it leaves that loop. There waiting on the other side is the code that says, “Oh. Hey. Couldn’t find a match on the other sheet, and now you want me to give you a ride to sheet 3? I guess that’s cool.”

Hopefully that’s clear enough. Cuz that’s all I’ve got.

Love and kisses,

Tyler

Anatomy of a Stackoverflow Discussion

Introduction

I’ve mentioned Stackoverflow in a couple of other posts. It’s not the only place the cool kids in coding hang out, but it’s a pretty important one. And its sister sites aren’t just for coders. I had an interesting exchange there over the last couple of days that I thought would fit my “Learn to Code” series. After this, though, I’m going to spend some time digging into OTRS ITSM and writing about that. I’ve had several requests for it, and I’ve noticed that my blog is getting the most traffic for the OTRS stuff. I feel like the people have spoken. If you come around here for the Learn to Code posts, let me know where you’d like those to head next.

Scope of Application

This post references Microsoft Excel 2013 running on a Windows 8.1 machine. I’ll also be referencing Stackoverflow as experienced through Firefox 28.0 running in Sandboxie 4.08.

The Question

Stackoverflow, to severely oversimplify, is a Q&A site. It’s a really sophisticated Q&A site with some conventions that its users can be fairly zealous about, but overall it’s an awesome community that makes getting answers to programming questions about as easy as it could possibly be without having Dennis Ritchie as a personal advisor.

Every post starts with a question. In this case, the question had to do with an Excel macro. I won’t rehash the whole question for you here. You can follow the link and take a look. The format is fairly familiar: header, body, some up-/downvote arrows and a star to “favorite” the question. At the time that I’m writing this, the question has a score of “-3.” You can hover over the up-/downvote arrows to see how the site designers intended those features to be used. It’s hard to know exactly why questions get downvoted sometimes, but it’s also important to note that questions can be edited over time–don’t always trust a negative score. New users who are inexperienced programmers can have an especially hard time getting their first couple questions right on Stackoverflow, but many of them make quick edits and improve the question.

My guess is that this one was down-voted because the community at large didn’t find that the original question was framed well, or that it didn’t show enough leg work. A lot of folks get on the site and ask things as general as, “How do you add two numbers together?” (Ok. That’s a slight exaggeration… but only a slight one.) If you can Google the answer fairly easily, the community generally doesn’t like that.

The Answer

I don’t think my answer is perfect, but I did see a solution to the problem based on some similar issues I’d faced in the past. So I wrote and tested a quick macro that did what I understood to be the goal of the asker. It took a little more back and forth, and because the person asking the question is fairly new to macros, last time I checked, he still hadn’t quite gotten it to work with the real data. Because of my recent posts on macros, I thought I’d take this opportunity to explain my code for his sake and for anyone else who might be working at the same level.

The entirety of the macro is already on Stackoverflow, so I’m going to go ahead and go into the detail.

Terms

Some folks might be used to talking about Excel files and tabs. The official jargon for an Excel file is a workbook, and the tabs are worksheets. Knowing this makes understanding the code a little easier.

The Code

Here are the first few lines:

Dim rowCount1 As Long
Dim rowCount2 As Long

rowCount1 = ThisWorkbook.Sheets(1).Range("A2").SpecialCells(xlCellTypeLastCell).Row
rowCount2
= ThisWorkbook.Sheets(2).Range("A2").SpecialCells(xlCellTypeLastCell).Row

“Dim” is a keyword in VBA that you use whenever you want to declare a variable. (If you want to know why, Google has the answer.) So we’re declaring and assigning two variables as “Long” data types. When you declare a variable in VBA, you have to tell it whether the data is going to be a string of characters, a number, or something else. So you’ll see “Dim [myVariable] As [someType]” everywhere in VBA.

A “Long” is just a type of number. We want to be able to loop through a column of cells without having to tell Excel explicitly how many rows we’ve used in that column. We want Excel to figure out where the last used row is. And that’s what we’re doing with the next two lines. Their practically identical, but they’re looking at different sheets.  The line is pretty self-explanatory, but let’s take a quick close look:

  • ThisWorkbook
    • Refers to the workbook that contains the macro
  • Sheets(1)
    • This is how you tell Excel which sheet to look at. You can also pass it a name: Sheets(“Payments”)
  • Range(“A2″)
    • A Range in Excel is a group of cells. In this case, we’re referencing only a single cell, but you can reference more, as we’ll see later
  • SpecialCells(xlCellTypeLastCell)
    • This might look a little cryptic, but it’s pretty simple. “SpecialCells” is a method on the Range that takes one of a few specific arguments predefined by VBA. In this case, we’re telling it to find the last cell in the column with any information in it–xlCellTypeLastCell.
  • Row
    • SpecialCells is going to return a cell address. “Row” grabs the row number off of that address. Now our “rowCount” variables refer to the last row in Column A on their respective sheets.

The next section is really similar:

Dim rng1 As Range
Dim rng2 As Range

Set rng1 = ThisWorkbook.Sheets(1).Range("A2:A" & rowCount1)
Set rng2 = ThisWorkbook.Sheets(2).Range("A2:A" & rowCount2)

Here, we declare two new variables of the Range data type. That means that we’re going to refer to a couple of groups of cells. When you assign a Range variable, you have to use the “Set” keyword. Notice that we didn’t have to do that to assign the Long variables. This has to do with the different ways Excel handles different data types. I’m not going to get into the details of that here. For now, just know that if you try to set a Range variable without the Set keyword, you’re gonna have a bad time.

You already know what “ThisWorkbook.Sheets(1).Range” means, but the range reference is a little different than the one we saw before. Instead of simply A2, we have “A2:A” & rowCount1. If you’re familiar with Excel, you’ve probably used or seen notation like “A2:A10″ in a formula before. This refers to the range of cells in Column A, rows 2 through 10. If the notation were “A2:C10″, it would include all the cells in Columns A, B, C, Rows 1 through 10. The notation here means the exact same thing. “A2:A” tells Excel to refer to Column A, Row 2 through Column A… What?

You may have seen the rest of this notation in a formula somewhere, as well. The ampersand (&) is the concatenation symbol–concatenate being a fancy word for “smoosh together.” If you concatenate “antidisestablishment” with “arianism,” you get “antidisestablishmentarianism.” Simple as that. So that last piece of our assignment is telling Excel to assign rng1 to all the cells in Column A from row 2 through the last used row–the value we stored in that variable earlier.

The next variable is a little more complex, and I’m not going to go into a lot of detail on it. If you understand based on the explanation I give, great. If not, don’t worry about it. I’m not exactly starting at the beginning.

Dim sheet1() As Variant
ReDim sheet1(rowCount1 - 1,2)

Here I declare sheet1 as an array. You can tell it’s an array because of the parentheses–which up to this point we’ve only seen as part of a function or method. (See my post on the coin slot).  They also show up with array variables, because arrays hold collections of values instead of a single value, and we need a way to tell it which one we want. It’s not entirely wrong to think of an array as a kind of mini-function: You call its name and pass in an argument, and it gives back the value that matches that argument.

The Variant data type means that the array might (and in our case, definitely will) hold different types of data. They won’t all be numbers or all be letters. We’re going to mix it up.

The next line has a “ReDim” statement. If you really want to understand that now, you’ll have to Google it. I’ll leave my explanation at this: VBA needs you to tell it what size an array is going to be so it can reserve the appropriate amount of space. We didn’t reserve any space when we declared it, so we’re reserving that space with the ReDim statement.

I’m also using a multidimensional array, meaning each entry in the array will consist of multiple pieces of data. That’s why the coin slot has two values: rowCount1 – 1, and 2. The first dimension, rowCount1-1, is the size of the array, or the number of elements it will have. In this case, I need to store one element in the array for each row of data in my used range on Sheet1. Why do I subtract 1 from the row count? Let me explain roundaboutly. The second dimension, 2, indicates that each of my elements will have 3 pieces of data.

“Wait… it sounds like you just said 2 = 3.” Well, that’s because I did. You know how 0 is supposed to mean nothing? Well, not with arrays in programming. Arrays treat 0 like something. It’s the first element in an array. So 0 = 1. It’s called base 0, and it’s kind of annoying sometimes. But it will make more sense in a few lines.

Just to give you a more concrete idea of how a multidimensional array works, let’s say I have the following data on the characters of 30 Rock:

  • Liz Lemon
    • University of Maryland
    • Theater Tech
  • Jack Donaghy
    • Harvard
    • MBA
  • Kenneth Parcell
    • Kentucky Mountain Bible College
    • Television Studies and Bible Sexuality

These are related sets of data that I want to be able to reference together. For this data set, my multidimensional array would need to contain three elements, each of which has three pieces of data. I could declare this like so:

Dim 30Rock() As Variant
ReDim 30Rock(2,2)

 Cool? Cool.

We then declare another number variable and set it to 0.

Dim n As Long
n = 0

And now, something a little more interesting happens:

For Each cell In rng1.Cells
sheet1
(n,0)= cell.Value
sheet1
(n,1)= cell.Offset(0,2).Value
sheet1
(n,2)= cell.Offset(0,5).Value
Debug
.Print cell.Value
n
= n + 1
Next cell

We haven’t covered “For Each” loops yet, but you’re smarter than me. You understand that these tell the computer to loop through a certain section of code for each element in some kind of collection. In our case, we’re telling it to repeat these lines of code for each cell in the collection of cells in the range we assigned to rng1 several lines ago.

First, we get the value of the cell in Column A, which is the column our range is set to. “cell.Value” means whatever is in the cell. It may not be what is displayed on the screen. If the cell contains a formula, the value is the formula. The result of that formula would be in the text property: cell.Text.

We assign that value as the first piece of data in the first element of the array. Remember that we set n to 0, so what that first line actually means is “sheet1(0,0).” You’ll notice that we increment n by 1 at the end of each loop. That way we’re always moving up one element in the array. The second time we pass through, the first line would mean “sheet1(1,0)”, the next time “sheet1(2,0)”, and so forth.

The next line gets the value from the cell 2 columns to the right. The “Offset” property allows you to create relative references. You pass it a row number and column number, respectively, and it finds the cell at that location. For example, in the first pass of the above code, the address of “cell” is “A2.” So cell.Offset(0,2).Value says to Excel, “go 0 rows up or down, and go 2 columns to the right.” (Positive numbers go down and to the right, negative numbers go up and to the left.) This will refer to “C2.”

The “Debug.Print” statement is just a way to show in the Immediate Window of the VBA Editor if I’m grabbing the value of the cell that I expect to get.

The reason I’m gathering these values is rooted in the original question. Based on the sample data in the original question, you can see that the asker has values in columns A, C, and F on sheet 1 that he would like to compare to data in Columns A, B, and C on sheet 2. That’s why I’m using the offsets. I only have to refer to one column by its letter, an then I can use relative references to get the values out of the other columns.

It’s worth asking why I’m collecting these values into a multidimensional array instead of just comparing the two ranges in the two sheets directly. The same task could be accomplished either way. To be perfectly honest, I don’t know why I did it except that that’s how it occurred to me to do it. Maybe I’m too tired now to remember why, or maybe I was in too much of a hurry then to consider all of my options, but I did it this way, it worked, and so I passed my answer along. Other than possibly making the final loop a little easier to read, this approach doesn’t actually offer any major advantage that I can see. Thinking about it a little more, I may have thought there was a performance advantage to holding those cell values in memory rather than reading them out of the ell each time. I don’t think that’s accurate. So learn from my mistakes: don’t add unnecessary code!

Okay, next step. We declare another variable and set it to 1:

Dim currentRow As Long
currentRow
=1

The asker wants to take any data from sheet1 that matches data from sheet2 and copy the row to sheet3. We’ll use this variable to track which row on sheet3 we’re pasting into.

Finally, the heavy lifting:

For n = 0 To UBound(sheet1)
For Each cell In rng2.Cells
If cell.Value = sheet1(n,0) And cell.Offset(0,1).Value = sheet1(n,1) And cell.Offset(0,2).Value = sheet1(n,2) Then
ThisWorkbook
.Sheets(1).Rows(n + 2).Copy Destination:=ThisWorkbook.Sheets(3).Range("A"& currentRow)
currentRow
= currentRow +1
GoTo NextIteration
End If
Next
cell
NextIteration
:
Next n

First, we have another For loop. This one is just a tad different. Rather than saying For Each, we tell it to count. You can start from any value and count to any value. Since we’re looping through an array, we start at 0. We then tell it to count to the upper boundary (UBound) of an array–meaning its highest value. UBound is a function that takes an array as an argument. We give it sheet1.

Now we do something really inefficient. We nest a For Each loop inside a For loop. I haven’t thought of a better way to address this particular problem, but be cautious about doing this. Let’s say we have an array with 1,000 elements in it, and we run a For loop on every element in that array. For each element in our array, we compare it against each value in another array to see if it matches. Well, what if that second array has 1,000,000 elements? And what if nothing matches? We end up running that comparison a thousand million times. If there’s any way to avoid running so many stinkin’ loops, we should figure it out!

You can see where this is going. We want to check everything in our original array (the values from sheet 1) against the corresponding cells in sheet 2. So if the value in sheet 2, Column A matches the first piece of data in the first element of our array AND the value in sheet 2, Column B matches the second piece of data in the first element of our array AND the value in sheet 2, Column C matches the third piece of data in the first element of our array, THEN do the following stuff.

The next line should be fairly self-explanatory. We refer to the matching row back on sheet 1, and tell Excel to copy that row. We find the row number by adding 2 to n. Remember that our data started in the second row, but n starts at 0. This corrects for that difference. The “Copy” method takes a Range as its “Destination” argument, so we point it to the first unused row on the third sheet using the currentRow variable we set up earlier. Then we increment that to make sure the next time we copy, we don’t overwrite what’s already there.

“GoTo NextIteration”… goes to… the NextIteration label… I don’t know how to explain that any better. But the reason we need it is because otherwise Excel would stay inside that inner loop even after it finds a match. By sending the code outside of that loop, we can move to the next element in our array without looping through all the cells in the second sheet.

That’s it! Easy peasy, right?

Discrepancy

Now, the sample data included in the question didn’t match the data the asker was actually using. If you go to the question now, you’ll find a link to the data file. That wasn’t there the first time. So the macro didn’t work with the live data. It needed some edits. Below is the revised macro, taking into account the realization I had that the multidimensional array wasn’t really necessary. I’m not going to explain all the changes. I’ve explained everything else in enough detail that you ought to be able to look at the sample data file and the code below and figure out why the changes work. Or maybe I’m wrong and they don’t. Then I guess it’s up to you to fix it and let me know.

Sub Test()

Dim rowCount1 As Long
 Dim rowCount2 As Long
rowCount1 = ThisWorkbook.Sheets(1).Range("B20").SpecialCells(xlCellTypeLastCell).Row
 rowCount2 = ThisWorkbook.Sheets(2).Range("C2").SpecialCells(xlCellTypeLastCell).Row
Dim rng1 As Range
 Dim rng2 As Range
Set rng1 = ThisWorkbook.Sheets(1).Range("B20:B" & rowCount1)
 Set rng2 = ThisWorkbook.Sheets(2).Range("C2:C" & rowCount2)
Dim currentRow As Long
 currentRow = 1
For Each cell In rng1.Cells
 For Each cell2 In rng2.Cells
 If cell2.Value = cell.Value And cell2.Offset(0, -1).Value = cell.Offset(0, 5).Value And cell2.Offset(0, -2).Value = cell.Offset(0, 2).Value Then
 ThisWorkbook.Sheets(1).Rows(cell.Row).Copy Destination:=ThisWorkbook.Sheets(3).Range("A" & currentRow)
 currentRow = currentRow + 1
 GoTo NextIteration
 End If
 Next cell2
 NextIteration:
 Next cell
End Sub

Love and kisses,

Tyler

Paramuments: Making Functions more Functional

Introduction

We’re going to revisit the coin slot and see how we can use it to let functions take variable inputs to produce more dynamic outputs.

Scope of Application

Today’s post was drafted using Microsoft Word 2013 running on a Windows 8.1 machine. But what I’ll cover applies at least as far back as Word 2007 and Windows XP and the equivalent versions of Word for the Mac. If you don’t have Word, you can get a trial copy from Microsoft’s website.

A Quick Review of our singleDouble macro

In my Cheater’s Code trilogy, I showed you a macro that turned out something like this (edited for focus):

Sub singleDouble()
'
' singleDouble Macro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = ".*<"
.Replacement.Text = ".  "
.MatchWildCards = True
.MatchCase = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub

 

We used that to replace a period followed by anything leading up to the beginning of a word (“.*<”), and replace it with a period followed by two spaces (“.  “)–or, in other words, to find a period followed by any number of spaces, and replace it with a period followed by two spaces.

Then I pointed out that we’d have to correct for things like Dr., Mrs., etc. showing up elsewhere in the text by running a very similar macro:


Sub correctSingleDouble()
'
' correctSingleDouble Macro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "([DIJMNOPRS][cdnoprst]{1,3})(.  )(<?)"
.Replacement.Text = "\1. \3"
.MatchWildcards = True
.MatchCase = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub

 Well, you probably noticed that with the exception of the Text and Replacement Text, the code of these two macros is exactly the same. Now imagine that you have 10 different find and replace searches to perform on each document you work on. Repeating this one pattern 10 times would produce over 100 lines of code–but the only thing changing are the find and replace values. Sure, it’s easy to copy and paste all that, but it’s not really efficient. For that reason alone, we should look for a way to change the values without repeating the rest of the code. We’re looking for reusability.

Parameters

This brings me back to the coin slot. In case you don’t remember (or skipped my Cheater’s Code trilogy), I referred to those parentheses after the macro name as a coin slot and compared it to those machines at the mall that smoosh a penny. The machine has a place for you to pass something in, and when you do that, it sets to work on what you’ve given it. The machine doesn’t care what year the quarters were minted in, whether the penny is a wheat penny, or if you also have six nickels in your pocket. The machine will not, however, accept forms of currency it doesn’t expect. You can’t put an equivalent amount of Yen into the machine and make it work. It knows the size and the shape of the input it wants. And that’s what we would call a parameter in programming parlance.

Parameters basically allow you to do two things:

  • Enable a function to accept input
  • Describe the type of input the function will accept

In our macro, we want to pass in a Find value, and a Replace value. That means we’ll need two parameters. We create them by giving them names and identifying their types in the parentheses after the macro name–carving out the coin slot. Let’s create a new macro called “findReplace” and set up some parameters:

Sub findReplace(findThis As String, replaceWithThis As String)

End Sub

Different programming languages can handle this slightly differently, but in VBA you provide a name (something you make up), followed by As [Type]. If you don’t quite understand what I mean by “type,” I’ll be covering that in another post. Don’t worry about it too much now. You know that this particular macro is working with strings, so we need our parameters to be strings.

Let’s go ahead and fill in the rest of the macro:

Sub findReplace(findThis As String, replaceWithThis As String)

Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = findThis
.Replacement.Text = replaceWithThis
.MatchWildcards = True
.MatchCase = True
End With
Selection.Find.Execute Replace:=wdReplaceAll

End Sub

Notice that now the Text and Replacement Text now point to the names of our parameters. Going back to our penny smoosher comparison, this is like saying, “Take a quarter and a penny. If it’s a nickel or a dime, don’t accept it. Also, it doesn’t have to be any particular quarter or particular penny. It just needs to be a quarter and a penny.”

Now you can call this macro and pass in any two strings.

Arguments

When I was starting out, I found the difference between parameters and arguments to be a little confusing. Basically, it’s this: when you carve out a coin slot, you create parameters. The slot for the penny and the quarter are the parameters. The quarter and the penny–the objects actually going into the coin slots, are the arguments. Parameters define the input allowed, arguments are the input. (If anyone knows why we use the term arguments, I’d love to be able to answer that trivia question.)

Now that we have findReplace, we don’t need all that code in singleDouble. In fact, we really only need one line of code there:

Sub singleDouble

Call findReplace(".*<",".  ")

End Sub

 Simple, right? findReplace has a place for two strings, and we’re giving it two strings. It will use them as the Find and Replace values, respectively. We passed in the values we want to use as arguments. Hopefully now you see where the title of the post comes from.

We could make the same edit to correctSingleDouble, but in this case I’m pretty sure that whenever we replace one space after a period with two spaces after a period, we’ll want to correct for abbreviations. Since both operations always need to be performed, we can just stick them in the same macro. Remember, that would have originally meant 20 lines of code. Now that we have the findReplace abstraction, it’s just two lines:

Sub singleDouble

Call findReplace(".*<",".  ")
Call findReplace("([DIJMNOPRS][cdnoprst]{1,3})(.  )(<?)","\1.  \3")

End Sub

Now when we find ourselves in a situation where we need to run the same function on 10 different sets of strings, we don’t have to copy and paste 10 lines of code over and over. We just generate one new line of code for each new find and replace operation. That will make it easier to read, easier to edit, and boost performance.

Prompt

If we had 10 find and replace options to perform, how could we make this even more efficient?

Love and kisses,

Tyler

Discounted iOS Development Boot Camp

Somebody passed along this link, and so I thought I’d pass it along to you in case you were interested: http://stacksocial.kinja.com/udem-1517879920.

This is a generously discounted boot camp course for total beginners. You don’t need to know how to code at all to start, but you will need access to a Mac running OS X Snow Leopard or higher. If you’re thinking, “If I have to buy a Mac to do this, the discount doesn’t help much,” well, I agree. But if you can get your hands on an OSX86 ISO, you can run this in a Virtual Box. I haven’t experimented with that and so can’t provide any specific links or suggestions, but that’s how I’m told it’s done.

So for those who might be interested in developing for the  Mac ecosystem, this is a really good way to get in on the ground floor with some concrete direction.

Tools of the Trade

Introduction

This post points to a few outstanding tools for developers. It’s a short list of things that I’ve found really helpful as I’ve tried to teach myself to code. Obviously any resource is helpful, but right now these are some of the most popular and widely-used resources. You’ll get more deeply embedded into the culture more quickly by getting familiar with these tools early. As I’m a .NET developer above all else at the moment, these tools skew that direction.

Scope of Application

This applies to anyone looking to learn to code who has access to online resources. As of April 2014, most of this was pretty hot stuff and on the list of what the cool kids are using.

Stackexchange

As far as I know, this is the #1 place for Q&A information for programmers online. Stackexchange is an umbrella Q&A site that includes a long list of sites divided into general categories. It’s the coolest forum-like technology that I’ve seen. Specifically, you want an account on Stackoverflow.com. But Stackexchange users are protective of the site’s format and rules. Stackoverflow isn’t the right place for all questions. You might also want to link an account to Superuser.com, for example.

Generally, the community there is incredibly helpful. It’s mostly other developers hanging out, both asking and answering questions. Like any other online forum, it has its abrasive users, so if you “break a rule,” you might get bullied around just a tad. However, as long as you ask articulate questions and show yourself making an effort, you’ll be fine. And once you get a few tricks under your belt, you’ll also be able to answer other people’s questions. It feels good both because you’re giving back and because then you know you’re smarter than you were when you were asking the same question.

GitHub

To really understand GitHub, you have to learn a little bit about version control and open source. This article by James Bruce provides a pretty good overview. But to give you the elevator pitch – GitHub is a place and a way to store and share your code. Just as importantly, it’s a place to browse through tons of open source code.

(If you don’t know what open source is, I would describe it as code that anyone is allowed to download and read. Programs and services that run on open source code are not necessarily free, though the majority are. The opposite of open source is proprietary code, which is code that is only distributed in encrypted or compiled formats and isn’t intended to be read by humans. A good example is Microsoft Windows. The code used to build the Windows OS is proprietary and not freely distributed. However, many flavors of the Linux operating system are open source and can be reviewed by anyone who is interested in taking a look.)

Even if you don’t have any code to share yet or don’t feel quite ready to contribute to an open source project, this is a great place to dig into cool programs and libraries and start learning how they work.

GitHub does offer private hosting for a fee, but with a free account, you can host unlimited open source projects.

Gist

GitHub hosts a Pastebin service called Gist, as well. There’s not a huge difference between the overall concept of GitHub and Gist, but Gist has a more narrow scope. You use it to post single text files rather than entire projects or groups of files.

Visual Studio Express

I haven’t included a lot of actual downloads here, but I think this one is important. I started learning to code on a Windows machine and was tasked early on with developing solutions in a Windows environment. Visual Studio isn’t the only way to do that, but it’s the most powerful and the most convenient. When I first looked at the sticker price on Visual Studio, though, (and before I realized that most companies will purchase it for you if they expect you to use it (What can I say? I’m a dummy)), I was pretty intimidated. It’s an expensive tool. But Visual Studio Express is a free version that offers more than enough functionality for beginners. There are similar tools out there for programming to other environments, but I just wanted to point out for the total noobs that you can get your hands on Visual Studio and start using it now for $0.

Nuget

Nuget is a plug-in for Visual Studio that gives you quick and easy access to tons of cool code. If you decide to program for Windows, you will hear about Nuget, and you will quickly come to love it. Basically, Nuget makes it really easy to host and consume code libraries. If you don’t know what those are yet, get Nuget anyway. As soon as you find out what code libraries are, you’re going to want it.

Chocolatey

Chocolatey is Nuget’s Windows programs counterpart. What Nuget does for code libraries, Chocolatey does for programs. Quick snapshot: You know how when you want to download a program like Skype you have to go to the website, download the file, find the file, then run the installer? Well, Chocolatey makes it so you can just type the line “cinst skype” into the command line to do all of that automatically. In a lot of cases, you don’t even have to interact with the installer. It does everything for you.

Chocolatey doesn’t host every single program for Windows, but it hosts an impressive number. I’ve only found a handful of programs that I use that I can’t get through Chocolatey.

Boxstarter

Boxstarter is something I’m still figuring out, but I’m absolutely sure it’s awesome. Basically, Boxstarter works with Chocolatey to make setting up a Windows system a one-command process. Quick snapshot: You just got a new computer. Now you have to go find all your programs, download them, install, etc., etc. Boxstarter allows you to write a pretty simple PowerShell script (which you can host on Gist, by the way–see how things are coming together?), which will then do all of those things for you.

I haven’t traditionally been a PowerShell user, and I just got started on Cocolatey a few months ago, so I’m still trying to get a handle on Boxstarter. But again, I’m absolutely sure it’s awesome, and it’s going to change the way I spin up a new computer.

Pluralsight

This is the first thing on the list that has no free version–but it is worth ever penny. Pluralsight is web site that hosts training videos on a huge range of topics–everything from coding to professional development. It is heavier on the .NET technologies than open source, so you’ll probably get the most value out of it if you’re going to program for Windows. The training is well-composed, and they have a couple different subscriptions. One just gives you access to watch the videos. The next tier gives you access both online and on a mobile device, includes pre- and post-assessments of the various courses, and provides exercises. They also do an excellent job of labeling the material appropriately for your skill level. Beginner? Well, then don’t take the “Advanced” course to start out.

Coursera

You’ve probably already heard of this one, but I recommend getting an account. This is an awesome online learning center that is adding topics all the time. Unlike Pluralsight, which I would say is more like vocational training, Coursera is structured as an online academic institution, offering courses on everything from robotics to anti-terrorism to business management from schools such as Princeton, Stanford, and the University of Copenhagen. They just added a feature they call “Specializations,” which allows you to earn a series of certificates that demonstrate a proficiency on a certain topic. For example, they have specializations on Data Science, Challenges in Global Affairs, and Mobile Cloud Computing with Android, among several others. Whether or not future employers or academic institutions will recognize these credentials is debatable and beside the point. The courses here are challenging and offer you opportunities to grow your knowledge and skillset with a more academic mindset.

Khan Academy

I’ve found Khan Academy to be a little hit-or-miss, but it’s a force to be reckoned with. The range of topics is huge. It has some programming and computer science modules, but I’m actually recommending it for the math. As I’ve mentioned, computers were designed to do math. I didn’t come from that background. As a matter of fact, for better or worse, I spent a lot of my time in school figuring out ways to get out of doing math. Majoring in English helped a lot. Not a lot of my programming requires much more than basic math skills, and I handle that just fine. But every now and then a topic comes up that requires me to know just a little bit more than I really do. The nice thing about Khan Academy is that I can usually go straight to the module that I need and figure out where that sits in the spectrum. For example, I didn’t have a great grasp of logarithms, so I went to Khan Academy, found a great tutorial on it, and was able to see from there that this was an Algebra II topic. (Sometimes I don’t know when a problem is algebra, trig, or calculus. I don’t get the differences.) So Khan Academy is a big help in showing me knowledge dependencies.

Miscellaneous

These are a few others that I either know by reputation only or have used only lightly.

  • Udacity - like Coursera but more like Udacity
  • Plunker - like Github but can actually run code live for demos and such
  • JSFiddle - cool web dev tool let’s you test HTML, JavaScript, and CSS. The advantage is that you can manipulate all three files and see the output on a single page.
  • JSLint and JSHint - JavaScript parsers that will let you know how good a shape your JS code is in
  • Regexpal - Simple tester for regular expressions that will give you immediate feedback by highlighting matches in sample text. Especially useful for learning regular expressions.
  • Safari Books Online – Unrelated to the Safari browser, Safari Books is a subscription service that gives you access to a library of books on tech. The library is exhaustive and often includes books that have yet to go to press. They’re also starting to add videos, which might make it more valuable than Pluralsight in the long run.

 

 

The Cheater’s Code, Pt. III: Wildcards

Introduction

Time to finish off this Find and Replace macro by introducing wildcards. This post is the last in a three-part series. If you want to know how we got here, check out Part I and Part II.

Scope of Application

Today’s post relies on Microsoft Word 2013 running on a Windows 8.1 machine. But what I’ll cover applies at least as far back as Word 2007 and Windows XP and the equivalent versions of Word for the Mac. If you don’t have Word, you can get a trial copy from Microsoft’s website.

Where We Left Off

I’ve had a bit of a lull here. Things at work got pretty busy, and I spent several nights working on a library to help analyze lists of files against collections of files to see if they match up. It’s called VennDexer, and the source code is up on GitHub if you’re interested. (If you don’t know what GitHub is and don’t understand what Google is trying to tell you about it, I’ll help you out in an upcoming post where I talk about tools of the trade you’ll want to know.) I also built a lot more macros, so I’ve got a lot of material to post in the near future. I won’t be analyzing them in depth like I have our Find and Replace macro, but I think some of them are good use cases for programming basic repeatable tasks.

But to get back to where we left off, a quick recap:

  • In Part I, we recorded a macro that found a period followed by a space and replaced it with a period followed by two spaces. We also covered what a macro is, in general terms, and why they’re useful. However, our macro had a slight problem. Even when a period was already followed by two spaces, it added a space.
  • The recording process in Part I automatically generated some code for us, so in Part II we examine that code in detail to gain an understanding of how it worked.
  • At the end of Part II, we looked at the source of the problem in our original macro–our logic. The computer was doing exactly what we told it to: finding a period followed by a space and replacing it with a period followed by two spaces. The computer takes our instructions very literally. We didn’t tell it to look for a period followed by one space and only one space. So whether the period is followed by 1, 3, or 100 spaces, our macro is going to find the match and do its job.

Knowing that the computer is going to take you literally to a fault is an important understanding in programming. Sometimes the programming language will help make up for this a little bit, but generally speaking the computer does exactly what you tell it to do–not exactly what you expect it to do. It’s like the old communication exercise where you try to explain to someone how to make a sandwich. Every time you say something, it’s wrong.

You: Get the bread.

Student: Where is it?

You: In the cupboard.

Student: What’s a cupboard?

Really, dumb dumb?

But it gets worse. You have to explain to the student to go to the cupboard, open it, grab the bag with the bread (and you have to explain which bag that is), and so on and so forth. It’s a really useful technique for teaching us how much we take for granted in our communication, and that’s really good to remember when you’re programming. If the computer isn’t doing something you want it to do, you should double check that you told it to do that thing. If it’s doing something you don’t want it to do, make sure that you didn’t tell it to do that. It won’t always be your fault, but I’d say at least 85% of my programming problems are a result of miscommunication problems. The computer is always doing what I say instead of what I mean. (The other 15% of my programming problems stem from the computer being incapable of making a sandwich.)

So we need a way to go tell the computer to look for a period followed by a single space and only a single space. Another way to put it is that we need the computer to look for a period followed by a space, followed by any character that is not a space.

I’m not going to run you through the logic of all the bad options. Obviously it doesn’t make sense to tell the computer to search for “. A”, “. B”, “. C” one after the other until we’ve accounted for every possible set. Not only is that terribly inefficient, but it would be be almost impossible to account for every single character. Also, and this is another key to programming logic, we can safely assume that we are not the first people in the history of coding who have had this problem. Just like we didn’t have to make up a computer language to enjoy automated find and replace functionality, we don’t have to make up the solution to matching large, vague sets of characters. A tool exists.

Wildcards: Not Just for Poker Anymore

You’ve probably already used wildcards, whether you knew them by that name or not. If you’ve ever gone into a file folder to look for all your JPEG images, you might have typed *.jpg in the search bar. The asterisk, or star, tells Windows that you don’t care what comes before the dot. You want to match anything file whose name ends in .jpg. So if you had the following files in a directory

hippopotamus.jpg

todoatthezoo.docx

penguins.jpg

passwords.txt

tigers.jpg

directions.docx

zoobudget.xlsx

and then you searched for *.jpg, you’d get back the following list:

hippopotamus.jpg

penguins.jpg

tigers.jpg

The star (*) is a wildcard. In short, that just means it stands in for something else. Specifically, in this context, the star stands in for anything else. I won’t be covering all the wildcards or how they could be used, but here’s an article that expands on the topic. Also, I found a really well-done blog post on how to do advanced Find and Replace in Word, which includes some info on using wildcards. For something a little more advanced, read this.

You’ll often see wildcards mentioned in the same breath as regular expressions. Just to be clear, Word’s wildcards do not function the same way as the wildcards in regular expressions. There is some overlap, but it is minimal. As you get deeper into programming, you’ll likely come across some regular expressions.  They may look a lot like some of Word’s wildcards, but don’t get the two confused. It is best to think of them as estranged cousins who don’t play well together–who maybe even give each other the evil eye on occasion. Don’t invite them to the same barbecue.

There’s More Than One Wildcard

Just to get another pet peeve off of my chest, the star or asterisk is not the only wildcard. A lot of folks get the impression that it is. The question mark, at sign (@), and angled brackets (<>) can also be wildcards, in addition to other characters. This is more of a snotty nerd issue, but armed with this knowledge, when someone tells you to “use the wildcard,” you have enough snotty nerd clout to say, “Which one?”

But I’ve Searched for the * Before and Found It

Remember that Word’s Find and Replace has additional settings. If you hit Ctrl+F in Word and search for the asterisk, it will match only the asterisk–not any character. But when you hit the “More>>” button, you’ll see an option to use wildcards.

advanced-fr-usewildcards

When that option is turned on, searching for the asterisk will match everything.

How Wildcards Solve Our Problem

My gut instinct might be to immediately add the star to the string we’re trying to find.

.Text = ". *"

Of course, it will only take you a second to recognize the flaw in my dummy logic. The star matches anything. That means it will match another space. So as soon as Word finds a period followed by a space, followed by anything–including another space–it will consider it a match and substitute our replacement text.

But the problem is a little bigger than that. This would also match “. A” or “. t”, or any combination of period, space, letter. When it replaces that text, it will also replace the letter we found.

Poo.

To solve this problem, we need to learn one more wildcard feature. I think it might be a little easier to see the solution and work backward from there. The solution will look like this:

.Text = ".*<"

.Replacement.Text = ".  "

The angled brackets are wildcards that represent the beginning (<) or end (>) of a word, respectively. So what we’re saying here is “Hey, Word! Find a period, followed by anything leading up to the beginning of a word. Replace it with period, space, space.”

Why Does It Work?

The wildcard expression works because it stops matching when it gets to the beginning of a word, which Microsoft Word considers to be any character. It doesn’t match on the character. Just everything leading up to it. This actually means that the expression is pulling double-duty. Not only will it find the combination period-space-character, but it will find period-space-space-space-character. In fact, it will find any number of spaces between a period and the beginning of the next word. So it will ensure that periods with too many spaces are also replaced by a period followed by two spaces.

Actually, It Doesn’t Work… Yet

If you try to run the macro now, you probably won’t get any matches. You definitely won’t if you’re using the source text I was in Part I. You know why, though. We have to turn wildcard matching on:

.MatchWildcards = True

Now it works. If it doesn’t work, have a couple Oreos to calm yourself down and go back through the posts.

We’ve Still Got One Problem

Let’s say this sentence is in the third paragraph of our document:

Dr. Smith called Ms. Johnson and asked her to come in for an appointment the following Monday a.m.

Dr. Smith and Ms. Johnson are going to give us a problem. We’re going to end up with some added space between “Dr.” and “Smith,” as well as between “Ms.” and “Johnson.” Other abbreviations show up in the middle of sentences all the time, too: Inc., Rd., St., Mr., Jr., etc. Again, the computer is going to take us absolutely literally. If we want it to do something different with abbreviations than it does with the end of sentences, we have to give it specific instructions. But I think I’ve given you enough ammunition at this point to leave you with two hints. The first is this: in all but a few rare cases, there are more sentences than there are abbreviations. Fix the spaces after a sentence first. The second hint is the solution:

.Text = "([DIJMNOPRS][cdnoprst]{1,3})(.  )(<?)"
.Replacement.Text = "\1. \3"
.MatchWildcards = True
.MatchCase = True

That wildcard expression isn’t perfect. I was still learning how to use wildcards efficiently when I put that together. But it works. I’ll leave it to you to figure out why it works. If you really get stuck and have no idea what’s going on, feel free to leave a comment or two. I’ll be happy to point you in the right direction.

Love and kisses,

Tyler

Make a Mobile Game without Programming — Yes… For Real

Last week I saw a great presentation on a tool called Construct 2 that let’s you make mobile apps (mostly games) without any programming know-how. Will programming know-how help? Absolutely. Can you make a pretty outstanding game without any programming know-how? Yes! It’s actually kind of amazing. In under two hours, I watched this guy build a mobile game from scratch without writing a single line of code. Granted, he’d prepared a practiced presentation and already had all the tools downloaded and ready to go. But you could build a game from scratch in a week easy if you knew what you wanted to do.

I’ve been kicking around an idea for a mobile game for a couple of years now, but I haven’t ever had the patience to get into building it. Mobile is a different environment. Games are a different kind of work than the business application programming I usually do. It takes some getting used to. I’ve tried starting a couple of times, but I always run out of time or patience before I get into anything interesting. Construct 2 made it a piece of cake. I came home from the tutorial and within a couple hours I had a working prototype of the game I want to build… without writing a single line of code!

Now, of course, I like to code. I’d really like to understand the code that Construct 2 built for me. But I’m not a game programmer by trade. I don’t have 10 more game ideas ready to go. I only have the one idea, and that’s part of the trouble. It’s hard to motivate myself to learn how to program games to build one idea. I’ve got other stuff going on, after all. Justified isn’t going to just watch itself every week. Now I can build my game without the slow drudge of learning a whole new skill set. I just tell Construct 2 what platform I want to build for, and it gives me drag and drop tools. Call it lazy if you want, but when my game hits the app stores, you’ll be glad there’s a lazy entrance to game programming! (No. I can’t reveal the game idea yet. Now that you know about Construct 2, you could beat me to the punch.)

Construct 2 has really good documentation, tutorials, and an active user-base. Plus, it’s free. Well, the free version is free. There’s a paid version with some extra features. I’d start with the free one and see if you need the extra features first, though.

If you want to program games and you want to build something you can put in the Windows Store or Play market today without learning how to call the APIs in a physics engine, give Construct 2 a try. (Especially if the phrase “call the APIs in a physics engine” sounds like total gobbledygook to you.) And let me know when your game is ready to download. I want to see if you put my name in the credits!