summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDidierRLopes <dro.lopes@campus.fct.unl.pt>2023-06-09 03:08:58 -0700
committerDidierRLopes <dro.lopes@campus.fct.unl.pt>2023-06-09 03:08:58 -0700
commit718997cf16cc575d58ea6c86cda445fa1b40255f (patch)
tree372a7862cee1f8b0069a58d23defbdb35009f0db
parent32e86611f7c2e3cdbda817beae780ebc945ccaa6 (diff)
fix slicing for args that don't existroutinesargs
-rw-r--r--openbb_terminal/routine_functions.py300
1 files changed, 253 insertions, 47 deletions
diff --git a/openbb_terminal/routine_functions.py b/openbb_terminal/routine_functions.py
index 6e4623681cf..54dfade3924 100644
--- a/openbb_terminal/routine_functions.py
+++ b/openbb_terminal/routine_functions.py
@@ -5,8 +5,8 @@ from typing import Dict, List, Match, Optional, Tuple, Union
from dateutil.relativedelta import relativedelta
-from openbb_terminal.rich_config import console
from openbb_terminal.core.plots.backend import plots_backend
+from openbb_terminal.rich_config import console
# pylint: disable=too-many-statements,eval-used,consider-iterating-dictionary
# pylint: disable=too-many-branches,too-many-return-statements
@@ -274,13 +274,43 @@ def parse_openbb_script(
if VAR_NAME in ROUTINE_VARS:
values = eval(f'ROUTINE_VARS["{VAR_NAME}"]')
if isinstance(values, list):
- # TODO: This is a bit of a hack, but we need to do same here
- # for case user selects first $ARGV[n] with n>0 and then
- # tries to access $ARGV[0] which is empty
- templine = templine.replace(
- match[0],
- eval(f"values[{VAR_SLICE}]"),
- )
+ val = eval("values[0]")
+ if val:
+ templine = templine.replace(
+ match[0],
+ val,
+ )
+
+ else:
+ # This is a bit of a hack, but we need to do same here
+ # for case user selects first $ARGV[n] with n>0 and then
+ # tries to access $ARGV[0] which is empty
+ if in_production:
+ plots_backend().start(True)
+ args = plots_backend().call_routine(
+ f"Routine '{file_path}' requires variable '{VAR_NAME}[0]'",
+ [f"{VAR_NAME}[0]"],
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
+ )
+ if args and f"{VAR_NAME}[0]" in args:
+ # Update index 0 from $ARGV with user input
+ ROUTINE_VARS[VAR_NAME][0] = [
+ args[f"{VAR_NAME}[0]"]
+ ]
+ templine = templine.replace(
+ match[0],
+ args[f"{VAR_NAME}[0]"],
+ )
+ else:
+ return (
+ f"[red]Variable {VAR_NAME}[{VAR_SLICE}] is empty[/red]",
+ "",
+ )
+
else:
templine = templine.replace(match[0], values)
else:
@@ -291,12 +321,17 @@ def parse_openbb_script(
args = plots_backend().call_routine(
f"Routine '{file_path}' requires variable '{VAR_NAME}[{VAR_SLICE}]'",
[f"{VAR_NAME}[{VAR_SLICE}]"],
- Path(__file__).parent.parent / "openbb_terminal"
- / "core" / "routines" / "argv_input.html",
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
)
if args and f"{VAR_NAME}[{VAR_SLICE}]" in args:
# Update index 0 from $ARGV with user input
- ROUTINE_VARS[VAR_NAME] = [args[f"{VAR_NAME}[{VAR_SLICE}]"]]
+ ROUTINE_VARS[VAR_NAME] = [
+ args[f"{VAR_NAME}[{VAR_SLICE}]"]
+ ]
templine = templine.replace(
match[0],
args[f"{VAR_NAME}[{VAR_SLICE}]"],
@@ -334,17 +369,29 @@ def parse_openbb_script(
args = plots_backend().call_routine(
f"Routine '{file_path}' requires variable '{VAR_NAME}[{VAR_SLICE}]'",
[f"{VAR_NAME}[{VAR_SLICE}]"],
- Path(__file__).parent.parent / "openbb_terminal"
- / "core" / "routines" / "argv_input.html",
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
)
- if args and f"{VAR_NAME}[{VAR_SLICE}]" in args:
+ if (
+ args
+ and f"{VAR_NAME}[{VAR_SLICE}]" in args
+ ):
# Update index different than 0 from $ARGV with user input
# Note that we only get here if the user invokes $ARGV[n]
# with n != 0 for the first time, thus it means that we are
# ok with setting the first elements as empty since they haven't
# been used yet
- ROUTINE_VARS[VAR_NAME] += [""] * (int(VAR_SLICE)+1-len(ROUTINE_VARS[VAR_NAME]))
- ROUTINE_VARS[VAR_NAME][int(VAR_SLICE)] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
+ ROUTINE_VARS[VAR_NAME] += [""] * (
+ int(VAR_SLICE)
+ + 1
+ - len(ROUTINE_VARS[VAR_NAME])
+ )
+ ROUTINE_VARS[VAR_NAME][
+ int(VAR_SLICE)
+ ] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
templine = templine.replace(
match[0],
args[f"{VAR_NAME}[{VAR_SLICE}]"],
@@ -361,17 +408,28 @@ def parse_openbb_script(
# Handle the case the initial fields are empty
# because we invoked $ARGV[n] with n > 0 before creating n == 0
# so we check that the fields are missing and we ask for them
- if in_production and not variable[int(VAR_SLICE)]:
+ if (
+ in_production
+ and not variable[int(VAR_SLICE)]
+ ):
plots_backend().start(True)
args = plots_backend().call_routine(
f"Routine '{file_path}' requires variable '{VAR_NAME}[{VAR_SLICE}]'",
[f"{VAR_NAME}[{VAR_SLICE}]"],
- Path(__file__).parent.parent / "openbb_terminal"
- / "core" / "routines" / "argv_input.html",
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
)
- if args and f"{VAR_NAME}[{VAR_SLICE}]" in args:
+ if (
+ args
+ and f"{VAR_NAME}[{VAR_SLICE}]" in args
+ ):
# Replace the empty value that we have with the user input
- ROUTINE_VARS[VAR_NAME][int(VAR_SLICE)] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
+ ROUTINE_VARS[VAR_NAME][
+ int(VAR_SLICE)
+ ] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
templine = templine.replace(
match[0],
args[f"{VAR_NAME}[{VAR_SLICE}]"],
@@ -395,8 +453,11 @@ def parse_openbb_script(
args = plots_backend().call_routine(
f"Routine '{file_path}' requires variable '{VAR_NAME}[{VAR_SLICE}]'",
[f"{VAR_NAME}[{VAR_SLICE}]"],
- Path(__file__).parent.parent / "openbb_terminal"
- / "core" / "routines" / "argv_input.html",
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
)
if args and f"{VAR_NAME}[{VAR_SLICE}]" in args:
# Update index different than 0 from $ARGV with user input
@@ -404,8 +465,12 @@ def parse_openbb_script(
# with n != 0 for the first time, thus it means that we are
# ok with setting the first elements as empty since they haven't
# been used yet
- ROUTINE_VARS[VAR_NAME] = [""] * (int(VAR_SLICE)+1)
- ROUTINE_VARS[VAR_NAME][int(VAR_SLICE)] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
+ ROUTINE_VARS[VAR_NAME] = [""] * (
+ int(VAR_SLICE) + 1
+ )
+ ROUTINE_VARS[VAR_NAME][
+ int(VAR_SLICE)
+ ] = args[f"{VAR_NAME}[{VAR_SLICE}]"]
templine = templine.replace(
match[0],
args[f"{VAR_NAME}[{VAR_SLICE}]"],
@@ -433,26 +498,162 @@ def parse_openbb_script(
or VAR_SLICE.split(":")[1].isdigit()
)
):
- slicing_tuple = "slice("
- slicing_tuple += (
- VAR_SLICE.split(":")[0]
- if VAR_SLICE.split(":")[0].isdigit()
- else "None"
- )
- slicing_tuple += ","
- slicing_tuple += (
- VAR_SLICE.split(":")[1]
- if VAR_SLICE.split(":")[1].isdigit()
- else "None"
- )
- slicing_tuple += ")"
+ # The variable exists for us to slice it
+ if VAR_NAME in ROUTINE_VARS:
+ if not isinstance(ROUTINE_VARS[VAR_NAME], list):
+ return (
+ f"[red]Variable {VAR_NAME} is not a list and"
+ "thus it cannot be sliced.[/red]",
+ "",
+ )
- templine = templine.replace(
- match[0],
- ",".join(
- eval(f'ROUTINE_VARS["{VAR_NAME}"][{slicing_tuple}]')
- ),
- )
+ slice_start = (
+ VAR_SLICE.split(":")[0]
+ if VAR_SLICE.split(":")[0].isdigit()
+ else "None"
+ )
+ slicing_tuple = "slice("
+ slicing_tuple += slice_start
+ slicing_tuple += ","
+
+ slice_end = (
+ VAR_SLICE.split(":")[1]
+ if VAR_SLICE.split(":")[1].isdigit()
+ else "None"
+ )
+ slicing_tuple += slice_end
+ slicing_tuple += ")"
+
+ # When in production there's the chance that the user wants to slice
+ # variables that were previously empty because we created them in production
+ if in_production:
+ slice_st = (
+ int(slice_start) if slice_start != "None" else 0
+ )
+ slice_en = (
+ int(slice_end)
+ if slice_end != "None"
+ else len(ROUTINE_VARS[VAR_NAME]) - 1
+ )
+ for slice_individual_idx in range(
+ slice_st, slice_en
+ ):
+ # Check that we are trying to slice an array that exists and
+ # the slicing number makes sense but one of the values is empty
+ if (
+ slice_individual_idx
+ < len(ROUTINE_VARS[VAR_NAME])
+ and not ROUTINE_VARS[VAR_NAME][
+ slice_individual_idx
+ ]
+ ):
+ plots_backend().start(True)
+ name = f"{VAR_NAME}[{slice_individual_idx}]"
+ args = plots_backend().call_routine(
+ f"Routine '{file_path}' requires variable '{name}'",
+ [f"{VAR_NAME}[{slice_individual_idx}]"],
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
+ )
+ if (
+ args
+ and f"{VAR_NAME}[{slice_individual_idx}]"
+ in args
+ ):
+ # Update entire $ARGV with user input
+ # If it has a comma it means the ARGV has multiple values
+ # otherwise it is a single value
+ ROUTINE_VARS[VAR_NAME] = args[
+ f"{VAR_NAME}[{slice_individual_idx}]"
+ ]
+ templine = templine.replace(
+ match[0],
+ args[
+ f"{VAR_NAME}[{slice_individual_idx}]"
+ ],
+ )
+ else:
+ return (
+ f"[red]Variable {VAR_NAME}[{slice_individual_idx}] not given "
+ "for current routine script.[/red]",
+ "",
+ )
+
+ # We are trying to slice elements that don't exist, so we will ask the user
+ # to provide them
+ if (
+ slice_individual_idx
+ > len(ROUTINE_VARS[VAR_NAME]) - 1
+ ):
+ plots_backend().start(True)
+ name = f"{VAR_NAME}[{slice_individual_idx}]"
+ args = plots_backend().call_routine(
+ f"Routine '{file_path}' requires variable '{name}'",
+ [f"{VAR_NAME}[{slice_individual_idx}]"],
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
+ )
+ if (
+ args
+ and f"{VAR_NAME}[{slice_individual_idx}]"
+ in args
+ ):
+ # Add enough elements to fix missing values on the list
+ ROUTINE_VARS[VAR_NAME] += [""] * (
+ slice_individual_idx
+ + 1
+ - len(ROUTINE_VARS[VAR_NAME])
+ )
+ ROUTINE_VARS[VAR_NAME][
+ slice_individual_idx
+ ] = args[
+ f"{VAR_NAME}[{slice_individual_idx}]"
+ ]
+ templine = templine.replace(
+ match[0],
+ args[
+ f"{VAR_NAME}[{slice_individual_idx}]"
+ ],
+ )
+ else:
+ return (
+ f"[red]Variable {VAR_NAME}[{slice_individual_idx}] not given "
+ "for current routine script.[/red]",
+ "",
+ )
+
+ templine = templine.replace(
+ match[0],
+ ",".join(
+ eval(
+ f'ROUTINE_VARS["{VAR_NAME}"][{slicing_tuple}]'
+ )
+ ),
+ )
+
+ else:
+ templine = templine.replace(
+ match[0],
+ ",".join(
+ eval(
+ f'ROUTINE_VARS["{VAR_NAME}"][{slicing_tuple}]'
+ )
+ ),
+ )
+
+ # The variable doesn't exist f or us to slice it
+ else:
+ return (
+ f"[red]Variable {VAR_NAME} not given for "
+ "current routine script for it to be sliced.[/red]",
+ "",
+ )
# Just replace value without slicing or list
else:
@@ -507,15 +708,20 @@ def parse_openbb_script(
args = plots_backend().call_routine(
f"Routine '{file_path}' requires variable '{VAR_NAME}'",
[VAR_NAME],
- Path(__file__).parent.parent / "openbb_terminal"
- / "core" / "routines" / "argv_input.html",
+ Path(__file__).parent.parent
+ / "openbb_terminal"
+ / "core"
+ / "routines"
+ / "argv_input.html",
)
if args and f"{VAR_NAME}" in args:
# Update entire $ARGV with user input
# If it has a comma it means the ARGV has multiple values
# otherwise it is a single value
if "," in args[VAR_NAME]:
- ROUTINE_VARS[VAR_NAME] = args[VAR_NAME].split(",")
+ ROUTINE_VARS[VAR_NAME] = args[
+ VAR_NAME
+ ].split(",")
else:
ROUTINE_VARS[VAR_NAME] = args[VAR_NAME]
templine = templine.replace(