Saturday 28 February 2015

Summary of Object Oriented Programming Part 2

Since I already made a post on Object Oriented Programming concepts, and since the course syllabus is asking me to write a second, here is a follow up post covering a few more concepts I didn't get to cover the first time around.

Anyways, in my last post, I think I covered "what" object oriented programming is. In this one, I want to cover the "why". And the answer isn't at all obvious. I mean, many of the programs we've written thus far could have simply been written functionally, without a single class definition being written. However, to understand the value of objects will require that we first understand Abstract Data Types.

VI) Abstract Data Types:

Abstract Data Types are simply types of data. A type of data can be anything- such as a sequence of alphabetical characters spelling "I_love_you", or the number 4, or even a combination, like "no_i love_you_5ever". Data can also be something like the blueprints to a computer. Don't think too hard about the "data" part- think about the "abstract" part instead.

A big part of being abstract is to not just be a mere "instantiation" of something, but to be, in a way, connected to many types of things. Think back to our discussions on classes. A class, such as class "int", seems to be abstract, in that it isn't tied to any particular instance of the class (like the integer 4). Now, when I say "abstract" I do not mean "vague". Although both words seem to refer to properties not tied to individual instances of things, they are very different. Something which is abstract is, to some extent, well defined. For instance, a square. A square has 4 sides of equal length. This is true for all squares, and you would likely label the vast majority of things you see with four equal sides a "square". When something is vague, in contrast, it is not well defined. In fact, this is why it appears to be applicable to so many different kinds of problems, or able to be interpreted in so many different ways.

The key feature to object oriented programming, I think, is that it tries to take these sorts of abstract data types, and implement them in an intuitive way. I gives programmers the tools needed to do this herculean task- such as the ability to create classes, and to give special properties to any instances of the class. In this way, it affords programmers a plethora of ways to solve whichever given problem they are trying to tackle. Their theoretical toolbox is expanded to include nearly anything from their imagination.

Abstract Data Type: Tree

In week seven, we started working with a new abstract data type- trees. It was a notable experience- not just because of how useful they are, but because I worked with them in my "intro to syntactic patterns" course last semester. Oh, the nostalgia.

Anyways, if my understanding of trees is correct, they are simply a way of hierarchically storing data. There are relatively few parameters to worry about- it really just boils down to how "high" or "low" in the tree the data is relative to another piece of data. There are nodes- which are the elements in the tree which store the data, and there are branches- the lines which connect them and determine their relative positions. One Node must be the root which, contrary to it's name, is actually at the very top of the tree. In other words, there does not exist a node in the tree such that the root node would be a child or descendant to it (more on the definition of "child" later). Likewise, there are also leaves, which occur at the very bottom of the tree. The hierarchy of the tree is preserved by having a general rule, which is that for any given node (except the root), there must be only one node which is higher on the tree and there is a branch which connects it to that node. This superordinate node is referred to as a "parent", while the node itself is the "child". A node can have as many children as you desire- but each can only have 1 parent. In the end, this translates to a triangular object in which 1 node branches off downwards to a few more, than each of those translate down to a few more each, until you get the the bottom.

An example of a tree data type, pulled right from linguistics (and inspired by my first post), would be a syntactic tree. Syntactic trees are a method to model the way our minds organize the words and concepts behind them into, what we would deem "grammatical" sentences. It's the reason I cant spit just word soup out expect and you follow to it. Long story short, words have broad categories, and they are organized in a particular order in respect to those categories. Here is an image of a syntactic tree:



As you can see, different types of words seem to appear in different positions in the tree, based on certain relevant features. For instance, the phrase "is[cop] a mathematics machine" sits to the right of the node, "the computer". It appears that, whenever a property is predicated onto a subject, the phrase containing that property must occur to the right of it. Their position relative to each other on the sentence node "S" signifies which of the phrases is the subject and which is the predicate (at least, for simple active sentences).

I hope I have demonstrated a strong intuitive grasp of the idea behind tree structures, and their many applications. I'll write about them out later, but for now, I need sleep.


Syntactic Tree borrowed from article: Using nltk_lite’s chunk parser to detect prosodic phrase boundaries in the Aix-MARSEC corpus of spoken English. Although the article is focused on natural language processing and not linguistic theory per se, it still illustrates what a syntactic tree looks like.

Summary of Object Oriented Programming concepts ORIGINAL

I've edited and re-edited my "summary of object oriented programming concepts" blog post so many times, it's practically an entirely new blog post. So, I thought it would be an interesting idea to publish the original version. I hope you enjoy it!
_____________________________________________________________________________

 


I) Objects:

Perhaps the most important concept of object oriented programming is the titular objects themselves. Most python textbooks or websites will define an object as being a representation of a value, with a memory address that points to that value somewhere in the magical world of computer memory. For instance, the number 4 is an object. The memory address to the value of 4 is the same regardless of how we are pointing to that object, and any variable that refers to the object 4 will be considered identical (since they all point to the same value in computer memory, regardless of how that 4 was obtained).

>>> s = 2+2
>>> t = 4
>>> s is t
True

Note that the value to certain objects is not always the same. The mutable types, such as list objects, are a prime example. Even if we assign 2 variables the same value - an empty list- they will not be considered identical:

>>> t = []
>>> s = []
>>> s is t
False

Although its not obvious at first, the reason this happens is because the empty list s refers to is actually a different empty list than the one t refers to. If something is added to one, it will not be added to the other. However, they are still considered equivalent, as:


>>> s == t
True

As much as I love rambling about objects, I need to cover a few other concepts first. These concepts will incorporate and extend the concept of objects.


II) Classes:

A class is usually defined as a blueprint for building an object. Now, remember how we defined objects as values with associated memory addresses? Well, lets expand on that a little. Let us say that we are using a programming language which, somehow, has no classes. In this language, we could type in a sequence of alphabetical characters which just so happen to spell out the phrase "brown_nosing". Now what? Well, we could store it in a variable- but that's not very interesting. We could try to count every character in the sequence, or to return a copy of it in all caps. Perhaps we want to add the phrase "I_am_a" to the front of it. But how do we do those things? And worse off, what if we wanted to do these things to the phrase "you_are_an_amazing_person"? We would have to a lot of retyping, wouldn't we? However, what if we could create an infinite amount of sequences of alphabetical characters, which all have the same sorts of properties? Well, that's what classes are for. With a class like, oh I dunno, strings, we can create individual "string" instances, of which all share the same sorts of properties. For instance, whenever you put two strings together with a ' + ' in between, the two strings will be combined into one. This works with all strings, so now we can add the phrase "I_am_a" to "Brown_noser" or to "fan_of_you", without needlessly retyping things.

So, do be succinct, a class defines what all its members can do. And now to transition to a few more OOP concepts.


III) Properties of Class members

Now, what do I mean when I say that class members have properties? Well, think about how things in the outside world have properties. Consider an elephant. An elephant has things it can DO - such as  blow water out of its nose/snout thing. It also has things that represent what it IS- for instance, it has 4 legs and 1 long nose tubey-thing. Now, suppose we want to create a bunch of virtual elephants in our computer (because hey, Watson wrote a cook book so, why not?). If we make each elephant an object, which is a member of a class, than we need to have some way how the class determines what each elephant instance can do and what properties it has. These are the roles of methods and instance variables, respectively. Methods can be thought of as "instance functions", since they are functions that exist inside of every object which is a member of the class the method was defined in. Instance variables function in the same way, except that, for every property, it can either be a class variable (in which ever member of the class shares the variable with the exact same shared value initially), so they can be initialized- that is, the value of the instance variable is set as soon as an instance is created. How you chose to use both types of instance variables will depend of the type of problem you are trying to solve.


IV) Inheritance of properties

In much the same way that an object is an instance of a class- a class can also be an instance of another class. When this happens, some of the properties of the superordinate class can be shared by the subordinate "children" classes. This is inheritance.


V) Implications of the Instantiations of Classes:

Now, this is the last thing I want to cover. There are very technical terms I could also cover, such as the concept of property and the distinction between extending and overriding, but, in my opinion, they are really just variations of the same abstract concept of instantiation. When you instantiate, you create an object which is an instance of the class. This part should be clear by now. But think about the implications for a moment. This means that often, there is a one way relationship between class and the instance of the class. Although if may be the case that, if the object is an instance of class A, it gains such and such properties- having such and such properties isn't proof that all members of the class have those properties. In fact, often, we want to add to the properties of an object after it has been instantiated. The object does not stay the way it was initialized- in fact the reason it was initialized the way it was was to make modifying it easier.

The same thing applies to subclasses. In fact, you can completely override the properties of a subclass so that it functions completely differently than other subclasses of the original class (or the original class itself). Similarly, you can merely add properties to it- which is extending. In the end, whichever one of these techniques you utilize will depend on the problem at hand. In the workforce (from what I've been told), it is considered bad form to just completely change you code if other programs are working with it. In these cases, you would want to utilize extension, since the prior code would continue to run as intended, while newer code could utilize any of the newly added functionality.

Anyways, I hope that this was a suitable summary of some object oriented programming concepts. I wanted to cover what, in my opinion, was most fundamental to understanding the OOP philosophy, without going over too much. Well, that and I've been typing this for an hour, so now I need to sleep.

Sunday 8 February 2015

Summary of Object Oriented Programming concepts

I couldn't think of a better name. Anyways, here is a nifty little overview of some OOP concepts we've covered thus far in CSC148.


I) Objects:

Perhaps the most important concept of object oriented programming is the titular objects themselves. Most python textbooks or websites will define an object as being a representation of a value, with a memory address that points to that value somewhere in the magical world of computer memory. For instance, the number 4 is an object. The memory address to the value of 4 is the same regardless of how we are pointing to that object, and any variable that refers to the object 4 will be considered identical (since they all point to the same value in computer memory, regardless of how that 4 was obtained).

>>> s = 2+2
>>> t = 4
>>> s is t
True

Note that the value to certain objects is not always the same. The mutable types, such as list objects, are a prime example. Even if we assign 2 variables the same value - an empty list- they will not be considered identical:

>>> t = []
>>> s = []
>>> s is t
False

Although its not obvious at first, the reason this happens is because the empty list s refers to is actually a different empty list than the one t refers to. If something is added to one, it will not be added to the other. However, they are still considered equivalent, as:


>>> s == t
True

In order to better explain the philosophy behind objects, I must a few related concepts first.


II) Classes:

A class is usually defined as a blueprint for building an object. Now, remember how we defined objects as values with associated memory addresses? Well, lets expand on that a little.  Suppose we are using a programming language that has no classes. In this language, we could type in a sequence of alphabetical characters which just so happen to spell out the phrase "brown_nosing". Now what? Well, logically speaking, a human can do many things with it- like count every character in the sequence, or to create a copy of it in all caps. Or perhaps add the phrase "I_am_a_" to the front of it. We could simply create a new sequence of characters every single time- but that would be time consuming, wouldn't it? Plus, to make matters worse, we would have to completely create other, unrelated sequences of characters too, such as "you_are_an_amazing_person". Now, imagine if we could somehow take an already existing sequence of characters, and somehow be manipulated? Or better yet, what if every sequence of characters we create- regardless of which specific characters are used- have the potential to be manipulated in the same way? Well, that's what classes are for. With a class like- I dunno, strings- we can "string" objects- which are instances of the string class. All strings share the same sorts of basic properties, and can be manipulated in the same general way. For instance, whenever you put a "+" between two strings, they will be combined, or "concatenated", into a new one. This works with all instances of string objects, regardless of which specific characters appear in it, so now we can add the phrase "I_am_a" to the front of "Brown_noser" just as easily as we could to the phrase "fan_of_you".

In our hypothetical language without classes, there are no "defining features" to any given "thing" in a program. Every sequence of characters is considered a unique thing. However, we have an intuition in the world that certain things can be grouped together. For instance, when I visit my parents, I have this intuition that the little furry mammalian creature that jumps on me is, in some important sense, the same as the other little furry mammalian things I see in other peoples homes. I know that they can be grouped together in some meaningful sense, and that doing so can have great pragmatic value (such as making sure none of them consume chocolate). In my view, classes try to capture this intuition we have about the world. It allows us to group similar things together in a meaningful way, which can greatly improve the efficiency and organization of our programs.

And now, here's an uncreative transition to a few more OOP concepts.


III) Properties of Class members

Now, what do I mean when I say that all members of a class share properties? Well, try to thing, on an intuitive level, what kinds of properties things in the outside world share. Consider an elephant. An elephant has things it can DO- such as  blow water out of its nose/snout thing. It also has things that represent what it IS- for instance, it has four legs and a long, tube-like, nose things. Now, suppose we want to somehow create a bunch of virtual elephants in our computer (because hey, Watson wrote a cook book, so why not?). Now, if we make each elephant object an instance of some broad "elephant class", than this class could determine some of the attributes and abilities of each elephant instance. These are the roles of methods and instance variables, respectively. Methods can be thought of as "instance functions", since they are functions that exist inside of every object which is a member of the class the method was defined in. Instance variables operate in a similar way, except for variables which store values. Also of note is that these properties can be at either class level (in which every member of the class shares the exact same property initially), or at an instance level (in which the property is set when the instance is created, and usually varies between instances). Which types of properties you use, and on which level you use each of them, will depend of the type of problem you are trying to solve.


IV) Inheritance of properties

In much the same way that an object is an instance of a class- a class can also be an instance of another class. When this happens, some of the properties of the superordinate class can be shared by the subordinate "children" classes. This is inheritance.


V) Implications of the Instantiations of Classes:

Now, this is the last thing I want to cover. There are very technical terms I could also cover, such as the concept of property and the distinction between extending and overriding, but, in my opinion, they are really just variations of the same abstract concept of instantiation. When you instantiate, you create an object which is an instance of the class. This part should be clear by now. But think about the implications for a moment. This means that often, there is a one way causal relationship between a class and the instance of the class. For instance, if all instances of class A initially receive property B, than an object has property B doesn't necessitate that it is a member of class A.

The same thing applies to subclasses. In fact, you can completely override the properties of a subclass so that it functions completely differently than other subclasses of the original class (or the original class itself). So if every subclass of class A inherits property B, we can't even be sure that a given subclass of A will still have B. This is called "overriding" a class. Similarly, you can add new properties to it- which is called "extending" the class. So in this case, if a subclass of A has property C, we can't be sure that the original class A or any other subclasses will also have C. Again, the direction of causality is very limited. In the end, whichever one of these techniques you utilize will depend on the problem at hand. In the workforce (from what I've been told), it's considered bad form to completely chance you code if other programs are working with it. In these cases, you would want to utilize extension, since the prior code would continue to run as intended, while newer code could utilize the newly added functionality.

Anyways, I hope that this was a suitable summary of some object oriented programming concepts. I wanted to cover what, in my opinion, was most fundamental to understanding the OOP philosophy, without going over too much. Well, that and I've been typing this for an hour, so now I need to sleep.


EDIT this is one of the 3 blog posts that is intended to be graded.

Thursday 5 February 2015

Tracing Recursion: Thinking like a computer.

I like recursion. I don't know why it appeals to me- I just do. In fact, I used recursion in order to code the RPN calculator for the second lab. Without giving away too much, I made a method which would evaluate both operands and the operator of a binomial (written in RPN, of course). If the latter operand was itself a binomial, it would call itself to further break down the binomial into two operands and an operator. And than it keeps doing this until the most deeply nested binomial is broken down, and than evaluates all of them in that order. If I get permission from a TA, I'll post the code for it later on.

Anyways, to get back on topic,I find that tracing recursive code isn't all that different from tracing any other code- provided, of course, that you are used to the concept of recursion. All you need to do is constrain your thinking and just mindlessly follow the steps, without thinking about what the code is actually trying to accomplish. After all, this is what python does. It doesn't know what your program is trying to accomplish- even if it has a name like "count_list_depth". All it knows is that it has to follow the steps, no matter where they go. In a strange way, this is exactly how not to begin writing a program. Usually, if a programmer is needed, the problem isn't so simple that a small sequence of instructions can solve it. Usually, a sort of outline of the problem has to be devised, before any sort of solution can be attempted. Long story short- we need to be thinking at a high level of abstraction. Its not enough to know how to solve one or two parts of it- we need a skeleton which can account for everything. Only than can the details pertaining to implimentation be sorted out.


Anyways, I found the recursion tracing exercises to be surprisingly pleasant, and an invaluable source of practice. If I could give anyone advice though, it would be to get used to the syntax of recursive code- especially when it comes to list comprehensions. Worst comes to worst, you learned a new and more compact way to code list objects...

Monday 2 February 2015

CSC148 Term Test 1: To Do List

Last night I had this wonderful idea. The first term test is coming up soon, so why not blog a bit about it? Anyways, for your convenience, I've made a long and messy list of the concepts we'll be covering on this term test. I've also marked the concepts I still need to cover, so I can use it as a study guide during these next few... well... hours...


COURSE NOTES CHAPTER 1:

-Objects (information and behavior)
-ADT
-Implementation vs. Semantics
-Stacks (stores items, remove top, add to top, check if empty)
-expose interface
-interface
-clients
-docstring
-inheritence
-extension
-concretizing ADT
-classes
-operations and attributes of classes
-class instance
-initializing an instance
-Magic methods
-__eq__ (equivalence NOT identity)
-__init__
-equivolence vs identity
-__repr__
-__str__ (is set to __repr__ as default)
-Exception class
-privacy and property
-inheritence
-composition vs non composition
-subclass
-override vs extend
-inheritance (allows to override or extend)
-self
-__add__
-class exception
-raise
-try/except


LECTURE MATERIAL
-object oriented design
-help()
-client code
-interface
-public interface
-public
-magic methods __init__, __str__, __eq__
-overriding
-class object
-__repr__
-property
-eval()
-ADT
-stack ADT
-uses of stacks
-doctest
-parent class
-child class
-canonical use of inheritence
-extend vs override
-list comprehensions
-merge sort
-recursion
-recursive function
-tracing recursion
-measure of problem size (list depth, etc)
-formally thinking recursively

TUTORIAL MATERIALS
-object oriented design
-recipe for designing functions, methods, classes, etc
-tracing recursion
-writing recursive code
-pep8
-reading/writing to files


...Yes, I still need to cover pep8 and the CSC108 design recipe. I know how to use it to design functions, but I'm still not sure exactly how I should design methods, classes, etc, using those core principles. Should I worry about corner cases as much? Should I include anything in the class doc-string other than a core description or what the class represents and what public attributes are contained within it? Should it also list the public behaviors (methods) in the class? And speaking of privacy, I still cant think of any redundant, non-gimmicky ways to use it. At this state, I feel that it just makes our codes unnecessarily fatter and thus harder to read.

Well, that's it for now. Time to study.