CSC148 is now almost over! Only thing left are exams. So far CSC148 has been a great course and I have learned many new programming concepts like recursion, trees, linked lists, and more. Overall I found Danny's teaching to be great and the worksheets in lectures really helped. Though again due to the strike, some of our labs were cancelled and I was unable to fully understand some of the concepts that we learned later on.
Some of the hurdles that I had while taking the course was really trying understand recursion. It took a while until I understood what was going on when a recursive function called and what it exactly does. At first I found the tracing to be quite simple, but that was because we were just working with numbers. Though when we got into trees and implementing recursion into them, that's where I got really lost and confused.
The idea of passing in objects into recursive functions was what confused me the most because objects have properties and it is really difficult to keep track of the object being passed in after a couple recursion calls. I hope that for the final exam, I will have mastered recursion, trees, and linked lists.
What I found to be easy was what we did in the beginning of the semester, which was on OOP and inheritance. I found that those concepts were a lot more straight forward. I even did pretty well on the first midterm.
The assignments were pretty challenging too, especially assignment 2 with the whole minimax strategy. I remember that when I was working on assignment 2, I was really lost because I still had not understood recursion well yet and I thought that assigning us to figure out how to implement the minimax strategy was just too much of a challenge. In assignments 1 and 3, I had a few problems but overall I think I had a better understanding of what to do for those assignments than assignment 2.
Test 2 was also a small challenge but I did okay. I found the questions on Test 2 really challenged my understanding of trees and linked lists and was a fair test. I hope that I can make up for the marks I lost on the final exam as well.
So now that CSC148 is over, I hope to do well in next year's computer science course and learn many more concepts to expand my ability to program. Thanks for reading!
CSC148 SLOG
Monday, 6 April 2015
Tuesday, 31 March 2015
CSC148 Look Back Post #9
Looking back at all my posts so far, I have to agree with everything that I wrote except for the post about Why Geeks Need to Know How to Write. The reason being is that, for course materials, I mainly focused on writing about my understanding of the concept and relaying it in terms that someone who may not understand the concept would start to understand.
However, in my Why Geeks Write post, it was mostly my opinions. Now that I have written many slog posts, I can say that geeks need to know how to write because we need to be able to explain complex concepts to those who may not understand them. Take all my other slog posts for example, if someone who didn't know computer science happened to find my blog and started to read it, there is at least a small chance that they will come out having a general idea on what I'm talking about because I have included easy to understand concepts such as diagrams, code, examples, and explanations on why they work or why we need them.
This can also be brought into coding as well. Code without documentation will be useless to others because they will not know what the code does, and they will not want to touch the code either in fear of breaking it. Documentation is essential to a working program because it allows others to understand how to use the code.
I also took a look at my other classmate's slogs and so far we have talked about the same concepts and experiences from course material to assignments and tests. One slog, keirnslog.blogspot.ca/ actually put his lab solutions in his posts which I thought was really interesting because it allows me to see how he implements his code. It gives me a totally different view on how some functions could be done which is really helpful. Also for his post about why geeks write, is very similar to my reason above. Keirn's main point is that we write to clarify things for others.
That's all for this week, thanks for reading.
However, in my Why Geeks Write post, it was mostly my opinions. Now that I have written many slog posts, I can say that geeks need to know how to write because we need to be able to explain complex concepts to those who may not understand them. Take all my other slog posts for example, if someone who didn't know computer science happened to find my blog and started to read it, there is at least a small chance that they will come out having a general idea on what I'm talking about because I have included easy to understand concepts such as diagrams, code, examples, and explanations on why they work or why we need them.
This can also be brought into coding as well. Code without documentation will be useless to others because they will not know what the code does, and they will not want to touch the code either in fear of breaking it. Documentation is essential to a working program because it allows others to understand how to use the code.
I also took a look at my other classmate's slogs and so far we have talked about the same concepts and experiences from course material to assignments and tests. One slog, keirnslog.blogspot.ca/ actually put his lab solutions in his posts which I thought was really interesting because it allows me to see how he implements his code. It gives me a totally different view on how some functions could be done which is really helpful. Also for his post about why geeks write, is very similar to my reason above. Keirn's main point is that we write to clarify things for others.
That's all for this week, thanks for reading.
CSC148 Post #8
Not much happened this week other than writing test 2. I found that the test was pretty fair in terms of difficulty. It tested us on binary trees and linked lists and the recursive functions that go into these ADTs. The lab was quite short too as it was about the insert and delete functions in a binary tree. Essentially what they do is insert values into the tree and also delete values from a tree.
The thing that I did not understand at first though was that when we delete a value, what happens to that slot? Does it stay empty? So what really happens is that when a value is deleted, the next child node of that value replaces it.
Anyways, since there was no lab this week because of the strike, there hasn't really been much going on in lectures. Unfortunately I have nothing else to write about for this week, but thanks for reading!
Thursday, 12 March 2015
CSC148 Linked Lists Post #7
During week 8, we took a look at another ADT called Linked Lists. A Linked List is sort of a linear set of nodes where each node can only have one child node. An easy way that I thought of to help understand what Linked Lists are is to think of a Tree with only one child node for each node.
Now for Linked Lists I found that this concept was actually easier to understand compared to Binary Trees, and Binary Trees are already pretty easy to understand. I think it's because there is only one branch direction now, instead of a left and a right.
Another thing that I noticed about Linked Lists is that there is barely any recursion involved. In our labs, I used recursion only once in one function, but that was only to bring the arguments up from negative to positive to satisfy our if statements.
So what exactly is a Linked List?
A Linked List has three things, a front, a back, and a size. The front refers to the first node of the Linked List, the back refers to the last node of the list, and the size is the total number of nodes in the Linked List. These nodes, in our Python implementation are called LLNode, where each node has a value and a "child" node called nxt (since "next" is a built-in function). If you look at the representation of a Linked List, you can see it sort of resembles the representation of a Tree.
For example:
LLNode(1, LLNode(2, LLNode(3, LLNode(4))))
In this example, the front of the Linked List would be LLNode(1), the back would be LLNode(4), and the size would be 4. If you take a close look, you can notice that it is sort of like a Tree where each node has a child node, except for LLNode(4), which would essentially be a leaf. The only difference is that Trees can have multiple children coming from the same parent node, where as in Linked Lists, there can only be one.
Taking that into consideration, we can see that Linked List could be used in Trees to help represent them. A path in a Tree could basically be a Linked List because the path is referring to a linear set of nodes. For example,
I coloured each path of this Tree to show how a Linked List representation would work. Since in each path, there is only at most one child node coming from the previous node, We can use Linked Lists to represent each path. For example the red path would be, LLNode(A, LLNode(B, LLNode(D))), and the blue path would be, LLNode(A, LLNode(B, LLNode(F))).
That's all I've got this week about Linked Lists, thanks for reading.
Now for Linked Lists I found that this concept was actually easier to understand compared to Binary Trees, and Binary Trees are already pretty easy to understand. I think it's because there is only one branch direction now, instead of a left and a right.
Another thing that I noticed about Linked Lists is that there is barely any recursion involved. In our labs, I used recursion only once in one function, but that was only to bring the arguments up from negative to positive to satisfy our if statements.
So what exactly is a Linked List?
A Linked List has three things, a front, a back, and a size. The front refers to the first node of the Linked List, the back refers to the last node of the list, and the size is the total number of nodes in the Linked List. These nodes, in our Python implementation are called LLNode, where each node has a value and a "child" node called nxt (since "next" is a built-in function). If you look at the representation of a Linked List, you can see it sort of resembles the representation of a Tree.
For example:
LLNode(1, LLNode(2, LLNode(3, LLNode(4))))
In this example, the front of the Linked List would be LLNode(1), the back would be LLNode(4), and the size would be 4. If you take a close look, you can notice that it is sort of like a Tree where each node has a child node, except for LLNode(4), which would essentially be a leaf. The only difference is that Trees can have multiple children coming from the same parent node, where as in Linked Lists, there can only be one.
Taking that into consideration, we can see that Linked List could be used in Trees to help represent them. A path in a Tree could basically be a Linked List because the path is referring to a linear set of nodes. For example,
I coloured each path of this Tree to show how a Linked List representation would work. Since in each path, there is only at most one child node coming from the previous node, We can use Linked Lists to represent each path. For example the red path would be, LLNode(A, LLNode(B, LLNode(D))), and the blue path would be, LLNode(A, LLNode(B, LLNode(F))).
That's all I've got this week about Linked Lists, thanks for reading.
Thursday, 5 March 2015
CSC148 Binary Trees Post #6
After learning about Trees, we have moved into learning about Binary Trees. Really the only difference is that Binary Trees only have at most two children branching off the parent node. I found that for this topic, it was easier to understand than regular Trees because there were less children involved. I also found that the recursive code for Binary Trees to be a bit easier as well.
In class, we got two worksheets on Binary Trees. The first one talked about taking a look at the Binary Tree and evaluating the content of the Tree by first checking if the left and right nodes are empty and then recursively evaluating the left and right nodes.
The idea is that since we have only two children nodes, it is easy to represent a python expression with it, for example, the parent node could be an operator like "+" or "*", and the children nodes could be values such as 3.0 and 4.0. The recursive function would check if the children nodes are leafs, if not they will evaluate them using the parent node as the operator.
The second worksheet that we got goes into a bit more depth of what we can do with Binary Trees. Lets say that we have a Binary Tree with a ton of children nodes branching off and the root node contains some value. The problem is that we want to find a value that is somewhere in the Tree, but it would be inefficient to check every single node within the Tree.
How could we avoid that? Well Binary Trees have a special property where the values in the left side of the Tree will always be less than the value of the root node, and the right side of the Tree will be greater than the root node. If our root node value is 50, and the value we are looking for is 18, then we can immediately disregard the right side of the Tree and only look at the left side since everything on the right side will be greater than 50. This way we can save a lot of time and effort of having to check every single node in the Tree.
What is so great about this property is that when you implement it into a recursive function, we can continue to disregard the sides of the children nodes to even eliminate more checking required. From the previous example, lets say the value of the next child node from 50 on the left is 30. Since 18 is less than 30, we can disregard everything that is on the right side of 30 and focus on the left side, and we can do this again and again until we reach 18.
So Binary Trees are very friendly when it comes to searching for stuff in them, but I have yet to see a more practical use for them. Though compared to regular Trees, I think the difference is just in running time and which is more efficient. I also think that Binary Trees are rather job specific as well and that they are mainly used for their binary search properties. That is all for this week about Binary Trees, thanks for reading!
In class, we got two worksheets on Binary Trees. The first one talked about taking a look at the Binary Tree and evaluating the content of the Tree by first checking if the left and right nodes are empty and then recursively evaluating the left and right nodes.
The idea is that since we have only two children nodes, it is easy to represent a python expression with it, for example, the parent node could be an operator like "+" or "*", and the children nodes could be values such as 3.0 and 4.0. The recursive function would check if the children nodes are leafs, if not they will evaluate them using the parent node as the operator.
The second worksheet that we got goes into a bit more depth of what we can do with Binary Trees. Lets say that we have a Binary Tree with a ton of children nodes branching off and the root node contains some value. The problem is that we want to find a value that is somewhere in the Tree, but it would be inefficient to check every single node within the Tree.
How could we avoid that? Well Binary Trees have a special property where the values in the left side of the Tree will always be less than the value of the root node, and the right side of the Tree will be greater than the root node. If our root node value is 50, and the value we are looking for is 18, then we can immediately disregard the right side of the Tree and only look at the left side since everything on the right side will be greater than 50. This way we can save a lot of time and effort of having to check every single node in the Tree.
What is so great about this property is that when you implement it into a recursive function, we can continue to disregard the sides of the children nodes to even eliminate more checking required. From the previous example, lets say the value of the next child node from 50 on the left is 30. Since 18 is less than 30, we can disregard everything that is on the right side of 30 and focus on the left side, and we can do this again and again until we reach 18.
So Binary Trees are very friendly when it comes to searching for stuff in them, but I have yet to see a more practical use for them. Though compared to regular Trees, I think the difference is just in running time and which is more efficient. I also think that Binary Trees are rather job specific as well and that they are mainly used for their binary search properties. That is all for this week about Binary Trees, thanks for reading!
Saturday, 28 February 2015
CSC 148 Trees Post #5
In CSC148, we have started learning about Trees which are another ADT. To be quite honest, for me Trees are a bit difficult to understand, especially since a lot of the functions that Trees use have a lot of recursion in it and there is also a lot of terminology that are associated with trees. When we first started talking about them, professor Heap talked about what a Tree contains, such as nodes, children nodes, edges, root, leafs, height, depth, etc. and it is actually quite overwhelming.
Okay so what exactly is a Tree? So from all that terminology, a Tree is a set of nodes with directed edges between nodes. The root note or the parent node starts at the top, and all the other nodes that "branch" out from the root note are called children. The nodes that have children are called inner nodes while nodes that have no children are called leafs. Take a look at this example,
A is the root note with directed edges towards children nodes B and C. Node B which is an inner node also has children nodes D, E, and F. Nodes C, D, E, and F are all leafs because they have no children. The height and depth of node A is 3 and 0, while the height and depth at node F is 0 and 3.
What can we do with Trees? Well in Assignment 2, we are kind of using Trees to build all the possible moves for our games. I say "kind of" because we will see it as a Tree but its really going to be a bunch of lists. The reason we are using Trees is for the minimax strategy which takes a look at all the possible moves and chooses the best moves in order to win. Our job is to create that Tree and put together all the successive moves one after another and check which move would make the player win.
How are Trees implemented? So far we have covered over how to look into Trees, and basically we have implemented functions to check whether or not values are contained in Trees and whether or how many leaves there are. For A2, we will want to implement functions that will build a Tree where nodes branch off to all the next possible moves.
A friend of mine, in one of his slog posts, he posted a pretty funny picture of a Christmas tree in the shape of a Tree. In his post he also covers a little of what I talked about here as well. Go check it out here: http://timothylock.ca/sLOG/CSC148/?p=80
As I said earlier, I am not too comfortable with Trees and just thinking about how I will create a Tree that contains all the possible moves is just quite overwhelming. I guess I'll just need to practice more. Though thanks for reading!
What can we do with Trees? Well in Assignment 2, we are kind of using Trees to build all the possible moves for our games. I say "kind of" because we will see it as a Tree but its really going to be a bunch of lists. The reason we are using Trees is for the minimax strategy which takes a look at all the possible moves and chooses the best moves in order to win. Our job is to create that Tree and put together all the successive moves one after another and check which move would make the player win.
How are Trees implemented? So far we have covered over how to look into Trees, and basically we have implemented functions to check whether or not values are contained in Trees and whether or how many leaves there are. For A2, we will want to implement functions that will build a Tree where nodes branch off to all the next possible moves.
A friend of mine, in one of his slog posts, he posted a pretty funny picture of a Christmas tree in the shape of a Tree. In his post he also covers a little of what I talked about here as well. Go check it out here: http://timothylock.ca/sLOG/CSC148/?p=80
As I said earlier, I am not too comfortable with Trees and just thinking about how I will create a Tree that contains all the possible moves is just quite overwhelming. I guess I'll just need to practice more. Though thanks for reading!
Monday, 16 February 2015
CSC148 OOP Post #4
Reading week is here! Which means we are already half way through CSC148, I guess time flies by when you're busy programming! CSC148 has been great so far and I hope that it will be even better after the break. Throughout the first half of the course, we mainly focused on Object Oriented Programming or OOP for short. So in this slog post, I'm going to spend some time talking about OOP, why we need it, and where we use it.
In my second slog post, I did talk a little about OOP and the concepts that we looked at so far including creating classes and objects, special methods, and inheritance. In general, in OOP, the idea is to create objects of a particular class. When we instantiate an object, the object can come with properties and methods that belong to that object.
In Python, this is what we call the __init__ method, which assigns the properties to that object. We then have special methods such as __str__ which when called gives a string representation of the object, __eq__ which compares two objects together, and __repr__ which gives a string that can be put into the shell to create to create another object with the same properties. Objects also have normal methods where they just basically normal function calls.
Now inheritance is the concept of extending a class. In my second blog post I said that inheritance is not 100% needed to make your program work, but it helps reduce code, which is what the purpose of inheritance is. There are times where in a parent class, code may or may not be useful in some cases, but it may be very useful in other classes. So instead of rewriting the functions into a different class, we can extend the parent class onto the sub-class. The sub-class will "inherit" all the functions and properties of the parent class, thus reducing the amount of code in your program.
Okay, so why is this all important? Why do we need OOP? Well like inheritance, we want to eliminate any duplicate code, and sometimes, code can be changed. Professor Heap told us that code is always being fixed or added to create new features. However, if we drastically change our code on our end, it could spell problems on the client end. Essentially OOP is needed to easily change code.
If you copy and paste code all over the program, then when something needs to be fixed, all the duplicate code has to be fixed as well. If you accidentally miss something, let's just say good luck finding the bug. But with functions, you can change it once, and call it throughout the program. This is why we write methods and classes, which eliminates the need to duplicate code. And by reducing the amount of code in our function, we can also have a faster run time, but I'm going to leave that topic for another day.
Speaking of duplicate code, recursion does a great job in handling these sort of things. Since the idea of recursion is for a function to call itself, it eliminates the need to manually write out code for each case. I guess in a sense, recursion is sort of like a loop.
I came across another slog where they talked about how to come up with the design for classes from the description that they give you and they also talked about inheritance with a good easy example. You can check out his slog here.
So that is my summary of OOP, why we need it, and where its used in our programs. Thanks for reading!
In my second slog post, I did talk a little about OOP and the concepts that we looked at so far including creating classes and objects, special methods, and inheritance. In general, in OOP, the idea is to create objects of a particular class. When we instantiate an object, the object can come with properties and methods that belong to that object.
In Python, this is what we call the __init__ method, which assigns the properties to that object. We then have special methods such as __str__ which when called gives a string representation of the object, __eq__ which compares two objects together, and __repr__ which gives a string that can be put into the shell to create to create another object with the same properties. Objects also have normal methods where they just basically normal function calls.
Now inheritance is the concept of extending a class. In my second blog post I said that inheritance is not 100% needed to make your program work, but it helps reduce code, which is what the purpose of inheritance is. There are times where in a parent class, code may or may not be useful in some cases, but it may be very useful in other classes. So instead of rewriting the functions into a different class, we can extend the parent class onto the sub-class. The sub-class will "inherit" all the functions and properties of the parent class, thus reducing the amount of code in your program.
Okay, so why is this all important? Why do we need OOP? Well like inheritance, we want to eliminate any duplicate code, and sometimes, code can be changed. Professor Heap told us that code is always being fixed or added to create new features. However, if we drastically change our code on our end, it could spell problems on the client end. Essentially OOP is needed to easily change code.
If you copy and paste code all over the program, then when something needs to be fixed, all the duplicate code has to be fixed as well. If you accidentally miss something, let's just say good luck finding the bug. But with functions, you can change it once, and call it throughout the program. This is why we write methods and classes, which eliminates the need to duplicate code. And by reducing the amount of code in our function, we can also have a faster run time, but I'm going to leave that topic for another day.
Speaking of duplicate code, recursion does a great job in handling these sort of things. Since the idea of recursion is for a function to call itself, it eliminates the need to manually write out code for each case. I guess in a sense, recursion is sort of like a loop.
I came across another slog where they talked about how to come up with the design for classes from the description that they give you and they also talked about inheritance with a good easy example. You can check out his slog here.
So that is my summary of OOP, why we need it, and where its used in our programs. Thanks for reading!
Subscribe to:
Posts (Atom)

