Monday, August 29, 2011

Back to it, I hope

Wedding and honeymoon are accomplished so now it's time to get back to my regularly scheduled hobbies.

It's been a while so I need to get back to C as my primary goal. What I'd like to do is figure out what I'm strong at (loop structures, pointers/variables) and focus on what I'm weak at (recursion, memory management) and inexperienced at (advanced data structures, higher math computations, string handling). I think the best thing for me to do is return my focus to Project Euler problems and throw in some GTK when it fits like I did for problem 7.

I did a pretty good job of documenting my Python progress (here and elsewhere) so I'm not worried about stepping away from it for a bit.

I'm on Problem 9 now and I'd like to get through Problem 15 before the end of September. I think that's a reasonable goal.

Thursday, August 11, 2011

A break

I'll likely not be able to do any programming until after the wedding/honeymoon business is over. After that is the "busy season" at work, so we'll see. I need to get back to my C exploration and leave Python to studies of OOP and work-related stuff.

Monday, August 8, 2011

OOf

My mind keeps dwelling on this.

I started the project in earnest this evening, documentation and all. I'm hoping that once I show the functional application at the office I'll be allowed to spend work time on it so that I don't have to eat into my limited free time at home anymore. It's been a fun exercise but I need to get back to C and it is starting to feel more like work than play!

Another way

I always labor over some program and then think of a better way to do it soon after I finish.

The way I should have done it is to have a base class for loading the file. Subsequent classes that inherit that base class should be for paring down the data in the file for specific tasks.

So the closedcases class needs to only contain the data for the closed cases and any functions I'd want to run on that data. I need a way to mimic an array of structures so badly! I want to strip down the caselist to an array of paired start and end dates. I'd say that qualifies as an list of tuples, but I'm totally guessing because I'm still not strong on the Python data types.

The other looming issue is that column format is still in flux. I just made a change to the real case list that breaks compatibility and I'll have to add that to my test file and modify the program accordingly. It would be really awesome to have some kind of config file that pre-defined the column header names and matched them to an index (number).

I learned enough doing this to warrant a quick rewrite attempt. The code is in a "it will do the job but it ain't pretty" state but I'd like to future proof myself ASAP to prevent more intricate rewrites once the project gets fleshed out.

EDIT: I'd also like to restructure it to be called as a library from another program. Running the case reader program would simply initialize a test/sanity check program. There is a neat way to do this by having code in there that detects when it's run as a standalone program and runs things based on that condition. Like this:

if __name__ == "__main__":
stuff()

Saturday, August 6, 2011

slight modification?

I think the date subtraction function should be in the closeddates class.

One time I read a description of proper object/class use that went something like this: An object should contain data and all of the function necessary to manipulate that data.

That might be a oversimplification but it kind of rings true with Python. All lists are an instance of a class, and the .append() method is a part of that class. I'm not calling append() which then initializes the class and makes the manipulation. So, the act of manipulating the closed case data should be inside the class.

Then I can just say:

c = closedcases(filename).subtract_dates()

right?

Friday, August 5, 2011

The most frustrating program I've ever written



I think it's hard for anyone to take data in one format and get it into another to perform calculations. It's double hard when the language fights you a bit. I did everything I could to keep things "Pythony" but I'm still drastically unfamiliar with the language. I have a horrible suspicion that someone familiar with the language could do this in three lines of code.

Basically what the program does is this:
1) Read in a .csv file such that every row has its columns separated as individual elements in an array (Python list). Basically it makes a 2d array. List. Whatever

2) Remove the first row because it's the column names

3) Go through every row and copy over the ones that have something in the open date and close date columns. This makes a new list.

4) Take the new list and extract for each row the first and second column

5) Convert these extracted elements into a 3 element list

6) convert THAT list into a list of integers

7) convert that list of integers into a date and use it to calculate days between the close date and the open date

8) emit heavy sobs when it takes all damn evening to write, rewrite, write special simplified functions, rewrite again, insert a ton of print statements to get a handle on what's actually happening, finally figure out how to manipulate lists like you want, and then clean up any misc bugs and finally at your last nerve see it work.

I'm frustrated that I still don't know when to use classes vs a bunch of functions.

I'm frustrated that scope is horrifyingly ambiguous.

I'm frustrated that in a week I won't be able to read this code and make sense of it.

I'm happy that I tackled the hardest but most meaningful part of the analysis I want to do.

I can't balk at the fact it only took me a week to get well versed enough to first get through enough of LPTHW to comprehend the language and knock out the program. I started working on it this morning. I think I spent 3.5 hours on this total? Not bad, but it was an infuriating 3.5 hours. That time isn't counting when I walked away in frustration.

missing the point?

The thing is I feel like this an unnecessary use of objects. The whole caselist class could just be replaced by a function. The bulk of it IS a function!

Why encapsulate inside a class? What benefit does this provide?

The answers to those questions are one of the reasons I plowed into Python. I want to get the answer before I get mired in the minutiae of C++ or Obj-C.

a note on scope

Found something interesting here: http://docs.python.org/tutorial/classes.html

If a name is declared global, then all references and assignments go directly to the middle scope containing the module’s global names. Otherwise, all variables found outside of the innermost scope are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

That certainly explains what I saw a few days ago.

It's a start



This gets me to the bare minimum of getting the .csv file into a form I can work with. I'm not certain that this is the "pythony" way of doing things, but I know what to do with an array.

Thursday, August 4, 2011

Just to really beat it in...

Ok, here are some simple examples to drive the point home.

First is a script that has a variable assigned and a function called can see this variable.



The output of this script is:

Here is a variable I can see: 42
Here is an outside variable as seen from a function: 42

Ok, this makes sense. All well and good.

Here is a script that has a variable assigned, and a function called can see it BUT when it tries to modify it I get an error.



The output:

Here is a variable I can see: 42
Traceback (most recent call last):
File "scopetest2.py", line 10, in
afunction()
File "scopetest2.py", line 4, in afunction
print "Here is an outside variable as seen from a function: %d" % im_outside
UnboundLocalError: local variable 'im_outside' referenced before assignment

If, however, I simply first inside the function state "global im_outside" it becomes allowed to modify the variable.

Alright, let us see a C example:



Output is:

Here is a variable I can see: 42
Here is an outside variable as seen from a function 42

And altering the function to modify the variable:



And I get the result I wanted:

Here is a variable I can see: 42
Here is an outside variable as seen from a function 42
But now I'm going to modify it
And here it is: 27

I am certain I understand how scope works in C. It's pretty straightforward and a lot of the difficulty with understanding passing values/references to functions is a consequence of that simple straightforwardness. I think what this means is that I don't understand scope in Python. I just think if a function can "see" a variable it should also be able to modify that variable. Look, I get it that maybe having the "global" description happen elsewhere is a good idea because then you can let SOME functions modify the var but not others, but man is it not intuitive.

scumbag python

Ok wow.

So, you have to say:

global wumpus_room

BUT you can't declare it as global AND assign it at the same time.

Oh, and the kicker? You're after-the-fact declaring at as a global variable INSIDE the function you want to modify it in!

So:




I guess by "declaring" inside the function that it needs to be on the lookout for a outside-declared instance of wumpus_room that this makes it ok to alter. This does NOT AT ALL explain why I can see the initial value of the variable as defined outside of the function.

Is "global" only necessary to MODIFY a variable outside of the scope... but not read the value? Doesn't that make the concept of "scope" twisted?

EDIT: Here's the site I got from my google searching on the subject http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/

Python woes



Woof, I don't understand variable scope in Python.

I have what I thought was a global variable called "wumpus_room" that is a random whole number between (and including) 0 to 3. The script is borking at the fact that I have a line that could alter this variable inside of a function. If I comment out the block starting with

elif choice.lower() == "shoot north":

then there is no complaint.

This would not be confusing if it was crabbing about trying to alter a variable out of scope, but it gives a cryptic error:

UnboundLocalError: local variable 'wumpus_room' referenced before assignment

See.... I'd BELIEVE that if not for the fact I can comment out that reassignment line and everything works fine - this tells me the variable is indeed getting assigned!

How the heck do I declare a global variable and then edit that variable if necessary?!

Wednesday, August 3, 2011

LPTHW Exercise 35 and 36

LPTHW exercise 35 brought home a lot of function and control structure concepts with an example of a small text adventure game.

http://learnpythonthehardway.org/book/ex35.html

Exercise 36 asks that you take what you learned and make one of your own. I'm doing basically a five room "hunt the wumpus" game. The structure is basically every room has its own function, and each room asks which way you want to go or where you want to fire your arrow which then either calls the respective room's function, or the fire arrow function. It's not a "proper" way of organizing data for a game but it's just to drive home functions and control structures.

This really brings me back to middle school doing some QBasic programming along the same lines. I have a really strong grasp of control structures because of all the nested if-loops and while-loops of the text adventure games my friends and I used to make together. It sucks that ASCII graphics is now really hard to do since terminal interactivity is now considered an anachronism (among most folks, anyways).

The Python documentation makes no sense to me

Here's how a Python class function (method?) prototype is presented:

class datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])

I read this as tzinfo is an argument of microsecond which is an argument of second which is an argument of minute which is an argument of hour which is an argument of day. But this isn't the case. It's just a list of arguments that can be passed separated by a comma. So... why the brackets?!

Furthermore in THIS class function the non-bracketed variables are stated as required, and the bracketed ones are optional. So I say to myself "Ah, that's how they define optional and non-optional arguments. However, here:

class datetime.time(hour[, minute[, second[, microsecond[, tzinfo]]]])

the documentation says that all arguments are optional, which blows away that theory of operation.

So yea, the biggest hindrance to getting to the next level in Python is that I can't read the documentation.

labels

Huh, I guess I can tag my posts now. That's cool.

Tuesday, August 2, 2011

even more progress

I'm on exercise 27 now in LPTHW. I think I've spent a total of four or five hours on it. It really helps already being familiar with C since I don't have any issues comprehending the "advanced" stuff so far (functions, return values, taking arguments, importing functions from other files). I'm still weak on some of the formatting like %d and %s and %r in the print statements, but basically it's numbers, strings, and a different way of formatting string statements.

a little progress

I got through the first five exercises in LPTHW, which isn't saying much since it's just typing out the examples (no copy/paste is the rule in this book) and it only took about 45 minutes (including setting up the environment). So far It's all just printing and some light variable usage.

Here's where I stopped: http://learnpythonthehardway.org/book/ex5.html