Using argparse within a class for repeated iterations? - python

Maybe this isn't the best way to frame my problem. Right now, I have a program that already uses argparse to enter my class in 'manual' mode. So for example, if I type python parser.py --m, I go to Parse(args), which is my class. This all works fine.
Once this is done, the class parses the file for its table of contents list and prints it to the screen. The table of contents is an OrderedDict with the page number as the key and the page title as the value. The idea is that you could press a number and it would print out the text on that respective page, and that you could do this until you type any command that doesn't correspond to a number in the dict.
I was wondering if this would be possible to do with argparse or sys?

args = parser.parse_args() parses sys.argv[1:], the list like structure that the command line produced and gave to the Python interpreter. You can also call parse_args with any similar list of strings.
How to split a string like the shell in python?
ipython uses a modified argparse to handle its main input. It uses the config files to populate the parser, giving the user a last minute way of fiddling with the configuration. But its magic commands also parse their arguments with a form of argparse. For that it has its own REPL, rather than using input/raw_input.

Related

How to call a file name when I want to use a small portion of the name?

I am trying for my code to pull a file when only a portion of the file name changes.
Example: I want to pull the file named JEFF_1234.csv where 1234 is an input from a GUI window.
The reason for the file name to have this structure is I want to have one main database that has multiple files for a specific part number. So if the user inputs a part number of 1234 and that will point to 4 files. JEFF_1234.csv, SAM_1234.csv, FRED_1234.csv and JACK_1234.csv.
What you need is a way to update a template with some dynamic value.
A neat way to do this is to define a template string using curly brackets as place-holders for the content that will be generated at runtime.
jefffile_template = "JEFF_{t}.csv"
Then, once you've assigned a value to the unknown pointer, you can convert your template into an appropriate string:
jeff_filename = jefffile_template.format(t="1234")
Which will store the value of JEFF_1234.csv into the variable jeff_filename for usage later in your program.
There are other similar ways of calling formatting functions, but using this by name style is my preferred method.
...and in case you're wondering, yes, this was still valid in 2.7.

How can I create a custom help menu in Fabric?

When I run fab --list I get output as
error Call ``func`` with given error ``message``.
get_all_tags
get_head_position
get_latest_patch
get_latest_tag
get_pending_patches
glob Return a list of paths matching a pathname pattern.
handle_prompt_abort
help
indent Return ``text`` indented by the given number of spaces.
this contains several user defined functions like get_all_tags get_head_position etc but without any description.I wish to include the description for these functions as well so that my list looks something like this
error Call ``func`` with given error ``message``.
get_all_tags Returns a list of all available tags
get_head_position Returns the current Head position
get_latest_patch Returns most recently created patch file name
get_latest_tag Returns the most recent tags among all the tags
get_pending_patches Returns list of all patches which are yet to be applied
glob Return a list of paths matching a pathname pattern.
handle_prompt_abort
help
indent Return ``text`` indented by the given number of spaces.
How can I do this ?
Add docstring to the functions.
#task
def get_all_tags():
"This is a docstring ..."
The docstring is used to display help message.
According to fab -l option documentation:
Imports a fabfile as normal, but then prints a list of all discovered
tasks and exits. Will also print the first line of each task’s
docstring, if it has one, next to it (truncating if necessary.)

Parsing python command line arguments

Complete newbie question.
I am developing a class for searching a movie database using an API.
Here is how you make a query using the movie title and year from within the Python interpreter:
import moviesearch
movie_db = moviesearch.MovieSearch()
result = movie_db.search('Clockwork Orange', year='1971')
print result
Doing this particular query yields one result from the service I am using.
To save typing for testing, I have created the following script m.py:
from sys import argv
import moviesearch
script, movie_name, params = argv
movie_db = moviesearch.MovieSearch()
result = movie_db.search(movie_name, params)
print result
When I execute this script like so:
python m.py 'Clockwork Orange', year='1971'
the service yields two results.
So this means that there is something wrong with the way I am formatting my parameters when I am testing the class with the script. Can someone please tell me what I am doing wrong?
I am not including the class for querying the movie database because I don't think that's necessary for figuring out what's wrong. What I need to know is how to properly format my parameters when using the script so that it executes exactly as it does in the example above where I am using the class directly from the Python interpreter.
Thanks in advance for any help.
When you do this in the shell (I'm assuming a *nix platform with an sh-compatible shell; Windows is probably slightly different):
python m.py 'Clockwork Orange', year='1971'
The sys.argv list will be:
['m.py', 'Clockwork Orange,', 'year=1971']
So, when you do this:
script, movie_name, params = argv
You end up with movie_name set to the string 'Clockwork Orange,' (with an extra comma), and params set to the string 'year=1971'. So, your call is ultimately:
result = movie_db.search('Clockwork Orange,', 'year=1971')
This is not the same as:
result = movie_db.search('Clockwork Orange', year='1971')
So, how do you get what you want?
Well, you can parse the params, with code something like this:
params = dict(pair.split('=') for pair in argv[2:])
result = movie_db.search(movie_name, **params)
The first line will give you a dict with {'year': '1971'}. Then you can use the ** syntax to forward that dict as the keyword arguments to the function.
Finally, you should take out the extra comma in the arguments you use to run the script. (You could write code to strip it, but it seems like it's just a typo, so the better fix is to not make that typo.)

Asking for corrections on parsed text before processing

I have written a parser in Python that takes a tracklist of played songs in (for example) a podcast, and formats the tracks correctly for scrobbling to the last.fm website.
Because some tracklists feature odd tracks or sometimes tracks may be parsed incorrectly I wish to ask a user to correct the parsed input. I know of the raw_input() function, but that doesn't let me print a default text (like the complete parsed tracklist), meaning users would have to copy/paste the entire list before correcting.
Is there a way to print a 'suggestion' to use in the raw_input()?
Not sure if this is exactly what you're trying to do, but if you want to get line-by-line input and have a default value, this is what I did for a similar problem:
def get_input(prompt, default):
result = raw_input('%s [%s]:' % (prompt, default))
result = result or default
return result

Prompting script to replace placeholders in template file

How can I write a Python script that takes a plain text file littered with placeholders, and then prompts me to replace each placeholder before sending it out to a provided email address?
Essentially, I’m looking to use something similar to 'Replacing text with variables' but I’d like to input the different variables from the terminal like in a simple bash script (rather than defining them in the script). I’d like to begin scripting in Python rather than continuing to write bash scripts; it’s for the best.
Once you have the template with the placeholders, you just need to render it using a dictionary that contains all the variables you need in the template as context. This is the approach used by most of the templating systems.
For example,
value = raw_input('prompt> ')
template = 'This is the {value}'
context = {'value': value}
print template.format(**context)

Categories