[Tutor] os.system and/or subprocess.call problem...
I'm working on a program that calls another program recursively - this other program reads in ini file and processes it; my program creates a number of slightly different ini files and calls the other program for each one. I can successfully generate the ini file. The problem is that the other program doesn't seem to execute it correctly; or is unable to read its contents. I'm not sure what's going on from the error it's giving me - basically, it says there's nothing to do in the ini, so that's why I think it's either not reading the ini, or perhaps it's being executed as the wrong user or something. (Linux environment) What's really gotten me is that if I take the command that I generate and execute it manually, either on the shell command line, or even in the Python interactive shell, it works. It's only when I call it programmatically that it fails. I've tried a number of different methods, and at this point, I'm a little confused as to which did precisely what. For a while, I was getting a "file is busy" error, which wasn't solved by putting a few seconds' delay . So basically what I'm trying to do is: - Create a subdirectory (./timestamp/indexnumber - e.g. ./2009.07.08-11.55.24.12/1 - this works) - Write a file "bsf.ini" into that directory (this works) - Execute a program called "bluesky" from its directory, passing the ini file along using the appropriate parameter (I'm definitely generating the correct command to do this) An example of the command that works, slightly changed to protect the guilty, would be: /home/isaac/bluesky/bluesky -inifile=/home/isaac/loopy/2009.07.08-11.55.24.12/1/bsf.ini ('loopy' is my program. Not my choice, but it does 'loop' bluesky, so. hey. Heh. I'm *going* loopy, but that's a different problem entirely!) So when I execute the above on the command-line, it works perfectly. But when I do it via an os.system or subproces.call, bluesky basically says "hey, I found nothing to do here". What do you think? Can it be executing bluesky in such a way that it can't open the ini, or perhaps it's executing blueksy as a different user on the system or something? Sincerely, -Isaac Eiland-Hall ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.system and/or subprocess.call problem...
: Actually it sounds like you're calling it iteratively, not recursively. :blush: Indeed. : From what you write in here, my first thought is that the ini file : isn't being flushed out to disk before the subprocess starts up and : tries to read it. : : Are you either calling .flush() or .close() or something : equivalent BEFORE starting the subprocess? self.filename = 'bsf.ini' self.fullpath = self.thispath + self.filename self.fh = open(self.fullpath, 'w') self.fh.write(self.bsf_ini) self.fh.close Which doesn't show where the vars come from, but I am closing the file first. : When you start the subprocess, is it being started in the directory : you think it is? Well... I know that when I use os.system to create a directory, it starts in cwd, which in this case is /home/isaac/loopy/ -- I create a directory with the timestamp as the name, and successfully write out the bsf.ini files into subfolders underneath it... so I think I'm confident that, at least when I use os.system, it executes in cwd -- but I specific the path to the command, so I think that doesn't matter anyway, e.g.: /home/isaac/bluesky/bluesky --inifile=/home/isaac/loopy/[timestamp]/12/bsf.ini And I know the above is valid otherwise, as I have put in a print statement and copied the actual line I generated and it executed fine... :) Thank you for your reply; I appreciate all help I get on this. :) -Isaac ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.system and/or subprocess.call problem...
: > self.fh.close : > : > Which doesn't show where the vars come from, but I am closing the : file : > first. : : Actually, no, it doesn't. You forgot the () which are needed to : actually _call_ the close method on the last line. : :self.fh.close : : is an expression which evaluates to the close method object : belonging to the file object self.fh belonging to the object : instance in play here. : :self.fh.close() : : on the other hand, takes that method and calls it, and evaluates : to whatever that method call returns. I don't know whether to be happy it's a stoopid-newbie mistake or not... :) I am extremely grateful, however, for the help - and I already see one more reply pointing this out, so to Emile as well, and anyone else -- my hearty thanks. Think I'll go curl up in a ball in the corner for a while now. ;-) -Isaac ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to foreach over a dynamic number of levels
First, thank you VERY much for your help! That's amazingly much easier than I thought it would be... I was considering looping through and generating nested for loops, then exec'ing the whole mess.. UGH, and security risk, to boot... Couple of questions: > Make a list containing all the steps: > steps = [step1, step2, step3] > > Now you need to convert all steps to lists. This loop builds a new > list from the original step list, wrapping any bare strings in lists: > > step_lists = [] > for step in steps: > if isinstance(step, basestring): > step = [step] > step_lists.append(step) > > Now what you want is the Cartesian product of all the lists. Python > has a function (new in Python 2.6) in the itertools library module > that will do this: I'm stuck on 2.5.2 because of the framework I'm driving... Does that preclude this solution? > from itertools import product > for model_set in product(*step_lists): > print model_set > > (The * in the argument list means, take the elements of step_list and > use them as the arguments to product()) > > The output is > ('step1model-a', 'step2model-a', 'step3model-a') > ('step1model-a', 'step2model-a', 'step3model-b') > ('step1model-b', 'step2model-a', 'step3model-a') > ('step1model-b', 'step2model-a', 'step3model-b') > ('step1model-c', 'step2model-a', 'step3model-a') > ('step1model-c', 'step2model-a', 'step3model-b') I hate to ask such a n00b question, but I am still learning python, and I must just be missing how to do this: How can I reference the key name as well? Basically, what I'm imputing is more like this: date = {2008-01-01:2008-01-30} # I'll parse that into 30 days model1 = some_model1 model2 = {some_model2;othermodel2} # I'll parse into a real list [...] somekey = somevalue What I'm outputting is a series of INI files, one for each run. In this case, that's 30 days times the two models, but since any key/value pair can be an array, it may end up being hundreds or thousands (or millions) of runs... For each run, I output something like this: date = 2008-01-01 model1 = some_model1 model2 = some_model2 [...] somekey = somevalue So I have to be able to regurgitate the key name -- and I'm not sure how to address that... Like in PHP, I'd use a variable variable. (I feel like this is a st00pid n00b question, and if so, I do apologize, but I'm just... missing it somewhere... I'm honestly trying to improve my coding skills, but you know how it is - you don't know something until you learn it... and python is in some ways refreshing and awesome, and in some ways just blowing my mind...) > HTH > Kent Very much, indeed! :) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Iterating over letters or arbitrary symbols like they were numbers...
If there's an easy way to do this, I'd like to have a pointer to it (i.e. what functions would deal with this - not wanting my code written for me...) Right now, I have written code to generate a list of strings that happen to be a range of numbers. (The fact that they're strings is actually desirable to me). My code looks at the range given to the function and zero-pads based on the length of the start of the range. Ranges are indicated by number-colon-number, e.g. 1:9 or 01:99 or 1:99. (for reasons outside this snippet of code, I refer to these as "expressions" or "exp" for short...) Here's the code in question: __ exp_list = [] exp_range = exp.split(":") min_padding = len(exp_range[0]) for i in range(int(exp_range[0]),(int(exp_range[1])+1)): exp_list.append('%0*d' % (min_padding, i)) __ (in fact, I'm *actually* parsing something like n(1:9;13;15;17:25) - so I have multiple ranges and individual numbers to add to exp_list[], so in my actual code, the list exists elsewhere, and this code is executed if I find a colon in an element in the list created from splitting the original line on commas (and removing the n and parentheses) - hope that makes sense) I'm quite proud of that - for the level of programming I feel I'm at, I thought it was somewhat clever. ;-) But I'm open to feedback on that... BUT, here's what I need to do: That creates a list of numbers. I also need to do letters. That is, treat a-z as base 26, and do the same thing. The three examples I gave from before would be: 1:9 --> a:z 1:99 --> a:zz 01:99 -- no "zero" in alpha to worry about, so no padding necessary... So my first question is: Can I somehow treat letters like base 26? If I can, what about alphanumeric, i.e. 0-9+a-z would be like base 36... Am I stuck rolling my own arithmetic-type function? (i.e. z+a=aa and z+b=ab, etc) Thank you very much for any advice (and again, in addition to my actual question, I wouldn't mind hearing if my solution for the numbers is less clever than I thought-- i.e. not looking for praise; rather, looking for improvement if it's glaringly dumb) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Accessing a list inside a class...
I feel like I'm missing something simple, but I have now spent hours googling for an answer. I think I must not be searching for the right terms, or else this is something I'm not supposed to be doing - but it seems straightforward to me. Here's my test code (condensed from the actual much longer code I'm adapting from functions to objects - I'm new to OOP, but I'm trying J ): ___ class TestObject: def __init__(self): # options and arguments from commandline-->OptionParser self.opt = "" self.args = [] def load_cfg(self): # read+parse commandlnie self._parse_commandline() def load_ini(self): # I'm trying to get at 'inifile' from the commandline... # print self.opt['inifile'] def _parse_commandline(self): parser = OptionParser() parser.add_option("-i", dest = "inifile", help = "specify an ini file to load") (self.opt, self.args) = parser.parse_args() if __name__ == '__main__': # parses command-line argumenmts from optparse import OptionParser test = TestObject() test.load_cfg() test.load_ini() ___ In the middle is a comment with five hashes to show you the crux of my problem. If I eliminate "['inifile']", I can print the list. How in the world can I get just the 'inifile' element? Ideally, of course, I'm not printing this - I'm going to access it from outside the class, or even inside the class. The error I get when running the above code: Traceback (most recent call last): File "listinclass.py", line 34, in test.load_ini() File "listinclass.py", line 17, in load_ini print self.opt['inifile'] AttributeError: Values instance has no attribute '__getitem__' I've googled for "list in a class" and pretty much every variant I can think of, and I just can't seem to find a single example of someone trying to get to an element of a list stored in a class. so I apologize for asking a basic/simple question, but I just can't find it. Many thanks for your consideration. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor