Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Table Maker Class
#1
Hello everyone,

I've recently just started learning Python and programming as a whole and while tinkering with some MySQL and Python i noticed that MySQL outputs query results in a nice tabulated format and there was no such functionality in Python by default ( didn't know about modules like tabulate and pretty table and how to use them at that time Doh ), so i was striven to make something myself and i've put together some hacky/ slashy code to the best of my current ability while trying to learn how things like classes etc. work Tongue .

I know that the code looks bad and many things that could have been achieved using simpler/ better means were not. Please feel free to criticize the code as it will help me learn.

class tablemaker:
    """
    anylist :   Any list, tuple, set or string to be printed in ascii enclosed boxes (two dimensional maximum)
    title   :   Optional title for the list to be printed on top of the data
    headers :   Optional headers to be printed (Provide as a one dimensional list with each list item representing a column heading)
    """
    def __init__(self, provideddata, title, providedheaders):
        self.anydata=list(map(list,self.__all_strings(provideddata[:])))
        self.__addresses=self.__generate_addresses()
        self.title=title
        if isinstance(self.title,str) != True:
            raise TypeError('String expected for argument#2')
        self.headers=providedheaders
        if self.headers!="":
            self.headers=self.__all_strings(providedheaders)
        self.table=[]
        self.columns=0
        self.rows=0
        self.__process(self.__all_strings(self.anydata))

    def __generate_addresses(self):
        addressrange=[]
        maincounter=0
        innercounter=0
        for each in self.anydata:
            if isinstance(each,(list,tuple,set)):
                for eachinner in each:
                    addressrange.append([maincounter,innercounter])
                    innercounter=innercounter+1
                maincounter=maincounter+1
                innercounter=0
            else:
                addressrange.append([maincounter,innercounter])
                maincounter=maincounter+1
        return addressrange
        

    def value(self,r,c,value):
        if value!="":
            if [r,c] in self.__addresses:
                try:
                    self.anydata[r][c]=value
                except:
                    self.anydata[r]=value
            else:
                columnfound=[0,False]
                for loop in range(c,-1,-1):
                    if [r,loop] in self.__addresses:
                        columnfound=[loop,True]
                        break
                if columnfound[1]==True:
                    if not isinstance(self.anydata[r],list):
                        self.anydata[r]=[self.anydata[r]]
                    for loop in range(columnfound[0]+1,c):
                        self.anydata[r].append("")
                    self.anydata[r].append(value)
                else:
                    rowfound=[0,False]
                    for loop in range(r,-1,-1):
                        if [loop,0] in self.__addresses:
                            rowfound=[loop,True]
                            break
                    if rowfound[1]==True:
                        for loop in range(rowfound[0]+1,r+1):
                            self.anydata.append([])                            
                        for loop in range(1,c+1):
                            self.anydata[r].append("")
                        self.anydata[r].append(value)
            self.__addresses=self.__generate_addresses()
        else:
            raise ValueError('Invalid data provided in argument#3')

    def update(self):
        self.__process(self.__all_strings(self.anydata))
        
    def print(self):
        print("\n".join(self.table))

    def __all_strings(self,data):
        """Courtesy of Yoriz"""
        if type(data) == list:
            items = []
            for item in data:
                items.append(self.__all_strings(item))
            return items
        elif type(data) == tuple:
            return tuple(self.__all_strings(list(data)))
        elif type(data) == dict:
            new_dict = {}
            for key, value in data.items():
                new_dict[self.__all_strings(key)] = self.__all_strings(value)
            return new_dict
        elif type(data) == set:
            return set(self.__all_strings(list(data)))
        else:
            return str(data).strip()

    def __process(self,receivedlist):
        anylist=[]
        anylist=receivedlist[:]
        anylist=[i if i!=[] else "" for i in anylist]
        if len(anylist)>0:
            if self.headers!="":
                anylist.insert(0,self.headers)
            datalist=[]
            maxlen=len(self.title)
            collen=[]
            maxsubentry=1
            for entries in anylist:
                if isinstance(entries,(list,tuple)):
                    if len(entries)>maxsubentry:
                        maxsubentry=len(entries)
                    for subentry in entries:
                        if len(subentry)>maxlen:
                            maxlen=len(subentry)
                if len(entries)>maxlen:
                    maxlen=len(entries)
            collen=[0 for each in range(0,maxsubentry)]
            for entries in anylist:
                if isinstance(entries,(list,tuple)):
                    for subentry in entries:
                        if len(subentry)>collen[entries.index(subentry)]:
                            collen[entries.index(subentry)]=len(subentry)
                else:
                    if len(entries)>collen[0]:
                        collen[0]=len(entries)
            checklen=0
            for each in collen:
                checklen+=each
            if maxlen>checklen:
                collen[-1]=collen[-1]+(maxlen-checklen)
            else:
                maxlen=checklen
            if self.title!="":
                printstring="+"+"-"*(maxlen+maxsubentry-1)+"+"
                datalist.append(printstring)
                printstring="|"+self.title.upper()+" "*((maxlen+maxsubentry-1)-len(self.title))+"|"
                datalist.append(printstring)
                printstring="|"+"-"*(maxlen+maxsubentry-1)+"|"
                datalist.append(printstring)
            else:
                printstring="+"+"-"*(maxlen+maxsubentry-1)+"+"
                datalist.append(printstring)            
            for entries in anylist:
                if isinstance(entries,(list,tuple)):
                    printstring=""
                    counter=0
                    for subentry in entries:
                        printstring=printstring+"|"+subentry+" "*(collen[counter]-len(subentry))
                        counter+=1
                    if len(entries)<maxsubentry:
                        for count in range(len(entries)+1, maxsubentry+1):
                            printstring=printstring+"|"+" "*(collen[counter])
                            counter+=1
                    printstring=printstring+"|"
                    datalist.append(printstring)
                else:
                    printstring=""
                    printstring=printstring+"|"+entries+" "*(collen[0]-len(entries))
                    for count in range(0,maxsubentry-1):
                        printstring=printstring+"|"+" "*(collen[count+1])
                    printstring=printstring+"|"
                    datalist.append(printstring)
            printstring="+"+"-"*(maxlen+maxsubentry-1)+"+"
            datalist.append(printstring)
            if self.title!="":
                rowlen=len(datalist)-4
            else:
                rowlen=len(datalist)-2
            if self.headers!="":
                    rowlen=rowlen-1
            if self.headers!="":
                printstring="+"+"-"*(maxlen+maxsubentry-1)+"+"
                if self.title!="":
                    datalist.insert(4,printstring)
                else:
                    datalist.insert(2,printstring)
            self.table=datalist
            self.columns=len(collen)
            self.rows=rowlen
            return [datalist,len(collen),rowlen]
        else:
            raise ValueError('Invalid data provided in argument#1')

if __name__ == "__main__":
    citytable=tablemaker([["1","Tokyo","Japan","38,001,000"],
                          ["2","Delhi","India","25,703,168"],
                          ["3","Shanghai","China","23,704,778"],
                          ["4","Sao Paulo","Brazil","21,066,245"],
                          ["5","Mumbai","India","21,042,538"],
                          ["6","Mexico City","Mexico","20,998,543"],
                          ["7","Beijing","China","20,383,994"],
                          ["8","Osaka","China","20,237,645"],
                          ["9","Cairo","Egypt","18,771,769"]],
                         "Largest Cities by Population",
                         ["Rank","City","Country","Population"])
    citytable.print()
    print("\nUpdating incorrect value at row 6, column 2 i.e. China to Japan\n")
    citytable.value(6,2,"Japan")
    citytable.update()
    citytable.print()
    #print(citytable.table)
Cheers,
iMu
Reply


Messages In This Thread
Table Maker Class - by iMuny - Apr-09-2019, 08:00 AM
RE: Table Maker Class - by Gribouillis - Apr-09-2019, 09:03 AM
RE: Table Maker Class - by iMuny - Apr-09-2019, 09:23 AM
RE: Table Maker Class - by Ceegen - Apr-09-2019, 08:39 PM
RE: Table Maker Class - by iMuny - Apr-10-2019, 02:34 PM
RE: Table Maker Class - by Ceegen - Apr-12-2019, 11:02 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Extremely Simple RPG Character File Maker ashtons 0 2,386 Jan-09-2018, 10:46 PM
Last Post: ashtons

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020