Reformat with Black.

This commit is contained in:
Sergey Vartanov 2021-07-11 03:12:14 +03:00
parent 9613ec2cd4
commit 070ed05c8c
12 changed files with 157 additions and 117 deletions

View file

@ -32,7 +32,7 @@ class IconCollection:
extractor: ShapeExtractor, extractor: ShapeExtractor,
background_color: Color = Color("white"), background_color: Color = Color("white"),
color: Color = Color("black"), color: Color = Color("black"),
add_unused: bool = False add_unused: bool = False,
) -> "IconCollection": ) -> "IconCollection":
""" """
Collect all possible icon combinations in grid. Collect all possible icon combinations in grid.
@ -89,11 +89,16 @@ class IconCollection:
for icon_2_id in matcher.with_icon: for icon_2_id in matcher.with_icon:
for icon_3_id in matcher.with_icon: for icon_3_id in matcher.with_icon:
current_set = ( current_set = (
[icon_id] + [icon_2_id] + [icon_3_id] + [icon_id]
matcher.over_icon + [icon_2_id]
+ [icon_3_id]
+ matcher.over_icon
) )
if (icon_2_id != icon_3_id and icon_2_id != icon_id and if (
icon_3_id != icon_id): icon_2_id != icon_3_id
and icon_2_id != icon_id
and icon_3_id != icon_id
):
add() add()
specified_ids: Set[str] = set() specified_ids: Set[str] = set()
@ -127,10 +132,13 @@ class IconCollection:
:param outline: if true, draw outline beneath the icon :param outline: if true, draw outline beneath the icon
""" """
if by_name: if by_name:
def get_file_name(x) -> str: def get_file_name(x) -> str:
"""Generate human-readable file name.""" """Generate human-readable file name."""
return f"Röntgen {' + '.join(x.get_names())}.svg" return f"Röntgen {' + '.join(x.get_names())}.svg"
else: else:
def get_file_name(x) -> str: def get_file_name(x) -> str:
"""Generate file name with unique identifier.""" """Generate file name with unique identifier."""
return f"{'___'.join(x.get_shape_ids())}.svg" return f"{'___'.join(x.get_shape_ids())}.svg"
@ -167,8 +175,7 @@ class IconCollection:
for icon in self.icons: for icon in self.icons:
icon: Icon icon: Icon
rectangle = svg.rect( rectangle = svg.rect(
point - np.array((10, 10)), (20, 20), point - np.array((10, 10)), (20, 20), fill=background_color.hex
fill=background_color.hex
) )
svg.add(rectangle) svg.add(rectangle)
icon.draw(svg, point) icon.draw(svg, point)
@ -189,8 +196,11 @@ class IconCollection:
for selector in self.selectors: for selector in self.selectors:
for target in ["node", "area"]: for target in ["node", "area"]:
s += target + selector + " {\n" s += target + selector + " {\n"
s += ' icon-image: "icons/' + "___".join( s += (
self.selectors[selector].get_shape_ids()) + '.svg";\n' ' icon-image: "icons/'
+ "___".join(self.selectors[selector].get_shape_ids())
+ '.svg";\n'
)
s += " set icon_z17;\n" s += " set icon_z17;\n"
s += " icon-width: 16;\n" s += " icon-width: 16;\n"
s += "}\n" s += "}\n"
@ -213,9 +223,7 @@ def draw_icons() -> None:
icons_by_id_path: Path = out_path / "icons_by_id" icons_by_id_path: Path = out_path / "icons_by_id"
icons_by_name_path: Path = out_path / "icons_by_name" icons_by_name_path: Path = out_path / "icons_by_name"
for path in ( for path in (out_path, icons_by_id_path, icons_by_name_path):
out_path, icons_by_id_path, icons_by_name_path
):
path.mkdir(parents=True, exist_ok=True) path.mkdir(parents=True, exist_ok=True)
scheme: Scheme = Scheme(Path("scheme/default.yml")) scheme: Scheme = Scheme(Path("scheme/default.yml"))
@ -245,11 +253,11 @@ def write_mapcss() -> None:
) )
(out_path / "roentgen_icons").mkdir(exist_ok=True) (out_path / "roentgen_icons").mkdir(exist_ok=True)
with Path("data/roentgen_icons_part.mapcss").open() as input_file: with Path("data/roentgen_icons_part.mapcss").open() as input_file:
with ( with (out_path / "roentgen_icons" / "roentgen_icons.mapcss").open(
out_path / "roentgen_icons" / "roentgen_icons.mapcss" "w+"
).open("w+") as output_file: ) as output_file:
for line in input_file.readlines(): for line in input_file.readlines():
if line == "%CONTENT%\n": if line == "%CONTENT%\n":
output_file.write(collection.get_mapcss_selectors()) output_file.write(collection.get_mapcss_selectors())
else: else:
output_file.write(line) output_file.write(line)

View file

@ -254,8 +254,12 @@ class ShapeSpecification:
use_outline = structure["outline"] use_outline = structure["outline"]
return cls( return cls(
shape, color, offset, flip_horizontally, flip_vertically, shape,
use_outline color,
offset,
flip_horizontally,
flip_vertically,
use_outline,
) )
def is_default(self) -> bool: def is_default(self) -> bool:
@ -424,10 +428,9 @@ class Icon:
) )
def __lt__(self, other) -> bool: def __lt__(self, other) -> bool:
return ( return "".join(
"".join([x.shape.id_ for x in self.shape_specifications]) [x.shape.id_ for x in self.shape_specifications]
< "".join([x.shape.id_ for x in other.shape_specifications]) ) < "".join([x.shape.id_ for x in other.shape_specifications])
)
@dataclass @dataclass

View file

@ -47,7 +47,7 @@ class Painter:
show_missing_tags: bool = False, show_missing_tags: bool = False,
overlap: int = 12, overlap: int = 12,
mode: str = "normal", mode: str = "normal",
label_mode: str = "main" label_mode: str = "main",
): ):
self.show_missing_tags: bool = show_missing_tags self.show_missing_tags: bool = show_missing_tags
self.overlap: int = overlap self.overlap: int = overlap
@ -100,15 +100,16 @@ class Painter:
occupied = None occupied = None
else: else:
occupied = Occupied( occupied = Occupied(
self.flinger.size[0], self.flinger.size[1], self.overlap) self.flinger.size[0], self.flinger.size[1], self.overlap
)
nodes = sorted(constructor.points, key=lambda x: -x.priority) nodes = sorted(constructor.points, key=lambda x: -x.priority)
steps: int = len(nodes) steps: int = len(nodes)
for index, node in enumerate(nodes): # type: int, Point for index, node in enumerate(nodes): # type: int, Point
if (node.get_tag("natural") == "tree" and if node.get_tag("natural") == "tree" and (
("diameter_crown" in node.tags or "diameter_crown" in node.tags or "circumference" in node.tags
"circumference" in node.tags)): ):
continue continue
ui.progress_bar( ui.progress_bar(
index, steps * 3, step=10, text="Drawing main icons" index, steps * 3, step=10, text="Drawing main icons"
@ -142,6 +143,9 @@ class Painter:
("diameter_crown" in node.tags or ("diameter_crown" in node.tags or
"circumference" in node.tags)): "circumference" in node.tags)):
continue continue
scale: float = self.flinger.get_scale(node.coordinates)
if "circumference" in node.tags: if "circumference" in node.tags:
if "diameter_crown" in node.tags: if "diameter_crown" in node.tags:
opacity = 0.7 opacity = 0.7
@ -149,16 +153,18 @@ class Painter:
else: else:
opacity = 0.3 opacity = 0.3
radius = 2 radius = 2
self.svg.add(self.svg.circle( self.svg.add(
node.point, self.svg.circle(
radius * self.flinger.get_scale(node.coordinates), node.point,
fill=self.scheme.get_color("evergreen_color"), radius * scale,
opacity=opacity)) fill=self.scheme.get_color("evergreen_color"),
self.svg.add(self.svg.circle( opacity=opacity,
node.point, )
float(node.tags["circumference"]) / 2 / np.pi * )
self.flinger.get_scale(node.coordinates), radius = float(node.tags["circumference"]) / 2 / np.pi
fill="#B89A74")) self.svg.add(
self.svg.circle(node.point, radius * scale, fill="#B89A74")
)
def draw_buildings(self, constructor: Constructor) -> None: def draw_buildings(self, constructor: Constructor) -> None:
""" """
@ -311,7 +317,7 @@ class Painter:
"stroke": color.hex, "stroke": color.hex,
"stroke-linecap": "round", "stroke-linecap": "round",
"stroke-linejoin": "round", "stroke-linejoin": "round",
"stroke-width": scale * width + extra_width "stroke-width": scale * width + extra_width,
} }
path.update(style) path.update(style)
self.svg.add(path) self.svg.add(path)

View file

@ -31,9 +31,9 @@ def get_osm(
return result_file_name.open().read() return result_file_name.open().read()
matcher = re.match( matcher = re.match(
"(?P<left>[0-9.-]*),(?P<bottom>[0-9.-]*)," + "(?P<left>[0-9.-]*),(?P<bottom>[0-9.-]*),"
"(?P<right>[0-9.-]*),(?P<top>[0-9.-]*)", + "(?P<right>[0-9.-]*),(?P<top>[0-9.-]*)",
boundary_box boundary_box,
) )
if not matcher: if not matcher:
@ -61,7 +61,9 @@ def get_osm(
content = get_data( content = get_data(
"api.openstreetmap.org/api/0.6/map", "api.openstreetmap.org/api/0.6/map",
{"bbox": boundary_box}, is_secure=True) {"bbox": boundary_box},
is_secure=True,
)
result_file_name.open("w+").write(content.decode("utf-8")) result_file_name.open("w+").write(content.decode("utf-8"))
@ -69,8 +71,8 @@ def get_osm(
def get_data( def get_data(
address: str, parameters: Dict[str, str], is_secure: bool = False) \ address: str, parameters: Dict[str, str], is_secure: bool = False
-> bytes: ) -> bytes:
""" """
Construct Internet page URL and get its descriptor. Construct Internet page URL and get its descriptor.

View file

@ -66,7 +66,7 @@ class Tagged:
value: str = self.tags[key] value: str = self.tags[key]
float_value: float = parse_float(value) float_value: float = parse_float(value)
if float_value is not None: if float_value is not None:
return float_value return float_value
@ -77,7 +77,7 @@ class Tagged:
]: ]:
matcher = pattern.match(value) matcher = pattern.match(value)
if matcher: if matcher:
float_value: float = parse_float(matcher.group("value")) float_value: float = parse_float(matcher.group("value"))
if float_value is not None: if float_value is not None:
return float_value * ratio return float_value * ratio
@ -450,6 +450,10 @@ class OSMReader:
""" """
attributes = element.attrib attributes = element.attrib
self.map_.view_box = MinMax( self.map_.view_box = MinMax(
np.array((float(attributes["minlat"]), float(attributes["minlon"]))), np.array(
np.array((float(attributes["maxlat"]), float(attributes["maxlon"]))) (float(attributes["minlat"]), float(attributes["minlon"]))
),
np.array(
(float(attributes["maxlat"]), float(attributes["maxlon"]))
),
) )

View file

@ -22,6 +22,7 @@ class Occupied:
Structure that remembers places of the canvas occupied by elements (icons, Structure that remembers places of the canvas occupied by elements (icons,
texts, shapes). texts, shapes).
""" """
def __init__(self, width: int, height: int, overlap: float): def __init__(self, width: int, height: int, overlap: float):
self.matrix = np.full((int(width), int(height)), False, dtype=bool) self.matrix = np.full((int(width), int(height)), False, dtype=bool)
self.width: float = width self.width: float = width
@ -53,9 +54,16 @@ class Point(Tagged):
""" """
def __init__( def __init__(
self, icon_set: IconSet, labels: List[Label], tags: Dict[str, str], self,
processed: Set[str], point: np.array, coordinates: np.array, icon_set: IconSet,
priority: float = 0, is_for_node: bool = True, draw_outline: bool = True labels: List[Label],
tags: Dict[str, str],
processed: Set[str],
point: np.array,
coordinates: np.array,
priority: float = 0,
is_for_node: bool = True,
draw_outline: bool = True,
): ):
super().__init__() super().__init__()
@ -81,10 +89,7 @@ class Point(Tagged):
""" """
Draw main shape for one node. Draw main shape for one node.
""" """
keys_left = [ keys_left = [x for x in self.tags.keys() if x not in self.processed]
x for x in self.tags.keys()
if x not in self.processed # and not self.is_no_drawable(x)
]
if ( if (
self.icon_set.main_icon.is_default() self.icon_set.main_icon.is_default()
and not self.icon_set.extra_icons and not self.icon_set.extra_icons
@ -124,14 +129,19 @@ class Point(Tagged):
for icon in self.icon_set.extra_icons: for icon in self.icon_set.extra_icons:
self.draw_point_shape( self.draw_point_shape(
svg, icon, self.point + np.array((left, self.y)), svg, icon, self.point + np.array((left, self.y)),
occupied=occupied) occupied=occupied
)
left += 16 left += 16
if self.icon_set.extra_icons: if self.icon_set.extra_icons:
self.y += 16 self.y += 16
def draw_point_shape( def draw_point_shape(
self, svg: svgwrite.Drawing, icon: Icon, position, self,
occupied, tags: Optional[Dict[str, str]] = None svg: svgwrite.Drawing,
icon: Icon,
position,
occupied,
tags: Optional[Dict[str, str]] = None,
) -> bool: ) -> bool:
""" """
Draw one combined icon and its outline. Draw one combined icon and its outline.
@ -180,7 +190,7 @@ class Point(Tagged):
for label in labels: for label in labels:
text = label.text text = label.text
text = text.replace("&quot;", '"') text = text.replace("&quot;", '"')
text = text.replace("&amp;", '&') text = text.replace("&amp;", "&")
text = text[:26] + ("..." if len(text) > 26 else "") text = text[:26] + ("..." if len(text) > 26 else "")
self.draw_text( self.draw_text(
svg, text, self.point + np.array((0, self.y + 2)), svg, text, self.point + np.array((0, self.y + 2)),
@ -188,11 +198,18 @@ class Point(Tagged):
) )
def draw_text( def draw_text(
self, svg: svgwrite.Drawing, text: str, point, self,
occupied: Optional[Occupied], fill: Color, size: float = 10.0, svg: svgwrite.Drawing,
out_fill=Color("white"), out_opacity: float = 0.5, text: str,
out_fill_2: Optional[Color] = None, out_opacity_2: float = 1.0, point,
is_debug: bool = False occupied: Optional[Occupied],
fill: Color,
size: float = 10.0,
out_fill=Color("white"),
out_opacity: float = 0.5,
out_fill_2: Optional[Color] = None,
out_opacity_2: float = 1.0,
is_debug: bool = False,
) -> None: ) -> None:
""" """
Drawing text. Drawing text.

View file

@ -4,9 +4,7 @@ from pathlib import Path
from typing import List from typing import List
def rasterize( def rasterize(from_: Path, to_: Path, area: str = "", dpi: float = 90) -> None:
from_: Path, to_: Path, area: str = "", dpi: float = 90
) -> None:
""" """
Make PNG image out of SVG using Inkscape. Make PNG image out of SVG using Inkscape.
""" """

View file

@ -25,6 +25,7 @@ class LineStyle:
""" """
SVG line style and its priority. SVG line style and its priority.
""" """
style: Dict[str, Union[int, float, str]] style: Dict[str, Union[int, float, str]]
priority: float = 0.0 priority: float = 0.0
@ -33,6 +34,7 @@ class MatchingType(Enum):
""" """
Description on how tag was matched. Description on how tag was matched.
""" """
NOT_MATCHED = 0 NOT_MATCHED = 0
MATCHED_BY_SET = 1 MATCHED_BY_SET = 1
MATCHED_BY_WILDCARD = 2 MATCHED_BY_WILDCARD = 2
@ -55,13 +57,13 @@ def is_matched_tag(
if matcher_tag_value == "*": if matcher_tag_value == "*":
return MatchingType.MATCHED_BY_WILDCARD return MatchingType.MATCHED_BY_WILDCARD
if ( if (
isinstance(matcher_tag_value, str) and isinstance(matcher_tag_value, str)
tags[matcher_tag_key] == matcher_tag_value and tags[matcher_tag_key] == matcher_tag_value
): ):
return MatchingType.MATCHED return MatchingType.MATCHED
if ( if (
isinstance(matcher_tag_value, list) and isinstance(matcher_tag_value, list)
tags[matcher_tag_key] in matcher_tag_value and tags[matcher_tag_key] in matcher_tag_value
): ):
return MatchingType.MATCHED_BY_SET return MatchingType.MATCHED_BY_SET
return MatchingType.NOT_MATCHED return MatchingType.NOT_MATCHED
@ -71,6 +73,7 @@ class Matcher:
""" """
Tag matching. Tag matching.
""" """
def __init__(self, structure: Dict[str, Any]): def __init__(self, structure: Dict[str, Any]):
self.tags: Dict[str, str] = structure["tags"] self.tags: Dict[str, str] = structure["tags"]
@ -98,8 +101,8 @@ class Matcher:
config_tag_key: str config_tag_key: str
tag_matcher = self.tags[config_tag_key] tag_matcher = self.tags[config_tag_key]
if ( if (
is_matched_tag(config_tag_key, tag_matcher, tags) == is_matched_tag(config_tag_key, tag_matcher, tags)
MatchingType.NOT_MATCHED == MatchingType.NOT_MATCHED
): ):
matched = False matched = False
break break
@ -109,8 +112,8 @@ class Matcher:
config_tag_key: str config_tag_key: str
tag_matcher = self.exception[config_tag_key] tag_matcher = self.exception[config_tag_key]
if ( if (
is_matched_tag(config_tag_key, tag_matcher, tags) != is_matched_tag(config_tag_key, tag_matcher, tags)
MatchingType.NOT_MATCHED != MatchingType.NOT_MATCHED
): ):
matched = False matched = False
break break
@ -122,6 +125,7 @@ class NodeMatcher(Matcher):
""" """
Tag specification matcher. Tag specification matcher.
""" """
def __init__(self, structure: Dict[str, Any]): def __init__(self, structure: Dict[str, Any]):
# Dictionary with tag keys and values, value lists, or "*" # Dictionary with tag keys and values, value lists, or "*"
super().__init__(structure) super().__init__(structure)
@ -167,6 +171,7 @@ class WayMatcher(Matcher):
""" """
Special tag matcher for ways. Special tag matcher for ways.
""" """
def __init__(self, structure: Dict[str, Any], scheme: "Scheme"): def __init__(self, structure: Dict[str, Any], scheme: "Scheme"):
super().__init__(structure) super().__init__(structure)
self.style: Dict[str, Any] = {"fill": "none"} self.style: Dict[str, Any] = {"fill": "none"}
@ -186,6 +191,7 @@ class RoadMatcher(Matcher):
""" """
Special tag matcher for highways. Special tag matcher for highways.
""" """
def __init__(self, structure: Dict[str, Any], scheme: "Scheme"): def __init__(self, structure: Dict[str, Any], scheme: "Scheme"):
super().__init__(structure) super().__init__(structure)
self.border_color: Color = Color( self.border_color: Color = Color(
@ -206,6 +212,7 @@ class Scheme:
Specifies map colors and rules to draw icons for OpenStreetMap tags. Specifies map colors and rules to draw icons for OpenStreetMap tags.
""" """
def __init__(self, file_name: Path): def __init__(self, file_name: Path):
""" """
:param file_name: name of the scheme file with tags, colors, and tag key :param file_name: name of the scheme file with tags, colors, and tag key
@ -266,7 +273,7 @@ class Scheme:
if key in self.tags_to_write or key in self.tags_to_skip: if key in self.tags_to_write or key in self.tags_to_skip:
return True return True
for prefix in self.prefix_to_write + self.prefix_to_skip: # type: str for prefix in self.prefix_to_write + self.prefix_to_skip: # type: str
if key[:len(prefix) + 1] == f"{prefix}:": if key[: len(prefix) + 1] == f"{prefix}:":
return True return True
return False return False
@ -282,7 +289,7 @@ class Scheme:
if key in self.tags_to_write: if key in self.tags_to_write:
return True return True
for prefix in self.prefix_to_write: # type: str for prefix in self.prefix_to_write: # type: str
if key[:len(prefix) + 1] == f"{prefix}:": if key[: len(prefix) + 1] == f"{prefix}:":
return True return True
return False return False
@ -361,8 +368,7 @@ class Scheme:
processed.add("material") processed.add("material")
for tag_key in tags: # type: str for tag_key in tags: # type: str
if (tag_key.endswith(":color") or if tag_key.endswith(":color") or tag_key.endswith(":colour"):
tag_key.endswith(":colour")):
color = self.get_color(tags[tag_key]) color = self.get_color(tags[tag_key])
processed.add(tag_key) processed.add(tag_key)
@ -375,7 +381,8 @@ class Scheme:
main_icon.recolor(color) main_icon.recolor(color)
keys_left = [ keys_left = [
x for x in tags.keys() x
for x in tags.keys()
if x not in processed and not self.is_no_drawable(x) if x not in processed and not self.is_no_drawable(x)
] ]
@ -390,7 +397,7 @@ class Scheme:
if key in tags: if key in tags:
for specification in main_icon.shape_specifications: for specification in main_icon.shape_specifications:
if ( if (
DirectionSet(tags[key]).is_right() is False DirectionSet(tags[key]).is_right() is False
and specification.shape.is_right_directed is True and specification.shape.is_right_directed is True
or specification.shape.is_right_directed is True or specification.shape.is_right_directed is True
and specification.shape.is_right_directed is False and specification.shape.is_right_directed is False

View file

@ -11,9 +11,7 @@ class Handler(BaseHTTPRequestHandler):
update_cache: bool = False update_cache: bool = False
def __init__( def __init__(self, request, client_address, server):
self, request, client_address, server
):
super().__init__(request, client_address, server) super().__init__(request, client_address, server)
def write(self, message): def write(self, message):

View file

@ -17,6 +17,7 @@ class Label:
""" """
Text label. Text label.
""" """
text: str text: str
fill: Color = DEFAULT_COLOR fill: Color = DEFAULT_COLOR
size: float = 10.0 size: float = 10.0
@ -46,7 +47,7 @@ def get_address(
if "addr:street" in tags: if "addr:street" in tags:
street = tags["addr:street"] street = tags["addr:street"]
if street.startswith("улица "): if street.startswith("улица "):
street = "ул. " + street[len("улица "):] street = "ул. " + street[len("улица ") :]
address.append(street) address.append(street)
processed.add("addr:street") processed.add("addr:street")

View file

@ -23,62 +23,57 @@ def parse_options(args) -> argparse.Namespace:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
"-i", "--input", "-i",
"--input",
dest="input_file_name", dest="input_file_name",
metavar="<path>", metavar="<path>",
nargs="*", nargs="*",
help="input XML file name (if not specified, file will be downloaded " help="input XML file name (if not specified, file will be downloaded "
"using OpenStreetMap API)") "using OpenStreetMap API)",
)
parser.add_argument( parser.add_argument(
"-o", "--output", "-o",
"--output",
dest="output_file_name", dest="output_file_name",
metavar="<path>", metavar="<path>",
default="map.svg", default="map.svg",
help="output SVG file name (map.svg by default)") help="output SVG file name (map.svg by default)",
)
parser.add_argument( parser.add_argument(
"-b", "--boundary-box", "-b",
"--boundary-box",
dest="boundary_box", dest="boundary_box",
metavar="<lon1>,<lat1>,<lon2>,<lat2>", metavar="<lon1>,<lat1>,<lon2>,<lat2>",
help="geo boundary box, use space before \"-\" for negative values") help='geo boundary box, use space before "-" for negative values',
)
parser.add_argument( parser.add_argument(
"-s", "--scale", "-s",
"--scale",
metavar="<float>", metavar="<float>",
help="OSM zoom level (may not be integer, default is 18)", help="OSM zoom level (may not be integer, default is 18)",
default=18, default=18,
dest="scale", dest="scale",
type=float) type=float,
)
parser.add_argument( parser.add_argument(
"--cache", "--cache", help="path for temporary OSM files", default="cache"
help="path for temporary OSM files",
default="cache"
) )
parser.add_argument( parser.add_argument(
"--labels", "--labels",
help="label drawing mode: `no`, `main`, or `all`", help="label drawing mode: `no`, `main`, or `all`",
dest="label_mode", dest="label_mode",
default="main") default="main",
)
parser.add_argument( parser.add_argument(
"--show-missing-tags", "--show-missing-tags", dest="show_missing_tags", action="store_true"
dest="show_missing_tags", )
action="store_true")
parser.add_argument( parser.add_argument(
"--no-show-missing-tags", "--no-show-missing-tags", dest="show_missing_tags", action="store_false"
dest="show_missing_tags", )
action="store_false") parser.add_argument("--overlap", dest="overlap", default=12, type=int)
parser.add_argument( parser.add_argument("--mode", default="normal")
"--overlap", parser.add_argument("--seed", default="")
dest="overlap", parser.add_argument("--level", default=None)
default=12,
type=int)
parser.add_argument(
"--mode",
default="normal")
parser.add_argument(
"--seed",
default="")
parser.add_argument(
"--level",
default=None)
arguments: argparse.Namespace = parser.parse_args(args[1:]) arguments: argparse.Namespace = parser.parse_args(args[1:])

View file

@ -13,6 +13,7 @@ class MinMax:
""" """
Minimum and maximum. Minimum and maximum.
""" """
min_: Any = None min_: Any = None
max_: Any = None max_: Any = None