From de530753d6368a8080d70d83221141a3d4a85e51 Mon Sep 17 00:00:00 2001 From: Caleb Bell Date: Fri, 26 Jul 2024 13:36:35 -0600 Subject: [PATCH 1/2] new config file --- .ruff.toml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index ef196c3..028b9e2 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -10,13 +10,28 @@ exclude = [ # "UP031", # "UP032", # ] + + + +[lint] select = ["ALL"] + extend-ignore = [ + "FIX002", # TODO are OK + "FIX004", # HACK is OK + "D415", # First docstring line should end with a period, question mark, or exclamation point "DTZ004", # utcfromtimestamp makes sense for atmosphere model "PGH003", # type ignoring makes sense for numba-related things "S102", # Yes, exec is dangerous but it can be quite useful as well + "PYI056", # changing __all__ + + "RUF012", # not using typing today + "PERF403", # obvious, use an autofix if one becomes available + "PERF203", # `try`-`except` within a loop incurs performance overhead + "PERF401", # PERF401 Use a list comprehension to create a transformed list + # chemicals specific "E701", # lots of this here @@ -139,13 +154,15 @@ extend-ignore = [ "TRY002", "TRY003", "TRY004", - "TRY200", + "B904", "TRY201", "TRY300", "TRY301", "TRY400", "Q000", "Q002", + + "PYI024", # PYI024 Use `typing.NamedTuple` instead of `collections.namedtuple ] -[mccabe] +[lint.mccabe] max-complexity = 10 From 5af4e35b8c5a27ec6d31cdae080bc5bde2325ffe Mon Sep 17 00:00:00 2001 From: Caleb Bell Date: Fri, 26 Jul 2024 13:41:50 -0600 Subject: [PATCH 2/2] Ruff changes --- ht/conv_external.py | 2 +- ht/conv_free_immersed.py | 1 + ht/conv_jacket.py | 8 +++--- ht/conv_two_phase.py | 2 +- ht/core.py | 4 +-- ht/hx.py | 56 ++++++++++++++++++++-------------------- ht/units.py | 2 +- 7 files changed, 37 insertions(+), 38 deletions(-) diff --git a/ht/conv_external.py b/ht/conv_external.py index 3520e0a..282f12f 100644 --- a/ht/conv_external.py +++ b/ht/conv_external.py @@ -497,7 +497,7 @@ def Nu_cylinder_Perkins_Leppert_1964(Re, Pr, mu=None, muw=None): conv_external_cylinder_methods = conv_external_cylinder_turbulent_methods.copy() -_missing_external_cylinder_method = "Correlation name not recognized; the availble methods are %s." %(list(conv_external_cylinder_methods.keys())) +_missing_external_cylinder_method = f"Correlation name not recognized; the availble methods are {list(conv_external_cylinder_methods.keys())}." def Nu_external_cylinder_methods(Re, Pr, Prw=None, mu=None, muw=None, check_ranges=True): diff --git a/ht/conv_free_immersed.py b/ht/conv_free_immersed.py index 496d026..0e80717 100644 --- a/ht/conv_free_immersed.py +++ b/ht/conv_free_immersed.py @@ -908,6 +908,7 @@ def Nu_vertical_cylinder_McAdams_Weiss_Saunders(Pr, Gr, turbulent=None): Whether or not to force the correlation to return the turbulent result; will return the laminar regime if False; leave as None for automatic selection + Returns ------- Nu : float diff --git a/ht/conv_jacket.py b/ht/conv_jacket.py index 1433f42..f6f9fdb 100644 --- a/ht/conv_jacket.py +++ b/ht/conv_jacket.py @@ -132,12 +132,12 @@ def Lehrer(m, Dtank, Djacket, H, Dinlet, rho, Cp, k, mu, muw=None, vo = Q/(pi/4*Dinlet**2) if dT is not None and isobaric_expansion is not None and inlettype == 'radial' and inletlocation is not None: if dT > 0: # Heating jacket fluid - if inletlocation == 'auto' or inletlocation == 'bottom': + if inletlocation in ('auto', 'bottom'): va = 0.5*(2*g*H*isobaric_expansion*abs(dT))**0.5 else: va = -0.5*(2*g*H*isobaric_expansion*abs(dT))**0.5 else: # cooling fluid - if inletlocation == 'auto' or inletlocation == 'top': + if inletlocation in ('auto', 'top'): va = 0.5*(2*g*H*isobaric_expansion*abs(dT))**0.5 else: va = -0.5*(2*g*H*isobaric_expansion*abs(dT))**0.5 @@ -331,12 +331,12 @@ def Stein_Schmidt(m, Dtank, Djacket, H, Dinlet, if inletlocation and rhow: GrJ = g*rho*(rho-rhow)*dch**3/mu**2 if rhow < rho: # Heating jacket fluid - if inletlocation == 'auto' or inletlocation == 'bottom': + if inletlocation in ('auto', 'bottom'): ReJeq = (ReJ**2 + GrJ*H/dch/50.)**0.5 else: ReJeq = (ReJ**2 - GrJ*H/dch/50.)**0.5 else: # Cooling jacket fluid - if inletlocation == 'auto' or inletlocation == 'top': + if inletlocation in ('auto', 'top'): ReJeq = (ReJ**2 + GrJ*H/dch/50.)**0.5 else: ReJeq = (ReJ**2 - GrJ*H/dch/50.)**0.5 diff --git a/ht/conv_two_phase.py b/ht/conv_two_phase.py index 6add6ce..f659503 100644 --- a/ht/conv_two_phase.py +++ b/ht/conv_two_phase.py @@ -766,7 +766,7 @@ def Aggour(m, x, alpha, D, rhol, Cpl, kl, mu_b, mu_w=None, L=None, conv_two_phase_methods_ranked = ['Knott', 'Martin_Sims', 'Kudirka_Grosh_McFadden', 'Groothuis_Hendal', 'Aggour', 'Hughmark', 'Elamvaluthi_Srinivas', 'Davis-David', 'Ravipudi_Godbold'] -conv_two_phase_bad_method = "Correlation name not recognized; the availble methods are %s." %(list(conv_two_phase_methods.keys())) +conv_two_phase_bad_method = f"Correlation name not recognized; the availble methods are {list(conv_two_phase_methods.keys())}." """Generating code: for m in conv_two_phase_methods_ranked: (f_obj, args) = conv_two_phase_methods[m] diff --git a/ht/core.py b/ht/core.py index 20d03ce..022ec20 100644 --- a/ht/core.py +++ b/ht/core.py @@ -152,9 +152,7 @@ def countercurrent_hx_temperature_check(T0i, T0o, T1i, T1o): Tci, Tco = T0i, T0o if Thi < Tho: return False - if Tci > Tco: - return False - return True + return not Tci > Tco def is_heating_temperature(T, T_wall): diff --git a/ht/hx.py b/ht/hx.py index 0606f6d..5b7ccd3 100644 --- a/ht/hx.py +++ b/ht/hx.py @@ -55,7 +55,7 @@ try: if IS_NUMBA: # type: ignore # noqa: F821 __numba_additional_funcs__.append('factorial') - def factorial(n): # noqa: F811 + def factorial(n): return gamma(n + 1.0) except: @@ -325,7 +325,7 @@ def effectiveness_from_NTU(NTU, Cr, subtype='counterflow', n_shell_tube=None): return 1. -exp(-1.0/Cr*(1. - exp(-Cr*NTU))) elif subtype == 'crossflow, mixed Cmax': return (1./Cr)*(1. - exp(-Cr*(1. - exp(-NTU)))) - elif subtype == 'boiler' or subtype == 'condenser': + elif subtype in ('boiler', 'condenser'): return 1. - exp(-NTU) else: raise ValueError('Input heat exchanger type not recognized') @@ -538,7 +538,7 @@ def NTU_from_effectiveness(effectiveness, Cr, subtype='counterflow', n_shell_tub # Derived with SymPy max_effectiveness = (-((-Cr + sqrt(Cr**2 + 1) + 1)/(Cr + sqrt(Cr**2 + 1) - 1))**shells + 1)/(Cr - ((-Cr + sqrt(Cr**2 + 1) + 1)/(Cr + sqrt(Cr**2 + 1) - 1))**shells) raise ValueError('The specified effectiveness is not physically ' # numba: delete -'possible for this configuration; the maximum effectiveness possible is %s.' % (max_effectiveness)) # numba: delete +f'possible for this configuration; the maximum effectiveness possible is {max_effectiveness}.') # numba: delete # raise ValueError("Fail") # numba: uncomment NTU = -(1. + Cr*Cr)**-0.5*log((E - 1.)/(E + 1.)) @@ -1217,8 +1217,8 @@ def temperature_effectiveness_air_cooler(R1, NTU1, rows, passes, coerce=True): # https://stackoverflow.com/questions/62056035/how-to-call-math-factorial-from-numba-with-nopython-mode Np1 = N+1 factorials = [factorial(i) for i in range(N)] - K_powers = [K**j for j in range(0, N+1)] - NKR1_powers = [NKR1**k for k in range(0, N+1)] + K_powers = [K**j for j in range(N+1)] + NKR1_powers = [NKR1**k for k in range(N+1)] exp_terms = [exp(i*NTU1_N) for i in range(-N+1, 1)] # Only need to compute one exp, then multiply NKR1_powers_over_factorials = [NKR1_powers[k]/factorials[k] for k in range(N)] @@ -1236,7 +1236,7 @@ def temperature_effectiveness_air_cooler(R1, NTU1, rows, passes, coerce=True): tot = 0. for i in range(1, N): - for j in range(0, i+1): + for j in range(i+1): # can't optimize the factorial prod = factorials[i]/(factorials[i-j]*factorials[j]) tot1 = prod*exp_terms[j-i-1] @@ -1285,7 +1285,7 @@ def temperature_effectiveness_air_cooler(R1, NTU1, rows, passes, coerce=True): new_rows = rows = 5 if rows -1 == passes: new_rows, new_passes = rows -1, passes - elif (passes == 2 or passes == 3 or passes == 5) and rows >= 4: + elif (passes in (2, 3, 5)) and rows >= 4: new_rows, new_passes = 4, 2 return temperature_effectiveness_air_cooler(R1=R1, NTU1=NTU1, rows=new_rows, passes=new_passes) @@ -3736,7 +3736,7 @@ def NTU_from_P_plate(P1, R1, Np1, Np2, counterflow=True, return log(-1./(P1*(R1 + 1.) - 1.))/(R1 + 1.) except: # raise ValueError("impossible") # numba: uncomment - raise ValueError('The maximum P1 obtainable at the specified R1 is %f at the limit of NTU1=inf.' %Pp(1E10, R1)) # numba: delete + raise ValueError(f'The maximum P1 obtainable at the specified R1 is {Pp(1E10, R1):f} at the limit of NTU1=inf.') # numba: delete elif Np1 == 1 and Np2 == 2: NTU_max = 100. elif Np1 == 1 and Np2 == 3 and counterflow: @@ -4534,7 +4534,7 @@ def baffle_thickness(Dshell, L_unsupported, service='C'): i = 4 t = _TEMA_baffles_refinery[j][i] - elif service == 'C' or service == 'B': + elif service in ('C', 'B'): if L_unsupported <= 0.305: i = 0 elif 0.305 < L_unsupported <= 0.610: @@ -4648,7 +4648,7 @@ def L_unsupported_max(Do, material='CS'): elif _L_unsupported_Do[i] > Do: i -= 1 # too big, go down a length break - i = i if i < 11 else 11 + i = min(11, i) i = 0 if i == -1 else i if material == 'CS': return _L_unsupported_steel[i] @@ -4756,17 +4756,17 @@ def Ntubes_Phadkeb(DBundle, Do, pitch, Ntp, angle=30): Ns, Nr = floor(s), floor(r) # If Ns is between two numbers, take the smaller one # C1 is the number of tubes for a single pass arrangement. - if angle == 30 or angle == 60: + if angle in (30, 60): i = np.searchsorted(triangular_Ns, Ns, side='right') C1 = int(triangular_C1s[i-1]) - elif angle == 45 or angle == 90: + elif angle in (45, 90): i = np.searchsorted(square_Ns, Ns, side='right') C1 = int(square_C1s[i-1]) Cx = 2*Nr + 1. # triangular and rotated triangular - if (angle == 30 or angle == 60): + if (angle in (30, 60)): w = 2*r/3**0.5 Nw = floor(w) if Nw % 2 == 0: @@ -4781,7 +4781,7 @@ def Ntubes_Phadkeb(DBundle, Do, pitch, Ntp, angle=30): else: # 4 passes, or 8; this value is needed C4 = C1 - Cx - Cy - if (angle == 30 or angle == 60) and (Ntp == 6 or Ntp == 8): + if (angle in (30, 60)) and (Ntp in (6, 8)): if angle == 30: # triangular v = 2*e*r/3**0.5 + 0.5 Nv = floor(v) @@ -4818,7 +4818,7 @@ def Ntubes_Phadkeb(DBundle, Do, pitch, Ntp, angle=30): else: # 8 C8 = C4 - 4.*(Nz1 + Nz2) - if (angle == 45 or angle == 90): + if (angle in (45, 90)): if angle == 90: Cy = Cx - 1. # eq 6 or 8 for c2 or c4 @@ -4836,7 +4836,7 @@ def Ntubes_Phadkeb(DBundle, Do, pitch, Ntp, angle=30): else: # 4 passes, or 8; this value is needed C4 = C1 - Cx - Cy - if (angle == 45 or angle == 90) and (Ntp == 6 or Ntp == 8): + if (angle in (45, 90)) and (Ntp in (6, 8)): if angle == 90: v = e*r + 0.5 Nv = floor(v) @@ -4939,9 +4939,9 @@ def DBundle_for_Ntubes_Phadkeb(Ntubes, Do, pitch, Ntp, angle=30): ''' if square_C1s is None: # numba: delete _load_coeffs_Phadkeb() # numba: delete - if angle == 30 or angle == 60: + if angle in (30, 60): Ns = triangular_Ns[-1] - elif angle == 45 or angle == 90: + elif angle in (45, 90): Ns = square_Ns[-1] s = Ns + 1 r = s**0.5 @@ -4988,7 +4988,7 @@ def Ntubes_Perrys(DBundle, Do, Ntp, angle=30): .. [1] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, Eighth Edition. New York: McGraw-Hill Education, 2007. ''' - if angle == 30 or angle == 60: + if angle in (30, 60): C = 0.75 * DBundle / Do - 36. if Ntp == 1: Nt = (((-0.0006 * C - 0.0078) * C + 1.283) * C + 74.86) * C + 1298. @@ -5000,7 +5000,7 @@ def Ntubes_Perrys(DBundle, Do, Ntp, angle=30): Nt = (((-0.0006 * C - 0.0074) * C + 1.269) * C + 70.72) * C + 1166. else: raise ValueError('N passes not 1, 2, 4 or 6') - elif angle == 45 or angle == 90: + elif angle in (45, 90): C = DBundle / Do - 36. if Ntp == 1: Nt = (((0.0001 * C - 0.0012) * C + 0.3782) * C + 33.52) * C + 593.6 @@ -5066,9 +5066,9 @@ def Ntubes_VDI(DBundle=None, Ntp=None, Do=None, pitch=None, angle=30.): f2 = 90. # Estimated! else: raise ValueError('Only 1, 2, 4 and 8 passes are supported') - if angle == 30 or angle == 60: + if angle in (30, 60): f1 = 1.1 - elif angle == 45 or angle == 90: + elif angle in (45, 90): f1 = 1.3 else: raise ValueError('Only 30, 60, 45 and 90 degree layouts are supported') @@ -5137,9 +5137,9 @@ def D_for_Ntubes_VDI(N, Ntp, Do, pitch, angle=30): f2 = 105. else: raise ValueError('Only 1, 2, 4 and 8 passes are supported') - if angle == 30 or angle == 60: + if angle in (30, 60): f1 = 1.1 - elif angle == 45 or angle == 90: + elif angle in (45, 90): f1 = 1.3 else: raise ValueError('Only 30, 60, 45 and 90 degree layouts are supported') @@ -5189,9 +5189,9 @@ def Ntubes_HEDH(DBundle=None, Do=None, pitch=None, angle=30): Transfer. Heat Exchanger Design Handbook. Washington: Hemisphere Pub. Corp., 1983. ''' - if angle == 30 or angle == 60: + if angle in (30, 60): C1 = 13/15. - elif angle == 45 or angle == 90: + elif angle in (45, 90): C1 = 1. else: raise ValueError('Only 30, 60, 45 and 90 degree layouts are supported') @@ -5243,9 +5243,9 @@ def DBundle_for_Ntubes_HEDH(N, Do, pitch, angle=30): Transfer. Heat Exchanger Design Handbook. Washington: Hemisphere Pub. Corp., 1983. ''' - if angle == 30 or angle == 60: + if angle in (30, 60): C1 = 13/15. - elif angle == 45 or angle == 90: + elif angle in (45, 90): C1 = 1. else: raise ValueError('Only 30, 60, 45 and 90 degree layouts are supported') diff --git a/ht/units.py b/ht/units.py index 0bb6abd..e5765d9 100644 --- a/ht/units.py +++ b/ht/units.py @@ -45,7 +45,7 @@ for name in dir(ht): - if name == '__getattr__' or name == '__test__': + if name in ('__getattr__', '__test__'): continue obj = getattr(ht, name) if isinstance(obj, types.FunctionType) and obj not in [ht.get_tube_TEMA, ht.check_tubing_TEMA]: