From 81cb6f21d60e9a795fcc9f7c525ba803c4b53735 Mon Sep 17 00:00:00 2001 From: Shino Date: Sat, 8 Nov 2025 15:33:21 -0100 Subject: [PATCH] fix: alterado o parser.py com os valores a procurar --- crud.py | 8 +-- earthquakes.py | 75 ++++++++++++++++++++++++++-- info/descricao.docx | Bin 0 -> 8110 bytes parser.py | 118 +++++++++++++++++++++++--------------------- 4 files changed, 137 insertions(+), 64 deletions(-) create mode 100644 info/descricao.docx diff --git a/crud.py b/crud.py index 66ee24a..80c0a09 100644 --- a/crud.py +++ b/crud.py @@ -1,3 +1,5 @@ +# pyright: basic + import pandas as pd import parser import earthquakes as eq @@ -46,9 +48,7 @@ def read_table_row(df, event_id, row_number_1): info = [] for (i, col) in enumerate(tableCols): info.append(f"{i+1} {col}: {row[col]}") - # TODO corrigir numeros acima de 10 arruinando o alinhamento - infoString = f"Linha {row_number_1} do evento {event_id}:\n" + "\n".join(info) - return infoString + return f"Linha {row_number_1:02d} do evento {event_id}:\n" + "\n".join(info) def update_table_row(df, event_id, row_number_1, new_data): # atualiza uma linha específica da tabela do evento @@ -133,4 +133,4 @@ if __name__ == "__main__": df, msg = insert_table_row(df, 5, 3) eq.guardar_csv(df, "dados.csv") eq.guardar_df(df, "data.txt") -''' \ No newline at end of file +''' diff --git a/earthquakes.py b/earthquakes.py index 73a1611..1d4f448 100644 --- a/earthquakes.py +++ b/earthquakes.py @@ -1,7 +1,23 @@ #! /usr/bin/env python -import pandas as pd +# pyright: basic + import json -from parser import parse +import os + +import pandas as pd + +import parser +import crud + +HEADER = """=== Terramotos ===""" + +MENU ="""[1] Criar a base de dados +[2] Atualizar uma entrada +[3] Apagar uma entrada +[4] Visualizar uma entrada + +[Q] Sair +""" def guardar_df(df: pd.DataFrame, fname: str) -> bool: with open(fname, "w") as fp: @@ -29,9 +45,62 @@ def guardar_csv(df: pd.DataFrame, fname: str): return True def main(): - pass + isRunning = True + db = parser.parse("dados.txt") + retInfo = None + + while isRunning: + os.system("cls") + print(HEADER + "\n" + MENU) + usrIn = input("Opção: ").lower() + + match usrIn: + case "1": + os.system("cls") + print(HEADER + "\nCRIAR") + fname = input("Nome do ficheiro com os dados. (Branco para dados.txt)") + if fname == "": + fname = "dados.txt" + if _file_exists(fname): + db = parser.parse(fname) + else: + retInfo = "Nenhum ficheiro encontrado!" + pass + case "2": + if db is None: + continue + pass + case "3": + if db is None: + continue + pass + case "4": + if db is not None: + ids = crud.read_ids(db) + print(ids) + + input() + + else: + retInfo = "Base de dados não encontrada!" + case "q": + isRunning = False + continue + case _: + pass + + if retInfo: + print(retInfo) + retInfo = None + input("Clique Enter para continuar") +def _file_exists(name: str) -> bool: + currFiles = os.listdir(os.getcwd()) + if name in currFiles: + return True + return False + if __name__ == '__main__': diff --git a/info/descricao.docx b/info/descricao.docx new file mode 100644 index 0000000000000000000000000000000000000000..f798d5f4b27aee03f6ab65cfa6ff12b72772130f GIT binary patch literal 8110 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 bool: return len(l.strip(" ")) == 0 @@ -32,22 +39,24 @@ def into_dataframe(data) -> pd.DataFrame: return pd.DataFrame(data=aux) -# ------------ principal +def _concat(preamble, df: pd.DataFrame): + for (k,v) in preamble.items(): + df.insert(len(df.columns)-1, k, [v for _ in range(len(df))]) -def parse(fname="dados.txt"): + return df + + +# --- principal --- +def parse(fname): fp = open(fname) data = [l for l in fp.read().split("\n")] chunks = boundaries(data) df = pd.DataFrame() for (idx,c) in enumerate(chunks): - a = parse_chunk(data[c[0]:c[1]], idx) + a = parse_chunk(data[c[0]:c[1]]) aux = pd.concat([df, a], axis=0, ignore_index=True) df = aux - # print(df) - aux = df.loc[df["ID"] == 14] - # print(aux) fp.close() - return df def boundaries(data: list[str]): @@ -63,23 +72,18 @@ def boundaries(data: list[str]): start = None return boundaries - -def parse_chunk(chunk_lines: list[str], iD): +def parse_chunk(chunk_lines: list[str]): hIdx = None for (idx, l) in enumerate(chunk_lines): if l[-1] == "7": hIdx = idx break - headersRet = parse_header(chunk_lines[:hIdx]) - phaseRet = parse_type_7(chunk_lines[hIdx:]) + preambleRet = _parse_preamble(chunk_lines[:hIdx]) + phaseRet = _parse_type_7(chunk_lines[hIdx:]) - hDF = into_dataframe(headersRet) - hDF["ID"] = iD - phaseRet["ID"] = iD - return pd.concat([hDF, phaseRet]) - + return _concat(preambleRet, phaseRet) -def parse_header(hLines: list[str]): +def _parse_preamble(hLines: list[str]): aux = defaultdict(list) for line in hLines: @@ -91,13 +95,15 @@ def parse_header(hLines: list[str]): case "6": aux[6].append(line) case "E": - aux["E"].append(line) + pass + # aux["E"].append(line) case "I": aux["I"].append(line) case "F": - aux["F"].append(line) - case unknown: - warnings.warn(f"header type not implemented: {unknown}") + pass + # aux["F"].append(line) + case _: + pass headerDict = dict() for (k,v) in aux.items(): @@ -106,19 +112,7 @@ def parse_header(hLines: list[str]): return headerDict -def parse_mag(line: str): - magnitudes = [] - base = 55 - while base < 79: - m = line[base:base+4] - mt = line[base+4] - if not is_blank(m): - magnitudes.append({"M": m, "T": mt}) - base += 8 - return magnitudes - - -def parse_type_1(data: list[str]): +def _parse_type_1(data: list[str]): aux = data[0] y = int(aux[1:5]) mo = int(aux[6:8]) @@ -129,55 +123,65 @@ def parse_type_1(data: list[str]): mil = int(aux[19]) * 10**5 dt = datetime(y,mo,d,h,m,s,mil) - dist_ind = aux[21] - eId = aux[22] + dist_ind = DIST_IND[aux[21]] + ev_type = TYPE[aux[22]] lat = float(aux[23:30]) long = float(aux[30:38]) depth = float(aux[38:43]) - rep_ag = aux[45:48] + no_stat = int(aux[48:51]) - hypo = {"DateTime": dt.isoformat(), "Distance Indicator": dist_ind, "Event ID": eId, "Lat": lat, "Long": long, "Depth": depth, "Agency": rep_ag, "Magnitudes": list()} + hypo = {"Data": dt.isoformat(), "Distancia": dist_ind, "Event Type": ev_type, "Lat": lat, "Long": long, "Depth": depth, "No. Stations": no_stat, "Magnitudes": list()} for l in data: - hypo["Magnitudes"] = hypo["Magnitudes"] + parse_mag(l) + hypo["Magnitudes"] = hypo["Magnitudes"] + _parse_mag(l) return hypo -def parse_type_3(data: list[str]): - comments = [] +def _parse_mag(line: str): + magnitudes = [] + base = 55 + while base < 79: + m = line[base:base+4] + mt = line[base+4] + if not is_blank(m): + magnitudes.append({"Magnitude": m, "Tipo": mt}) + base += 8 + return magnitudes + + +def _parse_type_3(data: list[str]): + comments = {} for line in data: - comments.append(line[:-2].strip()) - return {"Comments": comments} + if line.startswith(" SENTIDO") or line.startswith(" REGIAO"): + c, v = line[:-2].strip().split(": ", maxsplit=1) + comments[c.capitalize()] = v + + return comments -def parse_type_6(data: list[str]): +def _parse_type_6(data: list[str]): waves = [] for l in data: waves.append(l.strip().split(" ")[0]) return {"Wave": waves} -def parse_type_7(data: list[str]): + +def _parse_type_7(data: list[str]): aux = io.StringIO("\n".join(data)) - dados = pd.read_fwf(aux, colspecs=[(1,5), (6,8), (9,10), (10,15), (16,17), (18,22), (23,28), (29,33), (34,40), (41,45), (46,50), (51,56), (57,60), (61,63), (64,68), (69,70), (72,75), (76,79)]) + dados = pd.read_fwf(aux, colspecs=[(1,5), (6,8),(10,15), (18,20), (20,22), (23,28), (34,38)]) return dados - -def parse_type_e(data: list[str]): +def _parse_type_e(data: list[str]): aux = data[0] error = {"Gap": int(aux[5:8]), "Origin": float(aux[14:20]), "Error_lat": float(aux[24:30]), "Error_long": float(aux[32:38]), "Error_depth": float(aux[38:43]), "Cov_xy": float(aux[43:55]), "Cov_xz": float(aux[55:67]), "Cov_yz": float(aux[67:79])} return error -def parse_type_f(data: list[str]): - return {} - - -def parse_type_i(data: list[str]): +def _parse_type_i(data: list[str]): aux = data[0] - dt = datetime.strptime(aux[12:26], "%y-%m-%d %H:%M") - return {"Action": aux[8:11], "Action Extra": {"Date": dt.isoformat(), "OP": aux[30:35].strip(), "Status": aux[42:57].strip(), "ID":int(aux[60:74])}} + return {"ID":int(aux[60:74])} -FUNCS = {1: parse_type_1, 3: parse_type_3, 6: parse_type_6, "E": parse_type_e, "F": parse_type_f, "I": parse_type_i} +FUNCS = {1: _parse_type_1, 3: _parse_type_3, 6: _parse_type_6, "E": _parse_type_e, "I": _parse_type_i} -parse() +parse("dados.txt")