Skip to content

Commit 31269b0

Browse files
authored
Merge pull request #68 from MolSSI-Education/command-line-solution
Command line solution
2 parents ee3832f + fc7000e commit 31269b0

File tree

1 file changed

+75
-7
lines changed

1 file changed

+75
-7
lines changed

_episodes/07-command_line.md

+75-7
Original file line numberDiff line numberDiff line change
@@ -417,18 +417,83 @@ if __name__ == "__main__":
417417
{: .challenge}
418418
419419
> ## Extension 1
420-
> Modify your script so that people can specify a wildcard character to read and write multiple files at once.
420+
> Modify your script so that people can specify a wildcard character to read and write multiple files at once.
421421
>
422422
> You should be able to call the script using:
423423
>
424424
> ~~~
425-
> $ python analyze_mdout.py data/*.mdout
425+
> $ python analyze_mdout.py "data/*.mdout"
426426
> ~~~
427427
> {: .language-bash}
428+
> **Note** - In the command above, we have used quotations around the filename. If you are on Linux or Mac, you can leave out the quotations. Your computer will expand the `data/*.mdout` into a list of all the files. This will not work on Windows. If you use the apprroach which works for Mac/Linux, you will need find a way for an argument in argparse to be a list for this. See [the documentation](https://docs.python.org/3/library/argparse.html#the-add-argument-method) for the `add_argument` function - you will find the answer there!
429+
>> ## Solution - All operating systems
430+
>> If you are working on Windows, this is the solution you will need. For this solution, you use quotation marks around the filename, and
431+
>> include the wildcard character (`*`). Recall that we used this character along with the `glob` library in the multiple file parsing lesson.
432+
>>
433+
>> ~~~
434+
>> import os
435+
>> import argparse
436+
>> import glob
437+
>>
438+
>> # Get filename from argparse
439+
>>
440+
>> parser = argparse.ArgumentParser("This script parses amber mdout file to extract the total energy.")
441+
>>
442+
>> parser.add_argument("path", help="The filepath of the file to be analyzed.")
443+
>>
444+
>> args = parser.parse_args()
445+
>>
446+
>> # Use glob to get a list of the files.
447+
>> filenames = glob.glob(args.path)
448+
>>
449+
>> for filename in filenames:
450+
>>
451+
>> # Figure out the file name for writing output
452+
>> fname = os.path.basename(filename).split('.')[0]
453+
>>
454+
>> # Open the file.
455+
>> f = open(filename, 'r')
456+
>>
457+
>> # Read the data.
458+
>> data = f.readlines()
459+
>>
460+
>> # Close the file.
461+
>> f.close()
462+
>>
463+
>> etot = []
464+
>> # Loop through lines in the file.
465+
>> for line in data:
466+
>> # Get information from lines.
467+
>> split_line = line.split()
468+
>>
469+
>> if 'Etot' in line:
470+
>> #print(split_line[2])
471+
>> etot.append(f'{split_line[2]}')
472+
>> values = etot[:-2]
473+
>>
474+
>> # Open a file for writing
475+
>> outfile_location = F'{fname}_Etot.txt'
476+
>> outfile = open(outfile_location, 'w+')
477+
>>
478+
>> for value in values:
479+
>> outfile.write(f'{value}\n')
480+
>>
481+
>> outfile.close()
482+
>> ~~~
483+
>> {: .language-python}
484+
>>
485+
> {: .solution}
428486
>
429-
> You will need find a way for an argument in argparse to be a list for this. See [the documentation](https://docs.python.org/3/library/argparse.html#the-add-argument-method) for the `add_argument` function - you will find the answer there!
430-
>> ## Solution
431-
>> For this solution, you would have to find the option `nargs` which would be added to `add_argument` which tells argparse that it may receive more than one value for the argument. T
487+
>> ## Solution - Mac and Linux
488+
>> This solution will work for Mac and Linux operating systems. For this solution, you would use the script without the quotes (below).
489+
>> Note that the solution given above will work for any operating system.
490+
>>
491+
>> ~~~
492+
>> $ python analyze_mdout.py data/*.mdout
493+
>> ~~~
494+
>> {: .language-bash}
495+
>>
496+
>> For this solution, you would have to find the option `nargs` which would be added to `add_argument` which tells argparse that it may receive more than one value for the argument. This works on Mac and Linux because these operating systems will automatically create a list of files when you use the wildcard character (`*`).
432497
>>
433498
>> ~~~
434499
>> import os
@@ -442,6 +507,7 @@ if __name__ == "__main__":
442507
>>
443508
>> args = parser.parse_args()
444509
>>
510+
>> # This will already be a list, so we don't need to use glob.
445511
>> filenames = args.path
446512
>>
447513
>> for filename in filenames:
@@ -450,7 +516,6 @@ if __name__ == "__main__":
450516
>> fname = os.path.basename(filename).split('.')[0]
451517
>>
452518
>> # Open the file.
453-
>>
454519
>> f = open(filename, 'r')
455520
>>
456521
>> # Read the data.
@@ -493,17 +558,20 @@ if __name__ == "__main__":
493558
>> ~~~
494559
>> import os
495560
>> import argparse
561+
>> import glob
496562
>>
497563
>> # Get filename from argparse
498564
>>
499565
>> parser = argparse.ArgumentParser("This script parses amber mdout file to extract the total energy.")
500566
>>
501567
>> parser.add_argument("path", help="The filepath of the file to be analyzed.", nargs='*')
568+
>>
569+
>> # store_true makes this True by default
502570
>> parser.add_argument("-make_plots", help="Flag to create plots", action='store_true')
503571
>>
504572
>> args = parser.parse_args()
505573
>>
506-
>> filenames = args.path
574+
>> filenames = glob.glob(args.path)
507575
>>
508576
>> for filename in filenames:
509577
>>

0 commit comments

Comments
 (0)