diff --git a/markdowntable/__init__.py b/markdowntable/__init__.py index 8da9390..db41809 100644 --- a/markdowntable/__init__.py +++ b/markdowntable/__init__.py @@ -1,285 +1,5 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +from __future__ import print_function, unicode_literals -from __future__ import absolute_import, print_function, unicode_literals - -from .exceptions import (SuppressedError, - TooManyValues) -from .messages import (not_enough_values, - overwrite_message, - no_more_rows) - - -# Todo: Add remove_column and remove row - - -class Table: - """docstring for Table. - This is the main class. It adds rows and columns, with data - - Usage: - - >>> t = Table('name') - - >>> t.all_columns('column_name') - - >>> t.add_row([value, value, value, ...]) - - >>> table_code = t.table #gets table code - - """ - - def __init__(self, name: str, debug: bool = True): # creates self variables - """ - The initiator of the Table() class. Creates all the initial self values - - :type name: str - :type debug: bool - :param name: The name of the first column - :param debug: Do you want to enable debug function? - """ - super(Table, self).__init__() # idk - self.to_debug = debug # debug? - self.rows = 0 # rows - self.columns = 1 # columns - self.table = '''|{}|'''.format(str(name)) - self.finalized = False - if self.to_debug: - self.functions = [] - self.finalized_run = False - - def debug(self, print_d=True): - """ - - :raise: SuppressedError - :type print_d: bool - :param print_d: Print the debug or return as string - :return: The debug value - :rtype: str - """ - global debugmessage - try: - debugmessage = '''Printing debug information: - Rows: {rows} - Columns: {cols} - Finalized?: {fin} - Table Content: {table} - Functions: {funcs}'''.format(rows=str(self.rows), - cols=str(self.columns), - fin=str(self.finalized), - table=self.table, - funcs=self.functions) - if print_d: - print(debugmessage) - else: - return debugmessage - except NameError: - pass - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), debugmessage) - - def add_column(self, name: str, all_cols: bool = False): - """ - Adds a column to the table. Must be used before adding rows. - - :type all_cols: bool - :type name: str - :param name: The name of the columns - :param all_cols: Determines if all_columns() called add_column() - :return: Nothing - :rtype: None - :raise: SuppressedError - """ - self.columns += 1 - self.table += '{}|'.format(str(name)) - try: - if all_cols: - return {'function': 'add_column', 'data': [str(name)]} - else: - self.functions.append({'function': 'add_column', 'data': [str(name)]}) - except NameError: - pass - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def all_columns(self, *args): - """ - Adds all columns, as many as you want - - :type args: str - :param args: The names of every column. Can be a list - :return: Nothing - :rtype: None - :raise: SuppressedError - """ - if isinstance(args[0], list): - self.all_columns_with_list(args[0]) - else: - try: - all_col_data = {'function': 'all_columns', 'data': []} - for value in args: - all_col_data['data'].append(self.add_column(str(value), all_cols=True)) - self.functions.append(all_col_data) - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def all_columns_with_list(self, list): - """ - - :param list: list - :return: None - """ - try: - all_col_data = {'function': 'all_columns', 'data': []} - for value in list: - all_col_data['data'].append(self.add_column(str(value), all_cols=True)) - self.functions.append(all_col_data) - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def finalize_cols(self): - """ - Finalizes columns. Can be called manually, but usually called by the first add_row() argument. - - :return: Nothing - :rtype: None - :raise: SuppressedError - """ - try: - finalizer = '\n|' - for i in range(self.columns): - finalizer += '---|' - self.table += finalizer - self.functions.append({'function': 'finalize_cols', 'data': finalizer}) - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def add_row(self, *args, show_warning_message: bool = True): - """ - Adds rows, one for each arg. A row may be in string or list form. If too little arguments are in the list, - then the rest will be blanked. If there are too many errors, an exception will be raised. - - :type args: str - :type show_warning_message: bool - :param show_warning_message: Shows warning messages if there is an exception. - :param args: The values for the row. - :return: Nothing - :rtype: None - :raises: SuppressedError, TooManyValues - """ - if isinstance(args[0], list): - self.add_row_with_list(args[0], show_warning_message=show_warning_message) - else: - try: - if self.finalized_run: - self.finalized_run = False - if not self.finalized: - self.finalize_cols() - self.finalized_run = True - self.finalized = True - add_row_data = {'function': 'add_row', - 'data': {'finalized_run': self.finalized_run, - 'show_warning_message': show_warning_message, - 'values': []}} - self.rows += 1 - row = '|' - rows_made = 0 - for i in range(int(len(args))): - row += '{}|'.format(str(args[i])) - rows_made += 1 - add_row_data['data']['values'].append(args[i]) - if self.columns > rows_made: - if show_warning_message: - print(not_enough_values(rows_made, self.columns)) - add_row_data['data']['message_shown'] = True - for i in range(int(self.columns - rows_made)): - row += ' |' - # noinspection PyTypeChecker - add_row_data['data']['values'].append('{} blank values added'.format(str(self.columns - rows_made))) - elif self.columns < rows_made: - raise TooManyValues(self.columns) - self.table += '\n{}'.format(row) - self.functions.append(add_row_data) - except TooManyValues: - raise - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def add_row_with_list(self, li: list, show_warning_message: bool = True): - """ - Adds a row based on a list. - - :type show_warning_message: bool - :type li: list - :param show_warning_message: Shows the debug message if there is an exception. - :param li: The list to be used to add values - :return: Nothing - :rtype: None - :raise: SuppressedError - """ - try: - if self.finalized_run: - self.finalized_run = False - if not self.finalized: - self.finalize_cols() - self.finalized_run = True - self.finalized = True - add_row_data = {'function': 'add_row', - 'data': {'finalized_run': self.finalized_run, - 'show_warning_message': show_warning_message, - 'values': []}} - self.rows += 1 - row = '|' - rows_made = 0 - for i in range(int(len(li))): - row += '{}|'.format(str(li[i])) - rows_made += 1 - add_row_data['data']['values'].append(li[i]) - if self.columns > rows_made: - if show_warning_message: - print(not_enough_values(rows_made, self.columns)) - add_row_data['data']['message_shown'] = True - for i in range(int(self.columns - rows_made)): - row += ' |' - # noinspection PyTypeChecker - add_row_data['data']['values'].append('{} blank values added'.format(str(self.columns - rows_made))) - elif self.columns < rows_made: - raise TooManyValues(self.columns) - self.table += '\n{}'.format(row) - self.functions.append(add_row_data) - except TooManyValues: - raise - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) - - def remove_row(self): - lines = self.table.split('\n') - last_line = lines[len(lines)] - new_table = '' - if '|---|' not in last_line: - lines.remove(lines[len(lines)]) - for line in lines: - new_table += line + '\n' - else: - print(no_more_rows) - - def export_table_to_file(self, filename: str = 'markdowntable', extension: str = 'txt', mode: str = 'w'): - """ - - :type mode: str - :type extension: str - :type filename: str - :param filename: The filename to use - :param extension: The extension to use - :param mode: The mode to write in, usually write and read - :return: Nothing - :rtype: None - :raise: SuppressedError - """ - try: - with open('{fname}.{ext}'.format(fname=str(filename), ext=str(extension)), str(mode)) as file: - file.write(self.table) - self.functions.append({'function': 'export_table_to_file', - 'data': {'filename': filename, 'extension': extension, 'writemode': mode}}) - except Exception as e: - raise SuppressedError(type(e).__name__, str(e), self.debug(print_d=False)) +import markdowntable.errors +from markdowntable.row import Row, Column +from markdowntable.table import Table diff --git a/markdowntable/errors.py b/markdowntable/errors.py new file mode 100644 index 0000000..3a354fd --- /dev/null +++ b/markdowntable/errors.py @@ -0,0 +1,71 @@ +"""This class defines all exceptions used by the module.""" + +from __future__ import unicode_literals + + +class MarkdownTableException(ValueError): + """This class is the base exception class for all exceptions in the module.""" + + +class DeletingOnlyException(MarkdownTableException): + """This class is the base exception class for exceptions that involve deleting a value that cannot be deleted.""" + + +class DeletingOnlyValueException(DeletingOnlyException): + """This class is for the exception of deleting the only value in a column.""" + + def __init__(self): + super(DeletingOnlyValueException, self).__init__('You tried deleting the only value in the column. To access ' + 'the value, do col[0]') + + +class DeletingOnlyColumnException(DeletingOnlyException): + """This class is for the exception of deleting the only column in a table""" + + def __init__(self): + super(DeletingOnlyColumnException, self).__init__('You tried deleting the only column in the table. To access ' + 'the column, do table[0]') + + +class InvalidException(MarkdownTableException): + """This class is the base exception class for exceptions that involve not having the same amount of values in a row + as the amount of values in the column.""" + + def __init__(self, rnum, expected, actual, val=''): + """Initializes the class + + Parameters: + :param int rnum: The row number + :param int expected: The expected values + :param int actual: The actual values + """ + super(InvalidException, self).__init__('Row number %d contains too %s values. It needs to contain %d values' + ', but contains %d values.' % (rnum, val, expected, actual)) + + +class TooLittleValuesException(InvalidException): + """This exception is for when there are too little values in a row.""" + + def __init__(self, rnum, expected, actual): + """Initializes the class + + Parameters: + :param int rnum: The row number + :param int expected: The expected values + :param int actual: The actual values + """ + super(TooLittleValuesException, self).__init__(rnum, expected, actual, 'little') + + +class TooManyValuesException(InvalidException): + """This exception is for when there are too many values in a row.""" + + def __init__(self, rnum, expected, actual): + """Initializes the class + + Parameters: + :param int rnum: The row number + :param int expected: The expected values + :param int actual: The actual values + """ + super(TooManyValuesException, self).__init__(rnum, expected, actual, 'many') diff --git a/markdowntable/exceptions.py b/markdowntable/exceptions.py deleted file mode 100644 index 0eef186..0000000 --- a/markdowntable/exceptions.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import unicode_literals - - -class MarkdownTableException(Exception): - """ - Base class exception for all exceptions in the module. - """ - def __init__(self, debug): - """ - The initiator - - :type debug: str - :param debug: Debug information from Table().debug() - :return: Nothing - :rtype: None - """ - Exception.__init__(self, - 'There is an error with your Markdown Table. Printing debug information. \n {debug}'.format( - debug=debug)) - - -class SuppressedError(MarkdownTableException): - """docstring for SuppressedError. The error is raised when an actual error is called, along with debug info.""" - - def __init__(self, error, message, debug): - """ - The initiator. - - :type error: str - :type message: str - :type debug: str - :param error: The error name - :param message: The error message - :param debug: Debug info from Table().debug() - """ - Exception.__init__(self, '''An error has occured. Printing error. information: - Error Name: {n} - Error Message: {m} - Debug Info: {d}'''.format(n=error, m=message, d=debug)) - - -class TooManyValues(MarkdownTableException): - """ - The error is raised when row info has more values than columns - """ - def __init__(self, columns): - """ - The initiator. - - :param columns: The amount of columns - :return: Nothing - :rtype: None - """ - Exception.__init__(self, - 'You entered in too many row values. Please only enter {} row names.'.format(str(columns))) - - diff --git a/markdowntable/inputs.py b/markdowntable/inputs.py deleted file mode 100644 index b62d8a5..0000000 --- a/markdowntable/inputs.py +++ /dev/null @@ -1,62 +0,0 @@ -from markdowntable import Table - - -def import_from_csv(filename: str, extension: str = 'csv'): - """ - Creates a table from a csv. - - :type extension: str - :type filename: str - :param filename: The csv filename - :param extension: The extension, default csv - :return: markdown.Table object - """ - global header_row, csv_table - with open(filename + '.' + extension, 'r') as file: - rows = file.read().split('\n') - row_num = 0 - for row in rows: - entries = row.split(',') - if row_num == 0: - header_row = True - if header_row: - first_entry = entries[0] - entries.remove(first_entry) - csv_table = Table(first_entry) - for entry in entries: - csv_table.add_column(entry) - header_row = False - else: - csv_table.add_row_with_list(entries) - - row_num += 1 - return csv_table - - -def import_from_code(code: str): - """ - The function makes a table from existing Markdown code. - - :type code: str - :param code: The code to use - :return: The table - :rtype: markdown.Table object - """ - global codetable - lines = code.split('\n') - altlines = [] - for line in lines: - if '|---|' not in line: - altlines.append(line) - lines = altlines - line_no = 0 - for line in lines: - entries = line.split('|') - if line_no == 0: - codetable = Table(entries[0]) - entries.remove(entries[0]) - codetable.all_columns_with_list(entries) - else: - codetable.add_row_with_list(entries) - line_no += 1 - return codetable diff --git a/markdowntable/messages.py b/markdowntable/messages.py deleted file mode 100644 index 7d5ab24..0000000 --- a/markdowntable/messages.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Part of Python-Markdown-Table. Contains the messages the main program uses. -""" - - -def not_enough_values(rows_made: str, columns: str): - """ - Displays the not_enough_values message with arguments - - :type columns: str - :type rows_made: str - :param rows_made: The amount of row values created by the program - :param columns: The total amount of columns - :return: The message - :rtype: str - """ - message = "You did not enter in enough values. You entered in {} values out of {} values. The values that you did" \ - " " \ - "not enter in will be filled in with a blank space. You can stop this message from appearing by adding " \ - "the argument show_warning_message = False".format(str(rows_made), str(columns)) - return message - - -overwrite_message = 'This file already contains content. Do you want to overwrite the contents of the file? You can ' \ - 'add the argument mode = a[+] to not overwrite. ' - -no_more_rows = 'There are no more rows left in the table. If you would like to remove a column, please use the ' \ - 'remove_column function.' diff --git a/markdowntable/row.py b/markdowntable/row.py new file mode 100644 index 0000000..90e756d --- /dev/null +++ b/markdowntable/row.py @@ -0,0 +1,123 @@ +from __future__ import unicode_literals + +from markdowntable.errors import DeletingOnlyValueException + + +class Row(list): + """The Row class. This allows the rows to be dynamically calculated in the Table class. + + The Row class is a subset of the list class, meaning that the Row acts like a list with extra functionality. + + Extra functionalities: + 1. Allows you to fill the list with values until it has x total values. + 2. Allows you to add x value y times. + """ + + def __init__(self, *values): + """Initiates the class. + + The class will not convert an iterable to list, so make sure to pass in the argument using the * operator. + + Example: + >>> t = (1,2,3,4,5,6,7,8,9,10) + >>> r = Row(t, num = 0) + >>> r + Row(num=0, values =(1,2,3,4,5,6,7,8,9,10)) + + >>> t = (1,2,3,4,5,6,7,8,9,10) + >>> r = Row(*t, num = 0) + >>> r + Row(num=0, values = 1,2,3,4,5,6,7,8,9,10) + + Parameters: + values: A tuple or list or other iterable of values to use. + + """ + super(Row, self).__init__(values) + + def add_values(self, *values): + for i in values: + self.append(i) + + def fill_empty(self, tonum): + """Fills the row until it has x total values. + + If the number provided is less than or equal to the total amount of values, it does nothing. + + Parameters: + :param int tonum: How many total values should be in the row. + + Returns: + :return: The amount of times it added an empty value. + :rtype: int + """ + ct = 0 + while len(self) < tonum: + self.append('') + ct += 1 + return ct + + def fill_with(self, amount, times): + """Fills the row with the value amount times times. + + If times is zero or lower, nothing will loop. + + Parameters: + :param str amount: The thing to add to the row. It should preferrably be a string. + :param int times: The amount of times to add it. + + :return: Nothing + :rtype: None + """ + for i in range(times): + self.append(amount) + + def __repr__(self) -> str: + return 'Row(values = %s)' % str(self).replace('[', '').replace(']', '') + + +class Column(Row): + """The Column class. It is nearly identical to the Row class except that you cannot delete the first entry.""" + + def __init__(self, value1, *values): + """Initalizes the class. + + Parameters: + :param str col1: The name of the first column + :param tuple cols: The names of the other columns + """ + super(Column, self).__init__(value1, *values) + + def pop(self, index): + """Removes the value at the position index. + + The method is identical to the pop used by list() except that an error is raised if the index is 0. + + Parameters: + :param int index: The index to delete at + + Returns: + :return: The value that was removed. + :rtype: Any + """ + if index == 0: + raise DeletingOnlyValueException + else: + return super(Column, self).pop(index) + + def __delitem__(self, key): + """Removes the value at the position key. + + The method is identical to the __delitem__ used by list() except that an error is raised if the index is 0. + + Parameters: + :param int key: The index to delete at + + Returns: + :return: The value that was removed. + :rtype: Any + """ + if key == 0: + raise DeletingOnlyValueException + else: + super(Column, self).__delitem__(key) diff --git a/markdowntable/table.py b/markdowntable/table.py new file mode 100644 index 0000000..4d860ac --- /dev/null +++ b/markdowntable/table.py @@ -0,0 +1,335 @@ +from __future__ import unicode_literals + +from markdowntable.errors import DeletingOnlyColumnException, TooLittleValuesException, TooManyValuesException +from markdowntable.row import Row, Column + + +class Table(list): + """The purpose of MarkdownTable is to make it easy to make a table and format it. The results will be printed in + Markdown format. The table will not be appropriately formatted. + + 1. How to make a Table: + + You will need at least one name for the column. You can either pass a Column instance or the values as arguments. + + Example: + Example 1: + >>> t = Table('Name') + Example 2: + >>> c = Column('Name') + >>> t = Table(c) + + In essence, the table created by either method is equal. + + 2. How to make a Row: + + There are two methods for making a Row. You can either initalize a Row class and pass it to the Table instance or + you can pass the values to the add_rows method. + + Example: + Example 1: + >>> t = Table('Name', 'Age') + >>> t.add_row('Brian', 23) + >>> t.add_row('Josh', 34) + Example 2: + >>> t = Table('Name', 'Age') + >>> t.add_row(Row('Brian', 23)) + >>> t.add_row(Row('Josh', 34)) + + 3. How to get the formatted table: + + There are two ways to get the table value. You can either call the make_table function, or ask for the string + version of the table object, which calls make_table. + + Example: + Example 1: + >>> t = Table('Name', 'Age') + >>> t.add_row('Brian', 23) + >>> t.add_row('Josh', 34) + >>> s = t.make_table() + Example 2: + >>> t = Table('Name', 'Age') + >>> t.add_row('Brian', 23) + >>> t.add_row('Josh', 34) + >>> s = str(t) + If we were to compare the two results, we would see that the outputs are equal. + + 4. How to modify the column + To modify the column, we can access it by getting the 0th key of the table. + + >>> t = Table('Test') + >>> c = t[0] + + A. Adding column values + We can add values to the column directly, or use the add_column_value method. + + >>> c.append('Test2') + + >>> t.add_column_value('Test2') + B. Removing column values + We can remove column values by using the remove() and pop() methods on the column interface, or by calling + the remove_column_value method + + >>> c.remove('Test2') + + >>> c.pop(1) + + >>> t.remove_column_value('Test2') + + >>> t.remove_column_value(1) + + As noted, the remove_column method is smart, as in it can detect if the argument is an int or not an int, + and call the appropriate method. + C. Replacing the entire column + If you have a new Column() and you would like to overwrite the old column, you can either set the 0th key of + the table to the new instance or call the overwrite_column method. + + >>> c2 = Column('Num1', 'Num2') + >>> t[0] = c2 + + >>> t.overwrite_column(c2) + + 5. How to modify a row + Unlike with a column, you must access a Row directly by calling it's key number. + + >>> t = Table('Name', 'Age', 'Grade') + >>> t.add_row('Andy') + >>> r1 = t[1] + + A. Add values to a row + We can either append each variable to the Row, or we can call the add_values method on the Row. + + >>> r1.append(15) + >>> r1.append(95) + + >>> r1.add_values(15,95) + B. Remove values from a row + We can either use the remove() or the pop() methods. + + >>> r1.remove(95) + + >>> r1.pop(2) + C. Remove entire row + We can either call pop() on the Table instance or call the remove_row method, which calles pop() + + >>> t.pop(1) + + >>> t.remove_row(1) + D. Overwrite row + If we have a new Row() class, we can just set the key value equal to the new Row or just call the + overwrite_row method. + + >>> r1new = Row('Andy', 15, 95) + >>> t[1] = r1new + + >>> t.overwrite_row(1, r1new) + """ + + def __init__(self, col1, *cols, fill_empty_rows=True, ignore_length_mismatches=False): + """Initalizes the class. + + It requires a column name to start the Column() class with. + + There are also a bunch of options. + + Parameters: + :param str, Column col1: The name of the first column + :param str, tuple cols: The names of the other columns + :param bool fill_empty_rows: This indicates whether or not to run fill_empty on the rows that have less + values than the amount of columns. + :param bool ignore_length_mismatches: This indicates whether or not to ignore rows that contain more values + then the amount of columns. + """ + if isinstance(col1, Column): + super(Table, self).__init__((col1,)) + else: + super(Table, self).__init__((Column(col1, *cols),)) + self.fill_empty = fill_empty_rows + self.ignore = ignore_length_mismatches + + def add_column_value(self, name): + self[0].append(name) + + def add_column_values(self, *names): + for i in names: + self.add_column_values(i) + + def add_row(self, *values): + """Adds a row. + + If the row is of class Row(), then it will use that instead of initalizing a new row with the arguments. + + Parameters: + :param Row, str values: A Row() class or a tuple of values to initalize a row with. + """ + if isinstance(values[0], Row): + self.append(values[0]) + else: + self.append(Row(values)) + + def add_rows(self, *rows): + """Adds a bunch of rows. + + This assumes that each of the values are a Row() class or an iterable with the values. + + Parameters: + :param tuple rows: A tuple or iterable of Row objects or iterables that contain the row values. + """ + for i in rows: + if isinstance(i, Row): + self.add_row(i) + else: + self.add_row(*i) + + def pop(self, index): + """Removes the value at the position index. + + The method is identical to the pop used by list() except that an error is raised if the index is 0. + + Parameters: + :param int index: The index to delete at + + Returns: + :return: The value that was removed. + :rtype: Any + """ + if index == 0: + raise DeletingOnlyColumnException + else: + return super(Table, self).pop(index) + + def __delitem__(self, key): + """Removes the value at the position key. + + The method is identical to the __delitem__ used by list() except that an error is raised if the index is 0. + + Parameters: + :param int key: The index to delete at + + Returns: + :return: The value that was removed. + :rtype: Any + """ + if key == 0: + raise DeletingOnlyColumnException + else: + super(Table, self).__delitem__(key) + + @staticmethod + def format_string(s, item): + """Duplicates a string, fills in each with either an item or copies the string item times. + + Parameters: + :param str s: The string to be used + :param item: The item or number of times to fill/duplicate the string + + Returns: + :return: The formatted/duplicated string + :rtype: str + """ + formatted_str = '|' + if isinstance(item, int): + for i in range(item): + formatted_str += s + else: + for i in item: + formatted_str += s % i + return formatted_str + + def format_row(self, row, count=None, num=None): + """Formats a row into string. + + If the count is given, then it will check the row and act accordingly. + + Parameters: + :param Row row: The Row to check. + :param int count: The amount of values to check for + :param int num: The row number + + Returns: + :return: The formatted string + :rtype: str + """ + + assert isinstance(row, Row), "A Row was not passed in the initial setup. Re-define the class." + if count is not None: + if len(row) < count: + row.fill_empty(count) + if not self.ignore: + if self.fill_empty: + row.fill_empty(count) + else: + raise TooLittleValuesException(num, count, len(row)) + elif len(row) > count: + if not self.ignore: + raise TooManyValuesException(num, count, len(row)) + return self.format_string('%s|', row) + + def make_table(self): + """Makes the table. + + Returns: + :return: The table in string format. + :rtype: str + """ + col_length = len(self[0]) + table = self.format_row(self[0]) + '\n' + self.format_string('---|', col_length) + for n, i in enumerate(self[0:]): + n += 1 + table += '\n' + self.format_row(i, col_length, n) + return table.strip() + + def __str__(self): + return self.make_table() + + def remove_column_value(self, param): + """Removes a column value. + + The function is smart as it will use remove or pop depending on type of value passed to param + + Parameters: + :param param: The number of the index of the value to remove or the value to remove. + + Returns: + :return: The value of the item removed + """ + if isinstance(param, int): + return self[0].pop(param) + else: + return self[0].remove(param) + + def overwrite_column(self, col): + """Overwrites a column with a new column. + + Parameters: + :param Column col: The new column to overwrite with + """ + if isinstance(col, Column): + self[0] = col + + def remove_row(self, index): + """Removes a row at index number index. + + Parameters: + :param int index: The index of the row to delete. + + Returns: + :return: The Row class deleted + :rtype: Row + """ + return self.pop(index) + + def overwrite_row(self, index, newrow): + """Overwrite the row at index number index with the row newrow. + + The column has it's own overwrite process, overwrite_column. + + Parameters: + :param int index: The index number to overwrite + :param Row newrow: The new Row instance to overwrite with + """ + if index > 0: + if isinstance(newrow, Row): + self[index] = newrow + else: + raise DeletingOnlyColumnException