[Tutor] What is the easiest way to ensure the current working directory is the same as the directory where the main program is saved?

dn PyTutor at DancesWithMice.info
Sat Jun 26 19:56:38 EDT 2021


On 26/06/2021 15.50, boB Stepp wrote:
> I have asked questions on this topic off and on in the past.  So far I
> have been able to make my programs do what I intend, but I have a
> feeling I am still not getting something fundamental.

Perhaps these feelings are related to progressing from writing
program(me)s which are relatively one-off or single-user, to a more
corporate 'delivery' model?


> Maybe this is where my misunderstandings are occurring.  To date, I
> have had no installation process.  Any programs that I need to be
> elsewhere, I copy the program to its new living facilities, whether
> elsewhere on my PC, somewhere else on a network, or to another PC.
> Does an actual installation process make these issues go away?  As a
> user of other people's programs that come with an installer one of the
> first choices the user usually must make is accept the default
> installation suggestion or choose a different location.  I suppose
> this is where the needed information is fed into the program and
> stored for later use?

Most toy- and academic-examples which involve I/O will place data-files
in the same directory as the script, or (like modules) in a
sub-directory thereof. Sadly, this 'paints a picture'. Another important
principle, often missing from the more mathematical application areas,
is that data-design is (also) important - and this doesn't merely refer
to laying-out fields in a DB table or file-record!

(I'm trying to rein-in the scope of the question. Be aware that data-
and app-security contexts also apply - and perhaps help to answer some
of the 'why?' questions that may arise)


>> Well, broadly you don't care where the code is. You care about the data
>> of the person using your programme, which they'll tell you. (Directly
>> with filenames or the like, or also by envionment variables.)
>
> <Scratch head>  But I *do* care about where my source code winds up,
> don't I?  How else do I load data from its data folder if I don't know
> where I am in the user's file system?


If we are both conducting experiments, should the app consolidate our
results because we are working 'together', or should they keep them
separate because my source-sample is quite different from yours?

If we are talking about an instant-messaging system, should all the
messages be stored in a central location, or kept separate by user/on
user devices (as above)?


Similarly, we should consider code-as-data: will your 'next great thing'
be implemented 'in the cloud' where you control (and can thus easily
update) one copy of the code, or will you make the app available for
others to copy/clone and implement themselves?


As soon as we start thinking like this, the question of 'where' becomes
question*s*, many questions...! The answers are multi-dimensional.

A multi-client or "multi-tenant" architecture, generally leads to each
client having his/her/their own database. Within that, the schema of
tables and relationships will be identical. As long as each client has
an unique "name", the databases are separate and dedicated.

A multi-user machine enables you/me separation by using sub-directories
beneath the respective home-directories. The different paths create
separation, even if (again) the data-files have the same name and
internal-structure/purpose.

When you wish to have a shared data-store, life becomes a little more
'interesting' - particularly if there is a need to identify
users/access. Even more-so, if company "A" using the application wants
their data kept quite separate from company "B". Now we have to find
some shared location, as well as implementing data-separation.


The above sets the scene (and probably sets your mind racing). Be aware
that there is no one data-structure 'to rule them all'! Also, that this
question has only slight relevance to, or solution within, "packaging".


Nevertheless you can find such in Python's own approach. If an
application running on my machine import-s a library, various system
directories under '/usr/lib64/' are searched, plus
'/usr/local/lib64/python3.9/site-packages' which likely include content
not present on your PC, then there are libraries which have been
designated for my use only (no other user on this PC can 'see' them), eg
 '/home/dn/.local/lib/python3.9/site-packages'. Thereafter, if we look
at enclosing a project within a (Python) virtual-environment, we have
yet another level of access/control/separation.
(bearing in-mind that we're talking about finding code-modules here, cf
data-files)


Various ones have mentioned Command-Line variables, Environment
Variables, and Configuration files. The first relies upon the user.
('nuff said?). The second 'feels' awkward to set-up (but perhaps that
says more about my lack of knowledge in 'packaging').

Accordingly, I habitually implement the latter (in fact, some find my
preference a bit OTT). Remember the sage advice to put all of a
program(me)'s 'constants' up-at-the-top of the code? The philosophy
behind this, anticipates that change may occur over-time. Thus, seeking
to obviate the need to hunt through the code-base to (be sure we) find
each reference.

Hang on for a moment! "Change":"Constant"???

Accordingly, I tend to put application 'constants' within a config- or
what we might think of as a 'preferences' file.

Now, if I have one application which will be delivered to multiple
clients, each can be instructed to edit that one file (don't mess with
MY CODE!) and change a single line to suit their own requirement(s), eg
to mention their name, experiment, grant, ... in the printed/displayed
headings:

header = "boB and dn's great adventure", or
header = "University of Pythonic Hard Knocks"

In this manner we can throw-in all manner of considerations, eg number
of relevant decimal-places, how accurately we wish to represent pi, how
close is close-enough for asymptotes...

NB there are whole articles debating if such files should be Python
code, .ini, .conf, JSON, YAML, or 'put your favorite format here'. IIRC
this also discussed as a "Friday Finking", way-back.

Perhaps I can 'get away with this' in the case of reasonably 'aware' and
'logical' users - who appreciate the agency and/or freedom for
experimentation. At the same time, there are many (many, many,...) cases
where such an approach should never be attempted. YMMV!


Righty-ho. As soon as we start talking about config files, we must
explore those different 'dimensions'. Are the 'constants' relevant only
at the 'app level', do others vary only by organisation, still more by
user? Then we can revert to the question(s) of where these files should
be located: related to the application code, identified by organisation,
or sitting in user-space (mentioned elsewhere in this thread)? Indeed,
it is quite possible that the above produces multiple answers, according
to the type of data, leading to the idea of having multiple
config-files, to suit variations which may occur within those different
'dimensions'.

As this complexity builds, you can see the appeal of Command-Line Variables!

I've recently built a WordPress (blogging) instance and noted that they
enable customisation with a front-end installation routine and/or
editing a config-file (the former editing the latter). Thus coping with
both 'simple folk' and 'advanced users'.


One 'nice thing' about tailoring config-files is that file and directory
references can be required to be absolute-paths. At which point, the
user's cwd/pwd, and the code-directory become irrelevant (we can assume
that the user executed the application using a correct path/script_name
(or directory_name, or zip_archive), else the config file wouldn't have
been found/opened!).


BTW:

>>> How do people deal with their
>>> Python applications that in theory may be installed anywhere in a
>>> user's file system?  There must be some standard way of dealing with
>>> this that I am too dense to uncover.

The technical/Python answer to the narrowest part of the question is
that most solutions front-load the search-path for modules (sys.path).

-- 
Regards,
=dn


More information about the Tutor mailing list