From ecd57ea3dcf7791567cc04830b1755213dc6f54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Tue, 11 Jun 2024 21:26:15 +0200 Subject: [PATCH] fixed items from code review --- shaketune/__init__.py | 2 - shaketune/commands/__init__.py | 2 - shaketune/commands/accelerometer.py | 6 +-- shaketune/commands/axes_map_calibration.py | 3 -- shaketune/commands/axes_shaper_calibration.py | 5 +-- shaketune/commands/compare_belts_responses.py | 3 -- .../commands/create_vibrations_profile.py | 5 +-- shaketune/commands/excitate_axis_at_freq.py | 4 +- shaketune/graph_creators/__init__.py | 2 - .../graph_creators/axes_map_graph_creator.py | 7 +--- .../graph_creators/belts_graph_creator.py | 24 ++++-------- shaketune/graph_creators/graph_creator.py | 2 - .../graph_creators/shaper_graph_creator.py | 39 +++++++------------ .../graph_creators/static_graph_creator.py | 4 +- .../vibrations_graph_creator.py | 25 +++++------- shaketune/helpers/common_func.py | 14 +++---- shaketune/helpers/motors_config_parser.py | 14 ++----- shaketune/helpers/resonance_test.py | 2 - shaketune/shaketune.py | 5 +-- shaketune/shaketune_config.py | 2 - shaketune/shaketune_process.py | 4 +- 21 files changed, 52 insertions(+), 122 deletions(-) diff --git a/shaketune/__init__.py b/shaketune/__init__.py index 297f10a..5c97c20 100644 --- a/shaketune/__init__.py +++ b/shaketune/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - ############################################ ###### INPUT SHAPER KLIPPAIN WORKFLOW ###### ############################################ diff --git a/shaketune/commands/__init__.py b/shaketune/commands/__init__.py index 17c7707..7565318 100644 --- a/shaketune/commands/__init__.py +++ b/shaketune/commands/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from .axes_map_calibration import axes_map_calibration as axes_map_calibration from .axes_shaper_calibration import axes_shaper_calibration as axes_shaper_calibration from .compare_belts_responses import compare_belts_responses as compare_belts_responses diff --git a/shaketune/commands/accelerometer.py b/shaketune/commands/accelerometer.py index 1a2e3c3..f8d55a1 100644 --- a/shaketune/commands/accelerometer.py +++ b/shaketune/commands/accelerometer.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # This file provides a custom and internal Shake&Tune Accelerometer helper that is # an interface to Klipper's own accelerometer classes. It is used to start and # stop accelerometer measurements and write the data to a file in a blocking manner. @@ -18,7 +16,7 @@ class Accelerometer: def find_axis_accelerometer(printer, axis: str = 'xy'): accel_chip_names = printer.lookup_object('resonance_tester').accel_chip_names for chip_axis, chip_name in accel_chip_names: - if axis in ['x', 'y'] and chip_axis == 'xy': + if axis in {'x', 'y'} and chip_axis == 'xy': return chip_name elif chip_axis == axis: return chip_name @@ -57,4 +55,4 @@ class Accelerometer: f.write('#time,accel_x,accel_y,accel_z\n') samples = bg_client.samples or bg_client.get_samples() for t, accel_x, accel_y, accel_z in samples: - f.write('%.6f,%.6f,%.6f,%.6f\n' % (t, accel_x, accel_y, accel_z)) + f.write(f'{t:.6f},{accel_x:.6f},{accel_y:.6f},{accel_z:.6f}\n') diff --git a/shaketune/commands/axes_map_calibration.py b/shaketune/commands/axes_map_calibration.py index 2cf22d3..c55a4fe 100644 --- a/shaketune/commands/axes_map_calibration.py +++ b/shaketune/commands/axes_map_calibration.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 - - from ..helpers.console_output import ConsoleOutput from ..shaketune_process import ShakeTuneProcess from .accelerometer import Accelerometer diff --git a/shaketune/commands/axes_shaper_calibration.py b/shaketune/commands/axes_shaper_calibration.py index 26009fa..2579480 100644 --- a/shaketune/commands/axes_shaper_calibration.py +++ b/shaketune/commands/axes_shaper_calibration.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 - - from ..helpers.common_func import AXIS_CONFIG from ..helpers.console_output import ConsoleOutput from ..helpers.resonance_test import vibrate_axis @@ -14,7 +11,7 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: hz_per_sec = gcmd.get_float('HZ_PER_SEC', default=1, minval=1) accel_per_hz = gcmd.get_float('ACCEL_PER_HZ', default=None) axis_input = gcmd.get('AXIS', default='all').lower() - if axis_input not in ['x', 'y', 'all']: + if axis_input not in {'x', 'y', 'all'}: raise gcmd.error('AXIS selection invalid. Should be either x, y, or all!') scv = gcmd.get_float('SCV', default=None, minval=0) max_sm = gcmd.get_float('MAX_SMOOTHING', default=None, minval=0) diff --git a/shaketune/commands/compare_belts_responses.py b/shaketune/commands/compare_belts_responses.py index 54ac8cb..fe6eb39 100644 --- a/shaketune/commands/compare_belts_responses.py +++ b/shaketune/commands/compare_belts_responses.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 - - from ..helpers.common_func import AXIS_CONFIG from ..helpers.console_output import ConsoleOutput from ..helpers.motors_config_parser import MotorsConfigParser diff --git a/shaketune/commands/create_vibrations_profile.py b/shaketune/commands/create_vibrations_profile.py index 62f1785..47b429b 100644 --- a/shaketune/commands/create_vibrations_profile.py +++ b/shaketune/commands/create_vibrations_profile.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 - - import math from ..helpers.console_output import ConsoleOutput @@ -39,7 +36,7 @@ def create_vibrations_profile(gcmd, config, st_process: ShakeTuneProcess) -> Non raise gcmd.error('Input shaper is not configured! Please run the shaper calibration macro first.') motors_config_parser = MotorsConfigParser(config, motors=['stepper_x', 'stepper_y']) - if motors_config_parser.kinematics == 'cartesian' or motors_config_parser.kinematics == 'corexz': + if motors_config_parser.kinematics in {'cartesian', 'corexz'}: main_angles = [0, 90] # Cartesian motors are on X and Y axis directly, same for CoreXZ elif motors_config_parser.kinematics == 'corexy': main_angles = [45, 135] # CoreXY motors are on A and B axis (45 and 135 degrees) diff --git a/shaketune/commands/excitate_axis_at_freq.py b/shaketune/commands/excitate_axis_at_freq.py index 0aa0afd..fdf9b7c 100644 --- a/shaketune/commands/excitate_axis_at_freq.py +++ b/shaketune/commands/excitate_axis_at_freq.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from ..helpers.common_func import AXIS_CONFIG from ..helpers.console_output import ConsoleOutput from ..helpers.resonance_test import vibrate_axis_at_static_freq @@ -29,7 +27,7 @@ def excitate_axis_at_freq(gcmd, config, st_process: ShakeTuneProcess) -> None: if create_graph: printer = config.get_printer() if accel_chip is None: - accel_chip = Accelerometer.find_axis_accelerometer(printer, 'xy' if axis in ['a', 'b'] else axis) + accel_chip = Accelerometer.find_axis_accelerometer(printer, 'xy' if axis in {'a', 'b'} else axis) k_accelerometer = printer.lookup_object(accel_chip, None) if k_accelerometer is None: raise gcmd.error(f'Accelerometer chip [{accel_chip}] was not found!') diff --git a/shaketune/graph_creators/__init__.py b/shaketune/graph_creators/__init__.py index 1b3c530..c433ba0 100644 --- a/shaketune/graph_creators/__init__.py +++ b/shaketune/graph_creators/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from .axes_map_graph_creator import AxesMapGraphCreator as AxesMapGraphCreator from .belts_graph_creator import BeltsGraphCreator as BeltsGraphCreator from .graph_creator import GraphCreator as GraphCreator diff --git a/shaketune/graph_creators/axes_map_graph_creator.py b/shaketune/graph_creators/axes_map_graph_creator.py index 10f0ee9..c128c14 100644 --- a/shaketune/graph_creators/axes_map_graph_creator.py +++ b/shaketune/graph_creators/axes_map_graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - ###################################### ###### AXE_MAP DETECTION SCRIPT ###### ###################################### @@ -66,7 +64,7 @@ class AxesMapGraphCreator(GraphCreator): return # No need to delete any files for old_file in files[keep_results:]: file_date = '_'.join(old_file.stem.split('_')[1:3]) - for suffix in ['X', 'Y', 'Z']: + for suffix in {'X', 'Y', 'Z'}: csv_file = self._folder / f'axesmap_{file_date}_{suffix}.csv' csv_file.unlink(missing_ok=True) old_file.unlink() @@ -421,8 +419,7 @@ def axesmap_calibration( title_line2 += f' -- at {accel:0.0f} mm/s²' except Exception: ConsoleOutput.print( - 'Warning: CSV filenames look to be different than expected (%s , %s, %s)' - % (lognames[0], lognames[1], lognames[2]) + f'Warning: CSV filenames look to be different than expected ({lognames[0]}, {lognames[1]}, {lognames[2]})' ) title_line2 = lognames[0].split('/')[-1] + ' ...' fig.text(0.060, 0.939, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) diff --git a/shaketune/graph_creators/belts_graph_creator.py b/shaketune/graph_creators/belts_graph_creator.py index 0ab1411..7da6ef3 100644 --- a/shaketune/graph_creators/belts_graph_creator.py +++ b/shaketune/graph_creators/belts_graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - ################################################# ######## CoreXY BELTS CALIBRATION SCRIPT ######## ################################################# @@ -88,7 +86,7 @@ class BeltsGraphCreator(GraphCreator): return # No need to delete any files for old_file in files[keep_results:]: file_date = '_'.join(old_file.stem.split('_')[1:3]) - for suffix in ['A', 'B']: + for suffix in {'A', 'B'}: csv_file = self._folder / f'beltscomparison_{file_date}_{suffix}.csv' csv_file.unlink(missing_ok=True) old_file.unlink() @@ -192,11 +190,10 @@ def mhi_lut(mhi: float) -> str: (0, 15, 'Mechanical issue detected'), ] mhi = np.clip(mhi, 1, 100) - for lower, upper, message in ranges: - if lower < mhi <= upper: - return message - - return 'Unknown mechanical health' # Should never happen + return next( + (message for lower, upper, message in ranges if lower < mhi <= upper), + 'Unknown mechanical health', + ) ###################################################################### @@ -220,9 +217,6 @@ def plot_compare_frequency( for _, (peak1, peak2) in enumerate(signal1.paired_peaks): label = ALPHABET[paired_peak_count] - # amplitude_offset = abs( - # ((signal2.psd[peak2[0]] - signal1.psd[peak1[0]]) / max(signal1.psd[peak1[0]], signal2.psd[peak2[0]])) * 100 - # ) amplitude_offset = abs(((signal2.psd[peak2[0]] - signal1.psd[peak1[0]]) / psd_highest_max) * 100) frequency_offset = abs(signal2.freqs[peak2[0]] - signal1.freqs[peak1[0]]) offsets_table_data.append([f'Peaks {label}', f'{frequency_offset:.1f} Hz', f'{amplitude_offset:.1f} %']) @@ -507,7 +501,7 @@ def belts_calibration( # Parse data from the log files while ignoring CSV in the wrong format datas = [data for data in (parse_log(fn) for fn in lognames) if data is not None] - if len(datas) > 2: + if len(datas) != 2: raise ValueError('Incorrect number of .csv files used (this function needs exactly two files to compare them)!') # Get the belts name for the legend to avoid putting the full file name @@ -569,15 +563,13 @@ def belts_calibration( if kinematics is not None: title_line2 += ' -- ' + kinematics.upper() + ' kinematics' except Exception: - ConsoleOutput.print( - 'Warning: CSV filenames look to be different than expected (%s , %s)' % (lognames[0], lognames[1]) - ) + ConsoleOutput.print(f'Warning: Unable to parse the date from the filename ({lognames[0]}, {lognames[1]})') title_line2 = lognames[0].split('/')[-1] + ' / ' + lognames[1].split('/')[-1] fig.text(0.060, 0.939, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) # We add the estimated similarity and the MHI value to the title only if the kinematics is CoreXY # as it make no sense to compute these values for other kinematics that doesn't have paired belts - if kinematics in ['corexy', 'corexz']: + if kinematics in {'corexy', 'corexz'}: title_line3 = f'| Estimated similarity: {similarity_factor:.1f}%' title_line4 = f'| {mhi} (experimental)' fig.text(0.55, 0.985, title_line3, ha='left', va='top', fontsize=14, color=KLIPPAIN_COLORS['dark_purple']) diff --git a/shaketune/graph_creators/graph_creator.py b/shaketune/graph_creators/graph_creator.py index b86c97c..d3ed4f5 100644 --- a/shaketune/graph_creators/graph_creator.py +++ b/shaketune/graph_creators/graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import abc import shutil from datetime import datetime diff --git a/shaketune/graph_creators/shaper_graph_creator.py b/shaketune/graph_creators/shaper_graph_creator.py index 73a871a..8733c8e 100644 --- a/shaketune/graph_creators/shaper_graph_creator.py +++ b/shaketune/graph_creators/shaper_graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - ################################################# ######## INPUT SHAPER CALIBRATION SCRIPT ######## ################################################# @@ -131,8 +129,7 @@ def calibrate_shaper(datas: List[np.ndarray], max_smoothing: Optional[float], sc shaper, all_shapers = helper.find_best_shaper(calibration_data, max_smoothing, ConsoleOutput.print) ConsoleOutput.print( - '\n-> Recommended shaper is %s @ %.1f Hz (when using a square corner velocity of %.1f and a damping ratio of %.3f)' - % (shaper.name.upper(), shaper.freq, scv, zeta) + f'\n-> Recommended shaper is {shaper.name.upper()} @ {shaper.freq:.1f} Hz (when using a square corner velocity of {scv:.1f} and a damping ratio of {zeta:.3f})' ) return shaper.name, all_shapers, calibration_data, fr, zeta, compat @@ -190,13 +187,7 @@ def plot_freq_response( perf_shaper_accel = 0 for shaper in shapers: shaper_max_accel = round(shaper.max_accel / 100.0) * 100.0 - label = '%s (%.1f Hz, vibr=%.1f%%, sm~=%.2f, accel<=%.f)' % ( - shaper.name.upper(), - shaper.freq, - shaper.vibrs * 100.0, - shaper.smoothing, - shaper_max_accel, - ) + label = f'{shaper.name.upper()} ({shaper.freq:.1f} Hz, vibr={shaper.vibrs * 100.0:.1f}%, sm~={shaper.smoothing:.2f}, accel<={shaper_max_accel:.0f})' ax2.plot(freqs, shaper.vals, label=label, linestyle='dotted') # Get the Klipper recommended shaper (usually it's a good low vibration compromise) @@ -226,40 +217,37 @@ def plot_freq_response( [], [], ' ', - label='Recommended performance shaper: %s @ %.1f Hz' % (perf_shaper_choice.upper(), perf_shaper_freq), + label=f'Recommended performance shaper: {perf_shaper_choice.upper()} @ {perf_shaper_freq:.1f} Hz', ) ax.plot( freqs, psd * perf_shaper_vals, - label='With %s applied' % (perf_shaper_choice.upper()), + label=f'With {perf_shaper_choice.upper()} applied', color='cyan', ) ax2.plot( [], [], ' ', - label='Recommended low vibrations shaper: %s @ %.1f Hz' - % (klipper_shaper_choice.upper(), klipper_shaper_freq), - ) - ax.plot( - freqs, psd * klipper_shaper_vals, label='With %s applied' % (klipper_shaper_choice.upper()), color='lime' + label=f'Recommended low vibrations shaper: {klipper_shaper_choice.upper()} @ {klipper_shaper_freq:.1f} Hz', ) + ax.plot(freqs, psd * klipper_shaper_vals, label=f'With {klipper_shaper_choice.upper()} applied', color='lime') else: ax2.plot( [], [], ' ', - label='Recommended best shaper: %s @ %.1f Hz' % (klipper_shaper_choice.upper(), klipper_shaper_freq), + label=f'Recommended performance shaper: {klipper_shaper_choice.upper()} @ {klipper_shaper_freq:.1f} Hz', ) ax.plot( freqs, psd * klipper_shaper_vals, - label='With %s applied' % (klipper_shaper_choice.upper()), + label=f'With {klipper_shaper_choice.upper()} applied', color='cyan', ) # And the estimated damping ratio is finally added at the end of the legend - ax2.plot([], [], ' ', label='Estimated damping ratio (ζ): %.3f' % (zeta)) + ax2.plot([], [], ' ', label=f'Estimated damping ratio (ζ): {zeta:.3f}') # Draw the detected peaks and name them # This also draw the detection threshold and warning threshold (aka "effect zone") @@ -288,7 +276,7 @@ def plot_freq_response( # Add the main resonant frequency and damping ratio of the axis to the graph title ax.set_title( - 'Axis Frequency Profile (ω0=%.1fHz, ζ=%.3f)' % (fr, zeta), + f'Axis Frequency Profile (ω0={fr:.1f}Hz, ζ={zeta:.3f})', fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold', @@ -368,6 +356,8 @@ def shaper_calibration( # Parse data from the log files while ignoring CSV in the wrong format datas = [data for data in (parse_log(fn) for fn in lognames) if data is not None] + if len(datas) == 0: + raise ValueError('No valid data found in the provided CSV files!') if len(datas) > 1: ConsoleOutput.print('Warning: incorrect number of .csv files detected. Only the first one will be used!') @@ -397,8 +387,7 @@ def shaper_calibration( peak_freqs_formated = ['{:.1f}'.format(f) for f in peaks_freqs] num_peaks_above_effect_threshold = np.sum(calibration_data.psd_sum[peaks] > peaks_threshold[1]) ConsoleOutput.print( - '\nPeaks detected on the graph: %d @ %s Hz (%d above effect threshold)' - % (num_peaks, ', '.join(map(str, peak_freqs_formated)), num_peaks_above_effect_threshold) + f"\nPeaks detected on the graph: {num_peaks} @ {', '.join(map(str, peak_freqs_formated))} Hz ({num_peaks_above_effect_threshold} above effect threshold)" ) # Create graph layout @@ -435,7 +424,7 @@ def shaper_calibration( title_line4 = f'| Max allowed smoothing: {max_smoothing}' title_line5 = f'| Accel per Hz used: {accel_per_hz} mm/s²/Hz' if accel_per_hz is not None else '' except Exception: - ConsoleOutput.print('Warning: CSV filename look to be different than expected (%s)' % (lognames[0])) + ConsoleOutput.print(f'Warning: CSV filename look to be different than expected ({lognames[0]})') title_line2 = lognames[0].split('/')[-1] title_line3 = '' title_line4 = '' diff --git a/shaketune/graph_creators/static_graph_creator.py b/shaketune/graph_creators/static_graph_creator.py index a02ed61..4903f6f 100644 --- a/shaketune/graph_creators/static_graph_creator.py +++ b/shaketune/graph_creators/static_graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import optparse import os from datetime import datetime @@ -137,6 +135,8 @@ def static_frequency_tool( raise ValueError('Error: missing frequency or duration parameters!') datas = [data for data in (parse_log(fn) for fn in lognames) if data is not None] + if len(datas) == 0: + raise ValueError('No valid data found in the provided CSV files!') if len(datas) > 1: ConsoleOutput.print('Warning: incorrect number of .csv files detected. Only the first one will be used!') diff --git a/shaketune/graph_creators/vibrations_graph_creator.py b/shaketune/graph_creators/vibrations_graph_creator.py index 49065ff..39ade9f 100644 --- a/shaketune/graph_creators/vibrations_graph_creator.py +++ b/shaketune/graph_creators/vibrations_graph_creator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - ################################################## #### DIRECTIONAL VIBRATIONS PLOTTING SCRIPT ###### ################################################## @@ -32,7 +30,7 @@ from ..helpers.common_func import ( setup_klipper_import, ) from ..helpers.console_output import ConsoleOutput -from ..helpers.motors_config_parser import MotorsConfigParser +from ..helpers.motors_config_parser import Motor, MotorsConfigParser from ..shaketune_config import ShakeTuneConfig from .graph_creator import GraphCreator @@ -62,7 +60,7 @@ class VibrationsGraphCreator(GraphCreator): def configure(self, kinematics: str, accel: float, motor_config_parser: MotorsConfigParser) -> None: self._kinematics = kinematics self._accel = accel - self._motors = motor_config_parser.get_motors() + self._motors: List[Motor] = motor_config_parser.get_motors() def _archive_files(self, lognames: List[Path]) -> None: tar_path = self._folder / f'{self._type}_{self._graph_date}.tar.gz' @@ -482,7 +480,7 @@ def plot_angular_speed_profiles( ax.plot(speeds, spectrogram_data[idx], label=label, color=KLIPPAIN_COLORS[color], zorder=zorder) ax.set_xlim([speeds.min(), speeds.max()]) - max_value = max(spectrogram_data[angle].max() for angle in [0, 45, 90, 135]) + max_value = max(spectrogram_data[angle].max() for angle in {0, 45, 90, 135}) ax.set_ylim([0, max_value * 1.1]) ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) @@ -542,13 +540,11 @@ def plot_motor_profiles( ) if motor_zeta is not None: ConsoleOutput.print( - 'Motors have a main resonant frequency at %.1fHz with an estimated damping ratio of %.3f' - % (motor_fr, motor_zeta) + f'Motors have a main resonant frequency at {motor_fr:.1f}Hz with an estimated damping ratio of {motor_zeta:.3f}' ) else: ConsoleOutput.print( - 'Motors have a main resonant frequency at %.1fHz but it was impossible to estimate a damping ratio.' - % (motor_fr) + f'Motors have a main resonant frequency at {motor_fr:.1f}Hz but it was impossible to estimate a damping ratio.' ) ax.plot(freqs[motor_res_idx], global_motor_profile[motor_res_idx], 'x', color='black', markersize=10) @@ -563,9 +559,9 @@ def plot_motor_profiles( weight='bold', ) - ax2.plot([], [], ' ', label='Motor resonant frequency (ω0): %.1fHz' % (motor_fr)) + ax2.plot([], [], ' ', label=f'Motor resonant frequency (ω0): {motor_fr:.1f}Hz') if motor_zeta is not None: - ax2.plot([], [], ' ', label='Motor damping ratio (ζ): %.3f' % (motor_zeta)) + ax2.plot([], [], ' ', label=f'Motor damping ratio (ζ): {motor_zeta:.3f}') else: ax2.plot([], [], ' ', label='No damping ratio computed') @@ -792,8 +788,7 @@ def vibrations_profile( ) formated_peaks_speeds = ['{:.1f}'.format(pspeed) for pspeed in peaks_speeds] ConsoleOutput.print( - 'Vibrations peaks detected: %d @ %s mm/s (avoid setting a speed near these values in your slicer print profile)' - % (num_peaks, ', '.join(map(str, formated_peaks_speeds))) + f"Vibrations peaks detected: {num_peaks} @ {', '.join(map(str, formated_peaks_speeds))} mm/s (avoid setting a speed near these values in your slicer print profile)" ) good_speeds = identify_low_energy_zones(vibration_metric, SPEEDS_VALLEY_DETECTION_THRESHOLD) @@ -855,7 +850,7 @@ def vibrations_profile( if accel is not None: title_line2 += ' at ' + str(accel) + ' mm/s² -- ' + kinematics.upper() + ' kinematics' except Exception: - ConsoleOutput.print('Warning: CSV filenames appear to be different than expected (%s)' % (lognames[0])) + ConsoleOutput.print(f'Warning: CSV filenames appear to be different than expected ({lognames[0]})') title_line2 = lognames[0].split('/')[-1] fig.text(0.060, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) @@ -923,7 +918,7 @@ def main(): opts.error('No CSV file(s) to analyse') if options.output is None: opts.error('You must specify an output file.png to use the script (option -o)') - if options.kinematics not in ['cartesian', 'corexy', 'corexz']: + if options.kinematics not in {'cartesian', 'corexy', 'corexz'}: opts.error('Only cartesian, corexy and corexz kinematics are supported by this tool at the moment!') fig = vibrations_profile(args, options.klipperdir, options.kinematics, options.accel, options.max_freq) diff --git a/shaketune/helpers/common_func.py b/shaketune/helpers/common_func.py index b56704c..67c9aeb 100644 --- a/shaketune/helpers/common_func.py +++ b/shaketune/helpers/common_func.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Common functions for the Shake&Tune package # Written by Frix_x#0161 # @@ -35,9 +33,9 @@ def parse_log(logname): # Check for a PSD file generated by Klipper and raise a warning if cleaned_line.startswith('#freq,psd_x,psd_y,psd_z,psd_xyz'): ConsoleOutput.print( - 'Warning: %s does not contain raw accelerometer data. ' + f'Warning: {logname} does not contain raw accelerometer data. ' 'Please use the official Klipper script to process it instead. ' - 'It will be ignored by Shake&Tune!' % (logname,) + 'It will be ignored by Shake&Tune!' ) return None @@ -48,8 +46,8 @@ def parse_log(logname): if not header: ConsoleOutput.print( - 'Warning: file %s has an incorrect header and will be ignored by Shake&Tune!\n' - "Expected '#time,accel_x,accel_y,accel_z', but got '%s'." % (logname, header.strip()) + f'Warning: file {logname} has an incorrect header and will be ignored by Shake&Tune!\n' + f"Expected '#time,accel_x,accel_y,accel_z', but got '{header.strip()}'." ) return None @@ -57,8 +55,8 @@ def parse_log(logname): data = np.loadtxt(logname, comments='#', delimiter=',', skiprows=1) if data.ndim == 1 or data.shape[1] != 4: ConsoleOutput.print( - 'Warning: %s does not have the correct data format; expected 4 columns. ' - 'It will be ignored by Shake&Tune!' % (logname,) + f'Warning: {logname} does not have the correct data format; expected 4 columns. ' + 'It will be ignored by Shake&Tune!' ) return None diff --git a/shaketune/helpers/motors_config_parser.py b/shaketune/helpers/motors_config_parser.py index 0275438..4b224f4 100644 --- a/shaketune/helpers/motors_config_parser.py +++ b/shaketune/helpers/motors_config_parser.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Classes to retrieve a couple of motors infos and extract the relevant information # from the Klipper configuration and the TMC registers # Written by Frix_x#0161 # @@ -41,7 +39,7 @@ class Motor: value_dict = new_value_dict # Then gets merged all the thresholds into the same THRS virtual register - if register in ['TPWMTHRS', 'TCOOLTHRS']: + if register in {'TPWMTHRS', 'TCOOLTHRS'}: existing_thrs = self._registers.get('THRS', {}) merged_values = {**existing_thrs, **value_dict} self._registers['THRS'] = merged_values @@ -97,10 +95,7 @@ class Motor: if not differences['registers']: del differences['registers'] - if not differences: - return None - - return differences + return None if not differences else differences class MotorsConfigParser: @@ -180,10 +175,7 @@ class MotorsConfigParser: # Find and return the motor by its name def get_motor(self, motor_name: str) -> Optional[Motor]: - for motor in self._motors: - if motor.name == motor_name: - return motor - return None + return next((motor for motor in self._motors if motor.name == motor_name), None) # Get all the motor list at once def get_motors(self) -> List[Motor]: diff --git a/shaketune/helpers/resonance_test.py b/shaketune/helpers/resonance_test.py index 9ce31b5..e828f14 100644 --- a/shaketune/helpers/resonance_test.py +++ b/shaketune/helpers/resonance_test.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # The logic in this file was "extracted" from Klipper's orignal resonance_tester.py file # Courtesy of Dmitry Butyugin for the original implementation diff --git a/shaketune/shaketune.py b/shaketune/shaketune.py index 0d01d1b..98d1ca3 100644 --- a/shaketune/shaketune.py +++ b/shaketune/shaketune.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 - - import os from pathlib import Path @@ -84,7 +81,7 @@ class ShakeTune: try: dummy_macros_cfg = pconfig.read_config(filename) except Exception as err: - raise config.error("Cannot load Shake&Tune dummy macro '%s'" % (filename,)) from err + raise config.error(f'Cannot load Shake&Tune dummy macro {filename}') from err for gcode_macro in dummy_macros_cfg.get_prefix_sections('gcode_macro '): gcode_macro_name = gcode_macro.get_name() diff --git a/shaketune/shaketune_config.py b/shaketune/shaketune_config.py index ae2e7d1..e029f51 100644 --- a/shaketune/shaketune_config.py +++ b/shaketune/shaketune_config.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from pathlib import Path from .helpers.console_output import ConsoleOutput diff --git a/shaketune/shaketune_process.py b/shaketune/shaketune_process.py index ec0b06a..4fc9e6b 100644 --- a/shaketune/shaketune_process.py +++ b/shaketune/shaketune_process.py @@ -1,7 +1,5 @@ -#!/usr/bin/env python3 - -import os import multiprocessing +import os import threading import traceback from typing import Optional