September Valentine

Hearts, particularly valentine hearts, tend to be a feature of February rather than September. Fortunately, my valentine isn’t crammed full of them. I’ll share it with you, below, as it’s a Snap project.  This school year, I’m providing what TEALS refers to as “lab support” for students in the morning class at DeKalb High School of Technology—South (DHSTS) in Decatur, Georgia.  And, as part of that, I’m working the projects, same as last year, although now, Snap, is not a stranger to me.

DHSTS is a magnet school.  Students are bused in from other high schools to spend half a school day (four periods) in my class, five days a week. This means we cover a lot of material in a short time. In fact, they’re doing an intro to tech first quarter, Code.org‘s Computer Science Principles during the second quarter and AP Computer Science (with Java and a test), third and fourth quarters.

Which brings me back to the valentine.  As part of the intro, we’re doing a little Snap and we’ve chosen what TEALS calls the Animated Storytelling Project.  Last year, I did a nursery rhyme, “Itsy Bitsy Spider” and all of my students did nursery rhymes as well. This year, it’s expanded. It does have to (loosely) tell a story/narrative and fulfill the rubric.

And so, I present to you.  Carol Ann Duffy’s poem “Valentine” in Snap.

is it in there?

Sometimes you want to know if something is in a list. If the list isn’t sorted, the only way you can know for sure is to look at every item in the list and see if it is what you’re looking for. That is called a sequential search and it’s pretty easy to do. Since we’re using Snap, I’ll draw you a picture.

This script reports whether the item was found in the search or not, but it could be modified to do other things. Suppose for example, you have a list of students and you’re looking for all students named Bob. You don’t want it to simply stop with the first student. So you’d need to modify the search to change the “found” half of the or on the repeat until … and instead have found be a variable that you set to an empty list before the loop and then add the index positions as list items to it when you find a Bob in the class. If there is one. If there are no students named Bob, you would have an empty list, same as what you started with. If there were two students named Bob, you would have a list with two index positions in it, telling you where the name Bob appears in the list.

Of course there are other ways. This is programming and, generally speaking, you can find several valid solutions to any problem.

If the list is sorted, there are shortcuts. You can split the list and look in the part of the list where you know something is. You do this when you look through any alphabetized anything. You know not to look for something that starts with a  in the r section.

i’ve got a secret

I said before Hangman is about lists. One of those lists is a list of blank letters that represent the word the player is trying to guess. The easiest way to deal with this is to write a custom block that generates a list of as many blanks as there are letters in the word.

In programming, there are always several right ways, however, there are usually many more wrong ones. Here is one idea of what that custom block to make a list of blanks might look like.

Someone could also build a word of blanks and then use this block from the Import Tools to turn it into a list.

However you build the custom block to make your list of blanks, to say three blanks the script would look like this:

In Hangman, the list of <length> blanks block would the beginning of my display word, before any letters were guessed. If the word were cat it would be three letters. Or run.

To code it, I’d make a variable to store that list. and then replace the blanks with letters as they were guessed correctly.The list variable would belong to all sprites so the host could do the work of checking it and the assistant could do the work of saying it.

making a list, checking it once

Checking a list is called traversal (actually, going through the list and doing anything to it is).  Here’s an example of a list and a traversal of it.  These are the Great Lakes of North America.

The script variable is a variable that does not belong to any sprite and is used only in the script.  This code only says the names of the Great Lakes, but if you take out that purple block and put something else in there, you could do other things.  For example, if you wanted to see which lake had the longest name, you could have a script variable called longest and store the first name there. Then, instead of saying the name, you could have an if block that checks if the current name is longer than the longest  name and if it is, make that name the longest name..  Then put your purple say block at the end and say longest for 2 secs.

background check

How do you get the background to move in Snap? How do you get trees or rocks or buildings to move when your hero goes across the stage? The quick answer is, you don’t. The stage doesn’t move. So how do you have moving tress, rocks, or buildings?  You make them sprites.

Making something a sprite doesn’t move it though, you need a script.  You also need to do some things outside of the script to ensure your sprites do what you want.  First of all, make sure that your sprite can only face one direction.  There are three buttons at the top that control the direction(s) your sprite can face.  Make sure to click the bottom one.That arrow pointing to the right means that the sprite can only point one way, and that’s the way the costume points by default.

Next, make sure the Draggable box is unchecked.  That keeps the player from moving your sprite around.

Now you’re ready for your script.  The important principle here is that when your hero moves right, your background sprites scroll to the left.  If you have a “forever” level, they need to also disappear and reappear when they get to the edge.  Scrolling is perfect for a custom block because you’re going to have more than one background sprite and you can reuse the same code with different speeds for the different sprites.   Sprites that are intended to be closer to the viewer move faster (and are generally lower on the screen) than sprites farther away.

Here is code for a sprite scrolling left.  Note that like any other code, it’s only one possible way,  not the only way.This allows you to plug in two parameters, the speed and the height.

Here, kitty-kitty-kitty

I have a platform game.  It doesn’t have a game name yet; the file name is CatStuff and it’s a cat and a zoomba (kinda like a  cross between a trademarked robot vacuum cleaner and a drone).  I have some very cool code in my pocket for this game.  Jumping.  for example.

In Snap, you animate by changing costume and moving the sprite. My cat has 12 costumes—eight walking and four jumping.  Walking animation is pretty simple.  You cycle through the costumes and change the x-coordinate by an amount.  depending on how fast you want to move.  Jumping involves the y-coordinate as well and you have to do both at the same time.  It’s tricky.  Here’s my code to walk right.

You see the variable for the number of steps to move.  That can be set for all the walking the cat does (and it figures into jumping too) in one place.  That’s the point of having it there.  -240 and 240 are magic numbers in Snap as they are the farthest left and right x-coordinates on the standard stage.

Now for jumping.  Because jumping is not an even process, I couldn’t easily abstract it into a loop like I did walking.  It’s long messy code.  I don’t have comments in the code I’m posting here because it makes it difficult to share the images neatly.You’ll notice there’s an if-else at the bottom.  This is to deal with repeating presses of the space bar that don’t resolve fluidly.  The cat will fall if too high and if somehow it gets below ground, it’ll pop back up.   That’s an in-case because I’ve not observed it, but it is theoretically possible.

Jumping is faster than walking but not twice as fast and I wanted a finagle factor so there’s a place to set one.  I’m math-impaired (really) so my formulas aren’t always mathematically sound.  They work for the game though.

Next time, I’ll talk about scrolling the scenery.

It’s a snap!

Snap is a programming language that is intended to teach programming concepts without the pesky need to learn syntax.  If you’ve ever worked with Legos, K’nex, Erector or other component systems, it’s a similar concept.  Sounds easy, right?  It’s harder than it looks.

Here’s the screenshot of Snap, which can be run entirely online.The area on the left is the set of blocks you can pick from; at the top there are eight options for sets of blocks you can have displayed there.  The default is the first one, Motion.

So, when I loaded Snap for the first time, I did what any respectable programmer would do—I set about writing a “Hello, world” program in Snap.  Oh, my!  Where to begin.  Well, you need to start the program and you need to “say” the text “Hello, world!” and you need to end the program.  Well it turns out the start and end stuff is under Control.  The stuff to say things is under Looks.  And the stuff to tell it, no, you can stop saying it already (forever is an option but ewww!) is under Controls too but the condition you need to test is under Sensing.

After fiddling around with it, I discovered if you only say “Hello, world!” and end, it disappears before the user even is aware it was said.  Not good. There are options. You can set a duration or you can set until an event. I chose an event and the event I chose was a mouse-click.  Here is my version of “Hello, world!” in Snap.Next up. Pong.  Yes, you read that right.  I’m going to be a teaching assistant for a school in Hillsboro, North Dakota (remotely) and I’ll be introducing high school students to programming through Snap and then Python. So for the next while, you’ll be reading more about TEALS than FreeCodeCamp.

TEALS (Technology Education and Literacy in Schools) is the program through which I’m lucky enough to get to reach out and teach the next generation.  I have five(!) kids and of them, only one did any amount of coding (and that was a phase—he’s becoming a paralegal). This is my way of sharing my passion.

pomodoro: for whom the clock beeps

Guess what. I don’t care if my clock has a few millisecond drift. Not enough anyway—the scale is minutes, not tenths-of-a-second, the precision isn’t that important. The default time is twenty-five minutes, which is 1.5 million seconds. There’s a lot of room for slop in there. Why this is important is because I decided I wasn’t going to implement a drift-checking timer, as per the link I posted last week.

I said I was going to talk about flexbox on Thursday and then spent it talking about git and GitHub.  So, a little about flexbox.

This is one of the ways to be responsive.  The CSS involves letting the parent element know that it has to display flex and anything about the overall flex display that it needs. Here’s a snippet from the CSS file for the wiki-viewer. In order to allow a grid display, I have to use flexbox. I wanted 3 per row and I have ten items, so I needed to wrap them.

1
2
3
4
5
6
7
8
.gridBox {
display: flex;
flex-wrap: wrap;
position: relative;
top: 55px;
margin-bottom: 20px;
font-size: 18px;
}

Here, the children need to know that they they only get 30% of the available horizontal space and that they can’t grow but hey can shrink. The flex works a lot like the border property in that you can either specify parts of it or shortcut it into one attribute. Here I shortcut it. The three values are flex-grow, flex-shrink, and flex-basis.

1
2
3
4
5
6
7
8
9
10
.gridDisp {
flex: 0 1 30%;
height: 350px;
margin: 5px;
padding: 5px;
cursor: pointer;
overflow-y: auto;
border: solid 1px #008800;
border-radius: 0px;
}

For the clock (which is what we’re supposed to be chatting about) the important issue was I wanted responsiveness while keeping my stuff aligned in columns and rows. It’s a little more involved so I’ll skip the code examples, but feel free to hit up the style.css on the repo and look around.

Back to the basic clock. I thought it was done when it counted down, but I hadn’t thought that someone might press [Start] twice. So I fixed it to where a second press of [Start] does nothing. Next, someone explained that what they expected, was, if you tried to increment or decrement the active counter, it would stop the countdown. Good call. I implemented that.

The beep. I have a file in .MP3 format that is five beeps. You only hear one because I only play the first second of it. It was taken from freesound.org

I also futzed around with the look of it. I decided having a button that changed from [Start] to [Stop] looked cool but might be confusing to the person using it (besides, the other two items have two buttons).

Here is the new look of the Pomodoro Clock.

calculator: the chain gang

Let me be blunt.  The calculator is not a difficult project once you’re aware of the eval() function that takes a string and treats it as an arithmetic expression and evaluates it. If I knew the name of the person who mentioned it, I’d share.  The trouble is, it was a toss-off comment in a reply to someone else and I happened to be paying attention.  For the record, attention is good.

I hang out in the gitter FreeCodeCamp room quite often and this sort of thing is there, going on all the time.  Someone posts a problem, whether it’s with a challenge (“how do I nest my image element in an anchor tag?”), an algorithm (“can someone check my Roman number code?”) or a project (“my Twitch viewer shows the same channel eight times instead of showing the eight channels from my array”) and others offer help. Usually, the problem is spotted and resolved (often the person posting sees the issue as soon as they shared it). Someone else’s calculator issue was solved by eval() and I was watching.  This was back when I was doing random quotes or something.

The difficult part of the calculator for me was how do I make something that looks like a calculator in HTML and CSS. The answer is by looking at someone else’s calculator.  Google Images to the rescue.  I found the OSX calculator icon. It has buttons on it for Clear and ± and memory management stuff in the top row that I don’t need. So if I delete the top row, I have a basic idea of what a calculator should have. If you look at it side-by-side with my calculator, you can see how it was inspired by this one. My phone calculator looks like someone was too lazy to bother making it look like it wasn’t an app on a phone. So using that as a guide would have given me something really ugly and not like the project was looking for.
OSX calculator icon phone calcmy calc

The colors for my calculator are courtesy of Computer Hopes HTML Color Codes & Names page.  I found the red for that button as a trinary color for the blue of the other buttons. You can find trinary colors by typing or pasting the hex code for a color in the box at the top. I got the display box color by sampling the color from the OSX calculator and averaging it. It took a bit of trial-and-error to get good button colors with my faceplate color.

But that’s only part of it, there are also fonts. For the display, I wanted a font with something in the zero.  A slash or dot or something. But not for the buttons. Zero on a button should look empty and the C should look reasonable.  So I hit up Google Fonts.  I specifically typed in the digits and the key signs (so I could see what the keys would look like) and told it to make that be the sample for all of the fonts.  Then I said I only wanted monospace fonts. And alphabetical because I was looking for specific things, not popularity. The fonts I chose were Abel for the the keys and Allerta for the display. I liked the look of the C in Abel and the fact the 4 was closed.

So, on to making it function.  I’m sure there’s a better way—there always is—but what I did was made a click event for each button and then handled it. For the digits, it was easy—check if the the entry was zero—if it was, replace it with the number, otherwise, add the digit to the string for the current number.  Decimal point was tough—you can only have one per number.  And signs meant I had to peel off the current number and make a new one.  And then the equals meant, run eval().  Okay, that all worked so I took it to gitter.

And someone said it didn’t “chain”.  Now, I could type 2+5*4  and press the equal sign and get 22 so I knew it worked.  But that wasn’t what they meant.  They meant, if I pressed equals again, it should repeat the last operation so I should get 88 (22 * 4) the next time, and so on.  While I was fixing it, we got into a side conversation about how I don’t generally use a calculator so I was unaware of that expected behavior.  Then, right when I had typed “try it now” they typed, “don’t worry about it, mine doesn’t do that, either,” and I had to laugh because, well, mine does it.

Here’s how.  I’m already keeping the current number separate from the rest of the current expression.  I have to so I can use the ± on it.  So what I need to do is grab the last operator from the string (it will be the last character) and combine them and put that in the chain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$("#eqButton").on("click", function(){
if(curNum != ""){
// if the expression isn't empty, evaluate it
curResult = eval(curExp + curNum);
if(curResult === 3/0){
curResult = "0&amp;nbsp;Divide&amp;nbsp;Error";
}
chain = curExp.substr(curExp.length-1) + curNum;
curExp += curNum;
oldExp = curExp;
}
else{
// they pressed = again
curResult = eval(oldExp += chain);
}
curNum = "";
dispResult();
curExp = "";
dispCurExp();
});

It’s still on CodePen but will be moved to GitHub before I turn it in.  The links on the right will always be current.

weather: conditions are changing

So I asked around and determined that the weather source for the FCC glitch.me pass through is OpenWeatherMap.  And the first thing I found out when starting work today is that I got an error message when trying to connect to it.  As always, “it used to work” only gets you so far in life, and I hit up the gitter rooms looking for help.  @Masd925 was there for me. It seems I wasn’t making the call right. Here’s the relevant line of code:

[js]url:”https://fcc-weather-api.glitch.me/api/current?lon=” +myLon+ “&amp;amp;lat=” + myLat,[/js]

I had not been “plussing” my variables and that had been okay but between my last post and today, that became broken.

On to condition codes.  When we left, I was searching for condition codes so I could use my icons instead of the sorry icons shown here with their associated weather conditions.  These icons are 50px by 50px PNG images. Like this one for a thunderstorm.

"Icon"

Jussayin’.  These are not real icons.  But hey, there are weather actual condition codes, like for clear skies or thunderstorms or whatever. I’m in luck, right?

This turned out to be a can of worms.  First off, DarkSky had had condition codes that included day or night so it would say, for example, “clear-day” as the condition description and I could then assign a sunny icon to display or “clear-night” and I could assign a moon icon.  Well, OpenWeather has a numeric code, in the weather[0].id field of the data object that corresponds to everything from “clear sky” to “hurricane” but it is not so kind as to tell you if it is day or night.  It does however, give you the sunrise, sunset and current time (in seconds since January of 1970 but who cares?) and you can thus figure out if it’s dark or not.  It’s only one more step, right?

Okay, achievement unlocked! I can determine which icon to display and I can use more of my wonderful weather-icons icons (which are actual icons, not PNGs) and thus respond to font-size: settings in CSS and otherwises comport themselves with aplomb. And I mean more because with OpenWeather’s coding system, there are so many more weather conditions that can be displayed.  Some have only one or two 3-digit code and others are ranges. I try to grab the special cases first for ease of coding, but not all of them, as the 800-level codes are odd.

You saw the aside on wind-bearing.  This is how I do stuff.   Here, without further apology is the mondo if structure for the condition codes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// first some special cases
if (icon == 962) { wIcon = "wi-hurricane";} else
if (icon == 902 || icon == 781) { wIcon = "wi-tornado";} else
if (icon == 906 &amp;&amp; !isNight) { wIcon = "wi-day-hail";} else
if (icon == 906 &amp;&amp; isNight) { wIcon = "wi-night-alt-hail";} else
if (icon == 711) { wIcon == "wi-smoke";} else
if (icon == 731 || icon == 751) { wIcon == "wi-sandstorm";} else
if ((icon == 611 || icon == 612) &amp;&amp; !isNight) { wIcon = "wi-day-sleet";} else
if ((icon == 611 || icon == 612) &amp;&amp; isNight) { wIcon = "wi-night-alt-sleet";} else
// now the general cases
if (icon &gt;= 200 &amp;&amp; icon &lt;= 299 &amp;&amp; !isNight) { wIcon = "wi-day-thunderstorm";} else
if (icon &gt;= 200 &amp;&amp; icon &lt;= 299 &amp;&amp; isNight) { wIcon = "wi-wi-night-alt-thunderstorm";} else
if (icon &gt;= 300 &amp;&amp; icon &lt;= 399 &amp;&amp; !isNight) { wIcon = "wi-day-rain-mix";} else
if (icon &gt;= 300 &amp;&amp; icon &lt;= 399 &amp;&amp; isNight) { wIcon = "wi-night-alt-rain-mix";} else
if (icon &gt;= 500 &amp;&amp; icon &lt;= 599 &amp;&amp; !isNight) { wIcon = "wi-day-rain";} else
if (icon &gt;= 500 &amp;&amp; icon &lt;= 599 &amp;&amp; isNight) { wIcon = "wi-night-alt-rain";} else
if (icon &gt;= 600 &amp;&amp; icon &lt;= 699 &amp;&amp; !isNight) { wIcon = "wi-day-snow";} else
if (icon &gt;= 600 &amp;&amp; icon &lt;= 699 &amp;&amp; isNight) { wIcon = "wi-night-alt-snow";} else
if (icon &gt;= 700 &amp;&amp; icon &lt;= 799 &amp;&amp; !isNight) { wIcon = "wi-day-fog";} else
if (icon &gt;= 700 &amp;&amp; icon &lt;= 799 &amp;&amp; isNight) { wIcon = "wi-night-fog";} else
if (icon == 800 &amp;&amp; !isNight) { wIcon = "wi-day-sunny";} else
if (icon == 800 &amp;&amp; isNight) { wIcon = "wi-night-clear";} else
if (icon == 801 &amp;&amp; !isNight) { wIcon = "wi-day-cloudy";} else
if (icon == 801 &amp;&amp; isNight) { wIcon = "wi-night-alt-cloudy";} else
if (icon &gt;= 802 &amp;&amp; icon &lt;= 899) { wIcon = "wi-cloudy";} else
{ wIcon = "wi-na";}; // if all else fails, display a giant N/A
iconStr = '&lt;i class="wi ' + wIcon + '" style="color:' + iColor+ ';"&gt;&lt;/i&gt;';

That iColor is my custom color I wrote about last time.  That gives me a color for the temperature and the icon based on the Celsius temperature. It has a mondo if too.

Next time, I submit it and push it to GitHub (in the other order, though). You always want to try to sleep at least once before turning in code to make sure you caught stuff. And yeah, that’s not always doable.