def input_float(prompt, allow_empty=False): ''' Read a float from the console, showing the given prompt. prompt: The prompt message. allow_empty: When `True`, allows an empty input. The default is to repeat until a valid float is entered. ''' from plumbum.cli import terminal if allow_empty: return terminal.prompt(prompt, type=float, default=None) else: return terminal.prompt(prompt, type=float)
def ask_for_data(): """This function asks the user the values of parameters, number of integration steps, initial conditions and simulation_ID. Then creates a '.temp_for_create_infiles.txt' file to store them. This file will be used by other functions to read the data""" while (True): in_data = terminal.prompt( "Type the data in the form 'mu k N_steps x1_0 x2_0 y1_0 simulation_identifier" ) split_values = in_data.split() if (len(split_values) != 7): print(colors.yellow | "You did not give 7 values. Try again.") continue try: mu = float(in_data.split()[0]) k = float(in_data.split()[1]) N_steps = int(in_data.split()[2]) if (N_steps < 20000): print( colors.yellow | "The number of integration steps may be too small. Convergence of Lyapunov exponents is not granted." ) x1_0 = float(in_data.split()[3]) x2_0 = float(in_data.split()[4]) y1_0 = float(in_data.split()[5]) simulation_ID = in_data.split()[6] except ValueError: print( colors.yellow | "Some of the parameter values you gave are not numbers. Please try again." ) continue if (0 < mu < 10**2 and 1e-2 < k < 1e+2): pass else: go_on1 = terminal.ask( colors.yellow | """The values of mu or k you choose may cause overflow issues. It is recommended that 0< mu< 10^2 and 10^-2< k < 10^2. Continue anyway?""") if (go_on1): break else: continue if ('.' not in simulation_ID): break else: go_on2 = terminal.ask( colors.yellow | """The presence of '.' character in simulation ID may cause issues when saving images. Continue anyway?""" ) if (go_on2): break outfile = open(".temp_for_create_infiles.txt", 'w+') outfile.write(in_data) outfile.close()
def query_user_data( questions_data: AnyByStrDict, answers_data: AnyByStrDict, ask_user: bool, envops: EnvOps, ) -> AnyByStrDict: """Query the user for questions given in the config file.""" type_maps: Dict[str, Callable] = { "bool": bool, "float": float, "int": int, "json": json.loads, "str": str, "yaml": parse_yaml_string, } env = get_jinja_env(envops=envops) result = DEFAULT_DATA.copy() _render_value = partial(render_value, env=env, context=result) _render_choices = partial(render_choices, env=env, context=result) for question, details in questions_data.items(): # Get default answer answer = default = answers_data.get( question, _render_value(details.get("default"))) # Get question type; by default let YAML decide it type_name = _render_value(details.get("type", "yaml")) try: type_fn = type_maps[type_name] except KeyError: raise InvalidTypeError() if ask_user: # Generate message to ask the user emoji = "🕵️" if details.get("secret", False) else "🎤" message = f"\n{bold | question}? Format: {type_name}\n{emoji} " if details.get("help"): message = ( f"\n{info & italics | _render_value(details['help'])}{message}" ) # Use the right method to ask if type_fn is bool: answer = ask(message, default) elif details.get("choices"): choices = _render_choices(details["choices"]) answer = choose(message, choices, default) else: answer = prompt(message, type_fn, default) result[question] = cast_answer_type(answer, type_fn) for key in DEFAULT_DATA: del result[key] return result
def test_validator(self, capsys): with send_stdin("12\n9"): assert prompt("Enter in range < 10", type=int, validator=lambda x: x<10) == 9 assert "try again" in capsys.readouterr()[0]
def test_typefail(self, capsys): with send_stdin("1.2\n13"): assert prompt("Enter int", type=int) == 13 assert "try again" in capsys.readouterr()[0]
def test_default(self, capsys): with send_stdin(""): assert prompt("Enter nothing", default='hi') == 'hi' assert capsys.readouterr()[0] == "Enter nothing [hi]: "
def test_str(self): with send_stdin("1234"): assert prompt("Enter a string", type=str) == "1234"
def test_try_twice(self, capsys): with send_stdin("\n13"): assert prompt("Enter a random int:", type=int) == 13 assert capsys.readouterr()[0] == "Enter a random int: Enter a random int: "
def test_simple(self, capsys): with send_stdin("12"): assert prompt("Enter a random int:", type=int) == 12 assert capsys.readouterr()[0] == "Enter a random int: "
def test_validator(self, capsys): with send_stdin("12\n9"): assert (prompt("Enter in range < 10", type=int, validator=lambda x: x < 10) == 9) assert "try again" in capsys.readouterr()[0]
def test_default(self, capsys): with send_stdin(""): assert prompt("Enter nothing", default="hi") == "hi" assert capsys.readouterr()[0] == "Enter nothing [hi]: "
def test_try_twice(self, capsys): with send_stdin("\n13"): assert prompt("Enter a random int:", type=int) == 13 assert capsys.readouterr( )[0] == "Enter a random int: Enter a random int: "
def env(self): # set current environment for creating file dev.docker-compose # TODO: use --env flag instead if not hasattr(self, '_env'): self._env = prompt('Current environment ?', default='dev') return self._env