Skip to content

Commit

Permalink
Merge pull request #59 from SkwalExe/fixes
Browse files Browse the repository at this point in the history
fixes, new version, new commands
  • Loading branch information
SkwalExe authored May 2, 2024
2 parents c7905c9 + 2a86def commit 28e67f1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 2.1.0 - Unreleased
# 2.1.0 - 2024-05-02

### Added
- Inverse mandelbrot set
Expand Down
2 changes: 1 addition & 1 deletion fractalistic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Terminal based fractal explorer, including Mandelbrot, Burning Ship, and Julia."""

__version__ = "2.0.0"
__version__ = "2.1.0"
43 changes: 35 additions & 8 deletions fractalistic/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ def set_command_list(self) -> None:
help="Set the data type used for Julia and Mandelbrot exponents.",
accepted_arg_counts=[0, 2],
extra_help=(
"[green]Usage : \\[mandel/julia] \\[int/float/mpc]\nUsage : no args[/green]\n"
"[green]Usage : \\[mandel/julia/burning_ship] \\[int/float/mpc]\nUsage : no args[/green]\n"
"If no argument is given, print out the current types. "
"Else, set the mandel/julia exponent type to \\[type].\n"
"- It is important to use the simplest type possible because it has a huge impact on performance.\n"
Expand Down Expand Up @@ -697,9 +697,11 @@ def action_reset(self) -> None:

@on(Input.Submitted, "Input")
def command_input_on_submitted(self, event: Input.Submitted) -> None:
# Get the command from the input and clear it
command = event.value.strip()
self.command_input.value = ""

# Ignore empty commands
if len(command) == 0:
return

Expand Down Expand Up @@ -846,7 +848,7 @@ def precision(self, value):
set_precision(value)
self.render_settings.wanted_numeric_precision = value

def get_command(self, name: str) -> Command | None:
def get_command(self, name: str) -> Command | CommandIncrement | None:
if name not in self.command_list:
self.log_error(f"[red]Cannot find command: [white on red]{name}")
return None
Expand Down Expand Up @@ -876,31 +878,58 @@ def remove_marker(self) -> None:
self.settings.marker_pos = None

def parse_command(self, text: str) -> None:
"""All executed commands are sent directly here."""

# Extract non-empty arguments, including the command name
args = list(filter(lambda x: len(x) > 0, text.split(" ")))

command_name = args.pop(0)

# Returns none if the command is not found
# Else, returns Command() or CommandIncrement()
command = self.get_command(command_name)

# Error message in case the command is not found
# is handled by get_command
if command is None:
return

# Check if the number of arguments is accepted by the command
if not len(args) in command.accepted_arg_count:
self.log_error(
f"Command [white on red]{command_name}[/white on red] expects "
f"{', or '.join([str(x) for x in command.accepted_arg_count])} arguments, but got {len(args)}")

return

# CommandIncrement() is a special case
# Else we just call the command with the arguments.
if isinstance(command, CommandIncrement):

# app_attribute example : "settings.render_settings.max_iter"
# means that the command will increment (self).settings.render_settings.max_iter
############################################################
# "attributes": ["settings", "render_settings", "max_iter"]
# we recursively go through the path to get the wanted attribute's value
attributes = command.app_attribute.split(".")
current_attribute_value = self
for attribute in attributes:
current_attribute_value = current_attribute_value.__getattribute__(attribute)

# If no args are provided, just print the current value here
if len(args) == 0:
self.log_info(f"The value is currently set to [blue]{current_attribute_value}")
return

# We pass the args and the current attribute value to CommandIncrement().parse_args()
value: CommandIncrementArgParseResult = command.parse_args(current_attribute_value, args)
if value.success:
# If the new value was successfully parsed, we call the command's funct
# which role is to set the new value, notice the user,
# and update the canvas according to the new value, if needed.
command.funct(value.new_value)
else:
# If the new value was not successfully parsed, we log the error message
self.log_error(value.error_message)
return
else:
Expand Down Expand Up @@ -1093,10 +1122,9 @@ def canvas_clicked(self, event: Click) -> None:
# Hide the marker since the fractal has changed
self.remove_marker()
self.render_settings.julia_click = c_num
self.log_info([
self.log_info(
"Current Julia Set:\n"
f"{self.render_settings.julia_click:.4f}",
])
f"{self.render_settings.julia_click:.4f}")
self.update_canv()
case "move":
self.render_settings.screen_pos_on_plane = c_num
Expand All @@ -1115,10 +1143,9 @@ def canvas_clicked(self, event: Click) -> None:
self.update_canv()
case "inv_mb_num":
self.render_settings.inv_mandel_numerator = c_num
self.log_info([
self.log_info(
"Current Inverse Mandelbrot Set numerator:\n"
f"{self.render_settings.inv_mandel_numerator:.4f}",
])
f"{self.render_settings.inv_mandel_numerator:.4f}")

self.update_canv()

Expand Down
9 changes: 4 additions & 5 deletions fractalistic/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,12 @@ def __init__(self, app_attribute: str, min_value=None, max_value=None, *args, **
self.app_attribute = app_attribute

def parse_args(self, current_attrib_value, args) -> CommandIncrementArgParseResult:
"""Returns the new value if the args are valid, else None"""
"""Returns the new attribute value if the args are valid, else None"""
result = CommandIncrementArgParseResult()
if len(args) == 0:
result.error_message = f"The value is currently set to [blue]{current_attrib_value}"
return result

elif len(args) == 1:
# len(args) == 0 is handled by app.py:parse_command

if len(args) == 1:
try:
result.new_value = int(args[0])
except ValueError:
Expand Down

0 comments on commit 28e67f1

Please sign in to comment.