I need to accept one of three switches on the command line, --major, --minor or --patch or none of them in which the default is minor. I'm doing this using optparse due to the limitations of the environment (Python 2.6.x) so I can't change that.
What I'd ideally like to achieve is that optparse does the heavy lifting so I don't have to write code to check that the options are exclusive etc. I'd also appreciate if it can give a neat and understandable output from --help such as, for example:
[--major|minor|patch] whether to build as a new major/minor/patch
version. minor is default.
Or something similar (i.e. ideally all on the same line). I tried the following:
parser.add_option('', '--major', dest='rel_type')
parser.add_option('', '--minor', dest='rel_type')
parser.add_option('', '--patch', dest='rel_type')
but for --help that gave me:
--major=REL_TYPE
--minor=REL_TYPE
--patch=REL_TYPE
I know it's possible to use:
... type='choice', choices=['major', 'minor', 'patch'] ...
but this isn't really what I want as these are value enumerations rather than switch options.
Is this possible, and if so how?
Related
I need to subset very many font files and I need to do that from within the python environment. Yet, Fonttools is very poorly documented and I cannot find a module and the proper function syntax to perform subsetting based on unicode from within python, not as a command line tool (pyftsubset). Some of my files contain various errors when read by the Fonttools and I cannot catch exceptions using !command inside jupyter.
pyftsubset is itself just a Python script, which calls fontTools.subset.main, which in turn parses sys.argv (command-line args) to perform subsetting. You can do the same thing pretty easily in your own script, for example:
import sys
from fontTools.subset import main as ss
sys.argv = [None, '/path/to/font/file.ttf', '--unicodes=U+0020-002F']
ss() # this is what actually does the subsetting and writes the output file
Obviously you'll want to use your own values for --unicodes plus the numerous other pyftsubset options, but in general this scheme should work. Possible caveat is if you have other parts of your program that use/rely on sys.argv; if that's the case you might want to capture the initial values in another variable before modifying sys.argv and calling the subsetter, then re-set it to the initial values after.
I think that should be a pythonic way to do it properly:
from fontTools import subset
subsetter = subset.Subsetter()
subsetter.populate(unicodes=["U+0020", "U+0021"])
subsetter.subset(font)
While font is your TTFont and you might need to check the documentation for how to exactly pass in the the list of unicodes. I didn’t test this exact code, but I tested it with subsetter.populate(glyphs=["a", "b"]) which does a similar job, but with glyphNames instead. The populate method can take these arguments as documented: populate(self, glyphs=[], gids=[], unicodes=[], text='')
I found a clue to that in this discussion.
How can I align my python arguments quickly in Vim. New to tabular plugin and cannot figure out command for aligning arguments properly:
Have this:
myfunc(arg1=value1,
arg2=value2,
arg3=value3,
arg4=value4,
arg5=value5,
arg6=value6,
arg7=value7)
Want this:
myfunc(arg1=value1,
arg2=value2,
arg3=value3,
arg4=value4,
arg5=value5,
arg6=value6,
arg7=value7)
You don't actually need Tabular.vim for this. Put your cursor at the top of myfunc (or a bit higher) and press =} (or =)). This runs equalprg across your function block to indent it appropriately.
From the help on 'equalprg':
External program to use for "=" command. When this option is empty
the internal formatting functions are used; either 'lisp', 'cindent'
or 'indentexpr'. When Vim was compiled without internal formatting,
the "indent" program is used.
Environment variables are expanded |:set_env|. See |option-backslash|
about including spaces and backslashes.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
BTW, if you do want to learn more about Tabular and its use cases, there’s a great video on vimcasts.
My python scripts often contain "executable code" (functions, classes, &c) in the first part of the file and "test code" (interactive experiments) at the end.
I want python, py_compile, pylint &c to completely ignore the experimental stuff at the end.
I am looking for something like #if 0 for cpp.
How can this be done?
Here are some ideas and the reasons they are bad:
sys.exit(0): works for python but not py_compile and pylint
put all experimental code under def test():: I can no longer copy/paste the code into a python REPL because it has non-trivial indent
put all experimental code between lines with """: emacs no longer indents and fontifies the code properly
comment and uncomment the code all the time: I am too lazy (yes, this is a single key press, but I have to remember to do that!)
put the test code into a separate file: I want to keep the related stuff together
PS. My IDE is Emacs and my python interpreter is pyspark.
Use ipython rather than python for your REPL It has better code completion and introspection and when you paste indented code it can automatically "de-indent" the pasted code.
Thus you can put your experimental code in a test function and then paste in parts without worrying and having to de-indent your code.
If you are pasting large blocks that can be considered individual blocks then you will need to use the %paste or %cpaste magics.
eg.
for i in range(3):
i *= 2
# with the following the blank line this is a complete block
print(i)
With a normal paste:
In [1]: for i in range(3):
...: i *= 2
...:
In [2]: print(i)
4
Using %paste
In [3]: %paste
for i in range(10):
i *= 2
print(i)
## -- End pasted text --
0
2
4
In [4]:
PySpark and IPython
It is also possible to launch PySpark in IPython, the enhanced Python interpreter. PySpark works with IPython 1.0.0 and later. To use IPython, set the IPYTHON variable to 1 when running bin/pyspark:1
$ IPYTHON=1 ./bin/pyspark
Unfortunately, there is no widely (or any) standard describing what you are talking about, so getting a bunch of python specific things to work like this will be difficult.
However, you could wrap these commands in such a way that they only read until a signifier. For example (assuming you are on a unix system):
cat $file | sed '/exit(0)/q' |sed '/exit(0)/d'
The command will read until 'exit(0)' is found. You could pipe this into your checkers, or create a temp file that your checkers read. You could create wrapper executable files on your path that may work with your editors.
Windows may be able to use a similar technique.
I might advise a different approach. Separate files might be best. You might explore iPython notebooks as a possible solution, but I'm not sure exactly what your use case is.
Follow something like option 2.
I usually put experimental code in a main method.
def main ():
*experimental code goes here *
Then if you want to execute the experimental code just call the main.
main()
With python-mode.el mark arbitrary chunks as section - for example via py-sectionize-region.
Than call py-execute-section.
Updated after comment:
python-mode.el is delivered by melpa.
M-x list-packages RET
Look for python-mode - the built-in python.el provides 'python, while python-mode.el provides 'python-mode.
Developement just moved hereto: https://gitlab.com/python-mode-devs/python-mode
I think the standard ('Pythonic') way to deal with this is to do it like so:
class MyClass(object):
...
def my_function():
...
if __name__ == '__main__':
# testing code here
Edit after your comment
I don't think what you want is possible using a plain Python interpreter. You could have a look at the IEP Python editor (website, bitbucket): it supports something like Matlab's cell mode, where a cell can be defined with a double comment character (##):
## main code
class MyClass(object):
...
def my_function():
...
## testing code
do_some_testing_please()
All code from a ##-beginning line until either the next such line or end-of-file constitutes a single cell.
Whenever the cursor is within a particular cell and you strike some hotkey (default Ctrl+Enter), the code within that cell is executed in the currently running interpreter. An additional feature of IEP is that selected code can be executed with F9; a pretty standard feature but the nice thing here is that IEP will smartly deal with whitespace, so just selecting and pasting stuff from inside a method will automatically work.
I suggest you use a proper version control system to keep the "real" and the "experimental" parts separated.
For example, using Git, you could only include the real code without the experimental parts in your commits (using add -p), and then temporarily stash the experimental parts for running your various tools.
You could also keep the experimental parts in their own branch which you then rebase on top of the non-experimental parts when you need them.
Another possibility is to put tests as doctests into the docstrings of your code, which admittedly is only practical for simpler cases.
This way, they are only treated as executable code by the doctest module, but as comments otherwise.
For a script, I'm currently using OptionParser to add variables to an input. However, all of my current options are booleans, and it seems it would just be easier to parse using argv instead. For example:
$ script.py option1 option4 option6
And then do something like:
if 'option1' in argv:
do this
if 'option2' in argv:
do this
etc...
Would it be suggested to use argv over OptionParser when the optionals are all booleans?
"However, all of my current options are booleans, and it seems it
would just be easier to parse using argv instead."
There's nothing wrong with using argv, and if it's simpler to use argv, there's no reason not to.
OptionParser has been deprecated, and unless you're stuck on an older version of python, you should use the ArgParser module.
For one-off scripts, there's nothing wrong with parsing sys.argv yourself. There are some advantages to using an argument parsing module instead of writing your own.
Standardized. Do you allow options like "-test", because the standard is usually 2 underscores for multichar options (e.g. "--test"). With a module, you don't have to worry about defining standards because they're already defined.
Do you need error-catching and help messages? Because you get a lot of that for free with ArgParse.
Will someone else be maintaining your code? There's already lots of documentation and examples of ArgParse. Plus, it's somewhat self documenting, because you have to specify the type and number of arguments, which isn't always apparent from looking at a sys.argv parser.
Basically, if you ever expect your command line options to change over time, or expect that your code will have to be modified by someone else, the overhead of ArgParse isn't that bad and would probably save you time in the future.
I know it can be achieved by command line but I need to pass at least 10 variables and command line will mean too much of programming since these variables may or may not be passed.
Actually I have build A application half in vB( for GUI ) and Half in python( for script ). I need to pass variables to python, similar, to its keywords arguments, i.e, x = val1, y = val2. Is there any way to achieve this?
If you are using Python <2.7 I would suggest optparse.
optparse is deprecated though, and in 2.7 you should use argparse
It makes passing named parameters a breeze.
you can do something fun like call it as
thepyscript.py "x = 12,y = 'hello world', z = 'jam'"
and inside your script,
parse do:
stuff = arg[1].split(',')
for item in stuff:
exec(item) #or eval(item) depending on how complex you get
#Exec can be a lot of fun :) In fact with this approach you could potentially
#send functions to your script.
#If this is more than you need, then i'd stick w/ arg/optparse
Since you're working on windows with VB, it's worth mentioning that IronPython might be one option. Since both VB and IronPython can interact through .NET, you could wrap up your script in an assembly and expose a function which you call with the required arguments.
Have you taken a look at the getopt module? It's designed to make working with command line options easier. See also the examples at Dive Into Python.
If you are working with Python 2.7 (and not lower), than you can also have a look at the argparse module which should make it even easier.
If your script is not called too often, you can use a configuration file.
The .ini style is easily readable by ConfigParser:
[Section_1]
foo1=1
foo2=2
foo3=5
...
[Section_2]
bar1=1
bar2=2
bar3=3
...
If you have a serious amount of variables, it might be the right way to go.
What do you think about creating a python script setting these variables from the gui side? When starting the python app you just start this script and you have your vars.
Execfile