Skip to content

Commit 3553108

Browse files
use sys.stdin instead of fileinput
1 parent d5eaab2 commit 3553108

File tree

4 files changed

+14
-13
lines changed

4 files changed

+14
-13
lines changed

calc_py_cli.html

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@
184184
$ python3.9 options.py -f '22'
185185
usage: options.py [-h] [-f F] [-b] [-o] [-x] [-v] ip_expr
186186
options.py: error: the following arguments are required: ip_expr
187-
</code></pre><h3><a class=header href=#accepting-stdin id=accepting-stdin>Accepting stdin</a></h3><p>The final feature to be added is the ability to accept both <code>stdin</code> and argument value as the input expression. The modified script is shown below.<pre><code class=language-python># py_calc.py
188-
import argparse, sys, fileinput
187+
</code></pre><h3><a class=header href=#accepting-stdin id=accepting-stdin>Accepting stdin</a></h3><p>The final feature to be added is the ability to accept both <code>stdin</code> and argument value as the input expression. The <code>sys.stdin</code> filehandle can be used to read <code>stdin</code> data. The modified script is shown below.<pre><code class=language-python># py_calc.py
188+
import argparse, sys
189189

190190
parser = argparse.ArgumentParser()
191191
parser.add_argument('ip_expr', nargs='?',
@@ -203,8 +203,7 @@
203203
args = parser.parse_args()
204204

205205
if args.ip_expr in (None, '-'):
206-
del sys.argv[1:]
207-
args.ip_expr = fileinput.input().readline().strip()
206+
args.ip_expr = sys.stdin.readline().strip()
208207

209208
try:
210209
result = eval(args.ip_expr)
@@ -224,7 +223,7 @@
224223
print(result)
225224
except (NameError, SyntaxError):
226225
sys.exit("Error: Not a valid input expression")
227-
</code></pre><p>The <code>nargs</code> parameter allows to specify how many arguments can be accepted with a single action. You can use an integer value to get that many arguments as a list or use specific regular expression like metacharacter to indicate varying number of arguments. The <code>ip_expr</code> argument is made optional here by setting <code>nargs</code> to <code>?</code>. If <code>ip_expr</code> isn't passed as an argument by the user, the attribute will get <code>None</code> as the value. The <code>-</code> character is often used to indicate <code>stdin</code> as the input data. So, if <code>ip_expr</code> is <code>None</code> or <code>-</code>, the code will try to read a line from <code>stdin</code> as the input expression.<p>Quoting from <a href=https://docs.python.org/3/library/fileinput.html>docs.python: fileinput</a>:<blockquote><p>... iterates over the lines of all files listed in <code>sys.argv[1:]</code>, defaulting to <code>sys.stdin</code> if the list is empty.</blockquote><p>To ensure the list is empty and options like <code>-f</code> doesn't get treated as filename, <code>del sys.argv[1:]</code> is used here. Since <code>parse_args()</code> has already processed <code>sys.argv</code> values, this is a safe choice to make. The <code>strip()</code> string method is applied to the <code>stdin</code> data to prevent newlines from messing up the output for <code>-v</code> option. Rest of the code is the same as seen before.<p>The help documentation for this script is shown below. The only difference is that the input expression is now optional as indicated by <code>[ip_expr]</code>.<pre><code class=language-bash>$ python3.9 py_calc.py -h
226+
</code></pre><p>The <code>nargs</code> parameter allows to specify how many arguments can be accepted with a single action. You can use an integer value to get that many arguments as a list or use specific regular expression like metacharacter to indicate varying number of arguments. The <code>ip_expr</code> argument is made optional here by setting <code>nargs</code> to <code>?</code>.<p>If <code>ip_expr</code> isn't passed as an argument by the user, the attribute will get <code>None</code> as the value. The <code>-</code> character is often used to indicate <code>stdin</code> as the input data. So, if <code>ip_expr</code> is <code>None</code> or <code>-</code>, the code will try to read a line from <code>stdin</code> as the input expression. The <code>strip()</code> string method is applied to the <code>stdin</code> data mainly to prevent newline from messing up the output for <code>-v</code> option. Rest of the code is the same as seen before.<p>The help documentation for this script is shown below. The only difference is that the input expression is now optional as indicated by <code>[ip_expr]</code>.<pre><code class=language-bash>$ python3.9 py_calc.py -h
228227
usage: py_calc.py [-h] [-f F] [-b] [-o] [-x] [-v] [ip_expr]
229228

230229
positional arguments:
@@ -246,14 +245,16 @@
246245
43 / 5
247246
8.6
248247

249-
# expression passed as argument, works the same as seen before
250-
$ python3.9 py_calc.py '5 % 2'
251-
1
252-
</code></pre><p>Without <code>del sys.argv[1:]</code>, the below examples would have failed as the options would have been treated as filenames by the <code>fileinput</code> module.<pre><code class=language-bash>$ echo '0b101 + 3' | python3.9 py_calc.py -vx
248+
# strip() will remove whitespace from start/end of string
249+
$ echo ' 0b101 + 3' | python3.9 py_calc.py -vx
253250
0b101 + 3 = 0x8
254251

255252
$ echo '0b101 + 3' | python3.9 py_calc.py -vx -
256253
0b101 + 3 = 0x8
254+
255+
# expression passed as argument, works the same as seen before
256+
$ python3.9 py_calc.py '5 % 2'
257+
1
257258
</code></pre><h3><a class=header href=#shortcuts id=shortcuts>Shortcuts</a></h3><p>To simplify calling the Python CLI calculator, you can create an alias or an executable Python script.<p>Use absolute path of the script to create the alias and add it to <code>.bashrc</code>, so that it will work from any working directory. The path used below would differ for you.<pre><code class=language-bash>alias pc='python3.9 /home/learnbyexample/python_projs/py_calc.py'
258259
</code></pre><p>To create an executable, you'll have to first add a <a href=https://en.wikipedia.org/wiki/Shebang_(Unix)>shebang</a> as the first line of the Python script. You can use <code>type</code> built-in command to get the path of the Python interpreter.<pre><code class=language-bash>$ type python3.9
259260
python3.9 is /usr/local/bin/python3.9

calculator.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
3939
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
4040
});
41-
</script><div id=content class=content><main><div class=sidetoc><nav class=pagetoc></nav></div><h1><a class=header href=#cli-calculator id=cli-calculator>CLI Calculator</a></h1><p>In this project, you'll learn various ways in which you can use Python as a calculator from the command line. You'll also learn how you can customize the features for your specific needs. This project is divided into two main sections. First, you'll see how you can directly pass Python code from the command line and create <code>bash</code> shortcuts to simplify the invocation. Second, you'll see how to use Python features to create a custom CLI application. The links to these two sections are given below:<ul><li><a href=./calc_bash_func.html>Bash shortcuts</a><li><a href=./calc_py_cli.html>Python CLI application</a></ul><h2><a class=header href=#topics-covered-in-this-project id=topics-covered-in-this-project>Topics covered in this project</a></h2><p>The following modules and concepts will be utilized in this project:<ul><li><a href=https://docs.python.org/3/library/sys.html>docs.python: sys</a><li><a href=https://docs.python.org/3/library/fileinput.html>docs.python: fileinput</a><li><a href=https://docs.python.org/3/library/argparse.html>docs.python: argparse</a><li><a href=https://docs.python.org/3/library/functions.html#eval>docs.python: eval</a><li><a href=https://docs.python.org/3/tutorial/modules.html>docs.python: Modules</a><li><a href=https://docs.python.org/3/tutorial/errors.html>docs.python: Exception handling</a></ul><h2><a class=header href=#exercises id=exercises>Exercises</a></h2><p>After you've completed the two sections, modify the scripts such that these additional features are also implemented.<ol><li>If the output is of <code>float</code> data type, apply <code>.2f</code> precision by default. This should be overridden if a value is passed along with <code>-f</code> option. Also, add a new option <code>-F</code> to turn off the default <code>.2f</code> precision.</ol><pre><code class=language-bash>$ pc '4 / 3'
41+
</script><div id=content class=content><main><div class=sidetoc><nav class=pagetoc></nav></div><h1><a class=header href=#cli-calculator id=cli-calculator>CLI Calculator</a></h1><p>In this project, you'll learn various ways in which you can use Python as a calculator from the command line. You'll also learn how you can customize the features for your specific needs. This project is divided into two main sections. First, you'll see how you can directly pass Python code from the command line and create <code>bash</code> shortcuts to simplify the invocation. Second, you'll see how to use Python features to create a custom CLI application. The links to these two sections are given below:<ul><li><a href=./calc_bash_func.html>Bash shortcuts</a><li><a href=./calc_py_cli.html>Python CLI application</a></ul><h2><a class=header href=#topics-covered-in-this-project id=topics-covered-in-this-project>Topics covered in this project</a></h2><p>The following modules and concepts will be utilized in this project:<ul><li><a href=https://docs.python.org/3/library/sys.html>docs.python: sys</a><li><a href=https://docs.python.org/3/library/argparse.html>docs.python: argparse</a><li><a href=https://docs.python.org/3/library/functions.html#eval>docs.python: eval</a><li><a href=https://docs.python.org/3/tutorial/modules.html>docs.python: Modules</a><li><a href=https://docs.python.org/3/tutorial/errors.html>docs.python: Exception handling</a></ul><h2><a class=header href=#exercises id=exercises>Exercises</a></h2><p>After you've completed the two sections, modify the scripts such that these additional features are also implemented.<ol><li>If the output is of <code>float</code> data type, apply <code>.2f</code> precision by default. This should be overridden if a value is passed along with <code>-f</code> option. Also, add a new option <code>-F</code> to turn off the default <code>.2f</code> precision.</ol><pre><code class=language-bash>$ pc '4 / 3'
4242
1.33
4343

4444
$ pc -f3 '22 / 7'
@@ -60,6 +60,6 @@
6060
120
6161
</code></pre><ol start=3><li>If the input expression has a sequence of numbers followed by <code>!</code> character, replace such a sequence with the factorial value. Assume that input will not have <code>!</code> applied to negative or floating-point numbers. Or, you can issue an error if such numbers are detected.</ol><pre><code class=language-python>$ pc '2 + 5!'
6262
122
63-
</code></pre><h2><a class=header href=#further-reading id=further-reading>Further reading</a></h2><p>Python has a rich ecosystem in addition to the impressive standard library. You can find plenty of modules to choose for common tasks, including alternatives for standard modules. Check out these projects for CLI related applications.<ul><li><a href=https://pypi.org/project/click/>click</a> — Python package for creating beautiful command line interfaces in a composable way with as little code as necessary<li><a href=https://github.com/chriskiehl/Gooey>Gooey</a> — turn Python command line program into a full GUI application<li><a href=https://clig.dev/>CLI Guidelines</a> — an opinionated guide to help you write better CLI programs</ul></main><nav class=nav-wrapper aria-label="Page navigation"><a rel=prev href=preface.html class="mobile-nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=calc_bash_func.html class="mobile-nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a><div style="clear: both"></div></nav></div></div><nav class=nav-wide-wrapper aria-label="Page navigation"><a rel=prev href=preface.html class="nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=calc_bash_func.html class="nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a></nav></div><script>
63+
</code></pre><ol start=4><li>Go through <a href=https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser>docs.python: ArgumentParser</a> and experiment with parameters like <code>description</code>, <code>epilog</code>, etc.</ol><h2><a class=header href=#further-reading id=further-reading>Further reading</a></h2><p>Python has a rich ecosystem in addition to the impressive standard library. You can find plenty of modules to choose for common tasks, including alternatives for standard modules. Check out these projects for CLI related applications.<ul><li><a href=https://pypi.org/project/click/>click</a> — Python package for creating beautiful command line interfaces in a composable way with as little code as necessary<li><a href=https://github.com/chriskiehl/Gooey>Gooey</a> — turn Python command line program into a full GUI application<li><a href=https://clig.dev/>CLI Guidelines</a> — an opinionated guide to help you write better CLI programs</ul></main><nav class=nav-wrapper aria-label="Page navigation"><a rel=prev href=preface.html class="mobile-nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=calc_bash_func.html class="mobile-nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a><div style="clear: both"></div></nav></div></div><nav class=nav-wide-wrapper aria-label="Page navigation"><a rel=prev href=preface.html class="nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=calc_bash_func.html class="nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a></nav></div><script>
6464
window.playground_copyable = true;
6565
</script><script src=elasticlunr.min.js charset=utf-8></script><script src=mark.min.js charset=utf-8></script><script src=searcher.js charset=utf-8></script><script src=clipboard.min.js charset=utf-8></script><script src=highlight.js charset=utf-8></script><script src=book.js charset=utf-8></script><script src=sidebar.js></script>

searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

searchindex.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)