def write_cocktail_instructions_return_next_row(
        cocktail_recipe: CocktailRecipe,
        ws: gspread.Worksheet = None,
        row: int = None) -> int:
    """
    Writes a cocktail_recipe recipe into a google sheet worksheet.
    Format:
        0, 0, 0,
        Cocktail name,
        Instruction 1,
        ...,
        Instruction limit
    The cocktail has a separator line after the previous entry in the
    worksheet, unless the worksheet is empty.
    :param ws: The worksheet where to write the cocktail_recipe to
    :param cocktail_recipe: The cocktail_recipe recipe to write
    :param row: the row the entries should populate from
    :return: The next empty row below the instructions for this cocktail.
    """
    current_row = write_cocktail_header_return_next_row(
        cocktail_recipe, ws, row)
    for instruction in cocktail_recipe.get_instructions():
        ws.update_cell(current_row, 2, instruction)
        current_row += 1
    return current_row
    def apply_to_sheet(self, worksheet: gspread.Worksheet):
        """
        Update the specified Google Sheet worksheet by altering the row
        corresponding to this update's edited message.
        """
        # Find existing cell with the same ID
        try:
            cell = worksheet.find(self.message_id)
        except gspread.CellNotFound:
            logger.error(f"Failed to edit message with id={self.message_id} - original message not found in sheet.")
            return

        if not cell.col == ColumnHeaders['MessageID'].value:
            logger.error(f"Failed to edit message with id={self.message_id} - no message with same ID found.")
            return

        # Get column value where the message is stored
        message_cell_col = ColumnHeaders['Message'].value
        # Get column value where edited timestamp is stored
        edited_timestamp_cell_col = ColumnHeaders['LastEdited'].value

        # Updated the cells with new edits
        worksheet.update_cell(cell.row, message_cell_col, self.message)
        worksheet.update_cell(cell.row, edited_timestamp_cell_col, self.edit_timestamp.isoformat())

        # Prints success to console
        logger.info(f"Cells ({cell.row}, {message_cell_col}), ({cell.row}, {edited_timestamp_cell_col}) updated")
def append_worksheet_values(worksheet: Worksheet, values: List[list]):
    _log.debug("appending %s rows values to worksheet...", len(values))

    cells = convert_values_to_cells(values,
                                    start_row=len(worksheet.col_values(1)) + 1)
    worksheet.add_rows(len(values))
    worksheet.update_cells(cells)
def set_worksheet_values(worksheet: Worksheet, values: List[list]):
    _log.debug("clearing worksheet: %s ...", worksheet)
    worksheet.clear()
    cells = convert_values_to_cells(values)
    _log.debug("updating worksheet values...")
    worksheet.update_cells(cells)
    _log.debug("worksheet values has been set!")
Exemple #5
0
 def update_date(self,
                 ws: Worksheet,
                 env: Env,
                 prog: TestProgress,
                 date: Optional[datetime] = None):
     ws.update_cell(self.id + 1,
                    self.columns.index(f'{env.name}_{prog.name}') + 1,
                    date.strftime(self.date_fmt) if date else '')
Exemple #6
0
def model_cell(wks: Worksheet, index: str) -> Cell:
    '''???'''
    cell = Cell(index)
    wks.unlink()
    cell.text_format['fontSize'] = 10
    cell.text_format['bold'] = True
    wks.link()
    return cell
Exemple #7
0
def sync_lang(sheet: Worksheet):
    raw_sheet_lang = sheet.row_values(1)
    sheet_lang = set(raw_sheet_lang)
    origin_lang = set(language_pack.languages)
    empty_langs = origin_lang - sheet_lang
    if empty_langs:
        data = [raw_sheet_lang + list(empty_langs)]
        acell = f'A1:{ascii_uppercase[len(data[0]) - 1]}1'
        print(f'update {acell} to ', data)
        sheet.update(acell, data)
def write_separator_line(ws: gspread.Worksheet, separator_row_index: int,
                         width: int, separator: Union[str, int]) -> None:
    """
    Writes a separator line to mark the start of a new entry.
    :param ws: Worksheet to write the line to
    :param separator_row_index: index of the row to write the line in
    :param width: How many cells should be written to in the given row
    :param separator: The value which to fills the cells with
    :return: None
    """
    for col in range(1, width + 1):
        ws.update_cell(separator_row_index, col, separator)
Exemple #9
0
def remove_keys(sheet: Worksheet, keys: List[str]):
    rows = []
    _remove_keys = []
    col_num = get_id_field_cell(sheet).col
    for k in keys:
        try:
            cell = sheet.find(k, in_column=col_num)
            rows.append(cell.row)
            _remove_keys.append(k)
        except Exception as e:
            pass
    if rows:
        sheet.delete_rows(rows)
        print(f'remove {len(rows)} keys')
        print(_remove_keys)
    def __post_init__(self, order: str, search_sheet: Worksheet):
        row = int(re.search(r"(R[0-9]+)", order).group(0)[1:])  # type: ignore
        column = int(
            re.search(r"(C[0-9]+)", order).group(0)[1:]  # type: ignore
        ) - 1
        self.cell_coordinates = (row, column)
        self.cell_address = search_sheet.cell(row, column).address
        self.steel_type = search_sheet.cell(row, 4).value
        self.steel_depth = search_sheet.cell(row, 5).value

        self.user_cell_color = get_format_safe(
            get_user_entered_format, search_sheet,
            self.cell_address).backgroundColor
        self.user_f_row_color = get_format_safe(get_user_entered_format,
                                                search_sheet,
                                                f"F{row}").backgroundColor
Exemple #11
0
def find_lang_col(sheet: Worksheet, sync=True):
    if sync:
        sync_lang(sheet)
    return {
        lang: sheet.find(lang, in_row=1).col
        for lang in language_pack.languages
    }
Exemple #12
0
def parse_list(sheet: Worksheet):
    cards = []
    for row in sheet.get_all_values():
        if row[0] and row[0] != 'ID' and row[2]:
            cards.append(Card(row))

    sorted_cards = sorted(cards, key=lambda e: e.id)
    return sorted_cards
    def apply_to_sheet(self, worksheet: gspread.Worksheet):
        """
        Add a row to the specified Google Sheet worksheet corresponding to
        this update's new Slack message.
        """
        user_name = slack_utils.get_user_display(self.user_id)
        row_data = [
            self.message_id,
            user_name,
            self.message,
            self.timestamp.isoformat()
        ]

        # Inserts row into the spreadsheet with an offset of 2
        # (After row 1 (header row))
        worksheet.insert_row(row_data, 2)
        logger.info(f"Message with id={self.message} by {user_name} added")
Exemple #14
0
def load_accounts_from_sheet(sheet: gspread.Worksheet) -> typing.List[list]:
    result = []
    for record in sheet.get_all_records():
        cols = [k.lower() for k in record.keys()]
        if 'date' in cols and 'account' in cols:
            result.append(record)
        else:
            logger.info(f"Skipping {record}")
    return result
def write_cocktail_names_based_on_ingredient_return_next_row(
        ingredient: str,
        ws: gspread.Worksheet,
        next_empty_row=None,
        limit: int = 1) -> int:
    """
    :param ingredient: The main ingredient of the drinks whose name to write.
    :param ws: The worksheet to insert the drink name to
    :param next_empty_row: If known, the next empty row where to write the drink names to.
    :param limit: The maximum number of drink names to write for the given ingredient.
    :return: The next empty row below where the drink names were written.
    """
    current_row = write_ingredient_header_return_next_row(
        ingredient, ws, next_empty_row)
    for cocktail in get_drinks_based_on_ingredient(ingredient, limit):
        ws.update_cell(current_row, 2, cocktail.get_name())
        current_row += 1
    return current_row
    def apply_to_sheet(self, worksheet: gspread.Worksheet):
        """
        Remove the row corresponding to this update's deleted message from
        the specified Google Sheet worksheet.
        """
        # Find existing cell with the same ID
        try:
            cell = worksheet.find(self.message_id)
        except gspread.CellNotFound:
            logger.error(f"Failed to delete message with id={self.message_id} - original message not found in sheet.")
            return

        if not cell.col == ColumnHeaders['MessageID'].value:
            logger.error(f"Failed to delete message with id={self.message_id} - no message with same ID found.")
            return

        worksheet.delete_row(cell.row)
        # Prints Success message to console
        logger.info(f"Successfully deleted message with id={self.message_id}.")
def write_cocktail_ingredients_into_spreadsheet_return_next_row(
        cocktail_recipe: CocktailRecipe,
        ws: gspread.Worksheet,
        next_empty_row=None) -> int:
    """
    Inserts the cocktail_recipe recipe into the bottom of the spreadsheet.
    The first entry in the row is the
    :param cocktail_recipe: The cocktail_recipe recipe to insert into the spreadsheet.
    :param ws: The worksheet to insert the cocktail_recipe to
    :param next_empty_row: If known, the next empty row where to write the ingredients to.
    :return The next empty row below the current row.
    """
    current_row = write_cocktail_header_return_next_row(
        cocktail_recipe, ws, next_empty_row)
    for ingredient, amount in cocktail_recipe.get_ingredients().items():
        ws.update_cell(current_row, 2, ingredient)
        ws.update_cell(current_row, 3, amount)
        current_row += 1
    return current_row
def write_cocktail_header_return_next_row(cocktail_recipe: CocktailRecipe,
                                          ws: gspread.Worksheet,
                                          row: int = None):
    """
    Writes a separator line and drink name into the spreadsheet at the next available row
    :param cocktail_recipe: Recipe to which to write the header for.
    :param ws: Worksheet that should be written to.
    :param row: Row which to write the header into.
    :return: The rwo below the cocktail header
    """
    top_margin_row = 3
    current_row = row
    if row is None:
        current_row = find_next_empty_row_index(ws)
    if current_row >= top_margin_row:
        write_separator_line(ws, current_row, width=3, separator="0")
        current_row += 1
    ws.update_cell(current_row, 1, cocktail_recipe.get_name())
    current_row += 1
    return current_row
def write_ingredient_header_return_next_row(ingredient: str,
                                            ws: gspread.Worksheet,
                                            row: int = None):
    """
    Writes a separator line and ingredient name into the spreadsheet at the next available row.
    If no row is given, it finds the next empty row in the worksheet.
    :param ingredient: The ingredient of the drinks
    :param ws: Worksheet that should be written to.
    :param row: Row which to write the header to.
    :return: The row below the ingredient header.
    """
    top_margin_row = 3
    current_row = row
    if current_row is None:
        current_row = find_next_empty_row_index(ws)
    if current_row >= top_margin_row:
        write_separator_line(ws, current_row, width=2, separator="0")
        current_row += 1
    ws.update_cell(current_row, 1, ingredient)
    current_row += 1
    return current_row
def gsheet_read(worksheet: gspread.Worksheet) -> pandas.DataFrame:
    """
    Read the specified worksheet directly into a DataFrame
    and remove rows, where no ID is given.
    """

    if not worksheet:
        return pandas.DataFrame()
    dataframe = pandas.DataFrame(worksheet.get_all_records(), dtype=str)
    if len(dataframe.index) == 0:
        return pandas.DataFrame(columns=GSHEET_HEADER)

    # Remove rows where the ID is missing
    empty_rows = dataframe[dataframe['id'] == '']
    if len(empty_rows.index) > 0:
        for row in empty_rows.index:
            worksheet.delete_rows(start_index=row + 2)
            dataframe.drop(index=row, inplace=True)
        dataframe.reset_index(drop=True, inplace=True)

    return dataframe
Exemple #21
0
def update_gsheet_cells(row, cursheet: gspread.Worksheet, line_num) -> None:
    """
    (helper) Paste values found in tracker_listings to the Needs Review Tracker

    Parameters
    ----------
    row : pandas Series
        The current row in the tracker_listings dataframe
    cursheet : gspread.Worksheet
        The current sheet. This should always be 'Needs Review Tracker'
    line_num : TYPE
        The index of the Needs Review Tracker where there is a blank value.
        This is based off of the length of the 'Date Assigned' column of the
        Needs Review Tracker

    Returns
    -------
    None

    """
    line_num += row[3]  # To go to the next row, according to the Priority Rank value
    cursheet.update_cell(line_num, 8, row[0])  # Date Assigned
    cursheet.update_cell(line_num, 10, row[1])  # client_id
    cursheet.update_cell(line_num, 13, row[2])  # total_sales
    cursheet.update_cell(line_num, 14, row[3])  # Priority Rank
    cursheet.update_cell(line_num, 15, row[4])  # Count - Priority Items
    time.sleep(5)  # Necessary, otherwise it'll throw an error from running too fast
def is_row_empty(ws: gspread.Worksheet, row: int,
                 min_horizontal_empty_cells: int) -> bool:
    """
    Checks whether a given row in a worksheet is empty
    :param ws: Worksheet to check whether the given row is empty on.
    :param row: The index of the row to check
    :param min_horizontal_empty_cells: Minimum number of empty continuous cells needed, from left to right.
    :return: Whether there are at least min_horizontal_empty continuous empty cells in the row from left to right.
    """
    for col in range(1, 1 + min_horizontal_empty_cells):
        if ws.cell(row, col).value:
            return False
    return True
Exemple #23
0
def find_lang_start_col(sheet: Worksheet):
    raw_sheet_lang = sheet.row_values(1)
    min_index = None
    for x in language_pack.languages:
        try:
            i = raw_sheet_lang.index(x)
            min_index = i if min_index > i else min_index
        except Exception as e:
            pass
    if min_index:
        start_lang_idx = min_index + 1
    else:
        start_lang_idx = len(raw_sheet_lang) + 1
    return start_lang_idx
    def __resize_sheet(self, ws: gspread.Worksheet, num_rows: int,
                       num_cols: int) -> tuple:
        """
        This *private* method resizes the worksheet to the given dimensions.

        :param ws: the one Google Worksheet in the file
        :param num_rows: number of rows
        :param num_cols: number of columns
        :return: None
        """
        try:
            if num_rows > 0 and num_cols > 0:
                # ws.resize() calls batch_update
                response = ws.resize(rows=num_rows, cols=num_cols)

                # NOTE: ws.resize() has a known BUG, it does not update the ws.row_count and ws.col_count properties
                #   of the gspread.Worksheet object. Some gspread methods rely on these properties.
                #   So the following two statements update those properties.
                ws._properties['gridProperties']['rowCount'] = num_rows
                ws._properties['gridProperties']['columnCount'] = num_cols
            return True, ''
        except Exception as e:
            return False, 'There was an error resizing the Google Sheet.'
Exemple #25
0
def make_update_records_data(worksheet: Worksheet, lang_index: dict):
    update_records_data = []
    get_acel = get_range()
    sort_lang = make_sort_lang(lang_index)
    print(sort_lang)
    for i, record in enumerate(worksheet.get_all_records()):
        data = {
            'range':
            get_acel(i + 1),
            'values':
            make_values(sort_lang,
                        language_pack.get_all_language_value(record[ID_FIELD]))
        }
        update_records_data.append(data)
    return update_records_data
Exemple #26
0
    def done(self,
             ws: Worksheet,
             env: Env,
             results: Optional[Dict[str, int]] = None,
             prefix_metrics: Optional[str] = None):
        self.update_state(ws, State.done, env)

        if env != Env.eval:
            self.update_date(ws, env, TestProgress.end, datetime.now())

        metrics = [
            Metrics.loss, Metrics.accuracy, Metrics.f1_score, Metrics.miou,
            Metrics.precision, Metrics.recall
        ]

        cells = []

        prefix_col = '' if env == Env.train else f'{env.value}_'
        for m in metrics:
            cell = ws.cell(self.id + 1,
                           self.columns.index(prefix_col + m.value) + 1)
            value = results[(prefix_metrics or '') + m.value]
            cell.value = "{:.6f}".format(value).replace('.', ',')
            cells.append(cell)

        if env != env.test:
            for m in metrics:
                name_key_best_val = f'best_{prefix_col}{m.value}'
                cell = ws.cell(self.id + 1,
                               self.columns.index(name_key_best_val) + 1)
                value = results['best_' + (prefix_metrics or '') + m.value]
                cell.value = "{:.6f}".format(value).replace('.', ',')
                cells.append(cell)
        cell = ws.cell(self.id + 1, self.columns.index('machine') + 1)
        cell.value = socket.gethostname()
        ws.update_cells([*cells, cell])
    def __enter_data_on_sheet(self, ws: gspread.Worksheet) -> tuple:
        """
        This *private* method enters the data into the worksheet.

        :param ws: the one Google Worksheet in the file
        :return:
        """
        if self.__data_list:
            data = [self.__header_list[2]] + self.__data_list
        else:
            data = [self.__header_list[2]]

        try:
            response = ws.update('A1', data, raw=False)
            return True, ''
        except Exception as e:
            return False, 'There was an error entering the data on the Google Sheet.'
Exemple #28
0
def parse_competences(wsh : gspread.Worksheet):
    ll = wsh.get_all_values()  # type: List[List[str]]
    comp = []  # type: List[Tuple[str, int, COMP_LEVEL]]
    for line in range(2, 10):
        comp.append((ll[line][COMP_NAME_COLUMN].strip().lower(), int(ll[line][COMP_SCORE_MAIN]), COMP_LEVEL.NORMAL))
    comp_level = COMP_LEVEL.NORMAL
    line = 13
    while ll[line][COMP_NAME_COLUMN] and ll[line][COMP_SCORE_XPABLE]:
        if not ll[line][COMP_SCORE_XPABLE].isnumeric():
            try:
                comp_level = STR_TO_COMP_LEVEL[ll[line][COMP_SCORE_XPABLE]]
            except KeyError:
                raise BotError(
                    f"Unexcepted value when parsing comp score, got \"{ll[line][COMP_SCORE_XPABLE]}\" at line {line} ({ll[line][COMP_NAME_COLUMN]})")
        else:
            comp.append((ll[line][COMP_NAME_COLUMN].strip().lower(), int(ll[line][COMP_SCORE_XPABLE]), comp_level))
        line += 1
    return comp
Exemple #29
0
def process_datasets(config: SettingConfig, sheet: Worksheet) -> None:
    print("Started running RASA")

    # Compute and write the title of the spreadsheet based on the loaded configurations
    spreadsheet_title = [config.identifier]
    sheet.insert_row(spreadsheet_title, 1)

    # For each scenario folder
    spreadsheet_row_index = SPREADSHEET_START_VERTICAL_OFFSET
    for file in os.listdir(config.datasets_path):

        # Compute the path for the scenario folder
        folder_path = os.path.join(config.datasets_path, file)
        if os.path.isdir(folder_path):

            # Break if the directory does not contain the splits
            if len(os.listdir(folder_path)) <= 2:
                print(
                    "Directory only contains train and test files, but no splits. Breaking."
                )
                break

            # Compute the scenario file name
            file_path = os.path.join(folder_path, file)

            # Compute the reports path and create the directory
            scenario_reports_path = os.path.join(folder_path,
                                                 'scenario_reports')
            os.mkdir(scenario_reports_path)

            # Compute the intent and slot reports paths and create them
            intent_reports_path = os.path.join(scenario_reports_path,
                                               'intent_reports')
            slot_reports_path = os.path.join(scenario_reports_path,
                                             'slot_reports')

            os.mkdir(intent_reports_path)
            os.mkdir(slot_reports_path)

            scenario_slot_results = [f'Slot - {file}']
            scenario_intent_results = [f'Intent - {file}']

            for split_id in range(config.splits):
                # Compute the identifier, get the train split and test split
                identifier = f" {file}, split {split_id}"
                train_split = file_path + "_train_" + f"{split_id}" + ".json"
                test_split = file_path + "_test_" + f"{split_id}" + ".json"

                # Run the subprocess for RASA training and testing, and wait for its completion
                command = [
                    config.rasa_script_path, train_split, test_split,
                    config.rasa_config_path
                ]
                subprocess.Popen(command, shell=True).wait()

                # Process the slot and intent errors & reports and save their return values
                intent_f1 = process_intent_result(identifier,
                                                  scenario_reports_path,
                                                  config)
                slot_f1 = process_slot_result(identifier,
                                              scenario_reports_path, config)

                # Move the confusion matrix to the results path
                copy_confusion_matrix(identifier, config)

                scenario_slot_results.append(float("{:0.4f}".format(slot_f1)))
                scenario_intent_results.append(
                    float("{:0.4f}".format(intent_f1)))

                print(f"Finished processing split {identifier}")

            # Append the mean value to each list for the scenario
            scenario_intent_results.append(
                float("{:0.4f}".format(mean(scenario_intent_results[1:]))))
            scenario_slot_results.append(
                float("{:0.4f}".format(mean(scenario_slot_results[1:]))))

            # Append the standard deviation to each list for the scenario
            scenario_intent_results.append(
                float("{:0.3f}".format(
                    stdev(scenario_intent_results[1:len(scenario_intent_results
                                                        ) - 2]))))
            scenario_slot_results.append(
                float("{:0.3f}".format(
                    stdev(scenario_slot_results[1:len(scenario_slot_results) -
                                                2]))))

            # Append the line in the google doc:
            sheet.insert_row(scenario_slot_results, spreadsheet_row_index)
            sheet.insert_row(scenario_intent_results, spreadsheet_row_index)
            spreadsheet_row_index += 3
Exemple #30
0
def write(sheet: gspread.Worksheet, df: pd.DataFrame) -> None:
    cells = sheet.get_all_values()
    set_with_dataframe(sheet, df, include_index=False,
                       include_column_header=False, row=len(cells) + 1, resize=False)