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: