Statistics, Python, Making a Stem Plot

I'm doing homework, and the book is covering Stem plots.
Well when I looked up stem plots, there were tons of options.
Look at MatPlotLib's stem plots:
https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.stem.html

I mean.  Wait wait wait.... My book has something like this:

STEM                   LEAF
1                            2, 3, 4
2                            5, 6, 8
3                            1, 3, 5



So,  what do I do when I can't visualize the data? 
I code.  And I glue it inside my teflon brain with that code.
This is how I learn, but it isn't necessarily how any one else does.

Pictures:  top= picture of excel file with stem plot.
bottom= picture of stem plot printed in terminal
           














"If a fish spends its life being judged by how it climbs a tree......... Will it ever swim?"

So here's today's code. 
A note:  I haven't found a specific purpose for the 'leaves' yet.  But I have a feeling there is one.
So that initiated attribute in the MakeStemPlot class is not used in the code yet.

As always,  feel free to comment.
Break it, share it, modify it, keep it, have fun.

**** Code block ****

# stem plot
import xlsxwriter
import os


#####          -----------               ########
#       Print a stem plot to terminal           # 
#####          -----------               ########


# copy past the data, this one had ; instead of commas.  Find-replace-all ; with , to make the list.
scores = [33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74, 78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100]

# first digit will be the stem.
def get_stem_leaf(alist):
    if type(alist) != list:
        message = "arguement alist in get_stem_leaf(alist) must be a list."
        print(message)
        raise TypeError
    if len(alist) <= 0:
        message = "length of alist:list in get_stem_leaf(alist) can not be 0."
        print(message)
        raise ValueError
    #make sure original list is in ascending order:
    alist.sort()
    stems = []
    leaves = []
    for number in alist:
        if type(number) != int:
            message = "items in alist:list for get_stem_leaf(alist) must be two digit integers."
            print(message)
            raise TypeError
        number = str(number)
        # conversion to string, or integer is not subscribable
        stem = number[0]
        leaf = number[1]
        # convert back to int and append to lists
        stem = int(stem)
        leaf = int(leaf)
        stems.append(stem)
        leaves.append(leaf)
    return stems, leaves


class MakeStemPlot(object):
    def __init__(self, stems, leaves, original, file_name=None):
        self.stems = stems
        self.leaves = leaves
        self.original = original
        self.verified = False
        self.file_name = file_name

    def check_branches(self):
        if self.verified:
            print("stems and leaves have been previously verified.")
            return True
        else:
            if type(self.stems) != list or type(self.leaves) != list:
                print("stems & leaves initializing value should be a list of single digit integers. Can not be empty.")
                print("lists are not verified.")
                return False
            if len(self.stems) <= 0 or len(self.leaves) <= 0:
                print("stems & leaves initializing value should be a list of single digit integers. Can not be empty.")
                print("lists are not verified.")
                return False
            for num in self.stems:
                if type(num) != int:
                    print("stems list could not be verified as integers only.")
                    return False
                if num < 0 or num >= 10:
                    print("stems are less than 0, or greater than equal to 10.  One digit integers only allowed.")
                    return False
            for num in self.leaves:
                if type(num) != int:
                    print("leaves list could not be verified as integers only.")
                    return False
                if num < 0 or num >= 10:
                    print("leaves are less than 0, or greater than equal to 10.  only one digit integers are allowed.")
                    return False
            print("Stems and leaves lists are acceptable.  Verification set to: True")
            self.verified = True
            return True
               
    def write(self):
        #test that data is usable: 
        #if self.check_length fails in the make array method, it will fail to the Error and message will be printed
        if not self.check_branches():
            print("Check branches failed, can not proceed with MakeStemPlot.write()")
            raise AssertionError
        ### printing in terminal:
        if self.file_name == None:
            print("No file name given to create.")
            index = 0
            new_set = set(self.stems)
            # make dictionary holding set items, with a None as value until it can be set.
            plot_dict = {}
            for item in new_set:
                plot_dict[item] = []
            #print(plot_dict)
           
        
            for nums in self.original:
               number = str(nums)
               num1 = number[0]
               num2 = number[1]               
               num1 = int(num1)
               num2 = int(num2)
               num_list = plot_dict.get(num1)
               num_list.append(num2)
               plot_dict[num1] = num_list

            #print it pretty.
            for key in plot_dict:
                print(key, plot_dict.get(key)) 
            return True

        else:
            new_set = set(self.stems)
            # make dictionary holding set items, with a None as value until it can be set.
            #print(plot_dict)
            ####  put the stems and leaves in the dict.
            plot_dict = {}
            for item in new_set:
                plot_dict[item] = []
                
            for nums in self.original:
               number = str(nums)
               num1 = number[0]
               num2 = number[1]               
               num1 = int(num1)
               num2 = int(num2)
               num_list = plot_dict.get(num1)
               num_list.append(num2)
               plot_dict[num1] = num_list
            ####

            file_name = self.file_name + '.xlsx'
            workbook = xlsxwriter.Workbook(file_name) #name your file here
            worksheet = workbook.add_worksheet()
            row = 0
            col = 0
            for key in plot_dict:
                data = plot_dict.get(key) 
                # row column data
                astring = ""
                for item in data:
                    astring += "  "
                    astring += str(item)
                worksheet.write(row, col + 1, astring)
                worksheet.write(row, col, key)
                row += 1
                

            print(f"file created under file name: {file_name}")
            Current_path = os.getcwd()
            print("file is currently saved in this directory: ", Current_path)
            workbook.close()

            return True


    def print_stems(self):
        if self.check_branches():
            stem_set = set(self.stems)
            print("  ~  " * 10)
            print("Stem set : ", stem_set)
            print("  ~  " * 10)
            length = len(self.original)
            print("length of original data: ", length)
            print("  ~  " * 10)
            length_a = len(stem_set)
            length_b = len(self.leaves)
            message = "There are " + str(length_a) + " stems and " + str(length_b) + " leaves."
            print(message)
            print("\n  ~  ~  ~  ~  ~  ~  ~  END  ~  ~  ~  ~  ~  ~\n")
            return True
        else:
            return False


        


def run_all_tests():
    test1()
    print("\n\n\t\t ************")
    test2()
    print("\n\n\t\t ************")
    test3()
    print("\n\n\t\t ************")
    test4()
    print("\n\n\t\t ************")
    test5()
    print("\n\n\t\t ************")
    test6()
    print("\n\n\t\t ************")
    test7()
    print("\n\n\t\t ************")
    test8()
    print("\n\n\t\t ************")
    test9()





def test1():
    x,y = get_stem_leaf(scores)
    print("printing stems: ")
    print("~" * 10)
    print(x)
    print("printing leaves: ")
    print("~" * 10)
    print(y)

def test2():
    #test1()
    print("~" * 20)
    print("Test 2 -- Verifing good lists pass check.")
    print("~" * 20)
    x,y = get_stem_leaf(scores)
    new_stem_plot = MakeStemPlot(x, y, scores)
    x = new_stem_plot.check_branches()
    assert x == True

def test3():
    print("~" * 20)
    print("Test 3 -- Verifing empty lists fail check.")
    print("~" * 20)
    bad_list1 = []
    bad_list2 = []
    new_stem_plot = MakeStemPlot(bad_list1, bad_list2, scores)
    y = new_stem_plot.check_branches()
    assert y == False


def test4():
    print("~" * 20)
    print("Test 4 -- Verifing non integer lists fail check.")
    print("~" * 20)
    bad_list1 = ['a', 'b', 'c']
    bad_list2 = ['cd', 'ef', 'gh']
    new_stem_plot = MakeStemPlot(bad_list1, bad_list2, scores)
    y = new_stem_plot.check_branches()
    assert y == False
   
def test5():
    print("~" * 20)
    print("Test 5 -- Verifing non-single-digit integer lists fail check.")
    print("~" * 20)
    bad_list1 = [22, 11, 33]
    bad_list2 = [2, 3, 99]
    new_stem_plot = MakeStemPlot(bad_list1, bad_list2, scores)
    y = new_stem_plot.check_branches()
    assert y == False


def test6():
    print("~" * 20)
    print("Test 6 -- Verifing MakeStemPlot.write will create set from scores and print.")
    print("Test 6 -- check_branches has been previously tested, will raise error return false on incompatible lists/types.")
    print("~" * 20)
    x,y = get_stem_leaf(scores)
    new_stem_plot = MakeStemPlot(x, y, scores)
    x = new_stem_plot.write()
    assert x == True

def test7():
    print("~" * 20)
    print("Test 7 -- see that original list is being separated into dictionary properly.")
    print("~" * 20)
    x,y = get_stem_leaf(scores)
    new_stem_plot = MakeStemPlot(x, y, scores)
    x = new_stem_plot.write()
    assert x == True

def test8():
    print("~" * 20)
    print("Test 8 -- print information on given stems. Fail if check_branches fails.")
    print("~" * 20)
    x,y = get_stem_leaf(scores)
    new_stem_plot = MakeStemPlot(x, y, scores)
    x = new_stem_plot.print_stems()
    assert x == True


def test9():
    """
    Window's will block the write function to an existing file if you don't have permission.
    Remeber if you need to,  to change the file name on each test.  Delete old files
    """
    print("~" * 20)
    print("Test 9 -- run MakeStemPlot.write() with file_name and valid data.")
    print("~" * 20)
    x,y = get_stem_leaf(scores)
    new_stem_plot = MakeStemPlot(x, y, scores, "TEST9-E") # file name to change

    new_stem_plot.write()

# run all tests to see it in action:   
run_all_tests()


*****

Comments

Popular posts from this blog

Pandas Python and a little probability

parenting, learning, and code