How to pass **kwargs to another function with changed values for that key?












-1















I have the following function that calculate the propagation of a laser beam in a cavity. It depends on many parameters that are stored in a dict called core_data, which is a basic parameter set.



def propagate(N, core_data, **ddata):
cd = copy.deepcopy(core_data) # use initial configuration
cd.update(ddata) # update with data I want to change
cavity = get_new_cavity(cd) # get new cavity object
P =
for i in range(N):
cavity.evolve(1)
P.append(cavity.get_power())
return P


If I want to change a parameter and see its effect on the laser, I can just call the function like, for instance



P0 = propagate(1000, core_data, L1=1.2, M5=17)


This works very well.



Now, I would write a function that passes this function to a ProcessPoolExecutor, with the values of **ddata being iterated over using the same key. It should work, for instance, like this (simpler example):



propagate_parallel(1000, core_data,
L1=np.linspace(1, 2, 2),
M5=np.linspace(16, 17, 2))


And should then do this in parallel:



propagate(1000, core_data, L1=1, M5=16)
propagate(1000, core_data, L1=1, M5=17)
propagate(1000, core_data, L1=2, M5=16)
propagate(1000, core_data, L1=2, M5=17)


Something like this works for my case:



xrng = np.linspace(110e-30, 150e-30, Nx)
yrng = np.linspace(6.6e-9, 6.7e-9, Ny)

futures =
with confu.ProcessPoolExecutor(max_workers=Ncores) as pool:
for y, x in it.product(yrng, xrng):
futures.append(pool.submit(propagate, RTs=1000,
core_data=core_data,
gdd_dm=x, dwl_filt=y))


The problem is that this is not flexible and I cannot get this into a nice function, as written above. It should be a function that can be called like this to reproduce the code from above:



propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng)


How would I pass the keys from **ddata with the iterated values of that corresponding key?



FYI, I used:



import numpy as np
import concurrent.futures as confu
import itertools as it









share|improve this question

























  • I don't get your problem. Your function doesn't work? What error do you get?

    – Hugo Luis Villalobos Canto
    Jan 18 at 22:21











  • The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

    – tinux
    Jan 18 at 22:32


















-1















I have the following function that calculate the propagation of a laser beam in a cavity. It depends on many parameters that are stored in a dict called core_data, which is a basic parameter set.



def propagate(N, core_data, **ddata):
cd = copy.deepcopy(core_data) # use initial configuration
cd.update(ddata) # update with data I want to change
cavity = get_new_cavity(cd) # get new cavity object
P =
for i in range(N):
cavity.evolve(1)
P.append(cavity.get_power())
return P


If I want to change a parameter and see its effect on the laser, I can just call the function like, for instance



P0 = propagate(1000, core_data, L1=1.2, M5=17)


This works very well.



Now, I would write a function that passes this function to a ProcessPoolExecutor, with the values of **ddata being iterated over using the same key. It should work, for instance, like this (simpler example):



propagate_parallel(1000, core_data,
L1=np.linspace(1, 2, 2),
M5=np.linspace(16, 17, 2))


And should then do this in parallel:



propagate(1000, core_data, L1=1, M5=16)
propagate(1000, core_data, L1=1, M5=17)
propagate(1000, core_data, L1=2, M5=16)
propagate(1000, core_data, L1=2, M5=17)


Something like this works for my case:



xrng = np.linspace(110e-30, 150e-30, Nx)
yrng = np.linspace(6.6e-9, 6.7e-9, Ny)

futures =
with confu.ProcessPoolExecutor(max_workers=Ncores) as pool:
for y, x in it.product(yrng, xrng):
futures.append(pool.submit(propagate, RTs=1000,
core_data=core_data,
gdd_dm=x, dwl_filt=y))


The problem is that this is not flexible and I cannot get this into a nice function, as written above. It should be a function that can be called like this to reproduce the code from above:



propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng)


How would I pass the keys from **ddata with the iterated values of that corresponding key?



FYI, I used:



import numpy as np
import concurrent.futures as confu
import itertools as it









share|improve this question

























  • I don't get your problem. Your function doesn't work? What error do you get?

    – Hugo Luis Villalobos Canto
    Jan 18 at 22:21











  • The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

    – tinux
    Jan 18 at 22:32
















-1












-1








-1








I have the following function that calculate the propagation of a laser beam in a cavity. It depends on many parameters that are stored in a dict called core_data, which is a basic parameter set.



def propagate(N, core_data, **ddata):
cd = copy.deepcopy(core_data) # use initial configuration
cd.update(ddata) # update with data I want to change
cavity = get_new_cavity(cd) # get new cavity object
P =
for i in range(N):
cavity.evolve(1)
P.append(cavity.get_power())
return P


If I want to change a parameter and see its effect on the laser, I can just call the function like, for instance



P0 = propagate(1000, core_data, L1=1.2, M5=17)


This works very well.



Now, I would write a function that passes this function to a ProcessPoolExecutor, with the values of **ddata being iterated over using the same key. It should work, for instance, like this (simpler example):



propagate_parallel(1000, core_data,
L1=np.linspace(1, 2, 2),
M5=np.linspace(16, 17, 2))


And should then do this in parallel:



propagate(1000, core_data, L1=1, M5=16)
propagate(1000, core_data, L1=1, M5=17)
propagate(1000, core_data, L1=2, M5=16)
propagate(1000, core_data, L1=2, M5=17)


Something like this works for my case:



xrng = np.linspace(110e-30, 150e-30, Nx)
yrng = np.linspace(6.6e-9, 6.7e-9, Ny)

futures =
with confu.ProcessPoolExecutor(max_workers=Ncores) as pool:
for y, x in it.product(yrng, xrng):
futures.append(pool.submit(propagate, RTs=1000,
core_data=core_data,
gdd_dm=x, dwl_filt=y))


The problem is that this is not flexible and I cannot get this into a nice function, as written above. It should be a function that can be called like this to reproduce the code from above:



propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng)


How would I pass the keys from **ddata with the iterated values of that corresponding key?



FYI, I used:



import numpy as np
import concurrent.futures as confu
import itertools as it









share|improve this question
















I have the following function that calculate the propagation of a laser beam in a cavity. It depends on many parameters that are stored in a dict called core_data, which is a basic parameter set.



def propagate(N, core_data, **ddata):
cd = copy.deepcopy(core_data) # use initial configuration
cd.update(ddata) # update with data I want to change
cavity = get_new_cavity(cd) # get new cavity object
P =
for i in range(N):
cavity.evolve(1)
P.append(cavity.get_power())
return P


If I want to change a parameter and see its effect on the laser, I can just call the function like, for instance



P0 = propagate(1000, core_data, L1=1.2, M5=17)


This works very well.



Now, I would write a function that passes this function to a ProcessPoolExecutor, with the values of **ddata being iterated over using the same key. It should work, for instance, like this (simpler example):



propagate_parallel(1000, core_data,
L1=np.linspace(1, 2, 2),
M5=np.linspace(16, 17, 2))


And should then do this in parallel:



propagate(1000, core_data, L1=1, M5=16)
propagate(1000, core_data, L1=1, M5=17)
propagate(1000, core_data, L1=2, M5=16)
propagate(1000, core_data, L1=2, M5=17)


Something like this works for my case:



xrng = np.linspace(110e-30, 150e-30, Nx)
yrng = np.linspace(6.6e-9, 6.7e-9, Ny)

futures =
with confu.ProcessPoolExecutor(max_workers=Ncores) as pool:
for y, x in it.product(yrng, xrng):
futures.append(pool.submit(propagate, RTs=1000,
core_data=core_data,
gdd_dm=x, dwl_filt=y))


The problem is that this is not flexible and I cannot get this into a nice function, as written above. It should be a function that can be called like this to reproduce the code from above:



propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng)


How would I pass the keys from **ddata with the iterated values of that corresponding key?



FYI, I used:



import numpy as np
import concurrent.futures as confu
import itertools as it






python kwargs






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 18 at 22:39







tinux

















asked Jan 18 at 21:52









tinuxtinux

13




13













  • I don't get your problem. Your function doesn't work? What error do you get?

    – Hugo Luis Villalobos Canto
    Jan 18 at 22:21











  • The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

    – tinux
    Jan 18 at 22:32





















  • I don't get your problem. Your function doesn't work? What error do you get?

    – Hugo Luis Villalobos Canto
    Jan 18 at 22:21











  • The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

    – tinux
    Jan 18 at 22:32



















I don't get your problem. Your function doesn't work? What error do you get?

– Hugo Luis Villalobos Canto
Jan 18 at 22:21





I don't get your problem. Your function doesn't work? What error do you get?

– Hugo Luis Villalobos Canto
Jan 18 at 22:21













The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

– tinux
Jan 18 at 22:32







The problem is that the stuff that works is not as flexible as a function. In the part that works, I am varying gdd_dm and dwl_filt in ranges xrng and yrng, respectively. If I I want to use a function for this, I want to be able to write propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng). But I do not know how to achieve that.

– tinux
Jan 18 at 22:32














2 Answers
2






active

oldest

votes


















0














You are looking for iterating over the cartesian product.



Here is a way to iterate over a cartesian.



from itertools import product
import numpy as np

L1=np.linspace(1, 2, 2)
M5=np.linspace(16, 17, 2)
dconf = dict(data=5)
size = L1.size
loop_size = size**2

def propagate(N, data, modifiers):
data.update(modifiers)
out =
for i in range(N):
out.append('%s : %s : %s : %s'%(i, *data.values()))
return out

mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

for outer in m:
for inner in outer:
print(inner)


This you can adapt to your code, and if you really need to go parallell (with all that this means in terms of info split between cores) maybe take a look into Dask.



Hope this is enough to get you going.



edit:
your question is quite hard to actually pinpoint.
Is your question really how to just achieve the simple "function call"?
I suppose one answer is just to make a wrap function, something like...



def propagate(N, data, modifiers):
...

def call_propagate(N, data, L1_, M5_):
mod = ...
m = map(...
return m

for outer in call_propagate(1000, dconf, L1, M5)
for inner in outer:
print(inner)





share|improve this answer

































    0














    I think I was somehow blocked... I kept thinking how to keep a variable name (for instannce L1) and pass this as a variable to another function.



    @ahead87: Already your first sentence unblocked me and I realized that **data can be handled simply via a dictionary. So, in the end, I simply needed to transform the input dict into a list of dicts for the next function, like so (with some irrelevant parts being snipped):



    def propagate_parallel(RTs, cav_data, **ddata):
    keys = list(ddata.keys())
    values = list(ddata.values())
    futures =
    res =
    with confu.ProcessPoolExecutor(max_workers=32) as pool:
    for i in it.product(*values):
    futures.append(pool.submit(propagate, RTs=RTs,
    cav_data=cav_data,
    **dict(zip(keys, list(i)))))
    for fut in futures:
    res.append(fut)
    return res


    In the end, I think I finally understand **kwargs, and that it can be handles as a dict. Thank you!






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54261907%2fhow-to-pass-kwargs-to-another-function-with-changed-values-for-that-key%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      You are looking for iterating over the cartesian product.



      Here is a way to iterate over a cartesian.



      from itertools import product
      import numpy as np

      L1=np.linspace(1, 2, 2)
      M5=np.linspace(16, 17, 2)
      dconf = dict(data=5)
      size = L1.size
      loop_size = size**2

      def propagate(N, data, modifiers):
      data.update(modifiers)
      out =
      for i in range(N):
      out.append('%s : %s : %s : %s'%(i, *data.values()))
      return out

      mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
      m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

      for outer in m:
      for inner in outer:
      print(inner)


      This you can adapt to your code, and if you really need to go parallell (with all that this means in terms of info split between cores) maybe take a look into Dask.



      Hope this is enough to get you going.



      edit:
      your question is quite hard to actually pinpoint.
      Is your question really how to just achieve the simple "function call"?
      I suppose one answer is just to make a wrap function, something like...



      def propagate(N, data, modifiers):
      ...

      def call_propagate(N, data, L1_, M5_):
      mod = ...
      m = map(...
      return m

      for outer in call_propagate(1000, dconf, L1, M5)
      for inner in outer:
      print(inner)





      share|improve this answer






























        0














        You are looking for iterating over the cartesian product.



        Here is a way to iterate over a cartesian.



        from itertools import product
        import numpy as np

        L1=np.linspace(1, 2, 2)
        M5=np.linspace(16, 17, 2)
        dconf = dict(data=5)
        size = L1.size
        loop_size = size**2

        def propagate(N, data, modifiers):
        data.update(modifiers)
        out =
        for i in range(N):
        out.append('%s : %s : %s : %s'%(i, *data.values()))
        return out

        mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
        m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

        for outer in m:
        for inner in outer:
        print(inner)


        This you can adapt to your code, and if you really need to go parallell (with all that this means in terms of info split between cores) maybe take a look into Dask.



        Hope this is enough to get you going.



        edit:
        your question is quite hard to actually pinpoint.
        Is your question really how to just achieve the simple "function call"?
        I suppose one answer is just to make a wrap function, something like...



        def propagate(N, data, modifiers):
        ...

        def call_propagate(N, data, L1_, M5_):
        mod = ...
        m = map(...
        return m

        for outer in call_propagate(1000, dconf, L1, M5)
        for inner in outer:
        print(inner)





        share|improve this answer




























          0












          0








          0







          You are looking for iterating over the cartesian product.



          Here is a way to iterate over a cartesian.



          from itertools import product
          import numpy as np

          L1=np.linspace(1, 2, 2)
          M5=np.linspace(16, 17, 2)
          dconf = dict(data=5)
          size = L1.size
          loop_size = size**2

          def propagate(N, data, modifiers):
          data.update(modifiers)
          out =
          for i in range(N):
          out.append('%s : %s : %s : %s'%(i, *data.values()))
          return out

          mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
          m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

          for outer in m:
          for inner in outer:
          print(inner)


          This you can adapt to your code, and if you really need to go parallell (with all that this means in terms of info split between cores) maybe take a look into Dask.



          Hope this is enough to get you going.



          edit:
          your question is quite hard to actually pinpoint.
          Is your question really how to just achieve the simple "function call"?
          I suppose one answer is just to make a wrap function, something like...



          def propagate(N, data, modifiers):
          ...

          def call_propagate(N, data, L1_, M5_):
          mod = ...
          m = map(...
          return m

          for outer in call_propagate(1000, dconf, L1, M5)
          for inner in outer:
          print(inner)





          share|improve this answer















          You are looking for iterating over the cartesian product.



          Here is a way to iterate over a cartesian.



          from itertools import product
          import numpy as np

          L1=np.linspace(1, 2, 2)
          M5=np.linspace(16, 17, 2)
          dconf = dict(data=5)
          size = L1.size
          loop_size = size**2

          def propagate(N, data, modifiers):
          data.update(modifiers)
          out =
          for i in range(N):
          out.append('%s : %s : %s : %s'%(i, *data.values()))
          return out

          mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
          m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

          for outer in m:
          for inner in outer:
          print(inner)


          This you can adapt to your code, and if you really need to go parallell (with all that this means in terms of info split between cores) maybe take a look into Dask.



          Hope this is enough to get you going.



          edit:
          your question is quite hard to actually pinpoint.
          Is your question really how to just achieve the simple "function call"?
          I suppose one answer is just to make a wrap function, something like...



          def propagate(N, data, modifiers):
          ...

          def call_propagate(N, data, L1_, M5_):
          mod = ...
          m = map(...
          return m

          for outer in call_propagate(1000, dconf, L1, M5)
          for inner in outer:
          print(inner)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 19 at 0:00

























          answered Jan 18 at 23:41









          ahed87ahed87

          40248




          40248

























              0














              I think I was somehow blocked... I kept thinking how to keep a variable name (for instannce L1) and pass this as a variable to another function.



              @ahead87: Already your first sentence unblocked me and I realized that **data can be handled simply via a dictionary. So, in the end, I simply needed to transform the input dict into a list of dicts for the next function, like so (with some irrelevant parts being snipped):



              def propagate_parallel(RTs, cav_data, **ddata):
              keys = list(ddata.keys())
              values = list(ddata.values())
              futures =
              res =
              with confu.ProcessPoolExecutor(max_workers=32) as pool:
              for i in it.product(*values):
              futures.append(pool.submit(propagate, RTs=RTs,
              cav_data=cav_data,
              **dict(zip(keys, list(i)))))
              for fut in futures:
              res.append(fut)
              return res


              In the end, I think I finally understand **kwargs, and that it can be handles as a dict. Thank you!






              share|improve this answer




























                0














                I think I was somehow blocked... I kept thinking how to keep a variable name (for instannce L1) and pass this as a variable to another function.



                @ahead87: Already your first sentence unblocked me and I realized that **data can be handled simply via a dictionary. So, in the end, I simply needed to transform the input dict into a list of dicts for the next function, like so (with some irrelevant parts being snipped):



                def propagate_parallel(RTs, cav_data, **ddata):
                keys = list(ddata.keys())
                values = list(ddata.values())
                futures =
                res =
                with confu.ProcessPoolExecutor(max_workers=32) as pool:
                for i in it.product(*values):
                futures.append(pool.submit(propagate, RTs=RTs,
                cav_data=cav_data,
                **dict(zip(keys, list(i)))))
                for fut in futures:
                res.append(fut)
                return res


                In the end, I think I finally understand **kwargs, and that it can be handles as a dict. Thank you!






                share|improve this answer


























                  0












                  0








                  0







                  I think I was somehow blocked... I kept thinking how to keep a variable name (for instannce L1) and pass this as a variable to another function.



                  @ahead87: Already your first sentence unblocked me and I realized that **data can be handled simply via a dictionary. So, in the end, I simply needed to transform the input dict into a list of dicts for the next function, like so (with some irrelevant parts being snipped):



                  def propagate_parallel(RTs, cav_data, **ddata):
                  keys = list(ddata.keys())
                  values = list(ddata.values())
                  futures =
                  res =
                  with confu.ProcessPoolExecutor(max_workers=32) as pool:
                  for i in it.product(*values):
                  futures.append(pool.submit(propagate, RTs=RTs,
                  cav_data=cav_data,
                  **dict(zip(keys, list(i)))))
                  for fut in futures:
                  res.append(fut)
                  return res


                  In the end, I think I finally understand **kwargs, and that it can be handles as a dict. Thank you!






                  share|improve this answer













                  I think I was somehow blocked... I kept thinking how to keep a variable name (for instannce L1) and pass this as a variable to another function.



                  @ahead87: Already your first sentence unblocked me and I realized that **data can be handled simply via a dictionary. So, in the end, I simply needed to transform the input dict into a list of dicts for the next function, like so (with some irrelevant parts being snipped):



                  def propagate_parallel(RTs, cav_data, **ddata):
                  keys = list(ddata.keys())
                  values = list(ddata.values())
                  futures =
                  res =
                  with confu.ProcessPoolExecutor(max_workers=32) as pool:
                  for i in it.product(*values):
                  futures.append(pool.submit(propagate, RTs=RTs,
                  cav_data=cav_data,
                  **dict(zip(keys, list(i)))))
                  for fut in futures:
                  res.append(fut)
                  return res


                  In the end, I think I finally understand **kwargs, and that it can be handles as a dict. Thank you!







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 19 at 14:35









                  tinuxtinux

                  13




                  13






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54261907%2fhow-to-pass-kwargs-to-another-function-with-changed-values-for-that-key%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Liquibase includeAll doesn't find base path

                      How to use setInterval in EJS file?

                      Petrus Granier-Deferre