Beispiel #1
0
 def graph(self, x_col, graph_type):
     """Graph the data wrt to x_col."""
     parsed_data = self.data.applymap(en.parse_data)
     graph_operations = {
             "line": lambda x_col : parsed_data.groupby(x_col).mean(),
             "bar" : lambda x_col : parsed_data.groupby(x_col).sum(),
             "count": lambda x_col, d=self.data[x_col].value_counts() : pd.DataFrame({x_col:d.index,"count":d.values}).groupby(x_col).sum()
             }
     try:
         if graph_type in graph_operations:
             data = graph_operations[graph_type](x_col)
         else:
             return r.Status(False, "\tGraph type \"%s\" invalid\n\tValid graph types: %s" 
                 % (graph_type, ", ".join(graph_operations.keys())))
     except pd.core.base.DataError as e:
         return r.Status(False, "\t" + str(e))
     x_data = list(data.index)
     for idx, col in enumerate(data.columns):
         y_data = list(data[col])
         if graph_type == "line":
             plt.plot(x_data, y_data, label=data[col].name)
         elif graph_type == "bar" or graph_type == "count":
             bar_count = len(data.columns)
             bar_width = 0.7 / bar_count
             index = np.arange(len(x_data))
             plt.bar(index + idx * bar_width, y_data, bar_width, label=data[col].name)
             x_ticks = index + (bar_count * bar_width - bar_width) / 2
             plt.xticks(x_ticks, x_data)
     if type(x_data[0]) == date:
         plt.gcf().autofmt_xdate()
     plt.legend()
     plt.show()
     return r.Status(True)
Beispiel #2
0
 def log(self, parameters):
     """Add new entries to an item."""
     usage = "\tUsage: log <item_name> [insert_index]"
     if not self.check_num_params(parameters, [1, 2], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     columns = item.get_columns()
     if len(parameters) == 2:
         index = parameters[1]
         if not index.isnumeric():
             return r.Status(False, "\tIndex must be an integer")
         index = int(index)
     else:
         index = None
     prompt = "Enter data for columns (%s) (Enter 'quit' when done): " % ", ".join(columns)
     user_in = input(prompt)
     while user_in != "quit":
         data = list(map(en.encode_input, user_in.split()))
         if len(data) != len(columns):
             print("\tColumn count mismatch: %d columns entered, needs %d." % (len(data), len(columns)))
         else:
             run = item.insert(data, index)
             if len(parameters) == 2:
                 index += 1
             if run.failed():
                 return run
         user_in = input(prompt)
     return r.Status(True)
Beispiel #3
0
 def delete_col(self, col_name):
     """Remove a column from the DataFrame."""
     if col_name not in self.get_columns():
         return r.Status(False, "\tColumn \"%s\" not found\n\tValid columns: %s" 
                 % (col_name, ", ".join(self.get_columns())))
     self.data = self.data.drop(col_name, axis=1)
     self.save()
     return r.Status(True)
Beispiel #4
0
 def edit_entry(self, index, data):
     """Edit an entry in the DataFrame."""
     dataf = pd.DataFrame([data], columns=self.get_columns())
     col_index = self.checktype(dataf)
     if col_index != -1:
         return r.Status(False, "\tInvalid type entered for column \"%s\"" 
                 % self.get_columns()[col_index])
     self.data.loc[int(index)] = data
     self.save()
     return r.Status(True)
Beispiel #5
0
 def delete_entry(self, index):
     """Delete an entry in the DataFrame."""
     if not index.isnumeric():
         return r.Status(False, "\tIndex must be numeric")
     else:
         index = int(index)
     if index not in self.data.index:
         return r.Status(False, "\tEntry number %d does not exist" % index)
     self.data = self.data.drop(index)
     self.save()
     return r.Status(True)
Beispiel #6
0
 def expand(self, col_name, data):
     """Add a column with data to the DataFrame."""
     if len(data) != len(self.data) and len(data) != 0:
         return r.Status(False, "\tInvalid number of entries: %d entered, 0 or %d needed" 
                 % (len(data), len(self.data)))
     if len(data) == 0:
         self.data[col_name] = [0 for x in range(len(self.data))]
     else:
         self.data[col_name] = data
     self.save()
     return r.Status(True)
Beispiel #7
0
 def tag(self, parameters):
     """Tag an item."""
     usage = "\tUsage: tag <\"add\", \"remove\", or \"show\"> [item_name] [tag_name]"
     if not self.check_num_params(parameters, [1,3], usage):
         return r.Status(False)
     if parameters[0] == "show":
         for tag, items in self.tags.items():
             print("\t" + tag + ": " + ", ".join(items))
         return r.Status(True)
     item = parameters[1]
     if not self.check_item(item):
         return r.Status(False)
     tag = parameters[2] 
     op = parameters[0]
     if op == "add":
         if tag not in self.tags:
             self.tags[tag] = []
         if item in self.tags[tag]:
             return r.Status(False, "\tItem \"%s\" already has tag \"%s\""
                     % (item, tag))
         self.tags[tag].append(item)
     elif op == "remove":
         if tag not in self.tags:
             return r.Status(False, "\tTag \"%s\" does not exist" % tag)
         if item not in self.tags[tag]:
             return r.Status(False, "\tItem \"%s\" does not have tag \"%s\""
                     % (item, tag))
         self.tags[tag].remove(item)
         if not self.tags[tag]:
             del self.tags[tag]
     else:
         return r.Status(False, "\tMust specify \"add\" or \"remove\"")
     self.save_tags()
     return r.Status(True)
Beispiel #8
0
 def insert(self, data, index=None):
     """Insert a new entry at index."""
     dataf = pd.DataFrame([data], columns=self.get_columns())
     col_index = self.checktype(dataf)
     if col_index != -1:
         return r.Status(False, "\tInvalid type entered for column \"%s\"" 
                 % self.get_columns()[col_index])
     if index == None or index >= len(self.data):
         self.data = self.data.append(dataf, ignore_index=True)
     else:
         data_a = self.data.iloc[:index]
         data_b = self.data.iloc[index:]
         self.data = data_a.append(dataf).append(data_b).reset_index(drop=True)
     self.save()
     return r.Status(True)
Beispiel #9
0
 def rename(self, name, col=None):
     """Rename this item, or a column."""
     if col == None:
         self.name = name
         os.remove(self.directory)
         self.directory = "logs/" + name + ".txt"
         self.save()
         return r.Status(True)
     else:
         if col not in self.get_columns():
             return r.Status(False, "\tColumn \"%s\" not found\n\tValid columns: %s" 
                     % (col, ", ".join(self.get_columns())))
         self.data = self.data.rename(columns={col:name})
         self.save()
         return r.Status(True)
Beispiel #10
0
 def copy(self, parameters):
     """Copy an item."""
     usage = "\tUsage: copy <item_name> <new_name>"
     if not self.check_num_params(parameters, [2], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     new_name = parameters[1]
     if new_name in self.logs:
         return r.Status(False, "\tItem \"%s\" already exists" % new_name)
     new_item = LoggedItem(new_name, copy_from=item)
     self.logs[new_name] = new_item
     return r.Status(True)
Beispiel #11
0
 def expand(self, parameters):
     """Add a column to an item."""
     usage = "\tUsage: expand <item_name> <new_column_name>"
     if not self.check_num_params(parameters, [2], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     new_col = parameters[1]
     if new_col in item.get_columns():
         return r.Status(False, "\tColumn %s already exists" % new_col)
     prompt = "\nEnter data for %d entries: " % (len(item.get_indices()))
     data = input(prompt).split()
     data = list(map(en.encode_input, data))
     return item.expand(new_col, data)
Beispiel #12
0
 def graph(self, parameters):
     """Graph an item."""
     usage = "\tUsage: graph <item_name> <x_column> [graph_type]"
     if not self.check_num_params(parameters, [2, 3], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     x_col = parameters[1]
     if x_col not in item.get_columns():
         return r.Status(False, "\tColumn \"%s\" not found\n\tValid columns: %s" 
                 % (x_col, ", ".join(item.get_columns())))
     if len(parameters) == 2:
         return item.graph(x_col, "line")
     else:
         graph_type = parameters[2]
         return item.graph(x_col, graph_type)
Beispiel #13
0
 def view(self, parameters):
     """View the log, with parameters given by user."""
     usage = "\tUsage: view <item_name> [column(s)] {filter_column} {filter_operation} {filter_value}"
     if not self.check_num_params(parameters, [1,2,4,5], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     logged_item = self.logs[item]
     if len(parameters) == 5:
         col, filter_col, filter_op, filter_val = parameters[1:]
         return logged_item.get_entries(filter_col, filter_op, filter_val, col)
     elif len(parameters) == 4:
         filter_col, filter_op, filter_val = parameters[1:]
         return logged_item.get_entries(filter_col, filter_op, filter_val)
     elif len(parameters) == 2:
         col = parameters[1]
         return logged_item.get_entries(col=col)
     elif len(parameters) == 1:
         return logged_item.get_entries()
Beispiel #14
0
 def edit(self, parameters):
     """Edit a previous entry."""
     usage = "\tUsage: edit <item_name> <entry_number>"
     if not self.check_num_params(parameters, [2], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     index = parameters[1]
     if not index.isnumeric():
         return r.Status(False, "\tIndex must be an integer")
     columns = item.get_columns()
     prompt = "\nEnter data for columns (" + ", ".join(columns) + "): "
     user_in = input(prompt).split()
     user_in = list(map(en.encode_input, user_in))
     for entry in user_in:
         if type(entry) == r.Status:
             return entry
     return item.edit_entry(index, user_in)
Beispiel #15
0
 def list(self, parameters):
     """List logged items."""
     usage = "\tUsage: list <\"all\" or \"tags\"> [tag1,tag2,...]"
     if not self.check_num_params(parameters, [1,2], usage):
         return r.Status(False)
     op = parameters[0]
     if op == "all":
         show_list = list(self.logs.keys())
     elif op == "tags":
         tags = parameters[1].split(",")
         show_list = []
         for tag in tags:
             if tag not in self.tags:
                 return r.Status(False, "\tTag \"%s\" does not exist" % tag)
             show_list += self.tags[tag]
         show_list = set(show_list)
     else:
         return r.Status(False, "\t Must specify \"all\" or \"tags\"")
     print("\tYour items: " + ", ".join(show_list))
     return r.Status(True)
Beispiel #16
0
 def delete(self, parameters):
     """Delete an entry from the table."""
     usage = "\tUsage: delete <item_name> [\"column\" or \"entry\"] [column_name or entry_number]"
     if not self.check_num_params(parameters, [1, 3], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     if len(parameters) == 3:
         delete_type = parameters[1]
         if delete_type == "column":
             col = parameters[2]
             if self.get_conf_delete(col, "column"):
                 return item.delete_col(col)
             else:
                 return r.Status(False, "\tInput does not match column name, delete cancelled")
         if delete_type == "entry":
             index = parameters[2]
             return item.delete_entry(index)
         else:
             return r.Status(False, "\tMust specify whether to delete column or entry")
         return item.delete_entry(index)
     elif len(parameters) == 1:
         if self.get_conf_delete(item.name, "item"):
             self.logs.pop(item.name)
             if self.tags:
                 to_remove = []
                 for tag, items in self.tags.items():
                     if item.name in items:
                         items.remove(item.name)
                     if not items:
                         to_remove.append(tag)
                 for tag in to_remove:
                     del self.tags[tag]
                 self.save_tags()
             return item.delete_item()
         else:
             return r.Status(False, "\tInput does not match item name, delete cancelled")
Beispiel #17
0
def parse_slice(string):
    """Convert a string inpout into a list of indices."""
    indices = []
    slice_in = string.split(':')
    if len(slice_in) != 2 and len(slice_in) != 3:
        return r.Status(
            False, "\tIndex must be in the form start:end or start:end:step")
    for num in slice_in:
        if not num.isnumeric():
            return r.Status(
                False,
                "\tInvalid index \"" + num + "\", index must be an integer")
        indices.append(int(num))
    if len(indices) == 2:
        indices.append(1)
    if indices[1] < indices[0]:
        return r.Status(
            False,
            "\tIndex must have a greater ending position than starting position"
        )
    indices[0] -= 1
    return indices
Beispiel #18
0
 def help(self, parameters):
     """Print out help information."""
     print("\tThis program is a manager and visualization tool for CSV (comma separated value) files")
     print("\tYou can enter commands in order to view, edit, graph, etc.")
     print("\tTo see how to use a command, enter the command name and press enter.")
     print("\tRequired arguments are denoted with angle brackets <>")
     print("\tOptional arguments are denoted with varying brackets, where each set of arguments uses the same symbol")
     print("\tIf you want to specify a date, make sure your input has a '/' character")
     print("\tIf you want to specify a a range of columns, use the notation begin:end:step")
     print("\tThe view command automatically generates an item called 'last'")
     print("\tYou can use the 'last' item to chain commands, such as viewing and graphing")
     print("\tTo get started, create a new item by typing \"view <item_name>\"")
     return r.Status(True)
Beispiel #19
0
 def rename(self, parameters):
     """Rename an item."""
     usage = "\tUsage: rename <item_name> {column_name} <new_name>"
     if not self.check_num_params(parameters, [2, 3], usage):
         return r.Status(False)
     item = parameters[0]
     if not self.check_item(item):
         return r.Status(False)
     item = self.logs[item]
     if len(parameters) == 2:
         new_name = parameters[1]
         if new_name in self.logs:
             return r.Status(False, "\tItem \"%s\" already exists" % new_name)
         if self.tags:
             for tag, items in self.tags.items():
                 self.tags[tag] = [new_name if (i == item.name) else i for i in items]
             self.save_tags()
         return item.rename(new_name)
     elif len(parameters) == 3:
         col = parameters[1]
         new_name = parameters[2]
         if new_name in item.get_columns():
             return r.Status(False, "\tColumn \"%s\" already exists" % new_name)
         return item.rename(new_name, col)
Beispiel #20
0
def parse_date(string):
    """Convert a string input into a date object."""
    today = date.today()
    year = today.year
    month = today.month
    day = today.day
    date_in = string.split('/')
    try:
        if len(date_in) == 2:
            if date_in[1]:
                day = int(date_in[1])
                month = int(date_in[0])
            elif date_in[0]:
                day = int(date_in[0])
        elif len(date_in) == 3:
            month, day, year = list(map(int, date_in))
        return date(year, month, day)
    except ValueError:
        return r.Status(False, "\tInvalid date entered: " + string)
Beispiel #21
0
 def get_entries(self, filter_col=None, filter_op=None, value=None, col=None):
     """Pull up entries corresponding to filter."""
     filters = {
             "=" : lambda c, v : c == v,
             ">" : lambda c, v : c > v,
             "<" : lambda c, v : c < v,
             ">=" : lambda c, v : c >= v,
             "<=" : lambda c, v : c <= v,
     }
     if filter_col:
         if filter_col not in self.get_columns():
             return r.Status(False, "\tColumn \"%s\" not found\n\tValid columns: %s" 
                     % (filter_col, ", ".join(self.get_columns())))
         if filter_op not in filters:
             return r.Status(False, "\tFilter operation \"%s\" invalid\n\tValid operations: %s"
                     % (filter_op, ", ".join(filters.keys())))
         column = self.data[filter_col].map(en.parse_data)
         value = en.parse_data(value)
         if type(column) is r.Status:
             return column
         if type(value) is r.Status:
             return value
         try:
             mask = filters[filter_op](column, value)
         except TypeError:
             return r.Status(False, "\tInvalid type entered (%s) for column type (%s)" 
                     % (type(value), type(column[0])))
     else:
         mask = [True for _ in range(len(self.data))]
     if col:
         col = en.parse_data(col)
         if type(col) == str:
             if col not in self.get_columns():
                 return r.Status(False, "\tColumn \"%s\" not found\n\tValid columns: %s" 
                         % (col, ", ".join(self.get_columns())))
         elif type(col) == list:
             if col[1] > len(self.get_columns()):
                 return r.Status(False, "\tColumn index %d out of bounds, max is %d" 
                         % (col[1], len(self.get_columns())))
             col = self.get_columns()[col[0]:col[1]:col[2]]
         elif type(col) == r.Status:
             return col
     else:
         col = self.get_columns() 
     filtered_data = self.data[col][mask]
     if type(filtered_data) == pd.core.series.Series:
         filtered_data = filtered_data.to_frame()
     print(filtered_data)
     filtered_data.to_csv("logs/last.txt")
     return r.Status(True)
Beispiel #22
0
 def delete_item(self):
     """Delete this item."""
     os.remove(self.directory)
     return r.Status(True)