From 833c0347ec59d397866a91867fca2f44d594b588 Mon Sep 17 00:00:00 2001 From: omedeiro Date: Wed, 26 Jun 2024 12:23:42 -0400 Subject: [PATCH 1/4] update env name. Create import_tdms() for new ICE log data format --- environment.yml | 12 +++++++++++- src/qnnpy/functions/logging/ice_logging.py | 20 +++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/environment.yml b/environment.yml index d354e53..7e97ef4 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,16 @@ -name: qnnpy_env +name: qnnpy channels: - conda-forge dependencies: - python=3.8 + - pip - numpy + - yaml + - pip: + - black + - ipykernel + - pre-commit + - pyvisa + - mariadb + - pandas + - nptdms diff --git a/src/qnnpy/functions/logging/ice_logging.py b/src/qnnpy/functions/logging/ice_logging.py index 3a5e605..44ab575 100644 --- a/src/qnnpy/functions/logging/ice_logging.py +++ b/src/qnnpy/functions/logging/ice_logging.py @@ -3,11 +3,11 @@ import time from datetime import datetime from pathlib import Path - import mariadb from numpy import array +import nptdms +import pandas as pd -sys.path.append(r"Q:\qnnpy") import qnnpy.functions.functions as qf @@ -149,4 +149,18 @@ def read_ice_log(path, date=False): load_data_to_database(path + "temp.log", "ice_log") file_to_rem = Path(path + "temp.log") file_to_rem.unlink() - return \ No newline at end of file + return + + +def import_tdms(file_path): + tdms_file = nptdms.TdmsFile.read(file_path) + group = tdms_file["Data"] + columns = group.columns() + + data = {} + for column in columns: + data[column] = group[column][:] + + df = pd.DataFrame(data) + + return df From e238db18aa2349eda146c841f6fd1bba16ccf4e0 Mon Sep 17 00:00:00 2001 From: omedeiro Date: Thu, 27 Jun 2024 17:17:07 -0400 Subject: [PATCH 2/4] update logging scripts for ICE software V4.0. Type hinting for database connection function. version --- environment.yml | 2 + pyproject.toml | 2 +- src/qnnpy/functions/functions.py | 8 +- src/qnnpy/functions/logging/ice_logging.py | 347 ++++++++++++--------- 4 files changed, 213 insertions(+), 146 deletions(-) diff --git a/environment.yml b/environment.yml index 7e97ef4..4734757 100644 --- a/environment.yml +++ b/environment.yml @@ -14,3 +14,5 @@ dependencies: - mariadb - pandas - nptdms + - scipy + - matplotlib diff --git a/pyproject.toml b/pyproject.toml index a4fc05b..41a8713 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ build-backend = "pdm.backend" [project] name = "qnnpy" -version = "0.1.6" +version = "0.1.7" authors = [ { name="O. Medeiros", email="omedeiro@mit.edu" }, diff --git a/src/qnnpy/functions/functions.py b/src/qnnpy/functions/functions.py index f869924..0ca36e5 100644 --- a/src/qnnpy/functions/functions.py +++ b/src/qnnpy/functions/functions.py @@ -22,6 +22,7 @@ import numpy as np import scipy.io import yaml +from mariadb import Connection from matplotlib import pyplot as plt if sys.platform == "win32": @@ -696,10 +697,10 @@ def output_log(parameters, path): file.close() -def database_connection(**kwargs): +def database_connection(**kwargs) -> Connection: if kwargs is None or len(kwargs) == 0: try: - conn = mariadb.connect( + conn: Connection = mariadb.connect( host="18.25.16.44", user="omedeiro", port=3307, @@ -711,7 +712,7 @@ def database_connection(**kwargs): raise ConnectionError else: try: - conn = mariadb.connect(kwargs) + conn: Connection = mariadb.connect(kwargs) except mariadb.Error as e: print(f"Error connecting to MariaDB Platform: {e}") raise ConnectionError @@ -1192,7 +1193,6 @@ def scope_setup(self, properties: dict, instrument_num: int = 0): self.scope = self.scope1 def meter_setup(self, properties: dict, instrument_num: int = 0): - appender: str = str(instrument_num) if instrument_num == 0: appender = "" diff --git a/src/qnnpy/functions/logging/ice_logging.py b/src/qnnpy/functions/logging/ice_logging.py index 44ab575..0701dfa 100644 --- a/src/qnnpy/functions/logging/ice_logging.py +++ b/src/qnnpy/functions/logging/ice_logging.py @@ -1,166 +1,231 @@ -import csv -import sys -import time -from datetime import datetime +import os +import tempfile from pathlib import Path + import mariadb -from numpy import array import nptdms import pandas as pd +from mariadb import Connection +from pandas.core.frame import DataFrame import qnnpy.functions.functions as qf -def load_data_to_database(filename: str, table_name: str, connection=None): - if connection is not None: - conn = connection - else: - conn = qf.database_connection() - +def load_data_to_database( + filename: str, table_name: str, connection: Connection = None +): + conn = connect_to_database(connection) + file_path = os.path.join(filename) + file_path = file_path.replace("\\", "/") + print(f"{file_path}") cur = conn.cursor() - command = ( - "LOAD DATA LOCAL INFILE '%s' IGNORE INTO TABLE `%s` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' " - % (filename, table_name) - ) - cur.execute(command) + command = f"LOAD DATA LOCAL INFILE '{file_path}' IGNORE INTO TABLE `{table_name}` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n';" + + print(command) + try: + cur.execute(command) + except mariadb.IntegrityError: + pass conn.commit() - time.sleep(2) conn.close() -def log_many_rows_to_database(table_name: str, connection=None, **kwargs): - """ - table_name [str]: name of table to insert rows to - kwargs: should be of form COLUMN_NAME:[list, of, values, in, column] - - executemany takes two arguments: - -1) the command string, with VALUES (%s, %s...%s) for #columns to write - -2) a list of tuples of rows, e.g. - data = [ - (row1_column1, row1_column2, ...row1_columnn), - ... - (rowm_column1, rowm_column2, ...rowm_columnn) - ] - """ +def connect_to_database(connection=None) -> Connection: if connection is not None: conn = connection else: conn = qf.database_connection() + return conn - cur = conn.cursor() - column_names = "`" + "`, `".join(kwargs.keys()) + "`" - values_sideways = array([v for v in kwargs.values()]) - values = values_sideways.T.tolist() - # values = "'"+"', '".join([str(v) for v in kwargs.values()])+"'" - for value in values: - try: - command = "INSERT INTO `%s` (%s) VALUES (%s)" % ( - table_name, - column_names, - str(value)[1:-1], - ) - cur.execute(command) - conn.commit() - time.sleep(0.5) - except mariadb.IntegrityError: - pass - if connection == None: - conn.close() - - -def read_ice_log(path, date=False): - log_columns = { - "date": [], - "time": [], - "epochtime": [], - "date_time": [], - "T1": [], - "T2": [], - "T3": [], - "T4": [], - "sensor1": [], - "sensor2": [], - "sensor3": [], - "sensor4": [], - "heater1": [], - "heater2": [], - "needlevalve": [], - "needlevalve2": [], - "null1": [], - "null2": [], - "setpoint2": [], - "20_1": [], - "ramprate2": [], - "null3": [], - "P": [], - "I": [], - "D": [], - "50_1": [], - "20_2": [], - "null4": [], - "null5": [], - "dump_pressure": [], - } - - datetime_format = "%m/%d/%Y %I:%M:%S %p" - - if not date: - # yesterday = datetime.now() - timedelta(1) - date = datetime.strftime(datetime.now(), "%Y-%m-%d") - - path = path + date + "/" +def import_tdms(file_path): try: - with open(path + date + ".log") as csvfile: - read = csv.reader(csvfile) - - with open(path + "temp.log", "w", newline="\n") as csvfile: - write = csv.writer(csvfile, delimiter=",") - - for i, row in enumerate(read): - log_columns["epochtime"].append(int(row[2])) - datetime_data = datetime.strftime( - datetime.strptime(row[3], datetime_format), "%Y-%m-%d %H:%M:%S" - ) - log_columns["date_time"].append(datetime_data) - log_columns["T1"].append(float(row[4])) - log_columns["T2"].append(float(row[5])) - log_columns["T3"].append(float(row[6])) - log_columns["T4"].append(float(row[7])) - log_columns["needlevalve"].append(float(row[14])) - log_columns["dump_pressure"].append(float(row[29])) - - write.writerow( - [ - log_columns["epochtime"][i], - log_columns["date_time"][i], - log_columns["T1"][i], - log_columns["T2"][i], - log_columns["T3"][i], - log_columns["T4"][i], - log_columns["needlevalve"][i], - log_columns["dump_pressure"][i], - ] - ) - except Exception as e: - print(e) - time.sleep(600) - - load_data_to_database(path + "temp.log", "ice_log") - file_to_rem = Path(path + "temp.log") - file_to_rem.unlink() - return + with nptdms.TdmsFile.open(file_path) as tdms_file: + group = tdms_file["Data"] + data_dict = {} + + for channel_name in group.channels(): + if channel_name.name in [ + "Unix Timestamp", + "1k", + "4k", + "50k", + "SORB", + "Needle Valve 1", + "Dump Pressure", + "Circulation Pressure", + ]: + channel = group[channel_name.name] + data_dict[channel_name.name] = channel[:] + + return data_dict + + except FileNotFoundError: + print("Error: File not found!") + + +def format_data(data_dict: dict) -> DataFrame: + df = pd.DataFrame(data_dict) + df["date_time"] = pd.to_datetime(df["Unix Timestamp"], unit="s") + df["date_time"] = df["date_time"].dt.strftime("%Y-%m-%d %H:%M:%S") + df = df.iloc[:, [0, 8, 3, 2, 1, 4, 5, 7, 6]] + df.columns = [ + "epochtime", + "datetime", + "T1", + "T2", + "T3", + "T4", + "needlevalve", + "pressure", + "dump_pressure", + ] + return df -def import_tdms(file_path): - tdms_file = nptdms.TdmsFile.read(file_path) - group = tdms_file["Data"] - columns = group.columns() +def export_to_csv(data_frame: DataFrame): + with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp: + data_frame.to_csv(temp.name + ".log", index=False, header=False) + return temp.name + ".log" + - data = {} - for column in columns: - data[column] = group[column][:] +def write_table_to_database(data_frame: DataFrame, table_name: str, connection=None): + temp_file = export_to_csv(data_frame) + load_data_to_database(temp_file, table_name, connection) + Path(temp_file).unlink() + os.remove(temp_file[:-4]) + return - df = pd.DataFrame(data) - return df +file_name = r"S:\SC\InstrumentLogging\Cryogenics\Ice\ice-log\Logs\2024_06_26_13_26_35_Ice_V4_Data.tdms" +data_dict = import_tdms(file_name) +df = format_data(data_dict) +write_table_to_database(df, "ice_log") + + +# -------------------------------------------------------------------------------------------- +# Archived functions for ICE Software V2.0 +# -------------------------------------------------------------------------------------------- + +# def log_many_rows_to_database(table_name: str, connection=None, **kwargs): +# """ +# table_name [str]: name of table to insert rows to +# kwargs: should be of form COLUMN_NAME:[list, of, values, in, column] + +# executemany takes two arguments: +# -1) the command string, with VALUES (%s, %s...%s) for #columns to write +# -2) a list of tuples of rows, e.g. +# data = [ +# (row1_column1, row1_column2, ...row1_columnn), +# ... +# (rowm_column1, rowm_column2, ...rowm_columnn) +# ] +# """ +# if connection is not None: +# conn = connection +# else: +# conn = qf.database_connection() + +# cur = conn.cursor() +# column_names = "`" + "`, `".join(kwargs.keys()) + "`" +# values_sideways = array([v for v in kwargs.values()]) +# values = values_sideways.T.tolist() +# # values = "'"+"', '".join([str(v) for v in kwargs.values()])+"'" +# for value in values: +# try: +# command = "INSERT INTO `%s` (%s) VALUES (%s)" % ( +# table_name, +# column_names, +# str(value)[1:-1], +# ) +# cur.execute(command) +# conn.commit() +# time.sleep(0.5) +# except mariadb.IntegrityError: +# pass +# if connection == None: +# conn.close() + + +# def read_ice_log(path, date=False): +# log_columns = { +# "date": [], +# "time": [], +# "epochtime": [], +# "date_time": [], +# "T1": [], +# "T2": [], +# "T3": [], +# "T4": [], +# "sensor1": [], +# "sensor2": [], +# "sensor3": [], +# "sensor4": [], +# "heater1": [], +# "heater2": [], +# "needlevalve": [], +# "needlevalve2": [], +# "null1": [], +# "null2": [], +# "setpoint2": [], +# "20_1": [], +# "ramprate2": [], +# "null3": [], +# "P": [], +# "I": [], +# "D": [], +# "50_1": [], +# "20_2": [], +# "null4": [], +# "null5": [], +# "dump_pressure": [], +# } + +# datetime_format = "%m/%d/%Y %I:%M:%S %p" + +# if not date: +# # yesterday = datetime.now() - timedelta(1) +# date = datetime.strftime(datetime.now(), "%Y-%m-%d") + +# path = path + date + "/" + +# try: +# with open(path + date + ".log") as csvfile: +# read = csv.reader(csvfile) + +# with open(path + "temp.log", "w", newline="\n") as csvfile: +# write = csv.writer(csvfile, delimiter=",") + +# for i, row in enumerate(read): +# log_columns["epochtime"].append(int(row[2])) +# datetime_data = datetime.strftime( +# datetime.strptime(row[3], datetime_format), "%Y-%m-%d %H:%M:%S" +# ) +# log_columns["date_time"].append(datetime_data) +# log_columns["T1"].append(float(row[4])) +# log_columns["T2"].append(float(row[5])) +# log_columns["T3"].append(float(row[6])) +# log_columns["T4"].append(float(row[7])) +# log_columns["needlevalve"].append(float(row[14])) +# log_columns["dump_pressure"].append(float(row[29])) + +# write.writerow( +# [ +# log_columns["epochtime"][i], +# log_columns["date_time"][i], +# log_columns["T1"][i], +# log_columns["T2"][i], +# log_columns["T3"][i], +# log_columns["T4"][i], +# log_columns["needlevalve"][i], +# log_columns["dump_pressure"][i], +# ] +# ) +# except Exception as e: +# print(e) +# time.sleep(600) + +# load_data_to_database(path + "temp.log", "ice_log") +# file_to_rem = Path(path + "temp.log") +# file_to_rem.unlink() +# return From dff8cc971a16300760eb9d424ff79d77405589c6 Mon Sep 17 00:00:00 2001 From: omedeiro Date: Mon, 1 Jul 2024 09:37:33 -0400 Subject: [PATCH 3/4] refactor Lecroy and AWG setups with the goal of removeing exec() commands. Multiple instruement support to be deprioritized. implement as needed basis --- src/qnnpy/functions/functions.py | 88 +++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/src/qnnpy/functions/functions.py b/src/qnnpy/functions/functions.py index 0ca36e5..82fa71b 100644 --- a/src/qnnpy/functions/functions.py +++ b/src/qnnpy/functions/functions.py @@ -431,9 +431,11 @@ def data_saver( parameters["Save File"]["sample name"] = ( parameters["Save File"][f"sample name {i+1}"] if parameters["Save File"].get(f"sample name {i+1}") - else parameters.get("Save File").get("sample name") - if parameters.get("Save File").get("sample name") - else "" + else ( + parameters.get("Save File").get("sample name") + if parameters.get("Save File").get("sample name") + else "" + ) ) res.append( data_saver( @@ -1079,6 +1081,8 @@ def attenuator_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("Attenuator" + appender) if properties[f"Attenuator{appender}"]["name"] == "JDSHA9": + from qnnpy.instruments.jds_ha9 import JDSHA9 + try: exec( f"self.attenuator{appender} = JDSHA9(properties['Attenuator{appender}']['port'])" @@ -1091,6 +1095,8 @@ def attenuator_setup(self, properties: dict, instrument_num: int = 0): except: print(f"ATTENUATOR{appender}: failed to connect") elif properties[f"Attenuator{appender}"]["name"] == "N7752A": + from qnnpy.instruments.keysight_n7752a import N7752A + try: exec( f"self.attenuator{appender} = N7752A(properties['Attenuator{appender}']['port'])" @@ -1116,6 +1122,8 @@ def counter_setup(self, properties: dict, instrument_num: int = 0): appender = "" self.instrument_list.append("Counter" + appender) if properties[f"Counter{appender}"]["name"] == "Agilent53131a": + from qnnpy.instruments.agilent_53131a import Agilent53131a + try: exec( f"self.counter{appender} = Agilent53131a(properties['Counter{appender}']['port'])" @@ -1133,6 +1141,8 @@ def counter_setup(self, properties: dict, instrument_num: int = 0): except: print(f"COUNTER{appender}: failed to connect") elif properties[f"Counter{appender}"]["name"] == "Keysight53230a": + from qnnpy.instruments.keysight_53230a import Keysight53230a + try: exec( f"self.counter{appender} = Keysight53230a(properties['Counter{appender}']['port'])" @@ -1158,26 +1168,34 @@ def scope_setup(self, properties: dict, instrument_num: int = 0): appender: str = str(instrument_num) if instrument_num == 0: appender = "" - self.instrument_list.append("Scope" + appender) + else: + appender = str(instrument_num) + inst_name = f"Scope{appender}" + self.instrument_list.append(inst_name) + + if properties[inst_name]["name"] == "LeCroy620Zi": + from qnnpy.instruments.lecroy_620zi import LeCroy620Zi - if properties[f"Scope{appender}"]["name"] == "LeCroy620Zi": try: - if properties[f"Scope{appender}"]["port"][0:3] == "USB": - exec( - f"self.scope{appender} = LeCroy620Zi('%s' % properties['Scope{appender}']['port'])" - ) + if properties[inst_name]["port"][0:3] == "USB": + visa_address = properties[inst_name]["port"] else: - exec( - f"self.scope{appender} = LeCroy620Zi('TCPIP::%s::INSTR' % properties['Scope{appender}']['port'])" - ) + visa_address = f"TCPIP::{properties[inst_name]['port']}::INSTR" - # self.scope_channel = properties[f'Scope{appender}']['channel'] + if instrument_num == 0: + self.scope = LeCroy620Zi(visa_address) + self.scope_channel = properties[inst_name]["channel"] + else: + NotImplementedError("Multiple scopes not supported yet") + # self.scope1 = LeCroy620Zi(visa_address) exec(f"self.instrument_dict['scope{appender}']=self.scope{appender}") print(f"SCOPE{appender}: connected") except: print(f"SCOPE{appender}: failed to connect") elif properties[f"Scope{appender}"]["name"] == "KeysightDSOX": + from qnnpy.instruments.keysight_dsox import KeysightDSOX + try: exec( f"self.scope{appender} = KeysightDSOX('%s' % properties['Scope{appender}']['port'])" @@ -1199,6 +1217,8 @@ def meter_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("Meter" + appender) if properties[f"Meter{appender}"]["name"] == "Keithley2700": + from qnnpy.instruments.keithley_2700 import Keithley2700 + try: print("in meter_setup, Keithley2700\n") exec( @@ -1213,6 +1233,8 @@ def meter_setup(self, properties: dict, instrument_num: int = 0): # exec(f"self.meter{appender} = mock_builder(Keithley2700)") elif properties[f"Meter{appender}"]["name"] == "Keithley2400": + from qnnpy.instruments.keithley_2400 import Keithley2400 + # this is a source meter try: @@ -1227,6 +1249,8 @@ def meter_setup(self, properties: dict, instrument_num: int = 0): # exec(f"self.meter{appender} = mock_builder(YokogawaGS200)") elif properties[f"Meter{appender}"]["name"] == "Keithley2001": + from qnnpy.instruments.keithley_2001 import Keithley2001 + try: exec( f"self.meter{appender} = Keithley2001(properties['Meter{appender}']['port'])" @@ -1252,6 +1276,8 @@ def source_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("Source" + appender) if properties[f"Source{appender}"]["name"] == "SIM928": + from qnnpy.instruments.srs_sim928 import SIM928 + try: exec( f"self.source{appender} = SIM928(properties['Source{appender}']['port'], properties['Source{appender}']['port_alt'])" @@ -1264,6 +1290,8 @@ def source_setup(self, properties: dict, instrument_num: int = 0): print(f"SOURCE{appender}: failed to connect") # exec(f"self.source{appender} = mock_builder(SIM928)") elif properties[f"Source{appender}"]["name"] == "YokogawaGS200": + from qnnpy.instruments.yokogawa_gs200 import YokogawaGS200 + try: exec( f"self.source{appender} = YokogawaGS200(properties['Source{appender}']['port'])" @@ -1277,6 +1305,8 @@ def source_setup(self, properties: dict, instrument_num: int = 0): print(f"SOURCE{appender}: failed to connect") # exec(f"self.source{appender} = mock_builder(YokogawaGS200)") elif properties[f"Source{appender}"]["name"] == "Keithley2400": + from qnnpy.instruments.keithley_2400 import Keithley2400 + try: exec( f"self.source{appender} = Keithley2400(properties['Source{appender}']['port'])" @@ -1302,6 +1332,8 @@ def sourcemeter_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("Sourcemeter" + appender) if properties[f"Sourcemeter{appender}"]["name"] == "KeysightB2912a": + from qnnpy.instruments.keysight_b2912a import KeysightB2912a + try: # exec(f"self.sourcemeter{appender} = KeysightB2912a(properties['Sourcemeter{appender}']['port'], properties['Sourcemeter{appender}']['port_alt'])") exec( @@ -1328,19 +1360,29 @@ def AWG_setup(self, properties: dict, instrument_num: int = 0): appender: str = str(instrument_num) if instrument_num == 0: appender = "" + else: + appender = str(instrument_num) self.instrument_list.append("AWG" + appender) if properties["AWG" + appender]["name"] == "Agilent33250a": + from qnnpy.instruments.agilent_33250a import Agilent33250a + try: - exec( - f"self.awg{appender} = Agilent33250a(properties['AWG{appender}']['port'])" - ) - exec(f"self.awg{appender}.beep()") - exec(f"self.instrument_dict['awg{appender}']=self.awg{appender}") + awg = Agilent33250a(properties["AWG" + appender]["port"]) + awg.beep() + + if instrument_num == 0: + self.awg = awg + else: + exec(f"self.awg{appender} = awg") + + self.instrument_dict[f"awg{appender}"]=awg print(f"AWG{appender}: connected") except: print(f"AWG{appender}: failed to connect") elif properties["AWG" + appender]["name"] == "Agilent33600a": + from qnnpy.instruments.agilent_33600a import Agilent33600a + try: exec( f"self.awg{appender} = Agilent33600a(properties['AWG{appender}']['port'])" @@ -1367,6 +1409,8 @@ def VNA_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("VNA" + appender) if properties["VNA" + appender]["name"] == "KeysightN5224a": + from qnnpy.instruments.keysight_n5224a import KeysightN5224a + try: exec( f"VNA{appender} = KeysightN5224a(properties['VNA{appender}']['port'])" @@ -1392,6 +1436,8 @@ def temp_setup(self, properties: dict, instrument_num: int = 0): self.instrument_list.append("Temperature" + appender) if properties["Temperature"]["name"] == "Lakeshore336": + from qnnpy.instruments.lakeshore336 import Lakeshore336 + try: exec( f"self.temp{appender} = Lakeshore336(properties['Temperature{appender}']['port'])" @@ -1415,6 +1461,8 @@ def temp_setup(self, properties: dict, instrument_num: int = 0): print(e) elif properties["Temperature" + appender]["name"] == "Cryocon34": + from qnnpy.instruments.cryocon34 import Cryocon34 + try: exec( f"self.temp{appender} = Cryocon34(properties['Temperature{appender}']['port'])" @@ -1569,7 +1617,9 @@ def __init__( SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '{0}' - """.format(table_name.replace("'", "''")) + """.format( + table_name.replace("'", "''") + ) ) if not cursor.fetchone()[0] == 1: print(f"Table {table_name} does not exist.") From 4859ca906a9b5e3ec681a31a03140a9c589e298a Mon Sep 17 00:00:00 2001 From: omedeiro Date: Mon, 1 Jul 2024 09:46:17 -0400 Subject: [PATCH 4/4] version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 41a8713..87312fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ build-backend = "pdm.backend" [project] name = "qnnpy" -version = "0.1.7" +version = "0.1.8" authors = [ { name="O. Medeiros", email="omedeiro@mit.edu" },