[Tut] How to Overwrite the Previous Print to Stdout in Python? - Printable Version +- Sick Gaming (https://www.sickgaming.net) +-- Forum: Programming (https://www.sickgaming.net/forum-76.html) +--- Forum: Python (https://www.sickgaming.net/forum-83.html) +--- Thread: [Tut] How to Overwrite the Previous Print to Stdout in Python? (/thread-99474.html) |
[Tut] How to Overwrite the Previous Print to Stdout in Python? - xSicKxBot - 05-29-2022 How to Overwrite the Previous Print to Stdout in Python? <div><div class="kk-star-ratings kksr-valign-top kksr-align-left " data-payload="{"align":"left","id":"374551","slug":"default","valign":"top","reference":"auto","count":"0","readonly":"","score":"0","best":"5","gap":"5","greet":"Rate this post","legend":"0\/5 - (0 votes)","size":"24","width":"0","_legend":"{score}\/{best} - ({count} {votes})"}"> <div class="kksr-stars"> <div class="kksr-stars-inactive"> <div class="kksr-star" data-star="1" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" data-star="2" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" data-star="3" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" data-star="4" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" data-star="5" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> </p></div> <div class="kksr-stars-active" style="width: 0px;"> <div class="kksr-star" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> <div class="kksr-star" style="padding-right: 5px"> <div class="kksr-icon" style="width: 24px; height: 24px;"></div> </p></div> </p></div> </div> <div class="kksr-legend"> <span class="kksr-muted">Rate this post</span> </div> </div> <p class="has-background" style="background-color:#1bdbd4"><strong>Summary: </strong>The most straightforward way to overwrite the previous print to stdout is to set the carriage return (<code>'\r'</code>) character within the print statement as <code>print(string, end = "\r")</code>. This returns the next stdout line to the beginning of the line without proceeding to the next line.</p> <hr class="wp-block-separator" /> <h2><strong>Problem Formulation </strong></h2> <p><strong>Problem Definition: </strong>How will you overwrite the previous print/output to stdout in Python?</p> <p><strong>Example: </strong>Let’s say you have the following snippet, which prints the output as shown below:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time for i in range(10): if i % 2 == 0: print(i, end="\r") time.sleep(2)</pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="600" height="165" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img1.gif" alt="" class="wp-image-379272" /></figure> <p><strong>Challenge: </strong>What we want to do is instead of printing each output in a newline, we want to replace the previous output value and overwrite it with the new output value on the same line, as shown below.</p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="600" height="165" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img2.gif" alt="" class="wp-image-379296" /><figcaption>Expected Output</figcaption></figure> <h2><strong>Method 1: Using Carriage Return (‘\r’) Character</strong></h2> <p><strong>Approach: </strong>The simplest solution to the given problem is to use the carriage return (‘<code data-enlighter-language="generic" class="EnlighterJSRAW">\r</code>‘) character within your print statement to return the stdout to the start of the same print line without advancing to the next line. This leads to the next print statement overwriting the previous print statement.</p> <p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f4cc.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /><strong>Note: </strong>Read <strong>here</strong> to learn more about the carriage return escape character.</p> <p><strong>Code:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time for i in range(10): if i % 2 == 0: print(i, end="\r") time.sleep(2) </pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="600" height="165" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_carriage-return.gif" alt="" class="wp-image-379340" /></figure> <p>That’s easy! Isn’t it? Unfortunately, this approach is not completely foolproof. Let’s see what happens when we execute the following snippet:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time li = ['start', 'Processing result'] for i in range(len(li)): print(li[i], end='\r') time.sleep(2) print('Terminate')</pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="410" height="178" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img3.gif" alt="" class="wp-image-381196" /></figure> <p><img src="https://s.w.org/images/core/emoji/13.1.0/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /><strong><code>print('Terminate')</code></strong> is unable to completely wipe out the previous output. Hence, the final output is erroneous.</p> <p>Since we are executing each output generated by a print statement <strong>on top </strong>of the previous output, it is not possible to display an output properly on the same line if the following output has a shorter length than the output before. </p> <p><strong>FIX: </strong>To fix the above problem, instead of simply overwriting the output, we must clear the previous output before displaying the next output. This can be done with the help of the following ANSI sequence: “<strong>\x1b[2K</strong>“.</p> <p><strong>Code:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="5,7" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time li = ['start', 'Processing result'] for i in range(len(li)): print(li[i], end='\r') time.sleep(2) print(end='\x1b[2K') # ANSI sequence to clear the line where the cursor is located print('Terminate')</pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="410" height="178" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img4.gif" alt="" class="wp-image-381233" /></figure> <h2><strong>Method 2: Clear Line and Print Using ANSI Escape Sequence</strong></h2> <p><strong>Approach: </strong>The idea here is to use an extra print statement instead of altering the <code data-enlighter-language="generic" class="EnlighterJSRAW">end</code> parameter of the print statement that is used to display the output. The extra print statement is used to move the cursor back to the previous line where the output was printed and then clear it out with the help of ANSI escape sequences. </p> <p><strong>Explanation:</strong></p> <ul> <li>Print a line that ends with a new line initially.</li> <li>Just before printing the next output on the new line, perform a couple of operations with the help of ANSI escape sequences: <ol> <li>Move the cursor up, i.e., to the previous output line using the escape sequence: ‘<strong>\033[1A</strong>‘.</li> <li>Clear the line using the escape sequence: ‘<strong>\x1b[2K</strong>‘ </li> </ol> </li> <li>Print the next output.</li> </ul> <p><strong>Code:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time UP = '\033[1A' CLEAR = '\x1b[2K' for i in range(10): if i % 2 == 0: print(i) time.sleep(2) print(UP, end=CLEAR)</pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="410" height="178" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img5.gif" alt="" class="wp-image-381313" /></figure> <p><strong>Discussion: </strong>Though this code might look a little more complex than the previous approach, it comes with a major advantage of the neatness of output. You don’t have to worry about the length of the previous output. Also, the cursor does not visually hinder the output being displayed. </p> <p>Here’s a handy guide to escape sequences with respect to cursor movements:</p> <figure class="wp-block-table is-style-stripes"> <table> <tbody> <tr> <td><strong>ESCAPE SEQUENCE</strong></td> <td><strong>CURSOR MOVEMENT</strong></td> </tr> <tr> <td>\033[<L>;<C>H</td> <td>Positions the cursor. Puts the cursor at line L and column C.</td> </tr> <tr> <td>\033[<N>A</td> <td>Move the cursor up by N lines.</td> </tr> <tr> <td>\033[<N>B</td> <td>Move the cursor down by N lines.</td> </tr> <tr> <td>\033[<N>C</td> <td>Move the cursor forward by N columns.</td> </tr> <tr> <td>\033[<N>D</td> <td>Move the cursor backward by N columns.</td> </tr> <tr> <td>\033[2J</td> <td>Clear the screen, move to (0,0)</td> </tr> <tr> <td>\033[K</td> <td>Erase the end of line.</td> </tr> </tbody> </table> </figure> <h2><strong>Method 3: Using “\b” Character</strong></h2> <p>Another way to overwrite the previous output line is to use the backspace character(“<strong>\b</strong>“) and write to the standard output.</p> <p><strong>Code:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import time import sys for i in range(10): if i % 2 == 0: sys.stdout.write(str(i)) time.sleep(1) sys.stdout.write('\b') sys.stdout.flush()</pre> <p><strong>Output:</strong></p> <figure class="wp-block-image size-full is-style-default"><img loading="lazy" width="600" height="157" src="https://blog.finxter.com/wp-content/uploads/2022/05/same_line_print_img5-1.gif" alt="" class="wp-image-381349" /></figure> <p><strong><mark style="background-color:var(--base-3);color:#f50404" class="has-inline-color">Caution:</mark> </strong>Ensure that you properly flush the buffer as done in the above snippet. Otherwise, you might see that only the last result is displayed at the end of the script. </p> <p class="has-medium-font-size"><strong>Bonus Read Ahead <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f447.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></p> <h2><strong>What is Carriage Return (\r) in Python?</strong></h2> <p>Simply put, <strong>carriage return </strong>is an escape character just like <code data-enlighter-language="generic" class="EnlighterJSRAW">\n</code>. Carriage return is denoted as <strong><code>\r</code></strong> and it is basically used to shift the cursor to the beginning of a line or string instead of allowing it to move on to the next line.</p> <p>Whenever you use the carriage return escape character <strong>‘\r’</strong>, the content that comes after the \r will appear on top of your line and will keep replacing the characters of the previous string one by one until it occupies all the contents left after the <code>\r</code> in that string.</p> <p><strong>Example:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="3" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">li = ['One', 'Two', 'Three'] for i in range(len(li)): print(li[i], end='\r') # OUTPUT-->Three</pre> <h2><strong>Conclusion</strong></h2> <p>To sum things up, the easiest way to overwrite the previous print is to use the carriage return <code>\r</code> character within your print statement using the end parameter. To ensure that the previous output is completely erased before printing the new output, you can use the <code>\x1b[2K</code> ANSI escape sequence. </p> <p>I hope this tutorial helped you. Here’s another interesting read that you may find useful: <strong><a href="https://blog.finxter.com/python-print-one-line-list/" target="_blank" rel="noreferrer noopener">Python Print One Line List</a></strong></p> <hr class="wp-block-separator" /> <ul> <li>One of the most sought-after skills on Fiverr and Upwork is <strong>web scraping</strong>. Make no mistake: <em><strong>extracting data programmatically from websites </strong></em>is a critical life skill in today’s world that’s shaped by the web and remote work.</li> <li>So, do you want to master the art of web scraping using Python’s BeautifulSoup?</li> <li>If the answer is yes – this course will take you from beginner to expert in Web Scraping.</li> </ul> <div class="wp-block-image is-style-default"> <figure class="aligncenter"><a href="https://academy.finxter.com/university/web-scraping-with-beautifulsoup/" target="_blank" rel="noreferrer noopener"><img loading="lazy" width="480" height="360" src="https://blog.finxter.com/wp-content/uploads/2021/06/scrape_bs4.png" alt="" class="wp-image-32250" srcset="https://blog.finxter.com/wp-content/uploads/2021/06/scrape_bs4.png 480w, https://blog.finxter.com/wp-content/uploads/2021/06/scrape_bs4-300x225.png 300w" sizes="(max-width: 480px) 100vw, 480px" /></a><figcaption><strong><a href="https://academy.finxter.com/university/web-scraping-with-beautifulsoup/" target="_blank" rel="noreferrer noopener">Join the Web Scraping with BeautifulSoup Masterclass</a></strong> now, and master it by tomorrow!</figcaption></figure> </div> </div> https://www.sickgaming.net/blog/2022/05/22/how-to-overwrite-the-previous-print-to-stdout-in-python/ |