Inheritance

Using a more realistic example with "Streams". In software development streams are used to communicate information. Sometimes they may be user input, files, or something else entirely.

The goal with these "Streams" is to convey a more realistic use for class inheritance.

Less realistic example first


In [73]:
class Animal:
    
    def __init__(self, name):
        self.name = name
    
    def pretty_version(self):
        return self.name
    
    def speak(self):
        pass
    
    def __str__(self):
        return '{} says {}'.format(self.pretty_version(), self.speak())
    

class Mammal(Animal):
    
    def __init__(self, name):
        super().__init__(name)
        self.classification = 'mammal'
    
    def pretty_version(self):
        return '{} of classification {}'.format(self.name, self.classification)

some_animal = Mammal('Some Name')

print(some_animal.speak())
print(some_animal)


None
Some Name of classification mammal says None

In [74]:
class Dog(Mammal):
    
    def speak(self):
        return 'bark'
    

dog_names = ['Rover', 'Carl', 'Sally', 'Baxter']

for name in dog_names:
    new_dog = Dog(name)
    
    print(new_dog.speak())
    print(new_dog,'\n')


bark
Rover of classification mammal says bark 

bark
Carl of classification mammal says bark 

bark
Sally of classification mammal says bark 

bark
Baxter of classification mammal says bark 


In [86]:
class WildCat:
    def __init__(self, name):
        
        self.name = name
    
    def speak(self):
        return 'RAWR'
        
    def __str__(self):
        return self.name

    
class DemesticCat(WildCat):
    
    def speak(self):
        return 'meow'

class BadSuperHouseCat(DemesticCat):
    
    def speak(self):
        return WildCat.speak(self)

    
class GoodSuperHouseCat(DemesticCat):
    
    def speak(self):
        return super().speak()


        
bad_super_cat = BadSuperHouseCat('bill')

print('bad cat call', bad_super_cat.speak())

good_super_cat = GoodSuperHouseCat('bill')

print('good cat call', good_super_cat.speak())


bad cat call RAWR
good cat call meow

In [92]:
class Default():
    pass

second_arg = Default
first_arg = Animal('meow')
"{name} says they like {sound}".format(
    name=first_arg, 
    sound=second_arg)


Out[92]:
"meow says None says they like <class '__main__.Default'>"

Using Read Streams


In [93]:
class ReadStream:
    """
    Base class for reading data.
    """
    def __init__(self, source=None):
        self.source = source
    
    def read(self):
        raise NotImplementedError('The sub class must implement the `read` method')
    
    def print_read(self):
        print(self.read())

read_stream_instance = ReadStream('some data')

read_stream_instance.print_read()


------------------------------------------
NotImplementedErrorTraceback (most recent call last)
<ipython-input-93-a6c1b0de25a5> in <module>()
     14 read_stream_instance = ReadStream('some data')
     15 
---> 16 read_stream_instance.print_read()

<ipython-input-93-a6c1b0de25a5> in print_read(self)
     10 
     11     def print_read(self):
---> 12         print(self.read())
     13 
     14 read_stream_instance = ReadStream('some data')

<ipython-input-93-a6c1b0de25a5> in read(self)
      7 
      8     def read(self):
----> 9         raise NotImplementedError('The sub class must implement the `read` method')
     10 
     11     def print_read(self):

NotImplementedError: The sub class must implement the `read` method

Using standard input as the read


In [94]:
class InputReadStream(ReadStream):
    """
    Used to read data from standard input
    """    
    def read(self):
        return input(self.source)


input_read_stream_instance = InputReadStream('How many dogs do you want? ')


input_read_stream_instance.print_read()


How many dogs do you want? I want a lot dogs
I want a lot dogs

Input with a URL


In [95]:
import requests # This is a library used to make HTTP web requests

class UrlReadStream(ReadStream):
    """
    Used to read data from a URL
    """
    
    def read(self):
        return requests.get(self.source).text

    
url_read_stream_instance = UrlReadStream('https://goo.gl/r7BDx9')



url_read_stream_instance.print_read()


Small example text from the internet.

Input using a file


In [96]:
class FileReadStream(ReadStream):
    """
    Used to read data from a URL
    """
    
    def read(self):
        return open(self.source, 'r').read()


# This works because there is a file within this directory called `smimple_text.txt`
file_read_stream_instance = FileReadStream('simple_text.txt')

file_read_stream_instance.print_read()


Some simple text in a file

Using Write Streams


In [98]:
class WriteStream:
    """
    Base class for writing data.
    """
    def __init__(self, source_data, destination=None):
        self.source_data = source_data
        self.destination = destination
    
    def write(self):
        raise NotImplementedError('Subclass must implement `write` method')


write_stream_instance = WriteStream('some_source_data', 'sample_output_file.txt')

write_stream_instance.write()


------------------------------------------
NotImplementedErrorTraceback (most recent call last)
<ipython-input-98-2a113fc6b76c> in <module>()
     13 write_stream_instance = WriteStream('some_source_data', 'sample_output_file.txt')
     14 
---> 15 write_stream_instance.write()

<ipython-input-98-2a113fc6b76c> in write(self)
      8 
      9     def write(self):
---> 10         raise NotImplementedError('Subclass must implement `write` method')
     11 
     12 

NotImplementedError: Subclass must implement `write` method

Writing to standard out


In [99]:
import sys
class OutputWriteStream(WriteStream):
    """
    Used to write data to a file
    """    
    def write(self):
        sys.stdout.write(self.source_data)

file_write_stream_instance = OutputWriteStream('some little data')

file_write_stream_instance.write()


some little data

Writing to a file


In [102]:
class FileWriteStream(WriteStream):
    """
    Used to write data to standard out
    """    
    def write(self):
        file = open(self.destination, 'w')
        file.write(self.source_data)
        print('Wrote to file: {}'.format(self.destination))

output_write_stream_instance = FileWriteStream('some other data that I wrote', 'sample_output_file.txt')

output_write_stream_instance.write()


Wrote to file: sample_output_file.txt

In [103]:
## Read the sample output file

file_name = 'sample_output_file.txt'

sample_output_file = FileReadStream(file_name)

sample_output_file.print_read()


some other data that I wrote

Read and Write to file in one class


In [104]:
class CopyFile:
    
    def __init__(self, read_file, write_file):
        self.read_file = read_file
        self.write_file = write_file
        
    def copy(self):
        read_file = FileReadStream(self.read_file)
        write_file = FileWriteStream(read_file.read(), self.write_file)
        write_file.write()
        
source_file_name = 'simple_copy_data.txt'
destination_file_name = 'simple_copy_of_data_file.txt'

# Create the first file
new_sample_file = FileWriteStream('Some data that needs to be copied', source_file_name)
new_sample_file.write()

# First have to write to the `destination_file_name` so it can be read
destination_file_writer = FileWriteStream('baby data', destination_file_name)
destination_file_writer.write()

# Show the desitnation file has nothing in it
print('\nThe data in the destiation file reads:')
destination_file_reader = FileReadStream(destination_file_name)
destination_file_reader.print_read()


# Copy the data from one file to the other
copy_file_instance = CopyFile(source_file_name, destination_file_name)
print()
copy_file_instance.copy()
print('\nThe data in the destiation file reads:')
destination_file_reader.print_read()


Wrote to file: simple_copy_data.txt
Wrote to file: simple_copy_of_data_file.txt

The data in the destiation file reads:
baby data

Wrote to file: simple_copy_of_data_file.txt

The data in the destiation file reads:
Some data that needs to be copied

In [114]:
class BaseClass:
    def some_func(self):
        print('hi')
        
class SubClass:
    def some_func(self):
        print(self)
        BaseClass.some_func(self)
    
    def __str__(self):
        return 'meow cats {}'.format(id(self))
    
    def return_self(self):
        return self
        
BaseClass.some_func('asdlkjasdfj')
my_sub_class = SubClass()

my_sub_class.some_func()

print(id(my_sub_class))

print(my_sub_class is my_sub_class.return_self())


hi
meow cats 4556727688
hi
4556727688
True

In [117]:
class Post:
    def __init__(self, title, author, body):
        self.title = title
        self.author = author
        self.body = body
        self.likes = 0

    def like(self):
        self.likes += 1

    def __str__(self):
        return self.title + " by " + self.author


class VideoPost(Post):
    def __init__(self, title, author, url):
        super().__init__(title, author, None)
        self.video_url = url
        self.plays = 0

    def play(self):
        self.plays += 1

    def __str__(self):
        return self.title + " played " + str(self.plays) + " times"

    
# Little Scream - Love As a Weapon played 2 times
# 10 Best Albums of 2016 by Chris Bay
# Cats in space by Crystal Martin
# LaunchCode's LC101: https://www.launchcode.org/lc101

# TODO - create ImagePost class based on class diagram
# file_name 

class ImagePost(Post):
    def __init__(self, title, author, file_name):
        super().__init__(title, author, None)
        self.file_name = file_name

# TODO - create LinkPost class based on class diagram
# url attribute
# click method
# clicks attribute

class LinkPost(Post):
    def __init__(self, title, author, url):
        super().__init__(title, author, None)
        self.url = url
        self.clicks = 0

    def click(self):
        self.clicks += 1

    def __str__(self):
        return self.title + ': ' + self.url

plain_post = Post("10 Best Albums of 2016", "Chris Bay", "1. Little Scream - Cult Following 2. ...")
vid_post = VideoPost("Little Scream - Love As a Weapon", "Chris Bay", "https://youtu.be/Tq4Vw4MB6eA")
pic_post = ImagePost("Cats in space", "Crystal Martin", "spacecats.gif")
url_post = LinkPost("LaunchCode's LC101", "LaunchCode Staff", "https://www.launchcode.org/lc101")

vid_post.play()
vid_post.play()
url_post.click()

print(vid_post)
print(plain_post)
print(pic_post)
print(url_post)

# Little Scream - Love As a Weapon played 2 times
# 10 Best Albums of 2016 by Chris Bay
# Cats in space by Crystal Martin
# LaunchCode's LC101: https://www.launchcode.org/lc101


Little Scream - Love As a Weapon played 2 times
10 Best Albums of 2016 by Chris Bay
Cats in space by Crystal Martin
LaunchCode's LC101: https://www.launchcode.org/lc101

In [ ]: