[GRASS-dev] Re: [GRASS-user] Python scripts for the Pareto Boundary, tested using spearfish60 data [How to merge multiple python scripts in one?]

Νίκος Αλεξανδρής wrote:

How is merging/ calling the several scripts in/ from within just one
script done best? What strategy is best? I really have trouble to get
this done.

It's hard to say without understanding likely workflows.

However, if you want to make most of the code into Python modules, one
suggestion is to have the body of the script (the code in the
"if __name__ == '__main__':" block) read the various fields from the
"options" and "flags" variables and pass them to the functions as
parameters, rather than having the functions read global variables
(Python doesn't actually have global variables; "global" variables are
local to a module).

BTW, this is wrong:

            flags = "-o",\

It happens to work at present, but the correct method to pass the
"--o" flag is to use "overwrite = True" (analogous to "quiet = True"
for the "--q" flag and "verbose = True" for the "--v" flag).

If you want to enable these flags throughout the script, you can use:

  os.environ['GRASS_OVERWRITE'] = '1' # --o
  os.environ['GRASS_VERBOSE'] = '0' # --q
  os.environ['GRASS_VERBOSE'] = '3' # --v

In general, it's best to leave these settings to the user. If the user
runs the script with --o, --q, and/or --v, the corresponding
environment variables will be set by grass.parser(). If the user has
those variables set in their environment, the values will be inherited
by the script.

If you want to examine the settings use the overwrite() and/or
verbosity() functions in grass.script.

Also, for writing log messages, string.Template is preferable when
there are multiple substitutions. E.g. rather than:

  print """\n + Vector grid of size %d rows x %d ( %s cells) columns created"""\
  % (rows, cols, cells)

using:
  print string.Template(
    """\n + Vector grid of size ${rows} rows x ${cols} (${cells} cells) columns created"""
    ).substitute(rows = rows, cols = cols, cells = cells)

makes it easier to correlate the fields with the values. It also makes
it easier to localise the message, as the fields can be re-ordered if
needed.

If you do a lot of this, consider a utility function, e.g.:

  def log(msg, **kwargs):
    grass.message(string.Template(msg).substitute(**kwargs))

I'm wondering whether grass.message() etc should be extended in this
manner.

--
Glynn Clements <glynn@gclements.plus.com>

Νίκος Αλεξανδρής wrote:

> If you want to enable these flags throughout the script, you can use:
>
> os.environ['GRASS_OVERWRITE'] = '1' # --o
> os.environ['GRASS_VERBOSE'] = '0' # --q
> os.environ['GRASS_VERBOSE'] = '3' # --v
>
> In general, it's best to leave these settings to the user.

Sometimes it is required to use them and prevent the user from _not_
using e.g. the "--o" flag (I think... ?).

The presence or absence of --o should definitely be honoured.

Ideally, a script should try to use unique names for any temporary
maps it creates, so that it doesn't inadvertently overwrite the user's
maps (using "tmp" and the PID in the mapname is sufficient, e.g.
mapname.tmp.<pid>; if the user gives their own maps such names,
tough).

Using overwrite=True to overwrite temporary maps created within the
script is okay, but the final output maps should honour the --o and
$GRASS_OVERWRITE settings, i.e. don't complain about overwriting maps
if --o is used, and don't overwrite maps if it wasn't.

The script shouldn't need to handle this explicitly. If the --o flag
was given, GRASS_OVERWRITE will have been set to "1" by grass.parser(),
and this will automatically be inherited by any child processes. The
only thing that the script needs to do is to *not* explicitly use
overwrite=True on any commands which create the final output maps, but
allow their overwrite behaviour be controlled by $GRASS_OVERWRITE.

> If the user
> runs the script with --o, --q, and/or --v, the corresponding
> environment variables will be set by grass.parser(). If the user has
> those variables set in their environment, the values will be inherited
> by the script.
>
> If you want to examine the settings use the overwrite() and/or
> verbosity() functions in grass.script.

# note-to-self:
# check functions overwrite(), verbosity() in grass.script

It's seldom necessary to check these explicitly. The settings will be
inherited by child processes, and if you use grass.message(),
grass.verbose(), etc for messages, whether or not the messages are
displayed depends upon the $GRASS_VERSBOSE setting.

> If you do a lot of this, consider a utility function, e.g.:
>
> def log(msg, **kwargs):
> grass.message(string.Template(msg).substitute(**kwargs))

This is supposed to reduce typing effort, right?

Yes, although it may also make the code easier to read and modify.

--
Glynn Clements <glynn@gclements.plus.com>

Νίκος Αλεξανδρής wrote:

> How is merging/ calling the several scripts in/ from within just one
> script done best? What strategy is best? I really have trouble to get
> this done.

On Sun, 2009-11-08 at 08:19 +0000, Glynn Clements wrote:

It's hard to say without understanding likely workflows.

However, if you want to make most of the code into Python modules, one
suggestion is to have the body of the script (the code in the
"if __name__ == '__main__':" block) read the various fields from the
"options" and "flags" variables and pass them to the functions as
parameters, rather than having the functions read global variables
(Python doesn't actually have global variables; "global" variables are
local to a module).

OK.

BTW, this is wrong:

            flags = "-o",\

It happens to work at present, but the correct method to pass the
"--o" flag is to use "overwrite = True" (analogous to "quiet = True"
for the "--q" flag and "verbose = True" for the "--v" flag).

OK, thanks! Maybe this can/ should be added in the wiki(?).

If you want to enable these flags throughout the script, you can use:

  os.environ['GRASS_OVERWRITE'] = '1' # --o
  os.environ['GRASS_VERBOSE'] = '0' # --q
  os.environ['GRASS_VERBOSE'] = '3' # --v

In general, it's best to leave these settings to the user.

Sometimes it is required to use them and prevent the user from _not_
using e.g. the "--o" flag (I think... ?).

If the user
runs the script with --o, --q, and/or --v, the corresponding
environment variables will be set by grass.parser(). If the user has
those variables set in their environment, the values will be inherited
by the script.

If you want to examine the settings use the overwrite() and/or
verbosity() functions in grass.script.

# note-to-self:
# check functions overwrite(), verbosity() in grass.script

Also, for writing log messages, string.Template is preferable when
there are multiple substitutions. E.g. rather than:

  print """\n + Vector grid of size %d rows x %d ( %s cells) columns created"""\
  % (rows, cols, cells)

using:
  print string.Template(
    """\n + Vector grid of size ${rows} rows x ${cols} (${cells} cells) columns created"""
    ).substitute(rows = rows, cols = cols, cells = cells)

makes it easier to correlate the fields with the values. It also makes
it easier to localise the message, as the fields can be re-ordered if
needed.

That is (very) true. Cool!

If you do a lot of this, consider a utility function, e.g.:

  def log(msg, **kwargs):
    grass.message(string.Template(msg).substitute(**kwargs))

This is supposed to reduce typing effort, right?

I'm wondering whether grass.message() etc should be extended in this
manner.

Thank you for your time Glynn, Nikos