Monday 6 April 2015

Looking back...

Right from the beginning at my second post...

Previously I did not concern myself with the special functions too much as I didn't find they did anything too important, just writing them as per convention so they would function as I deemed fit (Sure I could compare objects but I never thought I would use it for, say, testing if an object is in a correct state). However I wrote that they were something neat to learn but after going through the course and the assignments I realize how useful they can really be. I think the most often used one would be the __str__ method which could be used to not only compact our code, but would be extremely useful in producing a relevant output for the user. It could also be used as a tool to assist in debugging as I would be able to see the state of the object and not the mess of the object's id which I would be interested in.


Right after that we started on recursion I wrote that I thought it to be an extremely useful concept to know and obviously that is the case. Looking back at just Assignment 2 we had to create the minimax method while just given the algorithm of how it should be done. If I hadn't taken the time to completely understand recursion I guarantee you that I would have easily spent double the amount of time I spent writing minimax. Each time the function ran I had to know and have a clear image in my mind what it was doing in certain cases and why. As I wrote before, starting with the simplest cases and slowly moving forward and drawing/brainstorming on a piece of paper was indeed the best way to get started and to wrap my mind around the problem.

I learned to experiment with the code in order to see what worked and what didn't. While minimax was a single algorithm, there were many more, some efficient some not so much, ways to write it. I mean even in Assignment 2 we were given starter code which had the Subtract Square game implemented which was part of what we did in Assignment 1. It was a quite different implementation of what our group had done but worked similarly, we wrote it in a certain manner so it would function in a specific way, to interact with the other classes in the way we saw best. Now I'm not saying there is a single best way/solution for every problem, but each has its own benefits as well as drawbacks. All in all it also really does depend on the way you approach the problem too; many different paths to a single destination I suppose.

Wednesday 1 April 2015

Week 10

So week 10 we focused on, basically, assuring that the code we write is performing exactly what we expect and not passing simple tests by sheer luck, that there is no flaw. So in order to do this, we first must identify good test cases until we are confident in our code, testing the boundaries, any special cases, different sizes if applicable, etc. in other words:

In this specific case, we expect the result to be x. Now run the code and see if you get x.

Of course that's just simplifying everything. To test it we can use 'assert' statements which basically allow you to test if x condition is true, the code is correct, else raise an error in a simple line. Not really difficult to understand but just know the syntax is kind of different:
 assert (condition), (error message)

In order to even be able to test anything you have to create all the applicable objects and appropriate circumstances to test a specific case. We can use fixtures which involve being able to easily create/remove the objects required in order to test each case.

Now I had previously interpreted that incorrectly in the sense that we can simply create the objects ourselves at the beginning of the class and make adjustments accordingly inside the test cases. But obviously that would be tedious with a lot of test cases so we instead use help to create separate instances easily each time to prevent the tedium.

 Once our code gets even more complicated, all you can do is really take it step by step and look over each individual line independently and as a whole. Know what it does and how it interacts with everything else. Unintended interactions, bugs will almost always be created and it's never easy to find and fix the minute subtleties in your code!

Tuesday 24 March 2015

Week 8 & 9

 Linked Lists
So we started learning about linked lists to start which are basically another data structure with nodes. What's special about this one is that each node in the linked list has a reference to the next node in a 'list' of nodes and of course its own value. While the linked list itself has a reference to all the nodes starting from the front as well as the node at the very back.

With linked lists you can easily add elements in the middle of the linked list. If you had a linked list with two nodes you could add a third node in the middle of them, say x, and do this by simply setting the first node's reference of the next node to x and x's next node to the original second node. With a similar method you can seamlessly remove elements from the linked list too.

Sadly you can't just go into a linked list and say you want the data contained in the 6th element so you would have to use some sort of loop in order to access through the nodes sequentially until you find the data/x'th element that you wanted to find.

I really do think that these were pretty cool to learn about, creating our own method of storing data from scratch even though it is rather simple. You can customize them however you want and add different functions that are unique to it too.

Binary Search Trees
While we had already previously encountered BSTs we already know how they work. Given a node, n, it has a reference to its 2 children and the one on its left's data is less than n's data and the child on the right's data is greater than n's data, etc...

But we also started thinking about more functions that BST could have as well as the the efficiency in the manner in which we write code. I mean let me use the numbers 1-10 here for the sake of simplicity. You COULD make a BST such that it would look something like:

10
      9
          8
All the way down to 1. And you would have to access each and every value if you wanted to find if 1 was there.

It could also look like
          8
     7
          6
5
     3
And so on but it's much to tedious to try and illustrate that here without a picture or something instead. But here you can already see that if you want to find 6, you just have to look through the 5 and the 7, 2 nodes instead if we had the first example we would go through 10,9,8,7 to find 6. 

It really depends on how you write the code to perform certain actions. While there are undoubtedly a myriad of ways to perform a single action, more often than not one of the ways are the most efficient.

Saturday 28 February 2015

Object Oriented Programming Summary

When we have multiple 'copies' (or instances) of an object, for example an animal, we can use OOP as a way to store each of the data found in each of the objects. We would first create a class which is basically a general 'blueprint' of something whose attributes (or variables) and behavior (which we dictate with methods) are generally defined. Every single instance of this class will contain its own 'version' of this code. For example all animals would have characteristics such as age, height, etc, and have certain general actions such as 'make animal sound' or 'defecate'.

Inheritance
But when we get into more specifics animals, such as a bird, it would undoubtedly still have the characteristics that apply to all animals so there's no need to rewrite the code. In this case we can create a child or subclass of the parent class which would inherit (and be able to use) all the attributes and methods that were made in the parent class. It would extend the parent class. By doing so, we are able to reuse code we have already written which is a key aspect in OOP.
___________________________________________________________________________________
But in this more specific case of the general class, we would have additional variables such as flight speed and methods that are exclusive to this form of animal. We are able to simply add their own behaviors and attributes that are unique to a certain animal. When an instance of a bird is created, it will be BOTH an animal AND a bird and can function/change independently of every other animal or bird too.

Encapsulation
Regarding encapsulation, it is generally used in order to prevent unwanted modification and access to certain parts of our code. In java we would denote variables as private instead of the default public and use accessors and mutators to control how we want our attributes be seen/changed.

But in python there is not true sense of 'private' (Although we can, by convention, use underscores in front of the variable/method name as a representation to others what we don't want them to access). Instead we can use the property() method to control under what conditions we allow a variable to be changed/modified.

Abstraction
Furthermore, in the parent classes we can manage/influence what is required in all of its subclasses. It will create a common interface for all the subclasses that are created so they can all be managed easily. Sometimes it's as simple as denoting a method as abstract or in python we can write the name of a method that we want to be in all subclasses and raise NotImplementedError.

In general Object Oriented Programming allows us to easily create multiple distinct instances of objects that are similar to one another but each contain their own unique characteristics. We could have a single bird or easily initialize multiple instances of birds to create a whole flock of birds with varying ages, feather colours, etc; this allows for easier manipulation of your code and all your objects.

Friday 20 February 2015

Week 5 - Recursion

Recursion is used in order to repeat a similar task a (obviously) finite number of times. More specifically in code, this can be done by having a function to call itself. The thought is to divide up a problem into smaller parts and calculate those individually to finally get the answer as a whole.

For example, let's start with the most basic example of recursion I can think of:

def factorial(number):
    if number == 1:
        return 1
    return number*factorial(number-1)


Nothing complicated here, it was annoying enough to write it in this blog...Maybe next time I'll just put a screenshot of some code in an IDE. That would probably be easier.

The first part would be a base case for when the recursive function will simply return a result without going through any more iterations involving recursion. But before reaching the base case the function would call on itself in order to execute more steps recursively.

I had previously already encountered and learned about recursion so it was not difficult for me to understand it. Different syntax but not much change. I recall when I had first learned about recursion it would definitely help if I would actually write down each step on a piece of paper and go through the results backwards to see how the code works. Now I don't really have to do that with the rather simple examples we learned in class but it still is a good thing to learn. (The exercise/worksheet we did in class was pretty close to what I described but starting with multiple simpler examples instead of going through a more difficult one at the start) All in all recursion is a great concept and tool to learn and even though I know it can be incredibly difficult for some people to grasp at the beginning, at least they can be assured that it will be of great benefit to learn.

Wednesday 18 February 2015

Week 4

I ?think? this and next week has already been marked or something like that but I might as well go back and treat them as practice.

So here we go!

So in CSC148 we started with really the basics of OOP. With classes and basic inheritance which I'll delve into in a later blog. The use of property and the idea of encapsulating the our data to make it 'private'. Then we learned about ADTs as well as started recursion which I have mostly all learned about previously so there were not really any challenges here or new information for me to be learned which might make this post a bit shorter than I would like.

But through learning the implementation and syntax in python (which obviously includes PEP8 regarding the way we format our code/declare new functions and methods, etc...), something new I did learn was for example the __eq__ and the __repr__ functions which were not that hard to understand. It was neat learning about them and the way they are utilized as previously in my experience I hadn't had much of a chance or thought to for example compare 2 objects directly in such a manner

Overall the first few weeks I think were quite a nice review for me of some material as well as learning of new concepts. I do find that some concepts are only briefly mentioned about before moving on such as the small part about encapsulating our data. I honestly would not have remembered learning about it in class if I hadn't written down about 5 lines in my notes regarding it. Anyway here's hoping I'll be able to write my SLOGS on time in the future! (Obviously after catching up.)

Sunday 25 January 2015

Why Geeks should write

Communication is something that we learn to do since the beginning of our lives. We cry, pout and smile to show what we're feeling before we are even able to speak. Similarly we then learn to comprehend and analyze what other people say which once again, is used to communicate, to express their own opinions. Being able to write, and write effectively is essential to anyone's success.

Say for example you write some code to maybe contribute to an open source project. That's an awesome thing to do but what good is it if you don't document your change and explain to others why it was required? What happens if you change code you've already written without telling anyone? The other people that depended on your original functional code would be confused and their frustration will surely rise. However, that could have been changed if you were able to communicate to everyone involved exactly what was modified.

To be honest, I think writing, reading, and communicating, are all intertwined. I remember speaking to my friends about my reading habits and they were talking about how proud they were of NOT reading, how they can count the 7 books they claim to have only read in their lifetimes outside of school. (It was the Harry Potter series and I'm honestly glad that they at least took up some leisurely reading.). I was taken aback by their nonchalance and attitude. How could they be proud of not reading? Illiteracy isn't much worse than literacy if you don't make use of  your skills. Reading happens simultaneously with writing. Writing forces the writer themselves to proofread and understand their own faults in the way they communicate. If you don't read anything how can you know that what you've written is any good at all?...

Writing is a way to express our own ideas and to help others understand. No one can sit down with every single person and explain to them verbally. No, texts, novels, and even written code should be able to convey their meaning themselves. Writing forces you to be confident in your ideas and gives you a feeling of concreteness. While doing this you will realize your own faults and weaknesses. Writing not only helps conveys your ideas but helps you grow.