Creating an Excel sheet with random data table and Python

Today in my Statistics class we were using Excel to create tables of random numbers.
I don't know a ton about excel yet, so there may be a WAY easier way to set this up in Excel.
The problem in class was:  Every time you changed a cell in the excel file, the random numbers would refresh, and change.   If this was a real table we wanted to use to get actual statistics, we would want this table to stay,  and we would want to be able to save it for future reference.




So in class, I started tinkering.
After I got home, cut my dad's wonky hair, and fed myself some yummy broccoli salad, I sat down to make this code up.

It uses Python to create a random list of numbers.
Then it takes that random list of numbers, a size for columns and rows, and uses a formula I found on stackOverflow to write that array to an excel file.

It will also check to make sure all data is compatible.

If you want a 5 rows of 10 items each, the total length of the initial random numbers list should be 50.
If you want 3 by 6 = 18
ect....
So it checks for that too.
Currently this code only saves the xlxs file to the current directory.  And a reminder, I don't know a ton about Excel yet.  I'm not sure if you can save an xlxs(excel) file to a non windows computer.  I imagine you can, but I'm not sure how your going to look at it without excel.

If this all works out like I think it will,  I may be switching that prior experiment from using pandas to using excel.  We'll see.  I should do both.  Why not?

Code:
________start code block______________

import random
import xlsxwriter
import os


class modRandom(object):
    def __init__(self, bottom, top, unit_type=None):
        self.bottom = bottom
        self.top = top
        self.unit_type = unit_type

    def get_rand(self):
        if self.unit_type != 'float':
            print(random.randrange(self.bottom, self.top))
            return random.randrange(self.bottom, self.top)
        else:
            print("None is not a float")
            #return random.uniform(self.bottom, self.top)

    def return_list_of(self, max):
        if type(max) != int:
            message = "count entered for return_list_of(max) needs to be a whole positive integer."
            print(message)
            raise TypeError
        else:
            alist = []
            count = 0
            while count < max:
                new = self.get_rand()
                alist.append(new)
                count += 1

            return alist or None

 ###########    stackOverflow: https://stackoverflow.com/questions/31909722/how-to-write-python-array-into-excel-spread-sheet ####
        # import xlsxwriter

        #workbook = xlsxwriter.Workbook('arrays.xlsx')
        #worksheet = workbook.add_worksheet()

#       array = [['a1', 'a2', 'a3'],
         #  ['a4', 'a5', 'a6'],
         #  ['a7', 'a8', 'a9'],
         #  ['a10', 'a11', 'a12', 'a13', 'a14']]

#       row = 0

#       for col, data in enumerate(array):
#       worksheet.write_column(row, col, data)

#       workbook.close()

####################################
        

class CreateRandData(object):
    def __init__(self, row, col, data, file_name=None):
        self.row = row
        self.col = col
        self.data = data # a list from python class: modRandom(object)
        self.file_name = file_name
    
    def check_row_col(self):
        # make sure row and col are whole integer numbers
        if type(self.row) == int and type(self.col) == int:
            return True
        else:
            return False

    def check_length(self):
        # row * column should equal the length of list.
        # if it's a 4 by 10 grid of 40 items.  With either row as 4, column by 10 or visa versa
        # the length needs to be 40.
        if type(self.data) != list:
            message="The data given for CreateRandData(row, col, data) is not the proper length.\nLength should equal the number of rows multiplied by number of columns."
            print(message)
            return TypeError
        else:
            length = len(self.data)
            if length <= 0:
                message = "The python list -data argument- is empty.\nCheck to make sure list was populated before initiating CreateRandData(row, col, data)."
                print(message)
                return ValueError
            elif not self.check_row_col(): 
                message = "The col and row arguements must be whole integer values above 0."
                print(message)
                print("col = ", self.col)
                print("row = ", self.row)
                raise ValueError
            else:
                # now check that row * col is equal to length of list:
                total = self.row * self.col
                if length == total:
                    # tests pass continue
                    message = f"Your data will be put in a {self.row} by {self.col} grid."
                    print(message)
                    return True
                else:
                    print("The length of data is not equal to the size of grid (row * col).\nFormat=CreateRandData(row, col, data)")
                    raise ValueError


    def make_array(self):
        ## CHECK THAT DATA, COL, and ROW will be compatible
        if self.check_length():
            new_array = []
            ##-----------------------------------##
            ##     col1    col2    col3    col4  ##
            #------------------------------------##
            #row1    [a1,    a2,    a3,     a4]  ##
            #row2    [b1,    b2,    b3,     b4]  ##
            #row3    [c1,    c2,    c3,     c4]  ##
            #row4        [...]
            # we just need to start a new sub list once we reach column count.  This is length of row.
            max_len = self.col
            count = 0
            nums = []
            for num in self.data:
                nums.append(num)
                count += 1
                if count >= max_len:
                    new_array.append(nums)
                    nums = []
                    count = 0
            return new_array
           
    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
        array = self.make_array()
        ### printing in terminal:
        if self.file_name == None:
            print("No file name given to create.")
            for item in array:
                print(item)
        else:
            
            file_name = self.file_name + '.xlsx'
            workbook = xlsxwriter.Workbook(file_name) #name your file here
            worksheet = workbook.add_worksheet()
            row = 0

            for col, data in enumerate(array):
               worksheet.write_column(row, col, data)
            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()
            


        ###  MANUAL TESTS ###
def test1():
    new_rand_data = modRandom(1, 20)
    rand_list = new_rand_data.return_list_of(3)
    col = 1
    row = 3
    x = CreateRandData(row, col, rand_list)
    x.write()

def test2():
    new_rand_data = modRandom(1, 100)
    rand_list = new_rand_data.return_list_of(20)
    col = 4
    row = 5
    x = CreateRandData(row, col, rand_list)
    x.write()

def test3():
    new_rand_data = modRandom(1, 50)
    rand_list = new_rand_data.return_list_of(50)
    col = 5
    row = 10
    x = CreateRandData(row, col, rand_list, "testing1")
    x.write()
test3()












Comments

Popular posts from this blog

playing with color in powershell python

JavaScript Ascii animation with while loops and console.log

playing with trigonometry sin in pygame