### 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
leaf = number
# 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
num2 = number
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
num2 = number
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
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)
y = new_stem_plot.check_branches()
assert y == False

def test4():
print("~" * 20)
print("Test 4 -- Verifing non integer lists fail check.")
print("~" * 20)
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)
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()

``````

*****