# ==============================================================================
"""FIBOPLUS : generate the Fibonacci sequence with several options"""
# ==============================================================================
__author__  = "Christophe Schlick modified by Philippe Blasi"
__version__ = "1.0" # use 'parse' function with default values
__date__    = "2022-11-12"
__usage__   = """
User input : ['n =' <n>] ['u =' <u>] ['v =' <v>] ['file =' <filename>]
             - n:int = number of terms for the sequence (defaut = 10)
             - u:int = value of the first term (default = 0)
             - v:int = value of the second term (default = 1)
             - filename:str = name of output file (default = output on screen)
App ouput : Fibonacci sequence defined by user arguments

Note: to use all default values, simply enter <SPACE> as command"""
# ==============================================================================
from ezCLI import *
# ------------------------------------------------------------------------------
def fibo(n:int, u:int, v:int) -> int:
  """compute the nth term of the Fibonacci sequence starting from (u,v)"""
  a, b = u, v
  for p in range(n):
    a, b = b, a+b
  return a
# ------------------------------------------------------------------------------
def fibos(n:int, u:int, v:int) -> str:
  """return the 'n' first terms of the Fibonacci starting from (u,v)"""
  return '\n'.join(["fibo(%s) = %s" % (p, fibo(p,u,v)) for p in range(n+1)])
# ------------------------------------------------------------------------------
def parser(command:str) -> str:
  """parse 'command' and return Fibonacci sequence of provided arguments"""
  default = 'n=10 u=0 v=1 file=' # default values for all arguments
  # parse 'command' and use default values for missing arguments
  args = parse(command, default); #inspect()
  # store all values from dictionary 'args' into variables 
  n, u, v, file = (args[name] for name in ('n','u','v','file')); #inspect()
  assert type(n) is int and n >= 0, "%r : invalid value for 'n'" % n
  assert type(u) is int, "%r : invalid value for 'u'" % u
  assert type(v) is int, "%r : invalid value for 'v'" % v
  assert type(file) is str, "%r : invalid filename" % file
  if not file: return fibos(n, u, v) # show result on screen
  write_txt(file, fibos(n, u, v)) # write result in 'file'
  return "Fibonacci sequence (%s values) written in file %r" % (n, file)
# ==============================================================================
if __name__ == '__main__':
  userloop(parser)
# ==============================================================================
