Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

'indent'ing Python in windows bat

80 views
Skip to first unread message

David Smith

unread,
Sep 17, 2012, 9:08:32 PM9/17/12
to pytho...@python.org
Hello, I'm essentially a newbie in Python.
My problem in searching the archives is not knowing what words to use to
ask.

I'm converting windows bat files little by little to Python 3 as I find
time and learn Python.
The most efficient method for some lines is to call Python like:
python -c "import sys; sys.exit(3)"

How do I "indent" if I have something like:
if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
sys.exit(3)

My sole result in many attempts is "Syntax Error."

Thank you for any help.

Dave Angel

unread,
Sep 17, 2012, 9:22:04 PM9/17/12
to David Smith, pytho...@python.org
I don't understand your actual problem. Python is much more expressive
than batch, so why not actually convert it?

Write a file with an extension of .py, and run it the same way you'd run
a batch file. This assumes you have Python 3 associated with the .py
extension.

Now it won't matter if the python code has one line, or 100.

--

DaveA

Ian Kelly

unread,
Sep 17, 2012, 11:01:14 PM9/17/12
to Python
On Mon, Sep 17, 2012 at 7:08 PM, David Smith <dav...@invtools.com> wrote:
> How do I "indent" if I have something like:
> if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
> sys.exit(3)

How about:

if sR == 'Cope':
sys.exit(1)
elif sR == 'Perform':
sys.exit(2)
else:
sys.exit(3)

I don't really understand why you're trying to keep it all on one line.

Roy Smith

unread,
Sep 17, 2012, 11:17:54 PM9/17/12
to
In article <mailman.854.13479373...@python.org>,
sys.exit({'Cope':1, 'Perform':2}.get(sR, 3))
Message has been deleted

Tim Roberts

unread,
Sep 17, 2012, 11:59:44 PM9/17/12
to
David Smith <dav...@invtools.com> wrote:
>
>I'm converting windows bat files little by little to Python 3 as I find
>time and learn Python.
>The most efficient method for some lines is to call Python like:
>python -c "import sys; sys.exit(3)"
>
>How do I "indent" if I have something like:
>if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
>sys.exit(3)
>
>My sole result in many attempts is "Syntax Error."

The other responses asking "why" are excellent, but this will do that
specific job:

sys.exit( {'Cope':1,'Perform':2}.get(sR,3) )

The best way to convert a batch file to Python is to convert the whole file
to a Python script.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Chris Rebert

unread,
Sep 18, 2012, 12:22:19 AM9/18/12
to Dennis Lee Bieber, pytho...@python.org
On Mon, Sep 17, 2012 at 8:28 PM, Dennis Lee Bieber
<wlf...@ix.netcom.com> wrote:
> On Mon, 17 Sep 2012 21:08:32 -0400, David Smith <dav...@invtools.com>
> declaimed the following in gmane.comp.python.general:
>
>>
>> How do I "indent" if I have something like:
>> if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
>> sys.exit(3)
>>
> If the sole purpose of the BAT file is to set return codes, I
> wouldn't bother using Python... Python is /not/ a shell language
> substitute

FWIW, it kinda was, for the Amoeba OS, originally:
http://docs.python.org/faq/general#why-was-python-created-in-the-first-place

Cheers,
Chris

Terry Reedy

unread,
Sep 18, 2012, 1:08:54 AM9/18/12
to pytho...@python.org
On 9/17/2012 9:08 PM, David Smith wrote:
> Hello, I'm essentially a newbie in Python.
> My problem in searching the archives is not knowing what words to use to
> ask.
>
> I'm converting windows bat files little by little to Python 3 as I find
> time and learn Python.
> The most efficient method for some lines is to call Python like:
> python -c "import sys; sys.exit(3)"
>
> How do I "indent" if I have something like:
> if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
> sys.exit(3)

Quite aside from whether this is good idea, I believe putting \n
followed by spaces or \t in the quoted string should work. It does for exec.

--
Terry Jan Reedy

Dave Angel

unread,
Sep 18, 2012, 1:16:25 AM9/18/12
to Terry Reedy, pytho...@python.org
Don't forget, the OP uses Windows. Last I looked, the cmd processor had
miserable escaping features. But I could easily be wrong -- I haven't
used Windows deliberately for quite a while now.



--

DaveA

David Smith

unread,
Sep 18, 2012, 9:03:19 AM9/18/12
to pytho...@python.org
Thank you all. Roy Smith gets the most thanks, though he didn't answer
my general question -- he showed me how to look at that specific
structure differently. Terry Reedy might get thanks for her idea if I
can ever figure the correct escape sequences that will make both windows
and the Python interpreter happy. Bat makes bash/sed combos look like a
breeze...

I thought you guys wouldn't want a treatise about WHY I was doing it
this way and left it at one sentence. For whatever record, this is the
sentence most missed.
> I'm converting windows bat files little by little to Python 3 as I find time and learn Python.

I COULD stop doing all my other work to learn Python and convert all the
batch files in one fell swoop. Efficiency? Fast way to get fired. Better
to fit this in during the many small breaks I have. That's how the bat
files were built over time in the first place. Or this email.

I COULD break down each batch file and write dozens of mini python
scripts to be called. I already have a few, too. Efficiency? Speed is
bad, but these are bat files, after all. The cost of trying to work with
a multitude of small files is high, though, and I realized I had better
go to a mix.

Some sections can be broken down to one liners. Efficiency? Speed is
terrible, but it's far faster than typing commands. OTOH, I have the
organization I need on the original bat file, which is slowly being
rem'ed out. As I learn and have the time, the one-liners will melt
together into a py file to be called from the bat file. Eventually, the
bat will disappear back into the broken Window from whence it came.

Ugly, eh? I have under my belt scads of different languages from Fortran
(using JCL!), Pascal, C++ to bash, sed, awk to Forth, assembly and a
large cast of others. No big deal. My brain and Python, however, do NOT
mix. I have been trying to learn the thing for over a decade and figure
this will either force my brain into seeing the heart of the beast, or
be swallowed in the attempt.

Bat files are ugly cripples, but even on Windows a two-legged quick and
dirty dog is better than mistake-prone typing and button clicking. After
conversion, I'm aiming to make these erstwhile ugly cripples fly when I
find the time and as I stuff more Python down my gullet.

I agree. For those who have the unbroken time and understanding of
Python, this is idiotic.

back to work,

Jason Friedman

unread,
Sep 19, 2012, 12:12:41 AM9/19/12
to pytho...@python.org
> I'm converting windows bat files little by little to Python 3 as I find time
> and learn Python.
> The most efficient method for some lines is to call Python like:
> python -c "import sys; sys.exit(3)"
>
> How do I "indent" if I have something like:
> if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
> sys.exit(3)

Some months ago I posted what I think is a similar question in the
Unix world: I wanted to call a small portion of Python from within a
Bash script.

Someone on this list answered (for Bash):

#!/bin/bash
command1
command2
python -c "if True:
import module
if condition:
do_this
else:
do_that
"
command4
# end code

Perhaps something similar would work for a .bat file.

Hans Mulder

unread,
Sep 19, 2012, 3:53:44 AM9/19/12
to
He's using Windows.

If he were on Unix, there'd be no problem:

python -c 'import sys
if sR == "Cope":
sys.exit(1)
elif sR == "Perform":
sys.exit(2)
else:
sys.exit(3) '

Unfortunately, the Windows shell doesn't do multi-line strings,
so he has to cram it all on one line.


-- HansM


Thomas Rachel

unread,
Sep 19, 2012, 5:22:32 AM9/19/12
to
Am 18.09.2012 15:03 schrieb David Smith:

> I COULD break down each batch file and write dozens of mini python
> scripts to be called. I already have a few, too. Efficiency? Speed is
> bad, but these are bat files, after all. The cost of trying to work with
> a multitude of small files is high, though, and I realized I had better
> go to a mix.

In order to achieve this, it might be very useful to either have a
module for each (bigger) part to be achieved which you can call with

python -m modulename arg1 arg2 arg3

and putting the Python code into modulename.py.

Or you have one big "interpreter" which works this way:

class Cmd(object):
"""
Command collector
"""
def __init__(self):
self.cmds = {}
def cmd(self, f):
# register a function
self.cmds[f.__name__] = f
return f
def main(self):
import sys
sys.exit(self.cmds[sys.argv[1]](*sys.argv[2:]))

cmd = Cmd()

@cmd.cmd
def cmd1(arg1, arg2):
do_stuff()
...
return 1 # error -> exit()

@cmd.cmd
def cmd2():
...

if __name__ == '__main__':
cmd.main()


This is suitable for many small things and can be used this way:

bat cmds
python -m thismodule cmd1 a b
other bat cmds
python -m thismodule cmd2
...

HTH,

Thomas

David Smith

unread,
Sep 19, 2012, 8:27:20 AM9/19/12
to pytho...@python.org
On 2012-09-19 05:22, Thomas Rachel wrote:
> Am 18.09.2012 15:03 schrieb David Smith:
>
>> I COULD break down each batch file and write dozens of mini python
>> scripts to be called. I already have a few, too. Efficiency? Speed is
>> bad, but these are bat files, after all. The cost of trying to work with
>> a multitude of small files is high, though, and I realized I had better
>> go to a mix.
>
> In order to achieve this, it might be very useful to either have a
> module for each (bigger) part to be achieved which you can call with
...

> Or you have one big "interpreter" which works this way:
>
> class Cmd(object):
> """
> Command collector
> """
...
...
>
> This is suitable for many small things and can be used this way:
...
> Thomas

Thomas,
Beautiful. Gotta love it. I'll see if I can get the "interpreter" going.
I particularly like it because I will be able to copy and paste
wholesale when I stitch the final product back together again. Many thanks.

Going back to the one-liner, I discovered the following individual lines
work:
print('hi')
if 1: print('hi')
print('hi');print('hi2')
if 1: print('hi');print('hi2')

but not:
print('hi');if 1: print('hi')

Chokes on the 'if'. On the surface, this is not consistent.

I'll drop the one-liners for now since I have something that I can work
with as I learn to wrestle with Python.

thanks again.

Albert Hopkins

unread,
Sep 19, 2012, 1:51:44 PM9/19/12
to pytho...@python.org
On Tue, 2012-09-18 at 22:12 -0600, Jason Friedman wrote:
> > I'm converting windows bat files little by little to Python 3 as I find time
> > and learn Python.
> > The most efficient method for some lines is to call Python like:
> > python -c "import sys; sys.exit(3)"
> >
> > How do I "indent" if I have something like:
> > if (sR=='Cope'): sys.exit(1) elif (sR=='Perform') sys.exit(2) else
> > sys.exit(3)
>
> Some months ago I posted what I think is a similar question in the
> Unix world: I wanted to call a small portion of Python from within a
> Bash script.
>
> Someone on this list answered (for Bash):
>
> #!/bin/bash
> command1
> command2
> python -c "if True:
> import module
> if condition:
> do_this
> else:
> do_that
> "
> command4
> # end code

A better way (in *nix) would be, e.g.:

#!/bin/sh

read -p 'Enter a number ' count

python << EOF
print 'Odd numbers between 0 and ${count}'
for i in range(${count}):
if i % 2:
print i
EOF

Horribly bad example, but you get the idea.

Terry Reedy

unread,
Sep 19, 2012, 2:18:26 PM9/19/12
to pytho...@python.org
On 9/19/2012 8:27 AM, David Smith wrote:

> but not:
> print('hi');if 1: print('hi')
>
> Chokes on the 'if'. On the surface, this is not consistent.

Yes it is. ; can only be followed by simple statements. The keyword for
compound statememts must be the first non-indent token on a line. That
is why I suggested at the beginning of the thread to insert '\n',
stating correctly that it works for exec().

>>> exec("print('hi');if 1: print('hi')")
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
exec("print('hi');if 1: print('hi')")
File "<string>", line 1
print('hi');if 1: print('hi')
^
SyntaxError: invalid syntax
>>> exec("print('hi');\nif 1: print('hi')")
hi
hi
>>> exec("print('hi')\nif 1: print('hi')")
hi
hi

Someone raised the issue of whether the bat interpreter passes along the
quoted string unchanged or if it interprets '\' or '\n' itself and in
the latter case whether one to do anything so that python will see '\n'
after any fiddling by the bat interpreter. It seems that \ is not
interpreted within strngs by bat, but the problem is that the string is
then seen by python as code, not as a string literal, and so python does
not 'cook' it either. Running tem.bat from a command line (which echoes
line from .bat), so I see the output, I get (Win7)

C:\Programs\Python33>python -c "print(1)\nif 1: print(2)"
File "<string>", line 1
print(1)\nif 1: print(2)
^
SyntaxError: unexpected character after line continuation character

One gets the same response interactively from
>>> print('hi')\nif 1: print('hi')
or
>>> exec("print('hi')\\nif 1: print('hi')")

The fix is to quote and pass the exact code that worked above in the
python shell, keeping in mind that the outer quotes must be the double
quote characters recognized by windows.

C:\Programs\Python33>python -c "exec('print(1)\nif 1: print(2)')"
1
2

I did check that windows % interpolation of .bat args works within ''
quoted strings. Change tem.bat to
python -c "exec('print(%1)\nif 1: print(2)')"
and calling 'tem 3' prints
3
2

That said, if you have many multiline statements, putting them in a
separate file or files may be a good idea.

--
Terry Jan Reedy

Hans Mulder

unread,
Sep 19, 2012, 2:23:07 PM9/19/12
to
If you do it like that, you have to remember to not use certain
punctuation characters in your Python code, because they are
meaningful to the shell, even inside a <<EOF construct.

I'd prefer:

#!/bin/sh
read -p 'Enter a number ' count

python - $count <<'EOF'
import sys

count = int(sys.argv[1])

print "Odd numbers between 0 and %d" % count
for i in range(count):
if i % 2:
print i
EOF

When I use <<'EOF', I don't have to worry about the shell
interpreting some punctuation character in my Python code.

The downside is, I can't use ${count} to interpolate a shell
variable in my code; I have to pass it in as an explicit
argument. Or maybe that's an upside: explicit is better
than implicit, and all that.


Hope this helps,

-- HansM

David Smith

unread,
Sep 19, 2012, 4:09:50 PM9/19/12
to pytho...@python.org
On 2012-09-19 14:18, Terry Reedy wrote:
> stating correctly that it works for exec().

My mistake. I fancied you were talking shell, not python. I now see that
Python 3 has exec() as a built-in.

python -c "exec('print(\"hi\")\nif 0:\n print(\"hi\")\nelif 1:\n
print(\"hi2\")')"
worked right off the *.bat. Shades of sed!
Note I used a one space indentation. A tab works fine, too.

> python -c "exec('print(%1)\nif 1: print(2)')"
> and calling 'tem 3' prints
> 3
> 2
Thanks for the exhaustive study. :-) I'll keep it in mind. I hope I
don't have to do this, though.

> That said, if you have many multiline statements, putting them in a
> separate file or files may be a good idea.

ASAP I'm hoping to have each bat swallowed completely by python. My
current "bathon" or "pytch" file closes an old session then opens the
session I select just like the bat mom used to bake.

Thank you again, Terry, and thanks to all -- even the *nix'ers. Might
come in handy if I get back into that again.

Duncan Booth

unread,
Sep 20, 2012, 9:35:35 AM9/20/12
to
Provided there's only one Python block in the .bat or .cmd file then
there's no real problem; you just have to hide each language from the
other:

goto :start
"""
:start
@echo off
echo This is a CMD script
python -x %~f0 "%1"
echo Back in the CMD script
goto :eof
"""
import sys
print("Welcome to Python")
print("Arguments were {}".format(sys.argv))
print("Bye!")


You can put the Python code either before or after the triple-quote
string containing the CMD commands, just begin the file with a goto to
skip into the batch commands and end them by jumping to eof.

--
Duncan Booth http://kupuguy.blogspot.com
0 new messages