Wednesday, 29 January 2014

Issue 4: The Optimizing a Queue Challenge





A calm sea does not make a skilled sailor.
- African proverb  



Last week, we implemented a Stack and a Queue class for exercise purposes. A Queue is a list of objects that operate on a first-in, first-out basis. However, we noticed that the time it took to process a Queue increased linearly as the number of objects inside the Queue increased. This led us to a challenge: Can we design a Queue where the processing time is constant?

In order to complete this challenge, it is necessary for us to analyze two things. What method increases the processing time, and how can we adjust the method so that it behaves differently?

As it turns out, calling .pop() on a list is significantly faster than calling .pop(0). The reasoning behind this is due to how lists work inherently. Removing an element from the end of a list is easy, but removing an element from the beginning will require every single element to be shifted.

Thus, the implication is very straight forward - Always call .pop() and never .pop(0). However, the complication is that by definition: removing an object from a Queue results in the removal of the first object, and not the last.

This conveys to us that we must design our algorithm in a way such that attempting to remove an object from a Queue results in the removal of the last element, but at the same time, the last element must be the first object.

It is then a necessity that we should swap the first element with the last element, before calling .pop(). Luckily, swapping two elements is very simple. My proposed algorithm is as follow:


  • A variable is needed to keep track of our "front". This variable will tell us the index of the element that is to be removed next. Our "front" will begin at index 0.
  • A variable is needed to keep track of our "back". This variable will tell us the index of the element that we have just swapped our "front" with. Our "back" will begin at index -1.
  • If we try to add more items to the Queue in the middle of our algorithm, it will give us problems. A easy way out is to add a "buffer" that keeps track of newly added items until our algorithm has finished with the removal of all the items in the original Queue.
  1. When enqueuing onto an empty Queue, our "front" remains at index 0, but our "back" increases by 1.
  2. When we attempt to dequeue from a newly enqueued Queue, our "front" element is swapped with our "back" element. The last element is then removed from the Queue. "front" is increased by 1, while "back" is now the previous "front"
  3. When attempting to enqueue after any attempts of dequeue has been made, all objects will be appended to our "buffer" instead.
  4. Eventually, our "front" will become greater than or equal to last index. This signifies that we have reached the end of our list. 
  5. Upon reaching the end of our list, any further dequeues can be completed without swapping.
  6. When the list becomes empty, our "buffer" is transfered over into our Queue, and all indicators are reset. (i.e. "front" becomes 0 again, and "back" becomes the last index.)
Here is a visual example of each step outlined above:

>>> q = Queue()
>>> q._data
[]
>>> q._front
0
>>> q._back
-1
>>> q.enqueue(0)
>>> q.enqueue(1)
>>> q.enqueue(2)
>>> q.enqueue(3)
>>> q._data
[0, 1, 2, 3]
>>> q._front
0
>>> q._back
3
>>> q.dequeue()
0
>>> q._data
[3, 1, 2]
>>> q._front
1
>>> q._back
0
>>> q._dequeuing
True
>>> q.enqueue(4)
>>> q._data
[3, 1, 2]
>>> q._front
1
>>> q._back
0
>>> q._buffer
[4]
>>> q.dequeue()
1
>>> q._data
[3, 2]
>>> q._front
2
>>> q._back
1
>>> q._eol
True
>>> q.dequeue()
2
>>> q._data
[3]
>>> q.dequeue()
3
>>> q.is_empty()
False
>>> q._data
[4]
>>> q._buffer
[]
>>> q._front
0
>>> q._back
0

I verified this algorithm with the testqueue.py and timequeue.py provided for us. testqueue.py passed successfully in under 0.001 seconds, and timequeue.py gave me the following results:


Running time on 100000 items: 0.056036949157714844
Running time on 200000 items: 0.056036949157714844
Running time on 300000 items: 0.0570378303527832
Running time on 400000 items: 0.05903792381286621
Running time on 500000 items: 0.0570368766784668
Running time on 600000 items: 0.057038068771362305
Running time on 700000 items: 0.057038068771362305
Running time on 800000 items: 0.05803799629211426
Running time on 900000 items: 0.057038068771362305
Running time on 1000000 items: 0.057038068771362305


(I increased the number of items to make the difference more noticeable)

Here is my complete code for reference. I hope it helped!



       


class Queue:
    '''A list on a first in first out basis.
    
    Challenge: Optimize Queue so that execution time of enqueue and dequeue
    does not grow linearly. You must actually remove the object from the Queue.
    You cannot simply "hide it".
    
    
    The Problem: Attempting to pop/add an item at beginning of a list takes
    significantly longer than trying to pop/add at the end.
    
    Implication: We should only pop/add items at the end of the list.
    
    Concept:

    Example Queue: _data = [0, 1, 2, 3, 4, 5]
    
    We keep track of a front and back index
    _front = 0 # item is 0
    _back = 5 # item is 5
    
    We keep track of a buffer incase we are enqueuing in between dequeues
    _dequeuing = false
    _buffer = []
    
    We need to keep track of whether we reached the end of the list
    _eol = false
    
    When you enqueue before dequeuing, the _back is moved to the very end:
    _data.append(6) # [0, 1, 2, 3, 4, 5, 6]
    _back = len(_data) - 1 # index 6, item is 6
    
    When you dequeue, we want to swap the front and the back.
    _data = [6, 1, 2, 3, 4, 5, 0].pop()
    _back = _front # item is 6, index is 0
    
    Since we are poping the front, the front is now technically at index 1
    _front = front + 1 # index 1, item is 1
    _data = [6, 1, 2, 3, 4, 5]
    
    The first dequeue requires us to indicate this
    _dequeuing = true
    
    Another regular pop
    _data = [6, 5, 2, 3, 4, 1].pop()
    _back = _front # Item is 5, index is 1
    _front = _front + 1 # index 2, item 2
    _data = [6, 5, 2, 3, 4]
    
    Enqueuing in the middle of dequeuing adds to the buffer
    _data = [6, 5, 2, 3, 4]
    _buffer = [7]
    
    Dequeue #3
    _data = [6, 5, 4, 3, 2].pop()
    _back = _front # index 2, item 4
    _front = _front + 1 # index 3, item 3
    _data = [6, 5, 4, 3]
    
    Enqueueing again
    _buffer = [7, 8]
    
    Dequeue #4 reaches the end
    _front == len (_data) - 1
    i.e. _front = _back + 1
    
    _data = [6, 5, 4, 3].pop()
    _data = [6, 5, 4]
    
    Now we can just pop only.
    _eol = true
    
    furthur dequeues:
    
    if _eol == true:
        _data.pop()
        
    When the queue is empty, we put in the buffer and reset everything
    
    _data = _buffer
    _buffer = []
    _dequeuing = false
    _eol = false
    '''
    
    
    def __init__(self: "Queue") -> None:
        '''Initalize an empty Queue
        
        >>> q = Queue()
        >>> q._data
        []
        >>> q._front
        0
        >>> q._back
        -1
        >>> q.enqueue(0)
        >>> q.enqueue(1)
        >>> q.enqueue(2)
        >>> q.enqueue(3)
        >>> q._data
        [0, 1, 2, 3]
        >>> q._front
        0
        >>> q._back
        3
        >>> q.dequeue()
        0
        >>> q._data
        [3, 1, 2]
        >>> q._front
        1
        >>> q._back
        0
        >>> q._dequeuing
        True
        >>> q.enqueue(4)
        >>> q._data
        [3, 1, 2]
        >>> q._front
        1
        >>> q._back
        0
        >>> q._buffer
        [4]
        >>> q.dequeue()
        1
        >>> q._data
        [3, 2]
        >>> q._front
        2
        >>> q._back
        1
        >>> q._eol
        True
        >>> q.dequeue()
        2
        >>> q._data
        [3]
        >>> q.dequeue()
        3
        >>> q.is_empty()
        False
        >>> q._data
        [4]
        >>> q._buffer
        []
        >>> q._front
        0
        >>> q._back
        0
        '''
        self._data = []
        self._front = 0
        self._back = -1
        self._buffer = []
        self._dequeuing = False
        self._eol = False
    
    def enqueue(self: "Queue", x: object) -> None:
        '''Place x at the back of the Queue'''
        
        # When you enqueue before dequeuing, the _back is moved to the very end
        if not self._dequeuing:
            self._back = self._back + 1
            self._data.append(x)
        else:
            # Enqueuing in the middle of dequeuing adds to the buffer
            self._buffer.append(x)
        
    def dequeue(self: "Queue") -> object:
        '''Remove and return the object at the front of the Queue'''
        if self.is_empty():
            raise Exception ("Queue is empty.")
        
        # Record when we begin to dequeue
        self._dequeuing = True
        
        
        # If we are not at the end of the list, we dequeue by swaping
        if not self._eol:
            # When you dequeue, we want to swap the front and the back.
            self._data[self._front], self._data[-1] = self._data[-1], \
                self._data[self._front]
            
            self._back = self._front
            self._front = self._front + 1
        # Otherwise, we need to only pop from the end   
            
        return_buffer = self._data.pop()
        
        # Check whether we're at the end of the list
        if self._front >= len (self._data) - 1:
            self._eol = True
        
        if self.is_empty():
            # When the queue is empty, we put in the buffer and reset variables
            self._data = self._buffer
            self._buffer = []
            self._eol = False
            self._dequeuing = False
            self._front = 0
            self._back = len(self._data) - 1 
            if self._back < 0:
                self._back = 0
        return return_buffer
        
    def is_empty(self: "Queue") -> bool:
        '''Return whether or not the Queue has no objects'''
        return len(self._data) == 0
        
    def front(self: "Queue") -> object:
        '''Return the object at the front of the Queue'''
        return self._data[self._front]
    
if __name__ == "__main__":
    import doctest
    doctest.testmod()


As a foot note, I noticed that my writing style is very casual, whereas some people write in a very formal manner. Being that this is a blog, would you prefer that I write casually or formally? Please let me know!

Tuesday, 28 January 2014

Article 3.1: Object-Oriented vs Procedural





Everything has beauty, but not everyone sees it.
- Confucius  


Previously, I discussed the difference in mentality between an Object-Oriented programmer compared to a Procedural programmer. However, I argued that both methods work equally well, and that procedural programming isn't inherently wrong. I thought that I would back it up by giving a comparison of how procedural programming truly differs from object-oriented programming.

Earlier this week, our professor posted up a list of all the SLOGs for CSC148. I quickly skimmed through the list, and I now proclaim that my SLOG has the longest domain name! But how should I justify that? To prove this fact, I took a list of all the domain names and put it into a text file. (I only considered the domain name. Those who linked to a specific post were not considered.)
 
The text file slogAllURLs.txt looked like this:

http://1000589525.blogspot.com/
http://148aiwohaoma.blogspot.ca/
http://148courselog.blogspot.ca/
http://148journey.blogspot.ca/
http://148jz.blogspot.ca/
http://148reflections.blogspot.ca/
http://148sloooooog.blogspot.ca/
http://148theslog.blogspot.ca/
http://248148slog113.blogspot.ca/
http://47tulips.wordpress.com/
http://999830303csc148.blogspot.ca/
http://Endwithcolon.blogspot.com/
http://Raichubilibili.blogspot.ca/
http://a148slog.blogspot.ca/
http://a9mb4.blogspot.ca/
http://acccsc240.blogspot.ca/
http://achievementsuperlog.blogspot.ca/
http://adamscsblog.blogspot.ca/
http://adauoftcsc148.blogspot.ca/
http://address4blog.blogspot.ca/
http://adventuresofcsc148.blogspot.ca/
http://aerosolcsc148.blogspot.ca/
http://aheapofpythons.wordpress.com/
http://ailsaistryingtoleraning148.blogspot.ca/
http://albertcalzarettocs.blogspot.ca/
http://alexcsc148slog.blogspot.ca/
http://alexslogcsc148.blogspot.ca/
http://alexzhangslog.blogspot.ca/
http://allencsc148.blogspot.ca/
http://alphalambscsc148slog.blogspot.ca/
http://amandajbellslog.blogspot.ca/
http://aminslog.blogspot.ca/
http://andersoncsc148slog.blogspot.ca/
http://andyburtcsc148.blogspot.ca/
http://ang534001.blogspot.ca/
http://angelicaliley.wordpress.com/
http://angryprogram.blogspot.ca/
http://anthonycolli.blogspot.ca/
http://antonmoiseevslog148.blogspot.ca/
http://ardeaalba.blogspot.ca/
http://arloslog.blogspot.ca/
http://art5594.blogspot.ca/
http://asdfghjklasdfghjklas.blogspot.ca/
http://atsloggerheads.blogger.com/
http://ayoublslog.blogspot.ca/
http://becomingapythonista.blogspot.ca/
http://begincsc.blogspot.ca/
http://berkkarapence.blogspot.ca/
http://bighairyleg.blogspot.ca/
http://bloggincsc.blogspot.com/
http://blogsteria.wordpress.com/
http://bobs-slog.blogspot.ca/
http://bounce14.wordpress.com/
http://bponslog.blogspot.ca/
http://c1kooner.blogspot.ca/
http://c3elamir148.blogspot.ca/
http://c3kleine.blogspot.ca/
http://c3mckerr.blogspot.ca/
http://c3nemeth.blogspot.ca/
http://c3reiner.blogspot.ca/
http://calvinswpark.blogspot.com/
http://caronecsc148.blogspot.ca/
http://cedric1011slog1.blogspot.ca/
http://changslog.blogspot.ca/
http://chen-yichao.blogspot.ca/
http://chickenlikei.blogspot.ca/
http://chocolateshoulders.blogspot.ca/
http://chow-carmen.blogspot.ca/
http://chrislu0126.blogspot.ca/
http://chriswangorz.blogspot.ca/
http://chummycsc148.wordpress.com/
http://cjsridiculousslog.blogspot.ca/
http://claireslog148.blogspot.ca/
http://classycompscigeek.wordpress.com/
http://clicomputerscience.blogspot.ca/
http://codepanda.blogspot.ca/
http://codezerda.tumblr.com/
http://codingandstuffz.blogspot.ca/
http://codinginmotion.blogspot.ca/
http://commoncodemonkey.blogspot.ca/
http://compsci148courseblog.blogspot.com/
http://compscislog.wordpress.com/
http://compscislog148.blogspot.ca/
http://compscistuffz.blogspot.ca/
http://compstatnerd.blogspot.ca/
http://comscibro.blogspot.ca/
http://comscicourseblog.blogspot.ca/
http://confabulatingastringofcontrivances148.blogspot.ca/
http://cooleanvariable.blogspot.ca/
http://courseblog148.blogspot.ca/
http://cr148slog.blogspot.ca/
http://cs2eb.blogspot.ca/
http://csamirs.blogspot.ca/
http://csc148-blog.blogspot.ca/
http://csc148-slog-cba.blogspot.ca/
http://csc148-slog1-fundamentals-of-oop.blogspot.ca/
http://csc148-w2014slog.blogspot.ca/
http://csc148-winter2014.blogspot.ca/
http://csc148adventure.blogspot.ca/
http://csc148blog0.blogspot.ca/
http://csc148bloger.blogspot.ca/
http://csc148blogtim.blogspot.ca/
http://csc148blogwinter.blogspot.com/
http://csc148caoliu.blogspot.ca/
http://csc148courseblog.wordpress.com/
http://csc148courslog.blogspot.ca/
http://csc148cs.blogspot.ca/
http://csc148firstblog.blogspot.ca/
http://csc148ftw.blogspot.ca/
http://csc148gw.blogspot.ca/
http://csc148h.blogspot.ca/
http://csc148h1-slog.blogspot.ca/
http://csc148h1.blogspot.ca/
http://csc148h1s.blogspot.ca/
http://csc148h1s2014.wordpress.com/
http://csc148h1winter2014.blogspot.ca/
http://csc148jasonly1.blogspot.ca/
http://csc148jessica.blogspot.ca/
http://csc148journal.blogspot.ca/
http://csc148jr.blogspot.ca/
http://csc148jslog.blogspot.ca/
http://csc148kh.blogspot.ca/
http://csc148lschilling.blogspot.ca/
http://csc148minimalist.tumblr.com/
http://csc148mn.blogspot.ca/
http://csc148myt.blogspot.ca/
http://csc148python.blogspot.ca/
http://csc148reflections.blogspot.ca/
http://csc148reflectionss.blogspot.ca/
http://csc148slog1234.blogspot.ca/
http://csc148slog14.blogspot.ca/
http://csc148slog2014.blogspot.ca/
http://csc148slogbywu.blogspot.ca/
http://csc148slogcs.tumblr.com/
http://csc148sloggingalong.blogspot.ca/
http://csc148slogss.blogspot.ca/
http://csc148sloguoft.blogspot.ca/
http://csc148slogw14.wordpress.com/
http://csc148steven.blogspot.ca/
http://csc148studentlife.wordpress.com/
http://csc148studyjornal.blogspot.ca/
http://csc148sukumar.blogspot.ca/
http://csc148w14-slogpl.blogspot.ca/
http://csc148winter.blogspot.ca/
http://csc148winter2014.wordpress.com/
http://csc148world.tumblr.com/
http://csc148ycpark.blogspot.ca/
http://csc148yixiao.blogspot.ca/
http://csc148yw.blogspot.com/
http://csc165w14.blogspot.ca/
http://csc5million.blogspot.ca/
http://cscij.blogspot.ca/
http://cscneuro.blogspot.ca/
http://cscourselog.blogspot.ca/
http://cscouscous.wordpress.com/
http://cscslog148.blogspot.ca/
http://cscslogging.blogspot.ca/
http://cscslogging.wordpress.com/
http://cscxlviii.blogspot.ca/
http://csjpython.blogspot.ca/
http://cslog148.blogspot.ca/
http://daisyfangcsprogramming.blogspot.ca/
http://david148slog2014.blogspot.ca/
http://dc148.blogspot.ca/
http://dcuii.wordpress.com/
http://denislau148.blogspot.ca/
http://dianeslog.blogspot.ca/
http://dknslog.blogspot.ca/
http://dlam15.blogspot.ca/
http://dmpolarbear.blogspot.ca/
http://dogaisterslog.blogspot.ca/
http://donghyuk-slog.blogspot.ca/
http://double-ampersand.tumblr.com/
http://dozermanslog.blogspot.ca/
http://drdrpython.blogspot.ca/
http://dyuanslog.blogspot.ca/
http://ehslog.blogspot.ca/
http://elainesslogcsc148h1s2014.blogspot.ca
http://ellinlicsc148slog.blogspot.ca/
http://emce123.blogspot.ca/
http://epyonslog.blogspot.ca/
http://ericsiuslog148.blogspot.ca/
http://essentiallyprogramming.blogspot.com/
http://ethanwen1994.blogspot.ca/
http://etoileblancheluna.blogspot.ca/
http://everyonelovesaslog.blogspot.ca/
http://experiencepython.blogspot.ca/
http://flexographyslog.blogspot.ca/
http://flgqz.blogspot.ca/
http://flora3104.blogspot.ca/
http://fomcsc.blogspot.ca/
http://fraserxiong.com/word_press/
http://fred-csc148week3.blogspot.ca/
http://frederickoncsc148.blogspot.ca/
http://g3syzygy.blogspot.ca/
http://g4q5i5b5.blogspot.ca/
http://garykangslog.blogspot.ca/
http://ghhcsc148slog.blogspot.ca/
http://godough148.blogspot.ca/
http://goldenapple89.blogspot.ca/
http://gone-phishing.weebly.com/
http://gr148slog.blogspot.ca/
http://grigorgurmaSLOG.blogspot.com/
http://gt-csc148.blogspot.ca/
http://gurleenkaur23.blogspot.ca/
http://haitaoguo165.blogspot.com/
http://haleyyewslog.blogspot.ca/
http://harmandeepsranslog165.blogspot.ca/
http://heapofcode.blogspot.ca/
http://hepingsheng.wordpress.com/
http://hlslog.blogspot.ca/
http://hongjinlee.blogspot.ca/
http://hopelesslyconfusedbear.blogspot.ca/
http://hunter-csc148-slog.blogspot.com/
http://iamacsc148student.wordpress.com/
http://idlepython.blogspot.ca/
http://ihaveacravingforchickenwings.blogspot.ca/
http://includeiostream.blogspot.com/
http://introcsslog.blogspot.ca/
http://introtocompsci.wordpress.com/
http://introtocsc.blogspot.ca/
http://ishwantsodhi.wordpress.com/
http://itsaslogblog.blogspot.ca/
http://itssoclogged.blogspot.ca/
http://itsthecompblog.blogspot.ca/
http://ivenson.blogspot.ca/
http://ivycsc148slog.blogspot.ca/
http://jabb3rw0ck.blogspot.ca/
http://jack-mai.blogspot.ca/
http://jackjltian.blogspot.ca/
http://jaewonyun148.blogspot.ca/
http://jasonqiancsc148h.blogspot.com/
http://jeffcsc148slog.blogspot.ca/
http://jennycsc148.blogspot.ca/
http://jeremy-csc148.blogspot.ca/
http://jessecsc148.blogspot.ca/
http://jfmartelprogramming.blogspot.ca/
http://jhcsc148h1.blogspot.ca/
http://jiechen9597.blogspot.ca/
http://jingziwen.blogspot.ca/
http://jinzh92.blogspot.ca/
http://jmazzslog148.2kool4u.net/
http://johnaquino23.blogspot.ca/
http://johnnibrahim.blogspot.ca/
http://julianochoaslog.blogspot.ca/
http://jzyslog.blogspot.ca/
http://kashifkhanslog.blogspot.ca/
http://katherine-karin.blogspot.ca/
http://kawinsmusings.blogspot.ca/
http://kelin01.blogspot.ca/
http://kellycsc148h1s.blogspot.ca/
http://kentqian1000335078.blogspot.ca/
http://kevincolour.blogspot.ca/
http://kevincsc148.blogspot.ca/
http://kimsarmie.blogspot.ca/
http://kkcsc148.blog.com/
http://klslog.blogspot.ca/
http://koalabearking.blogspot.ca/
http://kouroshslog.blogspot.ca/
http://kreativemuse.wordpress.com/
http://labibacslog148.blogspot.ca/
http://lalalaoyeah.blogspot.ca/
http://lambda--x.blogspot.ca/
http://lbg940131.blogspot.ca/
http://lcx64.blogspot.ca/
http://liamsslog.blogspot.ca/
http://lianglcsc148slogw14.blogspot.ca/
http://liangyuzhong.blogspot.ca/
http://lindachengcsc148.blogspot.com/
http://lindsaychownslog148.blogspot.ca/
http://linjun110120.blogspot.ca/
http://listindexoutofrange.blogspot.com/
http://liwenzhang--iris.blogspot.com/
http://lizcsc148.blogspot.ca/
http://ljasonslog.blogspot.ca/
http://lopez-csc148.blogspot.ca/
http://lotfy2.blogspot.ca/
http://lsshslog.blogspot.ca/
http://luciapark.blogspot.ca/
http://lucycsc148.blogspot.com/
http://lwcsc148.blogspot.ca/
http://manbochenslog148.blogspot.com/
http://mariacsc148slog.blogspot.ca/
http://martinren.blogspot.ca/
http://maxisakov.blogspot.ca/
http://meeralslog148.blogspot.ca/
http://melcardoz.blogspot.ca/
http://melcsc148.blogspot.ca/
http://mirrorplusplus.blogspot.ca/
http://mjcaywt.blogspot.ca/
http://moeen-cscslog.blogspot.ca/
http://mrprofessorscientist.blogspot.ca/
http://muhammadimran148.blogspot.com/
http://mujtaba334.blogspot.ca/
http://muralislog.blogspot.ca/
http://my-thinking-towards-python.blogspot.ca/
http://my148slog.blogspot.ca/
http://mycsc148experience.blogspot.ca/
http://mycsc165slogatuoft.blogspot.ca/
http://myfirstslog.blogspot.ca/
http://myjourneyintocsc148.blogspot.ca/
http://mylearningtool.blogspot.ca/
http://myslog2014.blogspot.ca/
http://myswagcscblog.blogspot.com/
http://naiuhzcsc148.blogspot.ca/
http://natecsc148.blogspot.ca/
http://neococs.blogspot.ca/
http://netbirds2014.blogspot.ca/
http://nguyenquangminhcsc148.blogspot.ca/
http://nicknoir.blogspot.ca/
http://nickscsc148.blogspot.ca/
http://noah-the-cs-student.blogspot.ca/
http://nothingbutcsc148.blogspot.ca/
http://notyourdomain.blogspot.ca/
http://nozomicsc148.blogspot.ca/
http://objectnonetype.blogspot.ca/
http://objectprogrammingweek3.blogspot.ca/
http://omarsardarslog.blogspot.ca/
http://onefoureight-iam.blogspot.ca/
http://onefourtyeight.blogspot.ca/
http://ouyangjunaoyun.blogspot.ca/
http://overthrowsuperclass.blogspot.ca/
http://owen148slog.blogspot.ca/
http://parhamtahercsc148.blogspot.ca/
http://pbslog.blogspot.ca/
http://pendingcontent.blogspot.ca/
http://perrislog.blogspot.ca/
http://peterandtam.blogspot.ca/
http://philnslog148.blogspot.ca/
http://programming4lifee.blogspot.ca/
http://programmingtoinfinity.blogspot.ca/
http://pruode.wordpress.com/
http://prynk71.blogspot.ca/
http://pyslog.blogspot.ca/
http://pythonatemyhomework.blogspot.ca/
http://pythoncodeshark.wordpress.com/
http://pythoncsc148slog.blogspot.ca/
http://pythonisnotasnake.wordpress.com/
http://pythonslog.blogspot.ca/
http://rainmenger.blogspot.ca/
http://raise-stop-procrastinating-exception.blogspot.ca/
http://ramseyslog.blogspot.ca/
http://raymond111.blogspot.com/
http://realmofneutrino.blogspot.ca/
http://remyduringrem.blogspot.ca/
http://reshamshah.wordpress.com/
http://reyespaul.blogspot.com/
http://ricecrispislog.wordpress.com/
http://richardbrookcsblog.blogspot.ca/
http://rico148.blogspot.ca/
http://runningcomment-ary.blogspot.com/
http://ryancsc148.blogspot.ca/
http://ryancscslog.blogspot.ca/
http://samisdoingcsc148slog.blogspot.ca/
http://sandracsc148slog.blogspot.com/
http://sausage-slog-dog.blogspot.ca/
http://schwayslogs.blogspot.ca/
http://scpcsc148.blogspot.ca/
http://sett.com/slog/
http://shane417.blogspot.ca/
http://shuqiaowang.blogspot.ca/
http://siddcsc.blogspot.ca/
http://sikaili.blogspot.ca/
http://siyangcsc148w3.blogspot.ca/
http://siyinglicsc.blogspot.ca/
http://sjslog.blogspot.ca/
http://skaiden.blogspot.ca/
http://skyscraper121.blogspot.ca/
http://slog.alvihabib.com/
http://slog148.blogspot.ca/
http://slog148tailong.blogspot.ca/
http://slog1a.blogspot.ca/
http://slogalert.blogspot.ca/
http://slogatcsc148.blogspot.ca/
http://slogate.blogspot.ca/
http://slogblogblogblog.blogspot.ca/
http://slogblognamehere.blogspot.com/
http://slogcsc148h.blogspot.ca/
http://slogcsc148slog.blogspot.ca/
http://slogcsc148w.blogspot.ca/
http://slogforvivienneyeung.blogspot.ca/
http://sloggerblogger2014.blogspot.ca/
http://sloggeroo.blogspot.com/
http://sloggers148.blogspot.ca/
http://sloggingadventures.blogspot.ca/
http://sloggingthrough148.blogspot.ca/
http://sloggyslogblog.blogspot.ca/
http://sloglordscscslog.blogspot.ca/
http://slogmyblog.blogspot.ca/
http://slogonefoureight.blogspot.ca/
http://slogseanhan.blogspot.ca/
http://slogsforcs.blogspot.ca/
http://slogslogslog.blogspot.ca/
http://slogslogslogslog.blogspot.ca/
http://slogwow.blogspot.ca/
http://slogxcsc148.wordpress.com/
http://snowandcomputerscience.blogspot.ca/
http://sobbingmathematically.blogspot.ca/
http://sockeryslog.blogspot.ca/
http://songqiaocscjournal.blogspot.ca/
http://sophiataking148.blogspot.com/
http://sosocompsci.blogspot.ca/
http://soupzai.blogspot.ca/
http://stevenscourseslog.blogspot.com/
http://striga889.blogspot.ca/
http://student9312.blogspot.ca/
http://studiesincompsci.blogspot.ca/
http://submannifold.blogspot.ca/
http://sumancsc148.blogspot.ca/
http://supercskid.blogspot.ca/
http://superslog.blogspot.ca/
http://supersocketmaster.blogspot.ca/
http://svujosevic.blogspot.ca/
http://takoyakixdd.blogspot.ca/
http://tangaar4.blogspot.ca/
http://tcslog148.blogspot.ca/
http://teryx2014slog.wordpress.com/
http://theblogofcaerbannog.blogspot.ca/
http://thecoderslog.blogspot.ca/
http://thecrustyblogger.blogspot.ca/
http://thefabricofourpeople.blogspot.ca/
http://theinformationslog.blogspot.ca/
http://theslogofangela.blogspot.ca/
http://theslogspot148.blogspot.ca/
http://thirdweek0121.blogspot.ca/
http://thutoronto.blogspot.ca/
http://tianxia2014.blogspot.ca/
http://tiffany199205.blogspot.com/
http://timetoslog.blogspot.ca/
http://tlama1.blogspot.ca/
http://tmaftbbwaatmm.blogspot.ca/
http://tookitin.blogspot.ca/
http://torincsc148.blogspot.ca/
http://tracycsc148.blogspot.ca/
http://trevork-csc148.blogspot.ca/
http://tricomputersciencethoughts.blogspot.ca/
http://tt0923slog.blogspot.ca/
http://twcscslog.blogspot.ca/
http://udaracsc148.blogspot.ca/
http://umutbakkaya.blogspot.ca/
http://unicorns148blog1.blogspot.com/
http://uoftcsc148slog.blogspot.com/
http://uoftcsc148winterslog.blogspot.ca/
http://uoftslog148.blogspot.ca/
http://utcsslog.blogspot.ca/
http://v-slog148.blogspot.ca/
http://v332884053.blogspot.ca/
http://vibhavipeiris.wordpress.com/
http://vic148.blogspot.ca/
http://vigchand.blogspot.ca/
http://viviantancsc148slog.blogspot.ca/
http://vpodoroj.blogspot.ca/
http://vshahslog.blogspot.ca/
http://wanshanchang.blogspot.ca/
http://waynellin.blogspot.ca/
http://week3yingjieli.blogspot.ca/
http://weeklyslog.wordpress.com/
http://weicsc148slog.blogspot.ca/
http://weidong148.blogspot.ca/
http://weislog.blogspot.ca/
http://wendyxiao0609.blogspot.com/
http://wenwenbritha.wordpress.com/
http://whatsgabbening.blogspot.ca/
http://williamru.blogspot.ca/
http://wls148slog.blogspot.com/
http://wowchang.blogspot.ca/
http://www.CompProgBlog.blogger.ca/
http://www.aatiii.tumblr.com/
http://www.amcsc148slog.blogspot.ca/
http://www.anishslog.blogspot.ca/
http://www.aurachishiki.blogspot.ca/
http://www.cammipham.com/slog/
http://www.ckocan.blogspot.ca/
http://www.computusmaximus.blogspot.ca/
http://www.csc148slog99.blogspot.com/
http://www.csc148slogx.wordpress.com/
http://www.g3apples.blogspot.ca/
http://www.hanacsc148.blogspot.com /
http://www.i-eslog.blogspot.ca/
http://www.imnotawizardhagrid.blogspot.ca/
http://www.kchristiaens.blogspot.ca/
http://www.lawbstar.blogspot.ca/
http://www.mimiscsc148slog.blogspot.ca/
http://www.programming148.blogspot.ca/
http://www.szluzero.blogspot.com/
http://www.tabi148.wordpress.com/
http://www.utsgcsc148.blogspot.ca/
http://www.weihongwei.blogspot.ca/
http://yamsoupslog.blogspot.ca/
http://yangyangslog1.blogspot.ca/
http://yanqilee.blogspot.ca/
http://yansenyangslog.blogspot.com/
http://yfcsc148slog.blogspot.ca/
http://ygohslog.blogspot.ca/
http://yifanwucsc148.blogspot.ca/
http://yifeizhouslog.blogspot.ca/
http://yihsuncsc148.blogspot.ca/
http://yikucsc148slog1.blogspot.ca/
http://yimingcsc148.blogspot.ca/
http://yiting148slog.blogspot.ca/
http://youknownothingjonslog.blogspot.ca/
http://yqnslog.blogspot.ca/
http://yuanslog148.blogspot.ca/
http://yuegong0.blogspot.ca/
http://yuxuanli.blogspot.ca/
http://ywcsc148slog.blogspot.com/
http://yyhcsc148.blogspot.ca/
http://zanecsc148.blogspot.ca/
http://zhanghan415.blogspot.ca/
http://zhangxiangyu17.blogspot.ca/
http://zhenancsc148.blogspot.com/
http://ziweifanslog148.blogspot.ca/
http://zjmutcsc.blogspot.ca/
http://zoecsc148.blogspot.com/
https://jackchenyixiong.blogspot.com/
https://somerandomcsc148blog.blogspot.com/
http://kencsc148slog.blogspot.com/
 


I concluded that a program is necessary to help me analyze the longest domain name out of all the URLs. However, I am still accustomed to the Procedural style of programming and before long, my code was starting to resemble a Procedural program again! So I thought that I would write the exact same program with both Procedural and Object-oriented style, and compare how they look. Here's how it turned out:


Procedural Programming


       

    if __name__ == "__main__":
    slogURLs_file = open("slogAllURLs.txt")
    
    # Keep track of the total number of slogs
    slogs = 0
    
    # Keep track of the shortest slog
    slog_shortest = None
    slog_shortest_length = -1
    
    # Keep track of the longest slog
    slog_longest = None
    slog_longest_length = -1
    
    # Keep track of my slog
    my_slog = "http://confabulatingastringofcontrivances148.blogspot.ca/"
    my_slog_length = len(my_slog)
    
    for slogURL in slogURLs_file:
        slogs += 1
        
        # Remove the new line character
        slogURL = slogURL [:-1]        
        slogURL_length = len(slogURL)
        
        # Check whether this is shorter than the shortest slog
        if slogURL_length < slog_shortest_length or slog_shortest == None:
            slog_shortest_length = slogURL_length
            slog_shortest = slogURL
            
        # Check whether this is longer than the longest slog
        if slogURL_length > slog_longest_length or slog_longest == None:
            slog_longest_length = slogURL_length
            slog_longest = slogURL            
        
    print("There are a total of {} slogs.".format(slogs))
    print("The shortest slog URL is {} with {} characters.".format(
        slog_shortest, slog_shortest_length))
    print("The longest slog URL is {} with {} characters.".format(
        slog_longest, slog_longest_length)) 
    print("My slog is {} and has {} characters.".format(
            my_slog, my_slog_length))    
    
    # Reread the file from the beginning and find all ties.
    slogURLs_file.seek(0)
    
    slog_shortest_ties = []
    slog_longest_ties = []
    
    for slogURL in slogURLs_file:
        # Remove the new line character
        slogURL = slogURL [:-1]        
        slogURL_length = len(slogURL)
        
        # Check whether it ties for the shortest
        if slogURL_length == slog_shortest_length and slogURL != slog_shortest:
            slog_shortest_ties.append(slogURL)
            
        # Check whether it ties for the longest
        if slogURL_length == slog_longest_length and slogURL != slog_longest:
            slog_longest_ties.append(slogURL)            
        
    # Output the ties
    print ("-" * 10)
    print ("The following slogs are tied for the shortest URL of {} characters"
           .format(slog_shortest_length))
    for slogURL in slog_shortest_ties:
        print(slogURL)
        
    print ("-" * 10)
    print ("The following slogs are tied for the longest URL of {} characters"
           .format(slog_longest_length))
    for slogURL in slog_longest_ties:
        print(slogURL)        
        
    slogURLs_file.close()

       
 

Object-Oriented Programming


       


class SLOG:
    '''A SLOG object with a url to a slog.'''
    
    
    def __init__(self: "SLOG", url: str) -> None:
        '''Initalize a SLOG object with the url .'''
        self.url = url
        self.length = len(url)
        
    def __gt__(self: "SLOG", other: "SLOG") -> bool:
        '''Compare two SLOG objects and return whether self has a longer url 
        than other'''
        return self.length > other.length
    
    def __lt__(self: "SLOG", other: "SLOG") -> bool:
        '''Compare two SLOG objects and return whether self has a shorter url 
        than other'''
        return self.length < other.length    
    
    def __eq__(self: "SLOG", other: "SLOG") -> bool:
        '''Compare two SLOG objects and return whether self and other has the
        exact same urls.'''
        return self.url == other.url     
        
class SlogURLs:
    '''A SlogURLs object that contains a list of SLOG objects'''
    
    
    def __init__(self: "SlogURLs", file: "str") -> None:
        '''Initalize a SlogURLs object by opening the file  and 
        creating a list of SLOG objects'''
        self.file = open(file)
        self.slogurls = []
        
        for slogs in self.file:
            # Remove the new line character
            slogs = slogs [:-1]
            
            slog_obj = SLOG (slogs)
            self.slogurls.append (slog_obj)
            
        self.file.close()
    
    def longest(self: "SlogURLs") -> "SLOG":
        '''Return the SLOG object with the longest url'''
        self.longest_url = max (self.slogurls)
        return self.longest_url
    
    def shortest(self: "SlogURLs") -> "SLOG":
        '''Return the SLOG object with the shortest url'''
        self.shortest_url = min (self.slogurls)
        return self.shortest_url
    
    def total(self: "SlogURLs") -> "SLOG":
        '''Return the total number of SLOG objects'''
        return len(self.slogurls)
    
    def longest_ties(self: "SlogURLs") -> "SLOG":
        '''Return a list of SLOG objects tied for the longest url'''
        ties = []
        
        # Sort the list of SLOG urls from smallest to largest
        self.slogurls.sort()
        
        # If it is sorted, the last slog object should have the longest url
        length = self.slogurls[-1].length
        
        # Reverse the list so that we start looking at the longest urls first
        self.slogurls.reverse()
        
        for slog in self.slogurls:
            if slog.length == length and slog != self.longest_url:
                ties.append (slog)
                
        return ties
    
    def shortest_ties(self: "SlogURLs") -> "SLOG":
        '''Return a list of SLOG objects tied for the shortest url'''
        ties = []
        
        # Sort the list of SLOG urls from smallest to largest
        self.slogurls.sort()
        
        # If it is sorted, the first slog object should have the shortest url
        length = self.slogurls[0].length
        
        for slog in self.slogurls:
            if slog.length == length and slog != self.shortest_url:
                ties.append (slog)
                
        return ties    
    
    
    
if __name__ == "__main__":
    # Keep track of my slog
    my_slog = "http://confabulatingastringofcontrivances148.blogspot.ca/"
    my_slog_length = len(my_slog)
    
    slogURLs = SlogURLs("slogAllURLs.txt")
    print("There are a total of {} slogs.".format(slogURLs.total()))
    print("The shortest slog URL is {} with {} characters.".format(
        slogURLs.shortest().url, slogURLs.shortest().length))
    print("The longest slog URL is {} with {} characters.".format(
        slogURLs.longest().url, slogURLs.longest().length)) 
    print("My slog is {} and has {} characters.".format(
            my_slog, my_slog_length))      
    
    # Output the ties
    print ("-" * 10)
    print ("The following slogs are tied for the shortest URL of {} characters"
           .format(slogURLs.shortest().length))
    for slogURL in slogURLs.shortest_ties():
        print(slogURL.url)
        
    print ("-" * 10)
    print ("The following slogs are tied for the longest URL of {} characters"
           .format(slogURLs.longest().length))
    for slogURL in slogURLs.longest_ties():
        print(slogURL.url)            
        


 

As it turns out, both code outputs the following:


There are a total of 517 slogs.
The shortest slog URL is http://sett.com/slog/ with 21 characters.
The longest slog URL is http://confabulatingastringofcontrivances148.blogspot.ca/ with 57 characters.
My slog is http://confabulatingastringofcontrivances148.blogspot.ca/ and has 57 characters.
----------
The following slogs are tied for the shortest URL of 21 characters
----------
The following slogs are tied for the longest URL of 57 characters


So it looks like my SLOG does in fact have the longest domain name! Woot!

As it turns out, both code executes extremely fast (< 0.01 seconds), and neither of them are difficult to read, nor difficult to program. So what's the difference? 

In the procedural style code, each line is a step. Everything is kept track of in a global variable, and loops are used to check each individual URLs and comparisons are made inside these loop. 

In the object oriented style code, URLs are made into objects. Methods such as __lt__ and __gt__ are defined so that the builtin python functions can be used. This allows urls to easily be sorted into lists. Information about the URLs are all stored in its own object.

What truly matters is simply how you think.

Wednesday, 22 January 2014

Issue 3: Object-Oriented Programming

Hello and welcome to Confabulating a String of Contrivances 148! (C.S.C. 148) This is the place where I discuss about various topics my Professor asks us to talk about. Come to think of it, I never wrote a blog before. In fact, I hardly read blogs except to gain information about obscure topics that most people don't care to know about; in that case, whether you are my T.A., my Professor, my classmate, my friend, future me, or none of the above, I hope that you find something useful among these bytes of words!

Object-Oriented Programming is not particularly a difficult concept in today's time. Many schools and universities teach it, while many others still insist on alternative methods of programming. I don't find it a challenging concept given my previous experience with the traditional style of Procedural Programming. I can liken the two in the sense that instead of creating many variables to represent one item (object), I can now create a single object that stores many variables.

I find that the hardest part of Object-Oriented Programming is not the logic, but rather the design. The problem here is that Object-Oriented Programming requires a different method of thinking. Intuitively, we first think about "what will my program do?" Yet with Object-Oriented Programming, we must instead think about "with what will my program work with?" (This is why we practiced high-lighting keywords in class.)

Procedural Programming

Let's say we're designing a simple two player soccer game. Intuitively, we will begin by considering how two players must kick the ball into the opposing net. This thinking will entice us to begin by coding controls for two player's movement separately. After doing so, we would intuitively move on to defining the coordinates of the ball, and a set of procedures in the form of while loops that governs how the ball move, how the ball interact and the condition for victory. By the time this is over, we would end up with a Procedural style Programming. The set of instructions would be easy enough to translate into a self-help manual, but it would not be a form of Object-Oriented Programming

Object-Oriented Programming

If we are designing the same ball game with Object-Oriented thinking, we must instead consider what the game will have. We must recognize the presence of a ball, the presence of two players, and the presence of two nets. It is then necessary for us to decide what we need to know about the ball, the players, and the net. Finally, we can consider what the ball, player, and net will do by themselves, and how they can interact with each other. The problem here is that designing an Object-Oriented program takes much longer. However, Object-Oriented programs can save a lot of frustration when we start to add new features to our program - such as playing soccer with two balls for instance. 

Being that I have mostly taught myself to program for the past few years, I have become more accustomed to the Procedural style of programming. I don't believe that Procedural style is "wrong". In fact, it works fine in many cases, and can be a huge time saver for small programs. I am however, very interested in using the Object-Oriented method more often - which I am sure we will get to do more often in 148 than 108 - as it offers much cleaner code and can potentially save a lot of time when repeating objects.