2013 Retrospective

2014-Jan-01, Wednesday 22:31
dorchadas: (Default)
Let's talk about the last year!

I guess the biggest change from the perspective of this blog is that I started actually posting here again. I got inspired by RPGs--as is often the case, I admit--and started my Dungeons & Design series, and I think it was mostly the fact of posting those that got me into the habit of posting about other subjects. There are other factors too, like how I have enough down time here and there at work that I can write posts in notepad, send them home, and then post them. I also stopped friend-locking everything and started defaulting to public posts, even when they're about my life. It's essentially security through apathy--I can see how many people visit my blog, and on an average day it's a couple dozen. I post all these updates to Facebook and Twitter and the truth is that most people don't care. That may be a little sad, but it certainly tells me that the excessive care I was taking about talking about anything remotely personal is unwarranted. Whatever I say will mostly just get lost in the flow of the internet anyway, unless people are specifically looking to read it.

I was hoping that we'd be paid back by at least one of the people who owed us money this year, but it didn't happen. Aggressively didn't happen, in the case of the Japanese Pension Office. Or perhaps passive-aggressively? Regardless, it led to some tight moments at times, especially during the summer, though I do admit that some of that is because I refuse to touch the principal. Now that [personal profile] schoolpsychnerd has a steady paycheck from her internship everything is okay, though I admit my grasping miserliness does mean I'm less happy with our finances that their absolute quality should lead me to be, but overall it's been on an upward trend. And maybe someone will actually pay us this year. A man can dream.

Work continues much the same as it has been. I had my annual review and did better than I did last year, and my job's bureaucracy and policies means that I'll get an automatic raise and a yearly bonus commensurate with my performance. It's theoretically possible that we won't get the bonus, since the amount and whether it occurs at all is based on the AMA's overall performance during the year, but I haven't heard of anything that would indicate that it's not coming. Even if it doesn't, I'll still get the raise. The benefits of working for a non-profit with no shareholders!

In terms of personal improvement, I took up programming! I originally thought about doing it back in May and was given a lot of resources, and later took a Coursera course that I wrote all about. I've even seen found an implementation of Python for the iPad, and since I have my iPad with me all the time at work, I can get that and then have time to bash my head against programs at work as well as at home! Indeed, during my interview for the job I was asked if I knew anything about HTML or programming and I had to say that I did not, so if I can actually learn programming to a useful level I can hopefully get a promotion. The end project was an implementation of Asteroids, and I'd love to do a lot more to work on it than I had to do for the class to keep my hand in, but what I did accomplish is reasonably impressive, I think.

Also, studied Japanese, but on that subject I'm less confident. I maintained my ability, and that's about it.

Last year, I told myself that if I maintained the weight I had reached in August (~77 kg) for a whole year, I'd go get my wedding ring resized because it's rather large now and I'm kind of worried that it will slip off at some point. Well...I did maintain my weight, but I didn't actually get the ring resized--see the above-mentioned grasping miserliness. I also linked up my new iPhone's M7 chip with LoseIt and started tracking my steps and apparently my average number of steps per day is...5,218. Out of the 10K that's recommended. Exercise is healthy basically no matter what, and getting that number up is something I'd like to improve on in the future, but so far I'm doing pretty well on that front.

I made much more of an effort to be social in 2013. In 2012, I think I had the tendency to hermit a lot more, turning down people's invitations and not really inviting anyone over to [personal profile] schoolpsychnerd and my apartment. I'm not sure what exactly it was. It might have been some remaining difficulty with adjusting to the pace of social life in America vs. what it had been like in Japan, maybe some Anxiety Cat--there's a really old one that I thought fit me really well that said something like "too nervous to talk to people, come off as arrogant or standoffish"--maybe just my typical introverted personality, but this year I tried to avoid falling into the trap of staying home all the time. I like to think I succeeded, or at least reasonably well. And it turns out that traveling out to other places isn't really that bad, even on a work night. I tend to apply the maxim "past performance is no indication of future results" to social events if I'm not careful, in the sense that sure I had fun the last time I went to a party, and the time before that, and probably the time before that...but what about this time!?!? That's not a productive attitude to take, honestly. So this year, I made sure to try to shut that off at the pass. Once I get out of the house, then inertia takes over and I'm not exactly going to turn around halfway there. And it turns out that my friends are awesome people and fun to be around to an extent that far outweighs the annoyance of having to change my physical location. Who would have thought, right? Obviously, this has always been true, but it's convincing that little voice that's the trick, and in 2013 I beat it into submission. Or at least, I inflicted grevious wounds.

All in all, it's been a pretty fantastic year, and I'm looking forward to what 2014 will bring.

I realize that posting song lyrics is incredibly emo and so early-2000s as to be aggressively unhip, but it's pseudo-tradition for me, so:

A long December and there's reason to believe
Maybe this year will be better than the last
I can't remember the last thing that you said as you were leavin'
Now the days go by so fast
And it's one more day up in the canyons
And it's one more night in Hollywood
If you think that I could be forgiven...I wish you would
The smell of hospitals in winter
And the feeling that it's all a lot of oysters, but no pearls
All at once you look across a crowded room
To see the way that light attaches to a girl
And it's one more day up in the canyons
And it's one more night in Hollywood
If you think you might come to California...I think you should
Drove up to Hillside Manor sometime after two a.m.
And talked a little while about the year
I guess the winter makes you laugh a little slower,
Makes you talk a little lower about the things you could not show her
And it's been a long December and there's reason to believe
Maybe this year will be better than the last
I can't remember all the times I tried to tell my myself
To hold on to these moments as they pass
And it's one more day up in the canyon
And it's one more night in Hollywood
It's been so long since I've seen the ocean...I guess I should...
dorchadas: (Dreams are older)
Well, that's finished, then. You can play my final project in the form I submitted it here--click the arrow in the upper left to start the game.

In some ways, the fears I expressed in previous posts were correct. A lot of the syntax we learned dealt with the specific implementation of Python that was used for the class that is not going to be the same anywhere else. Ways to load images, and take in mouse clicks and keyboard commands, and implement elements of the GUI, and so on. It's possible that they're similar to some kind of standard interpretation, but if so, I have no idea because we didn't learn about that. But programming isn't all just memorizing specific commands. It's more about learning ways of thinking and problem-solving skills that you can transfer over into any other programming language other than the one you started learning on, though this is obviously more or less difficult depending on the construction of the particular language.

I did run into some fun moments when I was developing this:



That was how it looked after I implemented multiple asteroids spawning and multiple missiles firing, but before I included anything about collisions. I messed around with it not just for the picture, but also to see if it was possible to have so many objects on the screen at one time that the game crashed, which it didn't. It did suffer from a lot of slowdown, which you'll also see if you try to play the finished version, but fixing that is one of the things I want to mess with now that the actual course is done. Right now it checks for collisions 60 times a second and it doesn't take position into account at all so it checks the entire screen every time even if there's only two objects on opposite ends of the screen. Hacking that down to maybe 4 times a second would probably make it work a lot better. See, an increasing number of objects becomes geometrically more intensive, because each object has to check for collision with everything already there, and everything already there has to check collision with it. Doing that when there's 12 asteroids and a ship and a few missiles and it's all being done through a browser-based code implementation which already slows everything down anyway is overkill.

On a further subject, look at the explosions in the game above. They weren't required as part of the assignment, but they were listed as a bonus step if we felt like we would be able to implement them, and I figured I'd give it a try. It only took about 15 minutes and was pretty easy. It was just loading the game, shooting things, getting an error message, fixing that, repeat until I finally didn't get any error messages. It was pretty much the perfect ideal of what bug-fixing should be like. Though once it worked, the explosion graphic was cycling through the various frames way too quickly and in the wrong location for the sprites, so that had to be fixed, but that just required checking how big the sprite was to make sure that I would cycle through to the next frame properly.

There's still more I want to do now, for my own personal improvement. Make the playing area bigger and the ship and missiles smaller. Maybe add powerups, that make missiles go further, or that shoot out two or three missiles with each press of the fire button, or a shield that blocks a single hit. A limited teleport that moves the ship elsewhere. Make the asteroids only spawn near the edge of the screen and drift toward the center instead of randomly appearing out of nowhere. Porting it over to regular Python instead of Codeskulptor's version of it.

Would I recommend this class? Not really. Even for a free class, I think it focused far too much on the idiosyncrasies of the class's specific implementation of Python and had several lazy practices, like the use of global variables because the GUI can't handle input any other way. That's not to say that I thought it was worthless, because it wasn't, but there are a bunch of other free sources for learning programming if, like me, you're cheapassunwilling to spend money.
dorchadas: (Kirby Walk)
a.k.a.: Lasers, pew pew!

This week and next week are the same project. We're doing an implementation of the old classic asteroids, though our version has sounds and actual sprite-based graphics because the professors programmed a GUI capable of handling such things.

It only took a couple hours to do, though I ran into a problem not based on programming but on math (to the extent that there's a difference anyway). So, you want to move a spaceship in the vacuum of space. That makes you need to take Newtonian mechanics into account, unless you're making X-Wing and want World War II dogfights in space, but we aren't. Except for the friction. We have friction in space. It's in the design requirements for the program.

I guess this like how in Power Rangers the moon has an atmosphere.

Anyway, Newtonian mechanics. If you don't know what I mean, it means that if you go forward, and then go left, you maintain your forward inertia and end up traveling at an angle, so I needed to calculate properly to make sure that happens when you're moving the ship around. In summary, the movement keys control acceleration, not velocity (at least for forward movement). Fortunately, it turns out that it's possible to turn an angle into a movement vector as long as you have the angle in radians, using the cosine and the sine of the angle. The problem I ran into was in correctly adding that to current movement to produce the new movement and make it look smooth, which took an hour and turned out to be incredibly simple, much like my problem with brackets and list comprehensions earlier. Just...add them. And include a constant to make sure the movement is smooth and scales up to the maximum possible velocity slowly, but that's easy enough. I'm starting to wonder how much of programming time is wasted in making simple problems harder than they should be. I guess that's why the Ballmer Peak is a real thing.

This is why I described programming as "math with more words" on Facebook. Even though the programs do the actual calculations for you, you still need to understand enough math to write the equations correctly. Or enough to Google how to write the equations correctly. Ahem.

Also, I wrote this method for the Ship class that handles the behavior of the player's ship:
def chargin_mah_lazor(self, pew_pew_pew):
global a_missile
lazor_bank = [self.pos[0] + angle_to_vector(self.angle)[0] * self.image_size[0] / 2, self.pos[1] + angle_to_vector(self.angle)[1] * self.image_size[1] / 2]
if pew_pew_pew == True:
a_missile = Sprite(lazor_bank, [self.vel[0] + angle_to_vector(self.angle)[0] * 3,
self.vel[1] + angle_to_vector(self.angle)[1] * 3],
self.angle, 0, missile_image, missile_info, missile_sound)

(indents not preserved during copying)
We can always use more laz0rs in our games, right? The documentation calls them missiles, but it's not like they have missile graphics. They're little blue star-shaped energy balls. That's as close to an 8/16-bit laser as makes no difference.

On the topic of things I learned this week, I learned about Magic Numbers, which are when you find random inexplicable numbers in the code whose value seems to be pulled out of nowhere. I did that when I wrote Pong and got called out for it, and almost did that this week when I was trying to make sure flying off one side of the screen would put the ship back on the other side. I was all ready to write in the raw numbers of the size of the playing field when I realized that the program template had set the Width and Height as globals precisely so that I could just say, for example, “pos[0] %= WIDTH” and then if I ever changed the size of the playing field, the rest of the code takes that into account and I don’t have the ship randomly disappearing and reappearing in other places.

Next week--the last week of the course--we deal with actually making the asteroids collide with the ship, making laz0rs blow up the asteroids, spawning new asteroids, keeping score, and so on. And then we're done! Though at the moment, my current plan is to keep tinkering with it. Adding some kind of limited-quality teleport, maybe adding powerups, other ships that try to kill you, that kind of thing. Sure, it's derivative, but it'll be a good learning experience.
dorchadas: (Green Sky)
This week was all about classes and objects and object-oriented programming.

Hmm. It's a good thing this class doesn't cover hardware or I'd be writing about master/slave systems.

Anyway, this week we programmed a graphical implementation of Blackjack. To my surprise, the graphical part was really easy--it was the logic of getting the cards to work that was hard and required some banging of my head against the wall. The way they suggested we did it involved three object classes: a Card class that handles the individual cards, including assigning values and suits to each of them and retrieving the proper image for drawing a single card to the GUI, all of which was implemented already in the program template we got; a Hand class that combines cards into a hand, deals with drawing new cards from the deck, and calculates the value of the hand for comparison, and a Deck class that assembled the proper 52 cards into a deck, figured out which card was on top and passed that card to each hand, and shuffled itself when starting a new game. Each class also had a method to report its contents which wasn't useful in the final program but was really, really helpful when I was trying to figure out what the hell was going wrong.

And oh, did things go wrong. Not with the graphical part--that was actually really easy to implement. But getting Hand and Deck to work was an adventure. First I couldn't get it to properly calculate the value of a hand, so it was a wildcard whether you won or lost. Then it was ignoring the ace special rules completely, so the classic blackjack hand was only worth 11. Then the Deck wasn't properly drawing cards, so I was pulling cards aren't that weren't on the top. Then when I fixed that and got both hands implemented, hitting worked, but standing caused an Index Out of Range error on an attempt to access a relative list element (blahblah[-1], which should get the last element in the list no matter how long the list is). Then I went and fiddled with something totally unrelated to fix the problem that after a single game the hands weren't cleared, so a new game would start with the hands from the previous game plus two new cards for each player. When I fixed that, all of a sudden the list index stopped returning errors because reasons, and despite extensive testing I couldn't get the index errors to show up again. Then I had a problem with calculating the score properly because sometimes I was doing it one way and sometimes another way, and sometimes the testing statement I printed showed the one way when it was actually using the other way, which is why you shouldn't rely entirely on print statements to debug your code. Then I extensively tested the program as an implementation in the console and made sure everything worked.

Then I implemented the GUI without problems. Crazy, right?
dorchadas: (Dreams are older)
This week was programming an implementation of Memory (the card game) and a big lesson on lists and dictionaries. There was also a lecture that was mostly devoted to the concept of iterative improvement and how important it is to programming.

The name does basically say it all, but I'll describe it anyway to avoid any confusion--don't do everything at once. Unless you are The One, destined to obtain power over the Matrix and defeat the machines, the programs you write will have errors. Some of them will be obvious because the program won't work at all, and modern languages tend to be reasonably good at telling you where a program breaks if the syntax is wrong. Sometimes the program works but it just provides a bad output, and if the entire program is all crafted at the same time, it's incredibly difficult to figure out exactly where the point of failure is. Much better to do step 1, make sure it works, do step 2, make sure that works with step 1, etc., until the entire thing works together.

Though as a story, sometimes syntax errors just screw things up. I was reading a forum thread where someone was trying to add a Coptic culture to Crusader Kings II and ended up with most of England filled with Noculture kingdoms speaking Noculturian. A later post in the thread suggested an unmatched parenthesis as the most probable cause. Oops.

I still have 100% in the course, though some feedback I got on last week's project was enlightening. I wrote Pong, and there were variables for the width of the paddle, the radius of the ball, the height of the paddle, and so on. When I calculated when score should be counted and when the ball should bounce back, I tended to calculate it in absolute distance by eyeballing it and adjusting the pixel count, and in the end, the program worked, so I submitted it. The feedback suggested I use the variables and that my code was hard to read because I hadn't used them, and until I saw that sentence, calculating the point where a score would be granted as if ball_pos[0] < PAD_WIDTH + BALL_RADIUS: instead of using the direct numerical values, because while it didn't matter here, it's best practices in the future to make sure that if the size of the playing field gets changed, then everything still works properly.

I also relearned the importance of math. For Memory, it's obviously important to know which card the player clicks on, and in the beginning all I could think of was needing a giant if statement--like, if click[0] > 0 and click[0] < 50:, and so on for every group of 50 for each of the cards, but I knew that there had to be an easier way, so I headed to the class forums. Someone there had the same problem, and a comment mentioned integer division, after which the light bloomed in my head and the rest of the coding was pretty easy. Since the cards are a standard width, just divide the X coordinate of the mouseclick by that width using integer division and the whole number left will tell me what card was clicked on. 382 // 50 = 7, so that's the 8th card, because 31 // 50 = 0, so the first card is the 0th card when checking the list of cards.

Incidentally, I think I've learned why Python list indices start at 0 instead of 1.
dorchadas: (Broken Dream)
I don't have as much to report this week. We learned how to use lists and tuples (etymology if, like me, you had no idea what that was), and programmed Pong.

Well, more like pseudo-Pong. See, our implementation doesn't keep track of the ball bouncing off the sides or corners of the paddle by using a "gutter" that's the same width as the paddle. That allows us to avoid having to do complicated math to figure out what direction the ball would have to bounce if it hit the edge, and by going all elementary physics and treating the ball as a spherical object in a vacuum--which, well, it is--we can just reverse the appropriate components of the velocity. It's pretty simplistic, though it was good practice for proper ordering of if-statements and a reminder that copying and pasting code can often be more trouble than just re-writing the same code. I spent ~15 minutes trying to figure out why the paddles were working in one direction but going berzerk in the other until I realized that when I copied the movement code from one paddle to the other, I didn't change all the variables, so the right paddle controlled itself and the left paddle controlled itself and the right paddle. Oops.

If you want to play an awesome version of Pong, don't play my version. Play Plasma Pong.

The overuse of global variables continues, and seems to be completely due to lazy coding for the GUI they're using. As near as I can tell, most UI elements that take player input cannot accept any input other than from the UI itself and can't call other functions, which makes passing variables around among functions difficult at best. It's something I'll have to keep in mind when I try to become a programmer, motherfucker.
dorchadas: (Drop Bear)
There was a forum thread (link provided even though it might be inaccessible) where one of the people in the class mentioned that a lot of the code they were reading was pretty inelegant and clunky, specifically citing the example of using a boolean global variable instead of using the timer.is_running() function to determine whether to award points in the stopwatch game, and that they had provided suggestions of how to improve the person's code while still only grading them on what was in the grading rubric.

Since I already wrote about timer.is_running I won't repeat myself, but I was kind of surprised at the reception the poster got. Even though they specifically said that they didn't take points off for inelegant code, they got downvoted like crazy and some kind of hostile comments, mostly about how this is an introductory course etc. etc. And that's true, but there's no reason to teach bad habits that people will just have to unlearn later. It's easier to learn than it is to unlearn and then learn something different.

I guess it's like the quote goes:
The trouble with most of us is that we'd rather be ruined by praise than saved by criticism.
-Norman Vincent Peale
Huh. Re-reading the thread, things are better now. When I first looked, the OP's posts were all getting downrated quite heavily. Perhaps I was too quick to judge.
dorchadas: (Green Sky)
I'm growing increasingly concerned that the processes I'm learning in this class aren't necessarily transferable, though I suppose that's also true of people who spend a long time with one company and have to work with their proprietary systems. See, the class is about learning to program through making games, and to facilitate this, the teachers made a bare-bones GUI that we use to get images and text to appear. That's all well and good, but I'm running up against programming best practices here. Global variables are bad, but as near as I can tell, the GUI requires the use of global variables to function at all, since some of the functions for manipulating the GUI don't take any inputs. It give me an added impetus to make sure I understand the underlying principles rather than just blinding writing random things until it works.

This week was just learning more ways to manipulate the GUI, though I did learn that graphics coordinates are measured from the upper left of the plane rather than the lower left as one might expect, apparently because of the way old CRTs scanned--from top to bottom and left to right. The actual program was a stopwatch game--stop the stopwatch on a whole number, get a point--and the program dealt with storing the time in deciseconds as an integer, converting that into a minutes:seconds.deciseconds format, and then properly accounting for 60 seconds becoming a new minute, prevent ~.1 from awarding points due to improper rounding, and prevent the player from spamming the stop button on ~.0 to rack up their score.

It's the last one that was a bit concerning. The teachers suggested using a global boolean variable to track whether the stopwatch was running and preventing it from increasing the score if it wasn't, which, okay. The problem is that the GUI includes a timer.is_running() function to innately determine that, which I learned about by reading the documentation, so I just used that. Why didn't the teachers mention that, since they programmed the damn GUI themselves? You'd think that would be relevant in the first assignment where we learned how timers work.

Animecharactersigh.jpg

In other news, I ran into a really odd situation during peer evaluation of last week's project. In the comments on the project, the guy who wrote it copyrighted it. I wouldn't have thought that this was more than an odd quirk of his personality--you're copyrighting a guess the number game? Sure, whatever, dude--except his code didn't even work. And I don't mean in some subtle way that required me to dig into it to figure it out, I mean that I pressed the "Random number 1-100" button and the program threw an error and quit. Not only that, but it was supposed to cycle through again after you ran out of guesses, so you could just keep playing over and over again if you want. His program didn't do that. It went through two cycles, but then threw an error and quit. Not only that, but getting the number correct on the last guess didn't properly credit you. The game just told you you lost and then started over, and then the second cycle was impossible to win because it errored out. I mean, this would have taken literally seconds to figure out from a cursory test, but he didn't do it.

I suppose this is how QA people feel all the time.

Edit: Poking around the class forums on the topic of global variables, I found this quote:
In event driven programming you need to keep state around between event handlers. Using global variables is the easiest way to do this at the beginning level. At the end of the course, I will discuss how you can migrate towards using better practices.

Global variables are bad because they lead to insidious problems that are often hard to track down in larger programs. In the small programs that we are writing here, they are often manageable, even if they are not really desirable (and still can lead to bugs).
So, we'll see how that turns out.
dorchadas: (Office Space)
Wherein I learn not to blindly trust advice from people who are supposed to be my betters!

So, context. This week, we're writing a program that plays a simple "guess the number" game. Using the GUI library that they wrote for the class, we have to make it pop up a window, provide two buttons that changes the range of the game from 1-100 or 1-1000, and an input field for the player to put in their guesses. Then the program gives the player a set number of guesses--because, for example, any number between 1 and 100 can be found in seven guesses using binary searching--and when the player runs out, the game fails the player, prints out what the number was, and starts over.

It's the last part that was giving me trouble. Following the instructions suggested by one of the instructors, I wrote the main part of the program like so:
>>>Call global variables into the function
>>>If statement to check if the player has no guesses left and end the game if that was true.
>>>Decrement the guess counter
>>>Turn the player's input from a string into an integer so it can be compared to the computer's choice.
>>>If statement to do the actual comparing. If the player is wrong, print "higher!" or "lower!" and run through the loop again. If the player is right, tell them they win and start a new game.

The problem I kept running into was that either the game would end after (number of guesses you were supposed to get - 1), or that the player would get the number of guesses they were supposed to, and then the game would ask for one more input, which would end the game no matter what even the player made that guess correctly. Can you see where I went wrong here?

The problem is the order I set up the operations. Since the checking for how many guesses are left comes before the actual processing of the guesses, it means that after the final guess, the only place to go is back to the beginning of the loop and wait for more input. Then it gets that input, realizes that guesses are zero, and quits the game before it processes the guess, so the player gets the correct number of guesses but has to input a last futile guess to correctly end the game.

Originally, I tried moving the decrement to above the if statement, but that doesn't change the order of processes. All it did was meant that the player got one fewer guess than they were supposed to. Only moving the processing of the guess to the end of the function properly kicked the player out after the last guess. At the very beginning, I had put the check as part of a single if statement that also checked the guess for correctness, but that didn't work, and it took me a while to figure out why. The reason is that it's an if statement, not a "perform one or more of the following as may apply" statement, so it had the same problem as my implemenetation above--namely, that it needed an input to realize that the player had no guesses left.


Apparently there's also a while operator, and I could have jammed the whole thing under while guess_count > 0 [blah blah blah] else: print "LOL UR BAD" / new_game(), but we haven't actually covered that and I didn't want to mess with it, though I might go back and screw around with logs to figure out how many guesses the program gives the player instead of hard-coding in the two possibilities--seven guesses for 1-100 and ten for 1-1000.

And I'm sure there are other ways to implement this. One of the things that peer grading the first assignment showed me is that the obviously correct answer that I, of course, used in my personal implementation of the project was not the only possible way to do it. I don't recall where I read it, but I read a quote that said that you can become an adequate programmer working by yourself, and even a good one, but you'll never become a great programmer unless you work on other people's code and have other people work on yours. There aren't any group projects in this class, but grading each other's assignments at least exposes us to the way other people code.

Also, it's the only possible way to do it because the class has thousands of students and nowhere near enough instructors to evaluate everyone's assignments, but the principle still applies.
dorchadas: (Gendowned)
I'm pretty sure this is the week that a lot of people flee in terror when they realize that programming is just math with more words. And not only that, the words are things like "random.randrange()" and "print" and "def" and "if/elif/else" and not actual sentences.

Fucking random.randrange().

Let me explain. In Python, there are two main ways to get a random integer (well, there's probably more, but there are two I know of). There's random.randint(), which returns everything from X to Y inclusive, and random.randrange, which returns everything from X to (Y-1). Forgetting that distinction let me to some problems in my program that I had to go back and fix because the program wasn't returning the full range of possible answers.

The assignment this week was to make a program that plays Rock-paper-scissors-lizard-Spock, has the computer make a random guess, and determine the winner. We haven't learned how to implement dynamic input yet, or how to implement a GUI, so it just takes hardcoded player "guesses" and then returns a range of responses, and it's up to us to show that those responses are properly random and the program interprets who wins and who loses correctly. This takes math.

The hard way is to implement a giant if/elif/else statement using Booleans that takes into account every possible combination of throws, which is really long and annoying, and the easy way is to convert the throws into numbers and use math, since it's possible to plot the throws on a wheel--as in the wiki article linked above--and assign them numbers. Subtract, interpret the number to determine winner or loser, and boom. It didn't take all that long, fortunately, but I do need to go back and look into doing modulo operations with negative numbers. 3 mod 5 is 3, because there's 3 left over after the 0 times 3 is divisible by 5 in integer division, but -2 mod 5 is also 3 because ??? Because of floor division and the difference between 2 and 5? Doing other mod operations makes it seem like that's the case, but I don't want to have developed a rule-of-thumb that turns out to be inaccurate later.

That's the thing--the computer only does what you tell it to, so you need to have at least some understanding of the underlying math or you won't be able to tell when the answer seems wrong. In this week's quiz, I had to build programs to calculate inputs into these formulas: ¼ n s2 / tan(π / n) and f(x) = -5x5 + 69x2 - 47 . Those are the kind of cases where knowing what the answer should be, even as a rough ballpark, is really handy.
dorchadas: (For the Horde!)
I typically like to use the kanji for my tags even if there's a kana equivalent, just because I think it looks more elegant, but sometimes I just don't have a choice because the kana version is far, far more common than the kanji one. Computer programming is one such tag.

So yesterday I started that programming class I mentioned a few months ago. Well, it's not actually the same class, since the original one that I wanted to take ended up being removed or vanishing for no obvious reason, but the new one might be a better fit for maintaining my interest. It's all about using Python for programming games. This week is "Week 0" and so I basically don't have to do anything--my assignment is to submit a program that's one line--but at least it's giving me a nice intro into the format of a Coursera class and what exactly to expect.

There's a custom implementation of Python they built to make it easy to submit programs you can play around with here if you want.

Code Monkeyization

2013-May-28, Tuesday 21:48
dorchadas: (Dreams are older)
So, I've been thinking for a couple months that I should really learn to code. I actually originally got into Penn's School of Engineering for Computer Science after taking a programming class focusing on C++ in high school, and with visions of string.h and void main()[1] dancing in my head, I went off to Penn, where they proceeded to focus on OCaml, which I both hated and couldn't wrap my head around--the two concepts may be related, come to think of it. Anyway, I transfered over to the School of Arts and Sciences, got a degree in English, and went into journalism, bailed on that for teaching, and bailed on that for data entry.

Increasingly, though, it seems like programming is just one of those things people should be familiar with the same way computer literacy became a thing everyone had to have over the last two decades. I've written before on Facebook about Peak Employment, and it may or may not happen and may or may not be as bad as the apocalyptic projections, but I think it's undeniable that the trend is toward increasing mechanization, streamlining, and computerization. There's still plenty of space at the moment for people to fill in the cracks where computers are inadequate--hell, that is literally the function of my entire department at the AMA--but that space is going to get smaller and smaller as time goes on.

This is also kind of a problem with my desire to do translation work. Japanese is different enough that anything more complicated than simple phrases has about a 50/50 chance of being total gibberish if run through automated translation, but it does keep getting better and better, and I've seen it get much better even just in the past few years, even if my friends do sometimes have to come to me to translate things because Google Translate isn't cutting it.

On a more practical note, during my interview for my current job, my boss asked me specifically if I had any programming experience, and I said that I did not. I obviously still got the job, but I wonder what would have happened if I had said that I did know how to program? That seems like a pretty good hint that it's something I should look into.

And in a more personal goal, I'd love to make my own roguelike. Much like with RPGs, I prefer a classless, levelless, skill-based system in my roguelikes, and the field is really small. There's Cthangband, and...sCthangband, and...basically nothing else. TOME4 and Dungeon Crawl: Stone Soup kind of have a level/skill hybrid, but it's nothing like the Cthangands.

I do have some resources already (for example), and since my father is a tech executive who used to be a particle physicist[2], I asked him for resources as well. It does add another task on to the pile of things I want to accomplish, both useful--study Japanese, read books and write reviews, finish my novel I'm already 100K words into--and less useful--beat the games in my Steam backlog, read books and write reviews[3], read the various forum threads I have saved in my Pocket account, catch up on my blogroll...

I never used to understand people who asked for more hours in the day, because I didn't have that many long-term goals I wanted to accomplish. Now, I'd gladly take a few extra hours.

[1]: Though checking on the internets, apparently "void main()" was nonstandard usage introduced by Microsoft's compiler and not anything inherent to C++ itself, and is now heresy like unto Monophysitism.
[2]: Or as he will clarify when asked, assistant particle physicist.
[3]: How useful this is is heavily dependent on the book I'm reading. Something like this is probably a waste of time, for example. :p
dorchadas: (For the Horde!)
Lolcode!

Example:
HAI
CAN HAS STDIO?
I HAS A VAR
IM IN YR LOOP
UP VAR!!1
VISIBLE VAR
IZ VAR BIGGER THAN 10? KTHXBYE
IM OUTTA YR LOOP
KTHXBYE

Clearly, this will revolutionize the computing world!

Profile

dorchadas: (Default)
dorchadas

October 2017

M T W T F S S
       1
2 345 67 8
9 101112 1314 15
16 171819202122
23242526272829
3031     

Syndicate

RSS Atom

Expand Cut Tags

No cut tags