PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, August 25, 2022

[FIXED] How to divide a script in a smaller script and a module and connect to workspace variable?

 August 25, 2022     module, namespaces, python     No comments   

Issue

I start up sessions in Jupyter with Python with a partly tailor-made script for the application I work with. The script contains both application dependent dictionaries and functions, but some function are of a general kind. I would like to make a general module and make the start-up script contain only application parts. The difficulty is that I want the functions in the general module have application dictionaries as default. So how to connect such workspace dictionaries to the imported functions?

A very simplifed example below illustrate the problem. First you see the original total startup script. This codes works.

import numpy as np
import matplotlib.pyplot as plt

parDict = {}
parDict['Y'] = 0.5
parDict['qSmax'] = 1.0
parDict['Ks'] = 0.1

def par(parDict=parDict, *x, **x_kwarg):
   """ Set parameter values if available in the predefined dictionaryt parDict. """
   x_kwarg.update(*x)
   x_temp = {}
   for key in x_kwarg.keys():
      if key in parDict.keys():
         x_temp.update({key: x_kwarg[key]})
      else:
         print(key, 'seems not an accessible parameter')
   parDict.update(x_temp)

And I can in the notebook give a command like par(Y=0.4) and then inspect the results in the dictionary parDict.

Second (below) you see an attempt to break out the general functions into a module and this functions are imported in the start-up script. And below the actual module. This code does not work. The error message is: name 'parDict' is not defined How to fix it?

parDict = {}
parDict['Y'] = 0.5
parDict['qSmax'] = 1.0
parDict['Ks'] = 0.1

from test_module import par

And test_module.py

def par(parDict=parDict, *x, **x_kwarg):
   """ Set parameter values if available in the predefined dictionaryt parDict. """
   x_kwarg.update(*x)
   x_temp = {}
   for key in x_kwarg.keys():
      if key in parDict.keys():
         x_temp.update({key: x_kwarg[key]})
      else:
         print(key, 'seems not an accessible parameter')
   parDict.update(x_temp)

If I in the function take away the default argument parDict then it works, but I must then have a lengthier call like par(parDict, Y=0.4). I would like avoid this lengthy call and provide the default parDict automatically. One idea is to in the start-up script make a new function from the imported function and here make the connection to the dictionary. But seems a clumsy way to do it, or the only choice?


Solution

Now I have put together an even better solution that I want to share with you! The key is to make use of Python class-concept that give the possibility to combine a dictionary with associated functionality and you import the class from a module. In the setup-file you then after import of the class populate the dictionary with application parameter names and value and you make a short name for the associated function. This could be described in terms of "abstract datatype" if you like.

The start-up script now look like this:

from test_module3 import ParDict

p = {}
p['Y'] = 0.5
p['qSmax'] = 1.0
p['Ks'] = 0.1

parDict = ParDict('Test3', p)

par = parDict.parX

and the updated test_module3 is now somewhat more complex:

class ParDict(object):
   """"Tool to associate a dictionary parDict with robustified way to   
       modifiy parameter values."""
          
   def __str__(self):
      return self.id

   def __init__(self, id, parDict):
      self.id = id 
      self.parDict = parDict
  
   def parX(self, *x, **x_kwarg):
      x_kwarg.update(*x)
      x_temp = {}
      for key in x_kwarg.keys():
         if key in self.parDict.keys():
            x_temp.update({key: x_kwarg[key]})
         else:
            print(key, 'seems not an accessible parameter')
      self.parDict.update(x_temp)
  

Finally out in the Jupyter notebook you can now change parmeter values in parDict as before with simplified command-line par(Y=0.4, Ks=0.08) etc.



Answered By - janpeter
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing