Thursday, 3 April 2014

Brian's CSC148 SLOG # 12 Conclusions

Hello! The train is slowly coming to a halt at the final stop of CSC148. 

It has been an incredible experience that opened my eyes, captivated me entirely and bestowed every ounce of knowledge possible each week. It is hard to believe that we have learned so much in such a short time frame and there was no topic that I wasn't excited about or interested in. Recursion, comprehensions, binary trees, binary search trees, abstract data types, object-oriented programming, algorithm time complexity, regular expressions, linked lists, program design; it's ALL incredible!

I am actually not in the Faculty of Arts and Science. I am from the Architecture Faculty and it's very unfortunate that students from the architecture faculty cannot take computer science for their double major. Only the minor is possible so hopefully I will meet the cut-off mark for it but if not, I have serious intentions of pursuing computer science further and may request an internal transfer to enroll into the specialist or major program. If I don't get enrolled, I still intend to take higher-up CSC courses as an elective and learn all that I can. Even then, architecture is actually a very flexible field to go into and as far as video game design goes, level design would benefit from an architect designers' perspectives. This is an example of how different fields of studies intersect and work together to create new designs.

I really appreciate those who read my courSe LOG, so thank you! 
I hope you were able to enjoy it or learn something from my more technical entries.

It has been a blast, best wishes to everyone.
Adios.



Thursday, 27 March 2014

Brian's CSC148 SLOG # 11 Sorting Algorithms and Efficiency

Hello!

This week's SLOG topic is all about sorting algorithms and efficiency.

As mentioned briefly in last week's SLOG, there are a couple sorting algorithms that we have been taught so far.

Here is the list again for reference:

Insertion Sort
Selection Sort
Quick Sort
Merge Sort
Built-In Python Sort
and the most interesting to me: Customized sorting algorithms

Each of these use different methods to sort order-able objects in a mutable collection such as lists and each have their own advantages in the different ways they sort a collection. Their respective run-times can be deduced by observing the code and identifying the worst case for a big-O run-time complexity. Bubblesort, although commonly seen as an inefficient sorting algorithm with an O(n^2) time complexity, has an advantage over other where we can immediately tell that part of the list is sorted if no exchanges are made after each pass. Merge Sort uses a divide and conquer method which recursively sorts separate parts of a list and has a very efficient time complexity of O(nlog(n)). An interesting thing to note is that these run times in Python are not optimized as opposed to other programming languages like C. Built-in Python Sort (or Timsort) uses language closer to machine code which means it is highly optimized. Timsort usually beats most sorting algorithms in terms of efficiency but some customized sorting algorithms can actually sort faster than Timsort depending on various factors such as number of elements in the list.

Efficiency and optimization of code is such an interesting topic to me because my goal is to become a video game developer. Program efficiency is incredibly important for game developers because people generally want their video game to run smoothly without putting too much strain on our CPU's (Central Processing Unit) or RAM (Random Access Memory). If we did not have optimized games, there would be no way to play them unless everyone was using top tier computers built specifically for gaming. Luckily, because optimization does exist, games are playable on lower end computers and everyone is happy! Asides from program efficiency, there is also graphics optimization which is not part of CSC148 but I hope I will have the opportunity to learn more about that as well.

Wednesday, 19 March 2014

Brian's CSC148 SLOG # 10

Hello! Welcome to my 10th SLOG post!

Has everyone been having a good week?

The winter term is slowly coming to an end and the assignments are ramping up in difficulty as we approach the end of the term. This week's lecture was crammed with new course concepts and also, Assignment 2 Part 2 is due tomorrow. Both the lecture and assignment 2 has taught me very interesting concepts and helped me think in a new way for solving new problems.

This week's SLOG focus will be on:
  • Assignment 2 Part 2
  • Sorting Algorithms
  • and my current situation in 148

Assignment 2 Part 2

Although I cant reveal too much as it isn't due yet, I will discuss my experience with Part 2. The assignment overall was not too difficult with one exception: regex_match. I began assignment 2 on Thursday night and finished 3 of the functions: is_regex, all_regex_permutations and build_regex_tree by Saturday night. These functions were not too hard because we didn't have to worry too much about how each of StarTree, DotTree, BarTree and Leaf would affect each other.

The way I handled is_regex, was to find valid regexes within the string and recursively call is_regex while simplifying the string until it eventually returned True. If my function found a single false regex during it's recursive calls, it would immediately return False.

For all_regex_permutations, we were basically given the answer as we had permission to use a code provided on the 148 website that would return all the permutations of a string! 

and for build_regex_tree, the idea is similar to is_regex in using recursion to simplify each call further and further until we reach the final answer and return a RegexTree object.

So what made regex_match so difficult?

We had to worry about how each subclass of RegexTree would interact with each other and this was incredibly difficult for me because I couldn't figure out how to get StarTree objects to properly interact with other the other sub-classes. After two days, I had finally finished some code that returned the correct bool for most cases. However, some complex cases were returning the incorrect bool and there was even infinite recursion in another case. Unable to solve my function for all test cases, I went to office hours and recieved some hints from Danny in approaching StarTree cases and Dustin helped me figure out the why my function was infinitely recursing. At last, I put the two helpful hints together and finished my function on the third day! Well, okay.. maybe three and a half days!

This is one of those moments where once you find out what the answer is, the next time you come across it, it will only take a minute to solve. I believe this is somewhat like the beginnings of thinking like a computer scientist! Spending lots of time at office hours, coding, tracing your program with pencil and paper until you get closer and closer to the answer. I don't feel good about having needed 3.5 days to solve a single function whereas a few of my classmates managed to solve it in a day. Nonetheless, I am happy it is finished and confident as it seems to work for very complex cases!

Sorting Algorithms

Sorting algorithms are incredibly interesting as they can greatly impact the performance of a program depending on the number of items we are sorting. Generally, we have touched on a couple sorting algorithms which are: 

Insertion Sort
Selection Sort
Quick Sort
Merge Sort
Built-In Python Sort
and Customized sorting algorithms

By randomizing the items in a list, we were able to see how long it took each different sorting algorithm to sort for lists with a very small amount of items (10 items) and lists with a VERY VERY VERY large amount of items! (160,000 items!). This comparison is priceless because we are able to figure out how much longer it takes a sorting algorithm to run depending on the size of the list. I believe the most interesting thing in understanding this is that we can deduce which sorting algorithms are better for our programs depending on the number of items that our program will be dealing with.

CSC148 so far..

Lately I've been feeling more confident in using recursion as it showed in my ability to solve the functions in Assignment 2 Part 2. I also used some comprehensions in the assignment which I mentioned I was struggling with a few weeks ago. So I am definitely feeling more confident as I think I reached a higher level of understanding in CSC148. However, the remaining weeks will definitely be more of a challenge as we will need to analyze algorithm running times which I have very little experience with. Hopefully this won't be a tough concept for me to grasp but I will definitely be vocal with my friends in 148 and discuss algorithm running times to get a better handle on it. Being vocal and discussing problems with friends and professors have helped me learn so much more than I would have had I not said anything!

With that said, I think I have covered everything I wanted to this week's post.

Thanks for checking out my 10th SLOG installment and check back soon as next week's topic will be in-depth about sorting algorithms and efficiency!

See you soon! 

Wednesday, 12 March 2014

Brian's CSC148 SLOG # 9

Hello and welcome to my 9th SLOG post!

I hope you all are doing well, this week has been havoc for me! I caught the flu, there was a snowstorm out this morning so imagine having a headache, sore throat, cough and runny nose while traversing through a flurry of snow blowing into your face. Nevertheless, I am still alive after gruesomely long commutes to and from school :P.

This week's topic will be about Assignment 2 Part 1 and a little rare surprise I had in my 8th CSC148 LAB.

Assignment 2 Part 1

Part 1 of Assignment 2 was a really unique opportunity for us students to design a RegexTree and represent it the way we wanted to. At first I thought there had to be only 1 absolute way to approach the task but we were actually given nearly boundless freedom to create the program. The only restriction that I am aware of is that we had to use inheritance and have a class hierarchy for our classes. Thus we couldn't create 1 single class to handle all the nodes.

So what knowledge was gained from completing this assignment?

Here is what I think:
  • Class hierarchy
  • Inheritance:
  • Reduction of duplicate code
  • An introduction to regular expressions used in various programming languages and utilities.

All of the above points work in tandem. Class hierarchy meant using inheritance and when calling functions from the classes, namespace would determine which function takes precedence over duplicate function names. For example: If I have a __repr__ method in my super class that calls on the __repr__ method of my Node classes, the __repr__ method of the Node classes will take precedence over the super class's __repr__ method even if we call it using the a RegexTree object.

Secondly, we can also easily reduce code by using inheritance and class heirarchy. I have actually completed two different designs of Assignment 2 Part 1 and have reviewed them with Professors Danny and Dustin. In one of my designs, I created an individual __repr__ method for every class which repeated code but on the other hand, showed how class hierarchy works. In the second design, I created a __repr__ class in the superclass RegexTree which would properly present a representation of all the different types of Regexes and since I have only 1 __repr__ method, there is less repetition of code in the program.

Another way to reduce code is in the __eq__ method. By writing a single __eq__ method in the superclass, we have reduced redundant code by rewriting one for every class. This method in particular could have been approached two ways. The first method is to simply compare the __repr__() methods of two different RegexTrees which meant that they had to have the exact same string to resolve to True.
The second method, which I think we could learn more from uses recursion. By simply checking if the symbol and children of a regex expression was equivalent, we could easily recurse over the children until both regular expressions had no children left and finally, return our desired bool.

Overall, Assignment 2 Part 1 was definitely a fun assignment to tackle given the freedom to design!

Lab 8

In this week's lab I had a rare opportunity to partner up with another friend of mine. He is a really crafty guy when it comes to programming and has knowledge of Java and uses comprehensions with ease.

His SLOG is here for those who are interested:
www.yanqilee.blogspot.ca

What made this an interesting experience is because we managed to solve the very last lab question in an interesting way. Apparently we were hinted to use the Stack class to solve BST's count_less method without using recursion. We struggled in trying to solve it using Stack but couldn't find an answer.
HOWEVER! We found a backdoor trick to solving it without using the Stack class at all!

The answer? BST's __str__ method. 

Our task was to count all the integers in a binary search tree lower than a given number for count_less method so we utilized __str__ instead. BST's __str__ method returned a representation of all the integers in a string that looked like a binary search tree. We simply split the string and removed all the newline characters. Afterwards, we looped over the integers and if it was lower than the number argument for count_less, we simply added one to count and returned count after the loop iteration.

Even the TA had a good laugh at how we accomplished the task!

That's all for this week so please check back soon for another SLOG installment!

All the best,
Brian

Wednesday, 5 March 2014

Brian's CSC148 SLOG # 8

Hello! How is everyone doing?
Welcome to my eight SLOG post.

This week has been quite alright! Term papers have been given back and I achieved 77.5% (B+) which is wonderful. I was expecting a grade in the B range but on the next test and the final exam I will be working harder to achieve even higher!

What's new in this SLOG post? 

This time I will be discussing:
  • A little bit of assignment 2 
  • Challenging concepts I am facing in CSC148
Without further ado, let's begin!

Assignment 2

Assignment 2 is all about creating Regexes and parsing Regexes and matching them with strings. As of now, we are only responsible for part 1: creating Regexes and part 2: parsing Regexes while matching them with strings will come later.

So what are Regexes? Regex is an abbreviation of regular expression which is used in different programming languages and other utilities to match entire classes of strings. For this assignment we will only be dealing with  regexes over the ternary alphabet {0, 1, 2} which is a non-empty string that consists of the symbols '0', '1', '2', 'e', '|', '.', '*', ')' and '('.

I managed to get insight for A2 by first creating a master class and subclasses that will later handle the creation of a regex such as ('2'|'3'). What information about regexes can we use to start coding our classes? By looking closely, we can tell that it has similar properties to a how trees are constructed. The nodes '0', '1', '2' and 'e' are the leaves and have no children and by knowing this, we can consider the bar '|' as the parent node. Comparing to a tree example such as: Tree(1, Tree(2), Tree(3)), we know 1 is the parent node, or root and 2 and 3 are the leaves that have no children. A regex can be represented similarly like so: Regex('|', [Regex(1), Regex(2)]).

With the insight that regexes can be expressed similarly like trees can in programming, I have managed to finish part 1 of assignment 2 which I will discuss in more detail next week. The deadline has been extended this week so I don't think I am able to share my full solutions just yet but look forward to my next post as I will explain be explaining it with great detail!

Challenges

University has been challenging for computer science courses. Very often I have had to take lots of time to consider how to approach new concepts and sometimes I feel that I am in the midst of somewhat understanding the new concepts but not yet fully. Comprehensions and recursion are the challenges for me right now. Comprehensions are very difficult for me because they are written quite differently from how I'm used to coding. Recursion is somewhat difficult for me. For easy problems I have no problem using recursion to solve them but for more complex ones, I struggle for long periods of time. The tough problems for me are usually a mix of comprehension and recursion in a single function. Asides from this, I can handle recursive functions at a good level. The only question is, whether or not I can understand comprehensions + recursion together before the end of the semester. I certainly hope so!

Thanks for reading my eight SLOG post! 
Have a wonderful week.

Wednesday, 26 February 2014

Brian's CSC148 SLOG # 7

Hey, how's it going!?

So this week, I had completed 148's FIRST TEST and I'm feeling quite good.

Sadly, after the test, I realized I made two small mistakes on two questions but I don't think I can provide precise details here but I can say that I have already looked into them and have learned from my errors :]. It's one of those computer science moments where you have a trick question and you know the answer is either Zero, None or Error.
My reasoning led me to the wrong answer (Doh!) but it was a good attempt and at least I was right about it being one of the three!

So what'll this week's SLOG be about? 

Hm... since I have been talking a lot about course material lately and I recently talked in-depth about OOP and recursion, I figured this week would be a good chance to talk about non-material course related things. Let's get started!

Piazza

At the start of 148, I didn't think much of Piazza and thought I could learn the course materials without relying on it. I was totally mistaken and my perspective of Piazza flipped right around at the beginning of exercise # 1.
It's an incredible experience when classmates, professors and TA's take time to discuss course concepts with you and try to hint you in the right direction if you're ever stuck on a submission. By discussing course concepts, or hinting someone who is stuck, everyone who is involved refines their knowledge of the computer science topic and even when we're mistaken, I noticed that the instructors will usually step in and correct our assumptions.
Without Piazza, I honestly think that most students in the program would have a lesser level of knowledge than they do now. That being said, I also hope that Piazza is included in future CSC courses.

Office Hours and Help Center

These two places are the place to be. Sometimes it's difficult to discuss a complicated code on Piazza so if further help is required, I would personally recommend one of the two. During assignment 1, I could not debug my code for TOAHModel.py. In fact, everything looked perfect but the default doctest would keep failing 3 out of 20 tests. After trying on my own for hours, I decided that I needed to discuss the code with someone who was well-versed in programming. I went to the Help Center and the friendly TA went over my code with me. We worked together and tracked down the error, which turned out to be a big issue but very easy to fix!
The issue? I wasn't creating Cheese objects when filling the first stool, just using regular integers for the cheeses which was why the doctest was failing. So the fix was quite simple: fill the first stool with Cheese objects instead!

I have been to office hours a few times this semester and I can't be thankful enough to Prof. Danny and Prof .Dustin for clarifying course material for me and showing me useful tricks to handle difficult problems such as recursive problems.
On another note, they have been replying to all of my e-mails within a day (Even on weekends!) and I am also thankful for that.

Office hours, Piazza, and the Help Center are truly indispensable resources for computer science learning.

Thoughts on Group Work

Let me first state that I strongly believe the current labs have been indubitably helpful to my own understanding of computer science. Nearly every school week there is a group lab where my partner (Ben) and I work through the challenging problems together. We discuss, brainstorm ideas and try them out until our answers are correct. We do try to get the code right the first time, but if it's inevitable we have multiple attempts until we arrive at the correct answer.
Personally, I enjoy the group work with Ben. We help point out each others mistakes and help each other understand things that we're unsure of. In fact, the labs have been so influential for us that we even discuss course concepts outside of school via Skype, phone and e-mail!
For those who are interested, please check out my partner's SLOG: http://mycsc148experience.blogspot.ca/

However, this is where I think a line must be drawn for group work. Although we are allowed to have groups for assignments, I also strongly believe that these should be done alone. By working alone, more students will develop their problem solving abilities but by working together, one group member may understand the solution whereas the others do not. If these students don't understand the concepts then they are at risk of doing poorly on the tests and perhaps in future courses as well.
I realize that in the real world we will be working with other peers but I think it would be meaningless if us students do not have a solid foundation on computer science concepts in the first place.

This is why I believe the perfect balance is to have groups for labs but not for assignments!


Thanks for reading my SLOG.
I will be finishing up assignment 2 this week so I'll make sure to discuss it in next week's entry.

Have a great week and see you again soon!



Monday, 17 February 2014

Assigned SLOG Topic # 2 - RECURSION! SLOG # 6

Wow! It's already the seventh week of the winter term.. how is everyone?

I have midterms in the coming week so I am hard at work. Writing tests are personally not my forte so I tend to double up the effort on assignments and even more so for test preparation.

Before I start this week's SLOG off, I have written a mid-week post on Object Oriented Programming (OOP) to discuss it in more detail since I had mistakenly not done so for the first assigned topic. Please give that a read if you have the time to and share your thoughts.

Seven weeks into the course, I'm finally comfortable with recursion to talk about it in depth, so let's get started!

How do we use recursion?

When solving a problem by repetitively using the same trick to get closer and closer to the final answer, we are using recursion.

Here is a real-life example of where recursion can be seen:

Imagine you've discovered a small diamond at the beach while going for a walk. Being the super clever person you are, you wonder if there are more undiscovered diamonds around this area. Using a metal detector and a shovel, you dig around the area, trying to uncover more. If there are no diamonds, you look around with the metal detector again and try the next spot. THIS is the example of recursion! You are repetitively doing the same task (shoveling and using the metal detector) in an attempt to get closer to the answer (the precious diamonds). Congratulations if this real-life recursion actually works out for you!

Programming example of recursion:

Perhaps you have a program that runs at different speeds depending on variable X and you'd like your program to run more efficiently. By using different cases of value X and running your program, you could deduce which case will be the most efficient. To do this, simply observe the amount of time it took each case to complete and trace the X value that completed your program in the shortest time. Although this sounds simple on paper, you are recursively calling your program for these different cases until you find the most optimal solution.

Here is a related example of another 148 student testing his functions for different run times:
http://berkeycolortran.wordpress.com/2014/02/15/week-6/
We should do so similarly as we want our program to run optimally by recursively testing various cases of X.

Define a stopping point!

When it comes to coding recursion, it's important to let our program know - "OK, that's enough!". It is super important to find a point where the program will finally stop recursively calling itself, otherwise it will continue on until our computers are out of memory. Some simple stopping points come from using for-loops over an iterable object such as lists, dictionaries and tuples or using conditions such that when the recursive function reaches the condition, it will stop rather than trying to call itself until our computers are out of memory.

A little technical example

As always, it's important to share some code as well. Simply talking about recursion without code isn't very helpful, especially to people who are new to it.

Let's define a function that will count the number of alphabetical objects in a nested list and let's define our list to be:
nested_list = [ 'race', 1, 'car', 2, 3, '4', ['hello!'], [1, ['ace', ['diamonds', 5]]]]

This should return a count of 4. Note that 'hello!' is not an alphabetical object since it has an exclamation mark (!) within the string. 'race', 'car', 'ace', 'diamonds' are all alphabetical.

def count_alpha(x: list) -> int:
    """
    Precondition: Items in x must be nested lists or string, integer and float objects.
 
    Returns the number of alphabetical objects inside a list.
    """
    count = [ ]
    def helper(x: list):
        for items in x:
            if isinstance(items, list):
                helper(items)
            else:
                if str(items).isalpha():
                    count.append(1)
    helper(x)
    return len(count)

Here is what this example does:
  • First we defined an empty list count as part of the outer function. 
  • We have defined an inner function 'helper(x)' so that when we recall our function, count does not get reset to an empty list.
  • For the body of helper(x), we utilize a for-loop so the program will stop after it iterates over all the items in list x; as stated above, it's important to define a stopping point for recursive functions.
  • The for-loop then iterates over x and if the items inside x happen to be a list, helper(items) is called which will loop through the items within the nested list.
  • Finally, if the for-loop happens to iterate through an object that is not a list, it will check if the object is alphabetical with the built-in isalpha().
    If this returns True, 1 is appended to count and the function will continue this pattern until the for-loop is completed.
  • len(count) is then returned, giving us our final answer.
Let's check our answer in Python Shell!

>>> nested_list = [ 'race', 1, 'car', 2, 3, '4', ['hello!'], [1, ['ace', ['diamonds', 5]]]]
>>> count_alpha(nested_list)
4

Voila!

Learning Recursion

Lastly but most importantly, I wanted to mention that learning recursion can be made MANY times easier by tracing your program on pencil and paper! I have done this for my labs, my assignments and for study material which helped me more than just reading about recursion or playing with recursive functions in Python. Tracing will provide tons of insight and is priceless for anyone interested in recursive functions. Using a visualizer helps as well but pencil and paper has personally been my saving grace.


Thanks for reading my lengthy but hopefully interesting SLOG post on recursion.

I have midterms to study for but do not fret, for I will be back with another post soon! :)
Wish me luck and see you readers later.








Sunday, 16 February 2014

Mid-Week Post on OOP (Object Oriented Programming) SLOG # 5

Hello! This is just a Mid-Week post on a subject I wanted to talk more about: Object Oriented Programming.

I actually didn't realize that for one of our 148 assigned SLOG topics, we were supposed to talk IN-DEPTH about OOP so I wanted to address it at least once. Oops!

Just to recap from my first SLOG, OOP is completely oriented on the creation and manipulation of objects as opposed to Procedural Programming which is oriented on the creation of functions with how they manipulate data.

Our starting point is the creation of a class which is like a blueprint to help us with the creation and usage of objects.

Afterwards, we can start defining methods of the class, which are functions that work specifically for the class's objects. With our newly defined methods we can now alter our objects in however we please or retrieve specific information about the object.

To clarify things, here's one example I recall from our 148 lab:

We can create a vehicle object that travels from place to place as long as it has enough fuel. How do we make Python do this?

Step 1: Create our vehicle class. (For example: class PublicBus)

Step 2: Initialize the vehicle class with default settings you would like to give it. Current fuel, fuel efficiency and current position are good examples of how vehicles are like in real world situations.

Step 3: Create our methods to make changes to our objects. Perhaps we'd like to fill up on gas, so how about a fill_up_gas method? Also we'd like to go from point A to point B, so how about a travel_to method? Of course our vehicle will need to meet the gas requirement so we can also add this in our travel_to method or create a helper method to check it for us.

Finally, we have done all we needed to and can start creating the actual object. It's quite simple actually. Just create an object using your blueprint (the vehicle class) like this: new_vehicle = PublicBus(100, 5).
100 here stands for the fuel, 5 stands for the fuel efficiency. These are the user-defined attributes of your new Public Bus object.

To get a bit technical, here is how it looks in Python code:

class PublicBus:
    """A PublicBus object. """

    def __init__(self, current_fuel, fuel_efficiency):
        """ Initializes PublicBus objects. """
        # Note: self refers to the object, it is named self by convention and is always         the first parameter for class methods.
        self.current_fuel = current_fuel
        self.fuel_efficiency = fuel_efficiency
        self.max_tank_capcity = 100
        self.current_pos = (0, 0)
        # Notice how current_pos isn't in the __init__ parameter? This is because             current_pos will ALWAYS start at (0, 0) coordinates when creating a new                 PublicBus object.

    def fill_up(self):
        """ Fills up the current fuel to the tank's max capacity. """
        self.current_fuel = self.max_tank_capacity  #  This is one of the class methods that will alter your object's attributes!

    def travel_to...
    def ....... so on, so forth. Keep defining methods until the object can meet all your requirements.

Now we can actually start using our object. Here is an arbitrary example that demonstrates how objects are created, used and how their attributes are changed.
NOTE: We use new_vehicle. (dot) in the code to call on the methods or check the class variables of the object's class. In this case, new_vehicle is the object and it's class is PublicBus.

>>> new_vehicle = PublicBus(100, 5)  # creating new object!
>>> new_vehicle.current_fuel  # checking object variable
100  # variable value
>>> new_vehicle.current_pos
(0, 0)
>>> new_vehicle.travel_to(5, 10)  # class method!
>>> new_vehicle.current_pos
(5, 10)
>>> new_vehicle.current_fuel
73  # new variable value!
>>> new_vehicle.fill_up()  # class method!
>>> new_vehicle.current_fuel
100  # class method fill_up() working properly.

This concludes the demonstration of how objects are interacted with and created in Python.

As you can see, OOP is totally emphasized on manipulating and creating objects. We have created an object, checked its' attributes, defined methods for it, initialized it and manipulated it all under one class.
Of course this is only one little object though. If we actually created a class for every type of  real-life vehicle, imagine all the knowledge we would have of them defined within our code. This is why OOP is important, it allows us to keep track of tons of information and change them as they are required; whether it be for games, medical, vehicles or any other purpose you can think of.

I hope this has been a good read for everyone.
Come back soon for more!

Tuesday, 11 February 2014

Brian's CSC148 SLOG # 4

Hello! How is everyone? This week has been a treat for me unlike the week before.

    If you recall, I was stuck on CSC148 assignment 1 last weekend on step 5 because I couldn't figure out what was wrong with my code. Then, on Monday's office hours, Prof. Danny pointed out the SLIGHTEST mistake in my code that completely flew over my head.

I was trying return a tuple and had forgotten to index the value I needed inside the tuple. When my function recursively recalled itself, it was trying to use the tuple instead of the value for simple calculations and thus was returning a TypeError. Bah! Still can't believe I couldn't find this error on my own. After this, I had finished A1 within a few hours. Asides from this, my midterms have been going really well.. I can feel it! So yup, good week!

OK. Pleasantries aside, I want to discuss a couple topics this week so here we go!

Topics:

Trees
Examples of copy.copy and copy.deepcopy

Trees

This is a totally new concept to me but I think it's very interesting with what you can do with trees. Perhaps the most interesting thing for me was learning how to traverse them, and using the data at these nodes with the used traversal method. Currently we learned of three: Post-Order Traversal, In-Order Traversal and Pre-Order Traversal. These three tree traversing methods allows us to manipulate our data in different ways. One example is an expression 1 + 2 * 3 expressed as a Tree.

Think of it like this:

+ is the root.
1 is the leaf child of the root.
* is the node child of the root.
2 and 3 are the leaf children of the * node.

If we use Pre-Order Traversal, we get the expression returned as + 1 * 2 3 which is the pre-fix expression of 1 + 2 * 3.
If we use Post-Order Traversal, we get the expression returned as  1 2 3 * + which is the post-fix expression of 1 + 2 * 3.
Lastly, using the In-Order Traversal, we simply get 1 + 2 * 3 which is an in-fix expression.

Although the expression example is trivial, I learned that we have many different ways of evaluating or storing expressions/data and I think this will become helpful once we have hundreds of different nodes and leaves to keep track of as opposed to just 1, 2 and 3!.

I came across one very helpful video that shows step-by-step binary tree traversals, have a look if you're interested! I especially recommend it if you're having a hard time understanding the concepts.

In-Order Traversals (Binary Tree): http://www.youtube.com/watch?v=gvPOTGGnn8k
Pre-Order Traversals (Binary Tree): http://www.youtube.com/watch?v=S5emQOEMiqc
Post-Order Traversals (Binary Tree): http://www.youtube.com/watch?v=X0pA5JOyI90

copy.copy, copy.deepcopy, assigning variables to values

Here's a tidbit of code that should explain this very well.

If we set x = [1, 2, 3]
and then set y = x
y and x will ALWAYS refer to the same object as long as we don't reassign y or x to new objects. This means, we can APPEND to the list object. So what happens when we do that? Have a look.

>>> x.append(4)
>>> x
[1, 2, 3, 4]
>>> y
[1, 2, 3, 4]

As you can see, there is no mistake, x and y will always be the same until a new value is assigned.

Now then.. rewind a little and we're back to:
x = [1, 2, 3]

Rather than assigning this time, we will import copy and use copy.copy.
>>> y = copy.copy(x)
>>> y
y = [1, 2, 3]

Nothing unusual yet.. but wait!
>>> x.append(4)
>>> x
[1, 2, 3, 4]
>>> y
[1, 2, 3]

Magic. No, just kidding. Now that we use copy.copy, y and x no longer refer to the same object and can be altered without causing an effect on each other. Note: copy.copy is also known as shallow copy.

copy.deepcopy is a little stronger. It actually goes through all the contents of your objects and recreates them individually at different memory addresses. It has a similar effect to copy.copy but goes that extra mile to keep them totally different. I hope this helps!

Check back soon for a another update! I'll be discussing a bit more about OOP (Object Oriented Programming) and for the coming week, recursion.

As always, thanks for reading my SLOG.
Brian


Tuesday, 4 February 2014

Brian's CSC148 SLOG # 3

Hello and how is everyone?

Boy, has this week has been rough!
Learned a lot in the 148 labs but the assignment is kicking my behind!

The first assignment was going swell until the 5th part, Tour.py.
I am unsure how to optimally make my program solve the problem. We are supposed to use recursion but my experience with it isn't sufficient.

I have tried a number of things through-out the entire day and I can't seem to find the root of the issue. For example, my code is supposed to solve the game with 4 stools and 5 cheeses in 13 moves but it has been giving me different values of moves like 21 or 7. I traced my program and realized there was an issue but it's a strange one due to the conditions of the formula for the minimum amount of moves.

Basically, when the formula calls on itself again, it uses a value that is not specified in the formula, so it has been returning a NoneType + an int. What happens when you add a NoneType and int? TypeError! Still working feverishly on this issue, trying to figure out where I'm going wrong.

Oh yes! There was a very interesting concept we learned this week in the labs.

  • copy.copy
  • copy.deepcopy
  • assigning values to variables

Basically, when you assign a value to something in python, it will be stored in memory address.
If you assign another variable equal to that value, and equate them with '==', this will return True.

copy.copy and copy.deepcopy will create a copy of the variable, BUT they will be assigned at different memory addresses.

EDIT: Oops! I made a mistake in my last post about these built-ins. Please disregard them and read here.
.
copy.copy and copy.deepcopy will both change the memory addresses of the variables! Equating them as they are will still be return True. However, recall what happens if these variables are both assigned to a number and you add to one of them. If copy.copy or copy.deepcopy is not used, adding to this number will change both variables and they can be equated to return True.

Now try it again with these two copy functions and add to one of the variables and what happens?
The answer: The number with the variable you have added to will be assigned the new value and the other variable will remain unchanged. Interesting stuff!

Thanks for reading my SLOG again.
Back to the assignment for me!








Tuesday, 28 January 2014

Brian's CSC148 SLOG # 2

Hello again! Thanks for reading my blog, really!

How is everyone's week so far? My keyboard broke over the weekend so I ordered one off of e-bay and for the first time took apart a laptop to get it fixed up. Turned out A-OK :]. My profs and friends had a good laugh at it though, especially since I was copy pasting the letter E to take notes.

So what's new in weeks 3-4? Well let's dive right in.

Overview
  • Diving deeper into recursion
  • Inheritance
  • Clarification on ADT's 
  • Testing code
  • MORE FRIGGIN AWESOME BUILT IN FUNCTIONS!
Recursion 

Cool stuff. Three visual examples of recursion were shown to us this week: Koch, Turtle and Sierpinski's triangle fractals. All of the functions work the same way, that is, they call themselves repeatedly until the code tells it to stop. If the code doesn't specify a stopping point, they will keep calling themselves recursively until your system runs out of memory! 

One really interesting thing that I noticed in the turtle recursive example was that each time it calls on itself, the function spawns 3 times the turtle of the previous function call. It starts with 3 turtles, one spawning at 0 degrees, another spawning at 120 degrees and the third spawning at 240 degrees. Then another 3 turtle spawns at each of the previous end points following the same degree order! So we have 3 turtles on the first call, 9 turtles on the second, 27 on the third... ETC. 
So we can conclude mathematically that it behaves as 3 to the n'th power where n is the number of specified (or unspecified!) calls.
Why is computer science so cool?

Inheritance

This is a really neat property in Python that allows us to combine other classes and how they work into a totally new class. Even though we can borrow from other classes, it has been mentioned that multiple inheritance should be totally avoided since things can get pretty confusing if multiple classes have the same functions. However, I wonder if it would be problematic at all if we combined classes that do not have multiples of the same functions. Hmmm..

ADT's

My previous post about ADT's was made totally clear to me by one of the professors in 148. So here it is: We have been using ADT's such as the built-in functions. These built-ins (isinstance, str, abs, ETC.) were programmed for our use without us having to worry how they were implemented. SUPER SIMPLE!

Testing Code

My weakness lies here. Out of habit, I test my own code without using doc tests or unit tests. During this week's lab, I was totally dependent on my partner for this part of the exercise. I actually know how to use doc testing but not unit tests. They are a bit harder to use as you have to write your own classes to perform them. They are however, much more reliable on finding bugs in the program than doc tests.

New Built-In Functions

raise allows us to call on our own defined Error Types! For example: If I were to follow coding design guidelines, I could raise a user-defined error if some programmer's code had lines longer than 80 characters *Cough, me, cough*.
exception allows our program to catch errors and tell it what to do if it encounters an error. Perhaps a client might use our program incorrectly, inputting a list of some sort instead of an int. If the program uses exception, we could easily add a little bit of code that will notify the client that the program will only take inputs of integers!
isnumeric checks if a string consists of an integer and returns True or False. I was lucky to learn of this built-in through a classmate in my lecture which helped me tons in the second exercise.

Check back next week for more awesome CSC stuff!
Comment and ask away if you please.

Ciao








Tuesday, 21 January 2014

Brian's CSC148 SLOG # 1

Introduction

Pleased to meet you!

I am a student studying at University of Toronto, doing my best to learn all I can in computer science. Currently, I have one huge goal that I have my heart set on: Creating a mind-blowing video game that will surpass all others that are currently available AND the ones to come in the future. If someone wishes to know the specifics of this video game, feel free to ask. :)

This courSe LOG is all about my perspective, experiences and knowledge of the material that is taught in CSC148. Hopefully this SLOG will be helpful to those who read it!

Introductions aside, let's move on to the interesting stuff taught during the first two weeks of 148.

Overview

Having taken CSC108 last semester, I was surprised from how much new content that was already taught in the first 2 weeks of class. 

Stuff we learned:
  • Abstract Datatypes (ADT's)
  • Stacks and Stack ADT's
  • Object Oriented Programming (OOP)
  • Ternary
  • Comprehensions
  • Recursion
  • New Built-in Functions
Abstract Datatypes (ADT's)

This was super confusing for me at first but I think I've got it down. It's called abstract since it allows the programmer (the provider) to create methods or programs without having to worry about how others (the clients) will use it. It's something that will save time for the programmer if the client intends on using it without worrying about the code, while also maintaining the code's consistency without having to go into the specifics of each and every method. I can see how this would be useful in certain work related projects where there are time constraints and also in certain methods where it isn't necessary to explain how it works.

Stacks and Stack ADT's

Stack was somewhat touched on in 108. In 108, tracing our Python programs was the method used for learning about call stacks. However, in 148, we learned that stacks can also be in the form of lists and sets. These stacks in particular follow a structure known as LIFO, (Last In, First Out). LIFO can be recalled in real life situations! Picture this: Imagine taking a newspaper from a newspaper stand. They are usually stacked face down by placing one on top of another. Then when you take a newspaper, you take the one that was last placed (the one on top!) and with or without knowing it, you just had a LIFO moment! Easy Peasy!

However, we can also change the algorithm of LIFO and for example, take the item at the bottom of the stack out rather than the top. There are many ways to program this to get different desired results and the programmer can choose to make the algorithm abstract (without worrying about how clients will use the code). If this is the case, we have a Stack Abstract Data Type.

Object Oriented Programming

This is simply a paradigm where focus is emphasized on creating objects by means of classes as opposed to another paradigm called Procedural Programming which is the creation of methods and how they manipulate data. The latter (Procedural Programming) was mostly what was taught in 108, which I think is the appropriate order to learn programming in for people who are new to computer science.

Ternary

In this case, ternary isn't about the ternary numbering system, but rather an expression that has three arguments. Here is a simple example:

if The time is 9:00 A.M. <-- 1st argument
    I need coffee <-- 2nd argument
else
    I don't need coffee <-- 3rd argument

Comprehensions

From what I know, comprehensions are simply reducing a code from being multiple lines long, into a shorter version of code that is no less concise than the prior. Taking my example from above, let's see how the comprehension form of it looks!

(I need coffee) if (The time is 9:00 A.M.) else (I don't need coffee.)

BAM! Simple as that and something I hope to get used to since my code from l08 was horrendously long.

Recursion

Alright, so this is very new to me and probably everyone else but I will try my best to explain this! In order to deal with a complicated problem, rather than writing incredibly long code, perhaps this problem can be tackled down in smaller sizes and every time you tackle a small problem, the solution becomes easier to obtain. Recursion gets its name from implying repetition in solving a larger problem at a smaller scale.
Picture this: You're the captain of a pirate ship (YARR!!) and you encounter a Kraken (basically a gigantic octopus). It's looking for a fight! If you try to smack it in the face with your cannon, it will block it and instantly crush your treasured ship. That's a BIG issue so let's deal with the smaller problem first: The arms. Smack the arms with your cannons first, then when they're all dealt with, go for the prize!
And that's my story version of recursion.

New Built-in Functions

Many, many new things built-in functions were taught in the first two weeks. These functions were perhaps the most interesting things I've learned so far. They are of interest to me since I now have a larger arsenal of weaponry to handle the tests, assignments and exam (heheheh).
So what's new?

set : Sets are another type that are different from lists as they do not permit the same two items in one set. so if you typed in python: x = set((1, 1)), x would equal {1}. You can also do subtraction with other sets which removes objects and convert them to lists as well using the built-in function list().
isinstance : This checks if an object is a certain type. So for example: isinstace(1, int) would return True. Lots of potential here when going through loops which we'll probably encounter in many programming problems.
intersection : intersection takes two sets and compares them, returning objects that are in both sets. Although we haven't done much with sets yet, I can't wait to see the usefulness of this in particular.
re.split : Remember the split method? This is its brother, and he's stronger! Keep in mind to use method re, you have to import it first, so include import re in the code before you call method re, or there'll be an error. It basically allows you to add an operator '^' without the quotations which will negate a set such as [0-9] or [A-z]. From experimenting, I learned that the lowercase and uppercase matters.
Here's an example I used while playing around with it.

>>> import re
>>> a = 'I am Robot #52'
>>> re.split("([^A-z])", a)
['I', ' ', 'am', ' ', 'Robot', ' ', '', '#', '', '5', '', '2', '']
As you can see, there are some empty strings but the '#52' string has been totally split apart and the 'I am Robot' is split nicely. There are many desirable things one could obtain with this!

Anyways I would like to end my first SLOG here. So a few final words.
Please discuss with me if you like, I would love to.
I have an AMAZING lab partner, here's his SLOG:
http://mycsc148experience.blogspot.ca/

Also I really enjoyed reading this student's SLOG, he/she was very clear in explaining the new material and even I learned from this person's real life examples which I thought were hilarious! Check it out if you'd like:
http://ddc-csc148slog.blogspot.ca/

Hope you enjoyed,
Ciao for now - Brian.