diff --git a/boxes/__init__.py b/boxes/__init__.py index 8d8a6dbe9..b74fa3468 100755 --- a/boxes/__init__.py +++ b/boxes/__init__.py @@ -202,13 +202,13 @@ def html(self, name, default, translate): options = "\n".join( """""" % (e, ' selected="selected"' if e == default else "", - translate("%s %s" % (e, self.names.get(e, "")))) for e in self.edges) - return """\n""" % (name, name, name+"_id", name+"_description", options) + translate("{} {}".format(e, self.names.get(e, "")))) for e in self.edges) + return """\n""".format(name, name, name+"_id", name+"_description", options) def inx(self, name, viewname, arg): return (' \n' % (name, viewname, quoteattr(arg.help or "")) + - ''.join(' \n' % ( + ''.join(' \n'.format( e, e, self.names.get(e, "")) for e in self.edges) + ' \n') @@ -406,10 +406,10 @@ def open(self): self.move(self.reference, 10, "up", before=True) self.ctx.rectangle(0, 0, self.reference, 10) if self.reference < 80: - self.text("%.fmm, burn:%.2fmm" % (self.reference , self.burn), self.reference + 5, 5, + self.text(f"{self.reference:.f}mm, burn:{self.burn:.2f}mm", self.reference + 5, 5, fontsize=8, align="middle left", color=Color.ANNOTATIONS) else: - self.text("%.fmm, burn:%.2fmm" % (self.reference , self.burn), self.reference / 2.0, 5, + self.text(f"{self.reference:.f}mm, burn:{self.burn:.2f}mm", self.reference / 2.0, 5, fontsize=8, align="middle center", color=Color.ANNOTATIONS) self.move(self.reference, 10, "up") if self.qr_code: diff --git a/boxes/gears.py b/boxes/gears.py index c98258d5c..1b1e6e392 100644 --- a/boxes/gears.py +++ b/boxes/gears.py @@ -437,7 +437,7 @@ def generate_spokes(self, root_radius, spoke_width, spokes, mount_radius, mount_ collision = True else: mount_radius = mount_hole/2 + adj_factor # small fix - messages.append("Mount support too small. Auto increased to %2.2f%s." % (mount_radius/unit_factor*2, unit_label)) + messages.append(f"Mount support too small. Auto increased to {mount_radius/unit_factor*2:2.2f}{unit_label}.") # then check to see if cross-over on spoke width for i in range(spoke_count): @@ -446,7 +446,7 @@ def generate_spokes(self, root_radius, spoke_width, spokes, mount_radius, mount_ if spoke_width >= angle * mount_radius: adj_factor = 1.2 # wrong value. its probably one of the points distances calculated below mount_radius += adj_factor - messages.append("Too many spokes. Increased Mount support by %2.3f%s" % (adj_factor/unit_factor, unit_label)) + messages.append(f"Too many spokes. Increased Mount support by {adj_factor/unit_factor:2.3f}{unit_label}") # check for collision with outer rim if r_outer <= mount_radius: @@ -488,7 +488,7 @@ def generate_spokes(self, root_radius, spoke_width, spokes, mount_radius, mount_ return messages def sizes(self, **kw): - self.options = self.OptionParser.parse_args(["--%s=%s" % (name,value) for name, value in kw.items()]) + self.options = self.OptionParser.parse_args([f"--{name}={value}" for name, value in kw.items()]) # Pitch (circular pitch): Length of the arc from one tooth to the next) # Pitch diameter: Diameter of pitch circle. pitch = self.calc_circular_pitch() @@ -550,7 +550,7 @@ def __call__(self, teeth_only=False, move="", callback=None, **kw): iterate through them - Turn on other visual features e.g. cross, rack, annotations, etc """ - self.options = self.OptionParser.parse_args(["--%s=%s" % (name,value) for name, value in kw.items()]) + self.options = self.OptionParser.parse_args([f"--{name}={value}" for name, value in kw.items()]) warnings = [] # list of extra messages to be shown in annotations # calculate unit factor for units defined in dialog. @@ -687,11 +687,11 @@ def __call__(self, teeth_only=False, move="", callback=None, **kw): notes.extend(warnings) #notes.append('Document (%s) scale conversion = %2.4f' % (self.document.getroot().find(inkex.addNS('namedview', 'sodipodi')).get(inkex.addNS('document-units', 'inkscape')), unit_factor)) notes.extend(['Teeth: %d CP: %2.4f(%s) ' % (teeth, pitch / unit_factor, self.options.units), - 'DP: %2.3f Module: %2.4f(mm)' % (25.4 * pi / pitch, pitch), + f'DP: {25.4 * pi / pitch:2.3f} Module: {pitch:2.4f}(mm)', 'Pressure Angle: %2.2f degrees' % (angle), - 'Pitch diameter: %2.3f %s' % (pitch_radius * 2 / unit_factor, self.options.units), - 'Outer diameter: %2.3f %s' % (outer_dia / unit_factor, self.options.units), - 'Base diameter: %2.3f %s' % (base_radius * 2 / unit_factor, self.options.units)#, + f'Pitch diameter: {pitch_radius * 2 / unit_factor:2.3f} {self.options.units}', + f'Outer diameter: {outer_dia / unit_factor:2.3f} {self.options.units}', + f'Base diameter: {base_radius * 2 / unit_factor:2.3f} {self.options.units}'#, #'Addendum: %2.4f %s' % (addendum / unit_factor, self.options.units), #'Dedendum: %2.4f %s' % (dedendum / unit_factor, self.options.units) ]) diff --git a/boxes/generators/alledges.py b/boxes/generators/alledges.py index 6fd3cd182..de8885014 100644 --- a/boxes/generators/alledges.py +++ b/boxes/generators/alledges.py @@ -56,6 +56,6 @@ def render(self): self.move(0, 0, "") self.moveTo(0, 3*t + self.edges[c].spacing()) - self.text("%s - %s" % (c, self.edges[c].description)) + self.text(f"{c} - {self.edges[c].description}") self.moveTo(0, 12*t) diff --git a/boxes/generators/angledbox.py b/boxes/generators/angledbox.py index 9905867b5..79e354337 100644 --- a/boxes/generators/angledbox.py +++ b/boxes/generators/angledbox.py @@ -125,21 +125,21 @@ def render(self): if j == 0 or n % 2: self.rectangularWall(lx, h, move="right", edges=b+"GfG" if fingers else b+"GeG", - label="wall {}".format(cnt)) + label=f"wall {cnt}") else: self.rectangularWall(lx, h, move="right", edges=b+"gfg" if fingers else b+"geg", - label="wall {}".format(cnt)) + label=f"wall {cnt}") for i in range(n): cnt += 1 if (i+j*((n+1)%2)) % 2: # reverse for second half if even n self.rectangularWall(side, h, move="right", edges=b+"GfG" if fingers else b+"GeG", - label="wall {}".format(cnt)) + label=f"wall {cnt}") else: self.rectangularWall(side, h, move="right", edges=b+"gfg" if fingers else b+"geg", - label="wall {}".format(cnt)) + label=f"wall {cnt}") diff --git a/boxes/generators/atreus21.py b/boxes/generators/atreus21.py index f370424d1..cc2ccc887 100644 --- a/boxes/generators/atreus21.py +++ b/boxes/generators/atreus21.py @@ -15,7 +15,7 @@ def __init__(self) -> None: super().__init__() self.add_common_keyboard_parameters( # By default, columns from Atreus 21 - default_columns_definition='4@3/4@6/4@11/4@5/4@0/1@{}'.format(self.btn_size * 0.5) + default_columns_definition=f'4@3/4@6/4@11/4@5/4@0/1@{self.btn_size * 0.5}' ) def render(self): diff --git a/boxes/generators/discrack.py b/boxes/generators/discrack.py index 21df7e6e0..57f7d84c5 100644 --- a/boxes/generators/discrack.py +++ b/boxes/generators/discrack.py @@ -165,21 +165,15 @@ def warn_on_demand(self): def word_thickness(length): if length > 0: - return "very thin (%.2g mm at a thickness of %.2g mm)" % ( - length, self.thickness) + return f"very thin ({length:.2g} mm at a thickness of {self.thickness:.2g} mm)" if length < 0: return "absent" if self.rear_outset < self.thickness: - warnings.append("Rear upper constraint is %s. Consider increasing" - " the disc outset parameter, or move the angle away from 45°." - % word_thickness(self.rear_outset) - ) + warnings.append("Rear upper constraint is %s. Consider increasing the disc outset parameter, or move the angle away from 45°." % word_thickness(self.rear_outset)) if self.lower_outset < self.thickness: - warnings.append("Lower front constraint is %s. Consider increasing" - " the disc outset parameter, or move the angle away from 45°." - % word_thickness(self.lower_outset)) + warnings.append("Lower front constraint is %s. Consider increasing the disc outset parameter, or move the angle away from 45°." % word_thickness(self.lower_outset)) # Are the discs supported where the grids meet? @@ -188,8 +182,7 @@ def word_thickness(length): inner_reardistance = r * self.lower_factor - self.rear_halfslit if inner_lowerdistance < 0 or inner_reardistance < 0: - warnings.append("Corner is inside the disc radios, discs would not" - " be supported. Consider increasing the factor parameters.") + warnings.append("Corner is inside the disc radios, discs would not be supported. Consider increasing the factor parameters.") # Won't the type-H edge on the rear side make the whole contraption # wiggle? @@ -200,9 +193,7 @@ def word_thickness(length): self.edgesettings['FingerJoint']['edge_width']) if slitlengthplush > max_slitlengthplush: - warnings.append("Joint would protrude from lower box edge. Consider" - " increasing the the disc outset parameter, or move the" - " angle away from 45°.") + warnings.append("Joint would protrude from lower box edge. Consider increasing the the disc outset parameter, or move the angle away from 45°.") # Can the discs be removed at all? # Does not need explicit checking, for Thales' theorem tells us that at diff --git a/boxes/generators/dividertray.py b/boxes/generators/dividertray.py index fc16f3514..f9e29c82b 100644 --- a/boxes/generators/dividertray.py +++ b/boxes/generators/dividertray.py @@ -251,39 +251,22 @@ def render(self): if self.debug: debug_info = ["Debug"] + debug_info.append(f"Slot_edge_outer_length:{slot_descriptions.total_length() + 2 * self.thickness:.2f}") debug_info.append( - "Slot_edge_outer_length:{0:.2f}".format( - slot_descriptions.total_length() + 2 * self.thickness - ) - ) - debug_info.append( - "Slot_edge_inner_lengths:{0}".format( + "Slot_edge_inner_lengths:{}".format( str.join( "|", [ - "{0:.2f}".format(e.useful_length()) + f"{e.useful_length():.2f}" for e in slot_descriptions.get_straight_edges() ], ) ) ) - debug_info.append( - "Face_edge_outer_length:{0:.2f}".format( - facing_wall_length - + self.thickness * sum([self.left_wall, self.right_wall]) - ) - ) - debug_info.append( - "Face_edge_inner_lengths:{0}".format( - str.join("|", ["{0:.2f}".format(e) for e in self.sx]) - ) - ) - debug_info.append("Tray_height:{0:.2f}".format(self.h)) - debug_info.append( - "Content_height:{0:.2f}".format( - self.h / math.cos(math.radians(self.Slot_angle)) - ) - ) + debug_info.append(f"Face_edge_outer_length:{facing_wall_length + self.thickness * sum([self.left_wall, self.right_wall]):.2f}") + debug_info.append("Face_edge_inner_lengths:{}".format(str.join("|", [f"{e:.2f}" for e in self.sx]))) + debug_info.append(f"Tray_height:{self.h:.2f}") + debug_info.append(f"Content_height:{self.h / math.cos(math.radians(self.Slot_angle)):.2f}") self.text(str.join("\n", debug_info), x=5, y=5, align="bottom left") def generate_finger_holes(self, length): @@ -411,14 +394,7 @@ def __init__( self.angle_compensation = angle_compensation def __repr__(self) -> str: - return ( - "StraightEdgeDescription({0}, round_edge_compensation={1}, angle_compensation={2}, outside_ratio={3})" - ).format( - self.asked_length, - self.round_edge_compensation, - self.angle_compensation, - self.outside_ratio, - ) + return f"StraightEdgeDescription({self.asked_length}, round_edge_compensation={self.round_edge_compensation}, angle_compensation={self.angle_compensation}, outside_ratio={self.outside_ratio})" def tracing_length(self): """ @@ -460,9 +436,7 @@ def __init__( self.angle = angle def __repr__(self) -> str: - return "SlotDescription({0}, depth={1}, angle={2}, start_radius={3}, end_radius={4})".format( - self.width, self.depth, self.angle, self.start_radius, self.end_radius - ) + return f"SlotDescription({self.width}, depth={self.depth}, angle={self.angle}, start_radius={self.start_radius}, end_radius={self.end_radius})" def _div_by_cos(self): return SlotDescription._div_by_cos_cache[self.angle] diff --git a/boxes/generators/gear.py b/boxes/generators/gear.py index 29825b57d..c97f9db80 100644 --- a/boxes/generators/gear.py +++ b/boxes/generators/gear.py @@ -87,10 +87,9 @@ def render(self): self.hole(t+r+r1+r2, t+r, self.shaft2/2) self.moveTo(0, 2*r+t) - self.text("""Pitch radius 1: %.1fmm -Outer diameter 1: %.1fmm -Pitch radius 2: %.1fmm -Outer diameter 2: %.1fmm -Axis distance: %.1fmm - """ % (r1, d1, r2, d2, r1+r2), align="bottom left") - + self.text(f"Pitch radius 1: {r1:.1f}mm\n" + f"Outer diameter 1: {d1:.1f}mm\n" + f"Pitch radius 2: {r2:.1f}mm\n" + f"Outer diameter 2: {d2:.1f}mm\n" + f"Axis distance: {r1 + r2:.1f}mm\n", + align="bottom left") diff --git a/boxes/robot.py b/boxes/robot.py index 6359ff971..fcaa4b0bc 100644 --- a/boxes/robot.py +++ b/boxes/robot.py @@ -27,7 +27,7 @@ def html(self, name, default, translate): ("""""" % (name, ' selected="selected"' if name == default else "", name, descr) for name, descr in self.robotarms)) - return """\n""" % (name, options) + return f"""\n""" class _RobotArm: diff --git a/boxes/servos.py b/boxes/servos.py index 937233f4a..f7c0b35b2 100644 --- a/boxes/servos.py +++ b/boxes/servos.py @@ -65,7 +65,7 @@ def html(self, name, default, translate): """""" % (name, ' selected="selected"' if name == default else "", name) for name in self.servos) - return """\n""" % (name, options) + return f"""\n""" class Servo: diff --git a/setup.py b/setup.py index 4e65033c3..010336e6c 100755 --- a/setup.py +++ b/setup.py @@ -12,18 +12,11 @@ class CustomBuildExtCommand(build_py): """Customized setuptools install command - prints a friendly greeting.""" def buildInkscapeExt(self): - os.system("%s %s %s" % (sys.executable, - os.path.join("scripts", "boxes2inkscape"), - "inkex")) + os.system("{} {} {}".format(sys.executable, os.path.join("scripts", "boxes2inkscape"), "inkex")) def updatePOT(self): - os.system("%s %s %s" % ( - sys.executable, - os.path.join("scripts", "boxes2pot"), - "po/boxes.py.pot")) - os.system("%s %s" % ( - "xgettext -L Python -j --from-code=utf-8 -o po/boxes.py.pot", - "boxes/*.py scripts/boxesserver scripts/boxes")) + os.system("{} {} {}".format(sys.executable, os.path.join("scripts", "boxes2pot"), "po/boxes.py.pot")) + os.system("{} {}".format("xgettext -L Python -j --from-code=utf-8 -o po/boxes.py.pot", "boxes/*.py scripts/boxesserver scripts/boxes")) def generate_mo_files(self): pos = glob.glob("po/*.po") @@ -34,7 +27,7 @@ def generate_mo_files(self): os.makedirs(os.path.join("locale", lang, "LC_MESSAGES")) except FileExistsError: pass - os.system("msgfmt %s -o locale/%s/LC_MESSAGES/boxes.py.mo" % (po, lang)) + os.system(f"msgfmt {po} -o locale/{lang}/LC_MESSAGES/boxes.py.mo") self.distribution.data_files.append( (os.path.join("share", "locale", lang, "LC_MESSAGES"), [os.path.join("locale", lang, "LC_MESSAGES", "boxes.py.mo")])) @@ -50,9 +43,7 @@ def run(self): # we are most probably building a Debian package # let us define a simple path! path="/usr/share/inkscape/extensions" - self.distribution.data_files.append( - (path, - [i for i in glob.glob(os.path.join("inkex", "*.inx"))])) + self.distribution.data_files.append((path, [i for i in glob.glob(os.path.join("inkex", "*.inx"))])) self.distribution.data_files.append((path, ['scripts/boxes'])) self.distribution.data_files.append((path, ['scripts/boxes_proxy.py'])) else: @@ -64,9 +55,7 @@ def run(self): if not os.access(path, os.W_OK): # Can we install globally # Not tested on Windows and Mac path = os.path.expanduser("~/.config/inkscape/extensions") - self.distribution.data_files.append( - (path, - [i for i in glob.glob(os.path.join("inkex", "*.inx"))])) + self.distribution.data_files.append((path, [i for i in glob.glob(os.path.join("inkex", "*.inx"))])) self.distribution.data_files.append((path, ['scripts/boxes'])) self.distribution.data_files.append((path, ['scripts/boxes_proxy.py'])) except CalledProcessError: