# ==============================================================================
"""MULDIV : table of GCD/LCM (Greatest Common Divisor/Least Common Multiple)"""
# ==============================================================================
__author__  = "Christophe Schlick modified by Philippe Blasi"
__version__ = "1.0"
__date__    = "2022-11-12"
__usage__   = """
User input : <n> (where n:int > 0)
App output: table of GCD/LCM from 1 to n"""
# ==============================================================================
from ezCLI import *
from ezTK import *
# ------------------------------------------------------------------------------
def gcd(p:int, q:int) -> int:
  """return Greatest Common Divisor between numbers 'p' and 'q'"""
  while q: p, q = q, p%q # compute GCD by using Euclids' algorithm
  return p
# ------------------------------------------------------------------------------
def lcm(p:int, q:int) -> int:
  """return Least Common Multiple between numbers 'p' and 'q'"""
  return p*q // gcd(p,q)
# ------------------------------------------------------------------------------
def cell(p:int, q:int) -> int:
  """return either the GCD or the LCM according to cell position (p,q)"""
  return lcm(p,q) if (p == 1) or (p > q) else gcd(p,q)
# ------------------------------------------------------------------------------
def show(table:list) -> None:
  """show the content of 'table' in a tk window"""
  rows, cols = len(table), len(table[0]) # get size of table
  win = Win(title='MULDIV', font='Arial 14', fold=cols)
  for row in range(rows):
    for col in range(cols):
      Label(win, text=table[row][col], width=3, border=1)
  win.loop()
# ------------------------------------------------------------------------------
def muldiv(n:int) -> str:
  """return a grid containing the GCD/LCM table from 1 to n"""
  table = [[cell(p,q) for q in range(1, n+1)] for p in range(1, n+1)]
  show(table); return ''
# ------------------------------------------------------------------------------
def parser(command:str) -> str:
  """parse 'command' as integer 'n' before calling 'muldiv(n)'"""
  n = convert(command); #inspect()
  assert type(n) is int and n > 0, "<n> must be a strictly positive integer"
  return muldiv(n)
# ==============================================================================
if __name__ == "__main__":
  userloop(parser, "Enter value for <n>")
# ==============================================================================
