#!/usr/bin/env python3
# vereda - notices and documentation at the end of the file
 
def main () :                                    # "main" is called from the end of the file
  '''Vereda'''                                   # it simulates the C [main function]
  init ()                                        # initialisation
  hello_world_function ()                        # [function]{Function_(computer_programming)}
                                                 # * objects
  variable ()                                    # [variable] {Variable (computer science)}
  listz,tuplez,setz,dictz = data_structure ()    # [data structure]
  data_structure_def ()                          # new  data structures definition
  variable_scope ()                              # local nonlocal global
                                                 # * [control flow]
  control_flow_if ()                             # [conditional] {Conditional_(computer_programming)}
  control_flow_switch ()                         # [switch statement]
  control_flow_loop_for (listz,tuplez,setz,dictz)# for loop [loop statement]
  control_flow_loop_while ()                     # while loop
  control_flow_error_handling ()                 # LBYL EAFP
                                                 # * function
  function_static ()                             # first call [static variable]
  function_static ()                             # second call
  a,b = function_fix ('arg1','arg')              # fix number of arguments
  function_var ('One','Two')                     # first call | variable number of arguments
  function_var ('One','Two','Three')             # second call
  function_kwarg ( a='AA', b='BB' )              # kwarg: keyword argument, arbitrary number of arguments
  function_call_by ()                            # call by value, reference and object
                                                 # Python Standard Library https://docs.python.org/3/library [library]
  standard_library_built_in ()                   # no import https://docs.python.org/3/library/functions.html
  standard_library_modules ()                    # import required
  external_modules ()                            # install and import | packages
                                                 # * external read and write
  command_line_arguments ()                      # get arguments
  kinput = keyboard_input (False)                # kinput: keyboard input | to enable set to "True"
  text = readfile ()                             # read whole text file
  appendfile (kinput,text)                       # append to file
  html ()                                        # generate HTML 
  csv ()                                         # CSV (Comma Separated Values)
  record_jar ()                                  # record-jar format
  json ()                                        # JSON
  sqlite ()                                      # SQLite
  csv_to_sqlite ()                               # read CSV into SQLite 
  pickle_ex ()                                   # binary format [serialisation]
  zipdir ()                                      # recursively zip directory
                                                 # * packages
  matplotlib_ex ()                               # matplotlib.org
  numpy_ex ()                                    # numpy.org
  pandas_ex ()                                   # pandas.pydata.org 
                                                 # * miscellaneous
  generate_documentation ()                      # zorro module documentation
  exit (0)

#------------------------------------------------#-------------------------------------------#
def init () :                                    # https://docs.python.org
  import sys
  from os import environ
  from platform import python_version            # https://docs.python.org/3/library/platform.html#module-platform
  from zorro import ZM , TIMESTAMP , mkdir , __file__  # zorro is a private module

  VERVERSION = 1                                 # Vereda version
  global VERHOME , ZM , TIMESTAMP , DOT          # avoid globals | constants not too bad
                                                 # no [constants] in Python: convention capitals are constants
  VERHOME = environ ['VERHOME']                  # VERHOME: vereda home | set by "source /foo/ver/lib/setup"
  DOT = VERHOME + '/output'                      # DOT: Directory OutpuT
  mkdir ( DOT )                                  # create directory if it does not exist
  file_stdout = ( DOT + '/stdout.txt' )
  sys.stdout = open ( file_stdout , 'w' )        # redirect standard output to file

  print ( '* Vereda standard output' )
  print ( '\n* init' )
  print ( 'Timestamp: ' , TIMESTAMP )            # yymmdd-hhmmss
  print ( 'Vereda version =' , VERVERSION ) 
  print ( 'Vereda file =', environ['_'] )
  print ( 'Zorro version =' , ZM ['version'] )   # ZM:Zorro metadata
  print ( 'Zorro file =' , __file__ )
  print ( 'Python version =' , python_version ())
  print ( 'Python file =' , sys.executable)

#------------------------------------------------#-------------------------------------------#
def hello_world_function () :
  print ('\n* hello_world_function')

#------------------------------------------------#-------------------------------------------#
def variable () :                                # docs.python.org/3/library/stdtypes.html
  '''Main built-in scalar types'''
  print ( '\n* variable\n' , variable.__doc__ )
  i = 42                                         # integer  id:s value:42    type:integer
  f = 3.14                                       # float    id:s value:3.14  type:float
  s = 'hello'                                    # string   id:s value:hello type:string
  b = True                                       # boolean  id:s value:True  type:boolean

  x = 2 + 9 - 3 * 4 / 2
  x += 1                                         # y += n

  s = '44'                                       # string
  i = int (s)                                    # convert string to integer | float ()
  y = 'Hello' + ' world'                         # concatenate strings
  print ( y )
  print ( 'slice y[2:4] = ' , y[2:4])            # https://realpython.com/lessons/string-slicing
 
  print ( i , f , s , b )

#------------------------------------------------#-------------------------------------------#
def data_structure () :
  '''Main built-in data structure types'''
  print ( '\n* data_structure\n' , data_structure.__doc__ )
                                                 # [array] [array dimension]
  listz   = [ 'zero' , 1 , 'two' , 'two' ]       # list  : ordered   | duplicates    | mutable
  tuplez  = ( 'Zero' , 1 , 'Two' , 'Two' )       # tuple : ordered   | duplicates    | immutable 
  setz    = { 'zero' , 1 , 2 }                   # set   : unordered | no duplicates | mutable

  dictz   = {                                    # dict  : ordered   | no duplicates | mutable
    'a'  : 'zero' ,                              # [associative array] [key-value]
    1    : 'one' ,
    '2'  : 'TWO'
  }

  a2 = [                                         # two dimensinal array, list of lists
    [ '00' , '01' ],                             # [matrix]
    [ '10' , '11' ],
    [ '20' , '21' ]
  ]

  s = listz [0]                                  # s = zero
  s = tuplez [0]                                 # s = Zero
  n = len (setz)                                 # n = 3 | items no referable by index
  s = dictz ['2']                                # s = TWO

  print ( 'Two dimensional array' )
  print ( 'All: ', a2 )
  print ( 'Row 1: ', a2[1] )
  print ( 'Element 2,1: ', a2[2][1] )
  print ( '\nDictionary: ', dictz )              # print the whole dict
  return listz,tuplez,setz,dictz

#------------------------------------------------#-------------------------------------------#
def data_structure_def () :                      # [compound data type] {wiki/Typedef}
  print( '\n* data_structure_def' )

  struct = {
    'a'  : None ,
    'b'  : None
  }
                                                 # Algorithms + Data Structures = Programs
  s = { 'a': 11 , 'b':22.0 }
  print( s )
  print( s['a'] )

#------------------------------------------------#-------------------------------------------#
def variable_scope () :                          # realpython.com/python-namespaces-scope
  a = 88                                         # a: local | global | nonlocal
 
#------------------------------------------------#-------------------------------------------#
def control_flow_if () :
  '''Control flow with the conditional statement (if)'''
  print ( '\n* control_flow_if\n' , control_flow_if.__doc__)
  i = 7

  if   i == 7 : s = 'seven' 

  if   i == 8 : s = 'eight'
  else        : s = 'not eight'

  print (s)

#------------------------------------------------#-------------------------------------------#
def control_flow_switch () :
  '''Control flow with the switch statement (case)'''
  print ('\n* control_flow_switch' )

  letter = 'a'

  match letter:
    case 'a' | 'e' | 'i' | 'o' | 'u' : print ( f'letter "{letter}" is a vowel')
    case 'y'                         : print ( f'letter "{letter}" may be a vowel')
    case _                           : print ( f'letter "{letter}" is not a vowel')

#------------------------------------------------#-------------------------------------------#
def control_flow_loop_for (listz,tuplez,setz,dictz) :
  '''Loop through data arrays'''
  print ('\n* control_flow_loop_for')

  print ('list=' , end='')
  for i in listz :
    print (i , '|' , sep='' , end='')

  print ('\ntuple=' , end='')
  for i in tuplez :
    print (i , '|' , sep='' , end='')

  print ('\nset=' , end='')
  for i in setz :
    print (i , '|' , sep='' , end='')

  print ('\nrange=' , end='')
  for i in range (2,8,2):                        # range (start, stop, step)
    print (i , '|' , sep='' , end='')
  print ('')

  control_flow_loop_for_dict (dictz)

#------------------------------------------------#-------------------------------------------#
def control_flow_loop_for_dict (dictz) :
  '''Loop through several options of dictionary'''
  print ('\n* control_flow_loop_for_dict')

  print ('\nkey=' , end='')
  for k in dictz :                               # k:key value:dictz[k]
    print (k , '=' , dictz[k] , '|' , sep='' , end='')

  print ('\nkey-value=' , end='')
  for k , v in dictz.items () :                  # k:key v:value
    print (k , '=' , v , '|' , sep='' , end='')  # v = dictz[k]

  print ('\ntuple=' , end='')
  for t in dictz.items () :                      # t: tuple
    print ( t , '|' , sep='' , end='')           # key = t[0] | value = t[1]

  print ()

#------------------------------------------------#-------------------------------------------#
def control_flow_loop_while () :
  '''While loop'''
  print ('\n* control_flow_loop_while ' )
  i = 0

  while i < 3 :
    print (i , '|' , sep='' , end='')
    i += 1

  print ()

#------------------------------------------------#-------------------------------------------#
def control_flow_error_handling () :
  print ( '\n* error_handling' )
  a = None
  b = 0

  if   b == 0 : print ( 'Look Before You Leap (LBYL): no zero division' )
  else        : a = 1/b

  try    : a = 1/b
  except : print ( 'Easier to ask for forgiveness than permission (EAFP): no zero division' )

  print ( a )

#------------------------------------------------#-------------------------------------------#
def function_static () :
  '''Simulating static local variable using function attribute'''
  print ('\n* function_static')
                                                 # Python does not have static variables
  try    : function_static.a += 1                # unassigned function_static.a raises exception
  except :
    function_static.a = 1
    print ('except')

  print ( function_static.a )

#------------------------------------------------#-------------------------------------------#
def function_fix (param1,param2) :               # param: parameter
  '''Function with paramenters'''                # number of parameters
  print ('\n* function_fix')
  return param2,param1                           # switch the values
                                                 # [call by value] [call by reference]
  # dev.to/adarshrawat7400/how-call-by-value-and-call-by-reference-work-in-python-am2

#------------------------------------------------#-------------------------------------------#
def function_var ( *argv ) :                     # also: ( arg1 , *argv )
  '''Function with variable number of arguments'''
  print ('\n* function_var')

  try    : function_var.flag += 1
  except :
    function_var.flag = 1
    print ('except')                             # print only the first time the function is called

  print (argv)                                   # parameter, but by convention "argv"

#------------------------------------------------#-------------------------------------------#
def function_kwarg ( **kwargv ) :                # kwarg: keyword argument
  print ( '\n* function_kwarg' )
  print ( kwargv)

#------------------------------------------------#-------------------------------------------#
def function_call_by () :
  '''Function call by value, reference and object '''
  print ('\n* function_call_by')                 # inmutable objects : call by value
                                                 # mutable objects   : call by reference
  def change ( a , b ) :
    a = 2                                        # inmutable : value changes only inside func
    b.append (9)                                 # mutable   : value changes also outside func
    print ( 'Inside function         :' , a , b , id(a) , id(b) )
                                                 # id: object identity
  a = 1                                          # integer : inmutable
  b = [8]                                        # list    : mutable
  print ( 'Outside function before :' , a , b , '  ' , id(a) , id(b) )
  change ( a , b )
  print ( 'Outside function after  :' , a , b , id(a) , id(b) )

#------------------------------------------------#-------------------------------------------#
def standard_library_built_in () :               # https://docs.python.org/3/library/functions.html
  print ('\n* standard_library_built_in')
  s = 'Some string'                              # docs.python.org/3/library
  l = len (s)                                    # function | len: length
  u = s.upper ()                                 # method of string | function vs. method
                                                 # dot notation | object-oriented programming (OOP) 
  print ( s , l , u )

#------------------------------------------------#-------------------------------------------#
def standard_library_modules () :                # import
  print ( '\n* standard_library_modules ' )      # docs.python.org/3/py-modindex.html 

  import zorro                                   # import the whole module
  print ( 'zorro module version=' , zorro.ZM ['version'] )

  from zorro import ZM                           # import one item
  print ( 'zorro module rights=' ,ZM ['rights' ] )

  import hello_mod                               # hello world module | private module
  hello_mod.world ()

  print ( 'datetime, pre-installed module' )
  from datetime import datetime
  cyear = int (datetime.now().strftime("%Y"))    # cyear: current year | ex. 2023
  print ('Current year:' , cyear)

#------------------------------------------------#-------------------------------------------#
def external_modules () :                        # install and import | Python Package Index (PyPI.org)
  '''
They must be installed
Example of popular packages: NumPy, Matplotlib
python3 -m pip install foo
pip3 install foo'''

  print ( '\n* external_modules' , external_modules.__doc__)

#------------------------------------------------#-------------------------------------------#
def command_line_arguments () :
  print ( '\n* command_line_arguments' )
  from sys import argv
  print ( argv )

#------------------------------------------------#-------------------------------------------#
def keyboard_input (flag) :
  print ( '\n* read_input' )
  '''Read input from the command line'''
  a = 'NO INPUT - set function to "True"'

  if flag :
    import sys
    print ( 'Type something: ' , end='' , file=sys.stderr )
    a = input ()

  b = 'You typed: [' + a + ']'
  print ( b )
  return b

#------------------------------------------------#-------------------------------------------#
def readfile () :
  print ( '\n* readfile' )
  from zorro import read_text
  fit = VERHOME + '/data/lane.txt'               # fit: File InpuT
  return read_text (fit)                         # check existance before reading

#------------------------------------------------#-------------------------------------------#
def appendfile ( ki , text ) :
  print ( '\n* appendfile' )
  from zorro import append_text
  fot = DOT + '/newlane.txt'                     # fot: File OutpuT
  append_text ( TIMESTAMP + '\n' + ki + '\n' + text + '\n\n' , fot )

#------------------------------------------------#-------------------------------------------#
def html () :
  print ( '\n* html' )
  buf = '''<!doctype html>
<html>
  <head>
    <title>Vereda</title>
    <meta charset=utf-8>
    <meta name=viewport content="width=device-width, initial-scale=1.0">
    <meta name=date content=2013-11-01>
    <meta name=creator content='M.T. Carrasco Benitez'>
    <meta name=rights content='CC BY-SA: Creative Commons Attribution-ShareAlike'>
    <link rel=stylesheet href=vereda.css type=text/css media=all>
  </head>
  <body>
    <span id=home><a href=../index.html>⌂</a></span>
    <h1>Vereda output</h1>
    <div id=logo><img id=logoi src='vereda.jpg'></div>

    <ul>
      <li><a target=_blank href='stdout.txt'>Standard output</a>

      <li><a target=_blank href='newlane.txt'>File with appended text</a> from
          <a target=_blank href='../data/lane.txt'>input data file</a>

      <li><a target=_blank href='ex.json'>JSON</a>

      <li><a target=_blank href='https://matplotlib.org'>Matplotlib</a>:
        <a target=_blank href='plot.pdf'>PDF</a>
        <a target=_blank href='plot.png'>PNG</a>

      <li><a target=_blank href='https://numpy.org'>NumPy</a>:
        <a target=_blank href='numerical.png'>PNG</a>

      <li><a target=_blank href='https://pandas.pydata.org'>pandas</a>:
        <a target=_blank
             href='https://pandas.pydata.org/docs/getting_started/intro_tutorials/04_plotting.html'>Air quality</a> |
        <a target=_blank href='../data/air_quality_no2.csv.txt'>data</a> | grahics:
        <a target=_blank href='air1.png'>1</a>
        <a target=_blank href='air2.png'>2</a>
        <a target=_blank href='air3.png'>3</a>
        <a target=_blank href='air4.png'>4</a>
        <a target=_blank href='air5.png'>5</a>

      <li><a target=_blank href='zorro.py.txt'>Zorro Module</a>
       |  <a target=_blank href='zorro.html'>documentation</a>
    </ul>
  </body>
</html>'''

  from shutil import copy
  copy ( VERHOME + '/lib/vereda.jpg' , DOT )
  copy ( VERHOME + '/lib/vereda.css' , DOT )
  copy ( VERHOME + '/lib/zorro.py'   , DOT + '/zorro.py.txt' )

  from zorro import write_text
  write_text ( buf , DOT + '/index.html' )

#------------------------------------------------#-------------------------------------------#
def csv () :                                     # 
  print ( '\n* cvs' )
  import csv
  fit = VERHOME + '/data/table.csv'              # fit: File InpuT

  with open ( fit , newline='' ) as fo :
    row = csv.reader ( fo , delimiter = ',' )
    table = list (row)

  from pprint import pprint                      # pretty printer docs.python.org/3.8/library/pprint.html
  pprint ( table )

#------------------------------------------------#-------------------------------------------#
def record_jar () :                              # www.catb.org/esr/writings/taoup/html/ch05s02.html#id2906931
  print ( '\n* record_jar' )
  from zorro  import read_record_jar
  fit = VERHOME + '/data/reja.txt'               # fit: File InpuT
  reja = read_record_jar ( fit )
  print ( 'type of reja:' , type (reja) )
  print ( reja )
  print ( reja[1] )
  print ( reja[1]['Planet'] ,'\n' )

  from pprint import pprint                      # pretty printer docs.python.org/3.8/library/pprint.html
  pprint (reja)

#------------------------------------------------#-------------------------------------------#
def json () :                                    # text format [serialisation]
  '''JSON: widely used, human readable'''
  print ( '\n* json' )                           # JSON: widely used, human readable
  from zorro import read_json , write_json       # [marshalling] {Marshalling_(computer_science)}
  d = { 'a' : 'AAA' , 'b' : 'BBB' }
  fot = DOT + '/ex.json'                         # fot: File OutpuT
  write_json ( d , fot )                         # if file exist, overwrite, not append
  print ( read_json (fot) )

#------------------------------------------------#-------------------------------------------#
def sqlite  () :
  print ( '\n* sqlite' )
  import os
  from sqlite3 import connect

  dbfile = DOT + '/item.sqlite'
  if os.path.isfile (dbfile) : os.remove(dbfile)
  
  db = connect ( dbfile )                        # db: db connector
  c  = db.cursor ()                              # c: cursor

  c.execute (            '\
    create table items (  \
        item varchar (20) \
      , no   int          \
  )')

  c.execute ( 'insert into items ( item , no ) values ( "apple"  , 4 ) ')
  c.execute ( 'insert into items ( item , no ) values ( "orange" , 2 ) ')
  c.execute ( 'insert into items ( item , no ) values ( "bed"    , 9 ) ')

  db.commit ()
  c.execute ( 'select * from items' )
  print ( c.fetchall () )

#------------------------------------------------#-------------------------------------------#
def csv_to_sqlite () :
  print ( '\n* cvs_to_sqlite' )
  import os
  from sqlite3 import connect
  import csv
  from zorro import basename
  from pprint import pprint
                                                 ## read CSV file
  airq = VERHOME + '/data/air_quality_no2.csv'
  with open ( airq , newline='' ) as fo :
    row = csv.reader ( fo , delimiter = ',' )
    table = list (row)
                                                 ## make string "s" to create table
  s = 'create table air ('
  for fn in table [0] :                          # fieldnames in the first line | fn: fieldname
    s = s + fn + ' varchar (99),'
  s = s[:-1] + ')'                               # replace last character ',' by ')'
                                                 ## make database and table
  dbfile = DOT + '/air.sqlite'
  if os.path.isfile (dbfile) : os.remove(dbfile) # delete database file, if exists
  db = connect ( dbfile )                        # create database | db: db connector
  c = db.cursor ()                               # c: cursor
  c.execute (s)                                  # create table

  fields = ' '.join ( table[0] )                 # convert list to string with the fieldnames
  del table[0]                                   # delete first item in the list with the column names
  c.executemany ( "INSERT INTO air VALUES(?, ?, ?,?)", table)
  db.commit()

  c.execute ( 'select rowid , * from air where rowid <= 5' )
  print ( 'file: output/' + basename (dbfile) )
  print ( 'fields: rowid' , fields )
  print ( 'rows 1 to 5:' )
  pprint ( c.fetchall () )

#------------------------------------------------#-------------------------------------------#
def pickle_ex () :                               # binary format [serialisation]
  print ( '\n* pickling_ex' )                    # format only for Python
  import pickle                                  # Pickle: only Python, binary (non human readable)
  d = { 'a' : 'AAA' , 'b' : 'BBB' }              #         unsafe as it can contain executable code 
  d_p = pickle.dumps (d)                         # pickle to variable
  d_u = pickle.loads (d_p)                       # unpickle from variable

  print ( f"d={d}")
  print ( f"d_p={d_p}")
  print ( f"d_u={d_u}")

  fot = DOT + '/ex.pickle'                       # fot: File OutpuT

  with open ( fot , 'wb') as fo :                # pickle to file
    pickle.dump (d , fo , pickle.HIGHEST_PROTOCOL)

  with open ( fot , 'rb') as fo :                # unpickle from file
    d_f = pickle.load (fo)

  print ( 'd_f=' ,  d_f )

#------------------------------------------------#-------------------------------------------#
def zipdir  () :
  '''Recursively zip directory to a file'''
  print ( '\n* zipdir' )
  from zorro import writezip
  dit = VERHOME + '/data'                        # dit: Directory InpuT
  fot = DOT + '/data.zip'                        # fot: File OutpuT
  writezip ( dit , fot )
  print ( 'Output to "output/data.zip"' )

#------------------------------------------------#-------------------------------------------#
def matplotlib_ex () :
  print ( '\n* matplotlib_ex' )
  import matplotlib.pyplot as plt                # matplotlib.org pypi.org
  from sys import modules
  plt.clf ()                                     # clear figure 
  v = modules [plt.__package__].__version__      # v: matplotlib version
  plt.title   ( 'Title | matplotlib version: ' + v )
  plt.ylabel  ( 'Y axis' )
  plt.xlabel  ( 'X axis' )
  plt.text    ( 2 , 4 , '⚫ (2,4)' )
  plt.plot    ( [1, 2, 3] , [1, 4, 9] )
  plt.savefig ( DOT + '/plot.png' )
  plt.savefig ( DOT + '/plot.pdf' )

#------------------------------------------------#-------------------------------------------#
def numpy_ex () :
  print ( '\n* numpy_ex' )
  import numpy as np                             # numpy.org
  import matplotlib.pyplot as plt                # matplotlib.org/stable/tutorials/pyplot.html#annotating-text
  plt.clf ()                                     # clear figure 
  t    = np.arange ( 0.0 , 9.0 , 0.01 )
  s    = np.cos    ( 2*np.pi*t )
  line = plt.plot  ( t , s , lw=2 )
  plt.ylim (-2, 2)
  plt.annotate ( 'local max' , xy=(2, 1) , xytext=(3, 1.5) , arrowprops=dict(facecolor='red',shrink=0.05))
  plt.savefig ( DOT + '/numerical.png' )

#------------------------------------------------#-------------------------------------------#
def pandas_ex () :                               # pandas.pydata.org
  print ( '\n* pandas_ex' )
  import pandas as pd                            # DataFrame : matrix

  print ( 'example 1' )                          ## example 1: pandas.pydata.org)
  df = pd.DataFrame (
    {                                            # Series : column
        "Name": [
            "Braund, Mr. Owen Harris",
            "Allen, Mr. William Henry",
            "Bonnell, Miss. Elizabeth",
        ],
        "Age": [22, 35, 58],
        "Sex": ["male", "male", "female"],
    }
  )

  print ( df , '\n' )
  print ( df ['Age'] , '\n' )
  print ( 'Max age = ' , df ['Age' ].max() , '\n' )
  print ( 'Describe = ' , df.describe () , '\n' )

  print ( 'example 2' )                          ##
  fit = VERHOME + '/data/table.csv'              # fit: File InpuT
  table = pd.read_csv ( fit )
  print (table , '\n' )
  print ( table.info() , '\n' )

  print ( 'example 3' )                          ## example 3: air quality, from pandas.pydata.org
  airq = VERHOME + '/data/air_quality_no2.csv'
  air_quality = pd.read_csv ( airq , index_col=0, parse_dates=True)
  print (air_quality , '\n' )

  import matplotlib.pyplot as plt
  air_quality.plot ()                                                            ; plt.savefig ( DOT + '/air1.png' )
  air_quality [ 'station_paris' ].plot()                                         ; plt.savefig ( DOT + '/air2.png' )
  air_quality.plot.scatter ( x='station_london' , y='station_paris', alpha=0.5 ) ; plt.savefig ( DOT + '/air3.png' )
  air_quality.plot.box ()                                                        ; plt.savefig ( DOT + '/air4.png' )
  air_quality.plot.area ( figsize = ( 12 , 4) , subplots=True )                  ; plt.savefig ( DOT + '/air5.png' )

#------------------------------------------------#-------------------------------------------#
def generate_documentation () :
  print ( '\n* generate_documentation' )
  from pydoc import writedoc
  from os import chdir
  import zorro as zormod
  chdir (DOT)                                    # change back
  print ( '\n* generate_documentation' )
  writedoc (zormod)
  from zorro import delete_nlines
  delete_nlines ( 6 , 8 , DOT + '/zorro.html' )  # delete lines 6 line from line number 8

#------------------------------------------------#-------------------------------------------#
main ()                                          # goto to "main" and never return
print ( 'ERROR: sentinel after main' )

#------------------------------------------------#-------------------------------------------#
'''
Notices and documentation

title:Vereda
description:A path through Python with code snippets 
version:1
date:2023-11-01
relation:Zorro
creator:M.T. Carrasco Benitez
rights:CC BY-SA - Creative Commons Attribution-ShareAlike
'''
##
