Reply to topic  [ 4 posts ] 
Question about retrieving variable names from .. than .pdb 
Author Message
Yorick Padawan

Joined: Tue Jun 07, 2011 1:46 pm
Posts: 32
Location: UNH
Post Question about retrieving variable names from .. than .pdb
Hi. I'm trying to write another save function but one that will check if the file exists.

So far, I have most of it working.

Code:
func save2(fn, .., pdir=)
/* DOCUMENT save2(fn, .., pdir=)
     A second save function that will save to a .pdb file, possibly .mat file too.
     Also will check if the file exists so you do not overwrite an important file
   by mistake.

   pdir is present working directory. Different name so it's possible to use pwd().
     If pdir is 1, it will prepend the filename with the present working directory.
     If pdir is 0, it will assume fn is the absolute file path and will check if
   it exists.
*/
{
   default, pdir, 1;
   if (pdir == 1)
      fn = swrite(format="%s%s", pwd(), fn);
   if (file_exists(fn))
   {
      write, format="File %s exists.\n", fn;
      overwrite = array(string);
      read, prompt="Do you want to overwrite it? Y / [N] ", overwrite;
      if (overwrite != "Y" && overwrite != "y")
         return 0;
   }
   f = createb(fn);
   while( more_args() > 0 )
   {
      print, next_arg();
      save, f, next_arg();
   }
   close, f;
   if (file_exists(fn))
   {
      write, format="File %s has been created.\n", fn;
      return 1;
   }
   else
   {
      write, format="File %s could not be created.\nPossible permission error?", fn;
      return 0;
   }
}


but, it will not save the variables inputted in the .. area of the function, and instead will error out. The reason is because it's trying to save the value instead of the variable name. How do I get just the variable name? In the past, dnagle showed me how to use get_members to retrieve the variable names from a file, and those were used to resave the variable. Is there a way to do it by inputting it into this function?

Code:
> test1 = "apple"; test2 = "grape";
> save2("fruits.pdb", test1, test2);


Regards,


Tue Aug 23, 2011 10:28 am
Profile
Yorick Master

Joined: Wed Jun 01, 2005 11:34 am
Posts: 112
Post Re: Question about retrieving variable names from .. than .p
Code:
while( more_args() > 0 )
   {
      print, next_arg();
      save, f, next_arg();
   }


There are two issues here.

The first is that you're skipping every other argument in the above and the function will give an error if you don't have a multiple of two extra arguments. So "save2, fn, a, b" will print a and save b, while "save2, fn, a" will print a and then give an error. You only want to call "next_arg()" once per iteration, not twice.

Secondly, what are you passing as input, string names for variables or actual variables? If you're passing actual variables like "save2, fn, a, b" then you'll need to investigate the wrap_args function. If you're passing the variable names as strings like 'save2, fn, "a", "b"', you'll need to use symbol_def to retrieve their value. In your current code, you're not actually providing a name for the variable so that would also cause an error -- the "save, f, foo" syntax requires that foo be a named value, it can't be a function call. As a consequence to this, you'll need to use add_variable to define the variable in the file first, then store the content using get_member.

Try replacing the above with this, which assumes you're passing strings as the variable names:

Code:
while( more_args() > 0 )
   {
      varname = next_arg();
      data = symbol_def(varname);
      write, varname;
      add_variable, f, -1, varname, structof(data), dimsof(data);
      get_member(f, varname) = data;
   }


It sounds more like what you actually want though is to pass the variables directly. That will require you to use wrap_args, which will allow you to retrieve the variable names even when they are provided like "save2, f, a, b". It is well documented, see "help, wrap_args".


Wed Aug 24, 2011 7:21 am
Profile
Yorick Padawan

Joined: Tue Jun 07, 2011 1:46 pm
Posts: 32
Location: UNH
Post Re: Question about retrieving variable names from .. than .p
I used the code you suggested and it worked.
Code:
> test = "string";
> f = "file.pdb";
> save2, f, "test";
File /media/disk/ALPS/Yorick/functions/file.pdb exists.
Do you want to overwrite it? Y / [N] y
test
File /media/disk/ALPS/Yorick/functions/file.pdb has been created.
> test = nil;
> f = openb(f);
> restore, f, test
> close, f
> test
"string"

Success! However, it's kind of annoying to use the double quotes each time to save a variable. So I tried to use the wrap_args() function, using this technique gets rid of the use of the quotation marks but I don't know how to keep the optional pdir= because if I use anything other than args, it will throw an error. For example: "func save2(args, pdir=)" will not work.

save2:
Code:
func save2(args)
{
   //default, pdir, 1;
   //default, mat, 0;

   //if (pdir == 1)
   fn = swrite(format="%s%s", pwd(), args(1));
   //fn = swrite(format="%s%s", pwd(), fn);
   if (file_exists(fn))
   {
      write, format="File %s exists.\n", fn;
      overwrite = array(string);
      read, prompt="Do you want to overwrite it? Y / [N] ", overwrite;
      if (overwrite != "Y" && overwrite != "y")
         return 0;
   }
   f = createb(fn);
   n = args(0);
   for (i = 2; i <= n; i++)
   {
      //print, args(-,i), args(i);
      save, f, args(-,i), args(i);
   }
   /*while( more_args() > 0 )
   {
      varname = next_arg();
      data = symbol_def(varname);
      write, varname;
      add_variable, f, -1, varname, structof(data), dimsof(data);
      get_member(f, varname) = data;
   }*/
   close, f;
   if (file_exists(fn))
   {
      write, format="File %s has been created.\n", fn;
      return 1;
   }
   else
   {
      write, format="File %s could not be created.\nPossible permission error?", fn;
      return 0;
   }
}
errs2caller, save2;
wrap_args, save2;

Use:
Code:
> f = "file.pdb";
> var1 = "var1";
> var2 = 2;
> save2, f, var1, var2
File /media/disk/ALPS/Yorick/functions/file.pdb has been created.

The only way I can think of doing it is if I make args(2) a specific variable that the program checks for such as...
Code:
   ...
   if ((args(-,2) == "pdir") && (args(2) == 1)
   {
      ...

Is there a better way to check for optional parameters with a function using wrap_args?


Wed Aug 24, 2011 12:09 pm
Profile
Yorick Master

Joined: Wed Jun 01, 2005 11:34 am
Posts: 112
Post Re: Question about retrieving variable names from .. than .p
The args object provides both positional and keyword arguments. Use args(-) to get a list of keyword arguments that were passed (if any). Their values can then be retrieved by passing the keyword to args. So if args(-) returns [], there were no keyword arguments. If it returns ["pdir"], then you have one keyword argument whose value you can retrieve via args("pdir"). The documentation for wrap_args details all of the above for further reading.


Fri Aug 26, 2011 6:09 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.