কীভাবে পূর্ববর্তী মুদ্রণটি অজগরে স্টডআউটে লিখিত?


113

আমার যদি নিম্নলিখিত কোড থাকে:

for x in range(10):
     print x

আমি আউটপুট পেতে হবে

1
2
etc..

আমি যা করতে চাই তা হল একটি নতুন লাইন মুদ্রণের পরিবর্তে, আমি পূর্ববর্তী মানটি প্রতিস্থাপন করতে এবং একই লাইনে নতুন মান দিয়ে ওভাররাইট করতে চাই।



পার্শ্ব নোট হিসাবে, নিশ্চিত হয়ে নিন যে উত্তরটি আগের লাইনের বর্তমান লাইনের চেয়ে দীর্ঘতর হলে পুরো লাইনে ফ্লাশ করতে সক্ষম ।
ফল

উত্তর:


119

একটি উপায় হ'ল '\r'পরের লাইনে অগ্রসর না হয়ে লাইনের শুরুতে ফিরে যাওয়ার জন্য ক্যারেজ রিটার্ন ( ) অক্ষরটি ব্যবহার করা :

for x in range(10):
    print '{0}\r'.format(x),
print

মুদ্রণ বিবৃতিটির শেষে কমা এটিকে পরবর্তী লাইনে না যাওয়ার কথা বলে। শেষ মুদ্রণ বিবৃতিটি পরবর্তী লাইনে অগ্রসর হয় যাতে আপনার প্রম্পটটি আপনার চূড়ান্ত আউটপুটকে ওভাররাইট করে না।

হালনাগাদ

পাইথন 2 হ'ল ইওএল, পাইথন 3 উত্তর আরও অর্থপূর্ণ করে তোলে। পাইথন 3.5 এবং এর আগে:

for x in range(10):
    print('{}\r'.format(x), end="")
print()

পাইথন ৩.6 এবং তারপরে, এফ-স্ট্রিংগুলি আরও ভালভাবে পড়তে পারে:

for x in range(10):
    print(f'{x}\r', end="")
print()

এটি কাজ করে, তবে আমি কয়েকটি অংশ বুঝতে পারি না ... '{0}' এবং। ফর্ম্যাট
সিসিওয়াইট 1

7
এটি পাইথন ২.6 এ প্রবর্তিত এবং এটি পাইথন 3-এ ফর্ম্যাট করার স্ট্রিংয়ের মানক উপায়; %অপারেটর অসমর্থিত হয়েছে। মূলত, সমস্ত স্ট্রিংয়ের এখন একটি বিন্যাস পদ্ধতি রয়েছে। এই ক্ষেত্রে, {0}মানে "প্রথম যুক্তি format()" (গণনা 0 থেকে শুরু হয়)
মাইক ডিসিমোন

আপনার যদি কিছু উইন্ডোজ-কেবল সফ্টওয়্যার ব্যবহার করতে হয় এবং ভিএম চালানোর জন্য চপগুলি না থাকে তবে একটি বিকল্প নয়।
মাইক ডিসিমোন

2
এবং যদি আপনি ক্রস-টার্মিনাল হতে চান re.sub(r'\$<\d+>[/*]?', '', curses.tigetstr('el') or ''), ব্যবহারকারীকে যে কোনও টার্মিনাল আছে তার জন্য আপনাকে সঠিক মুছা থেকে শেষের লাইনের স্ট্রিং দেবে। cursesমত কিছু দিয়ে আরম্ভ করার কথা মনে রাখবেন curses.setupterm(fd=sys.stdout.fileno())এবং sys.stdout.isatty()আপনার আউটপুট কোনও ফাইলে পুনঃনির্দেশিত হচ্ছে না তা নিশ্চিত করতে ব্যবহার করুন। কার্সার নিয়ন্ত্রণ এবং রঙ সমর্থন সহ পূর্ণ পাইথন মডিউলটির জন্য কোড.এ্যাকটিভস্টেট.com/recips/475116 দেখুন ।
মাইক ডিসিমোন

1
@ ফিলম্যাককে: আমি আমার ম্যাকের অজগরটিতে চেষ্টা করেছিলাম: ইন [৩]: "থিংট টু মুছে ফেলার জিনিস", মুদ্রণ করুন; সময়.স্লিপ (1); "-------------- \ r", -------------- আমি মনে করি আপনার সমস্যাটি উইন্ডোজ এবং এর আলাদা লাইন শেষ। এই চেষ্টা করুন: import curses; curses.setupterm(fd=sys.stdout.fileno()); print(hex(curses.tigetstr('cr')));এটা লাইনের শুরু পর্যন্ত যেতে চরিত্র ক্রম হেক্স কোডগুলি মুদ্রণ করা উচিত নয়।
মাইক ডিসিমোন

107

যেহেতু আমি এখানে গুগলের মাধ্যমে শেষ করেছি তবে পাইথন 3 ব্যবহার করছি তাই পাইথন 3 এ এটি কীভাবে কাজ করবে তা এখানে:

for x in range(10):
    print("Progress {:2.1%}".format(x / 10), end="\r")

সম্পর্কিত উত্তর এখানে: একটি মুদ্রণ বিবৃতি পরে আমি নতুন লাইনটি কীভাবে দমন করতে পারি?


3
আমি এটি চেষ্টা করেছিলাম এবং এটি বেশিরভাগ ক্ষেত্রে সূক্ষ্মভাবে কাজ করে। কেবলমাত্র সমস্যাটি এটি সেই লাইনে পূর্ববর্তী আউটপুটটি মুছে ফেলছে না, উদাহরণস্বরূপ: যদি আপনার প্রথম লুপ প্রিন্ট testingএবং testদ্বিতীয় পাসের পরে যদি আপনার দ্বিতীয় লুপ প্রিন্ট করে তবে আউটপুটটি এখনও থাকবে testing- এখন আমি দেখতে পাচ্ছি @ নাগাসাকি
45

15
আইপথন নোটবুকে, আমাকে করতে হবে:print("\r", message, end="")
গ্রিসাইটিস

1
এটি দুর্দান্ত কাজ করে, এটি লাইনটি মুছবে না তবে নিম্নলিখিত প্রিন্টে পর্যাপ্ত শ্বেতস্থান ব্যবহার করে কাজটি (যদিও এটি মার্জিত নয়)। একটি মন্তব্য আমি যুক্ত করতে পারি যে এটি ভিএস কোডের ডিবাগ কনসোলটিতে কাজ করে না, তবে এটি টার্মিনালে কাজ করে।
ফিলম্যাককে

31

@ মাইক ডিসিমোন উত্তর সম্ভবত বেশিরভাগ সময় কাজ করবে। কিন্তু ...

for x in ['abc', 1]:
    print '{}\r'.format(x),

-> 1bc

এটি '\r'কেবলমাত্র লাইনের শুরুতে ফিরে যায় তবে আউটপুট সাফ করে না।

সম্পাদনা: আরও ভাল সমাধান (নীচে আমার পুরানো প্রস্তাবনার চেয়ে)

যদি পসিক্স সমর্থনটি আপনার পক্ষে যথেষ্ট হয় তবে নিম্নলিখিতগুলি বর্তমান লাইনটি সাফ করবে এবং কার্সারটিকে তার শুরুতে ছেড়ে দেবে:

print '\x1b[2K\r',

এটি টার্মিনাল লাইন সাফ করতে এএনএসআই এস্কেপ কোড ব্যবহার করে। আরও তথ্য উইকিপিডিয়া এবং এই দুর্দান্ত আলোচনায় পাওয়া যাবে

পুরানো উত্তর

(এত ভাল নয়) সমাধানটি আমি দেখতে পেয়েছি এরকম দেখতে:

last_x = ''
for x in ['abc', 1]:
    print ' ' * len(str(last_x)) + '\r',
    print '{}\r'.format(x),
    last_x = x

-> 1

একটি সুবিধা হ'ল এটি উইন্ডোতেও কাজ করবে।


1
: আমি পুরনো উত্তর 'যে (উইন্ডোজ এমনকি) সঠিকভাবে কাজ করে আউট একটি ফাংশন তৈরী আমার উত্তর দেখুন stackoverflow.com/a/43952192/965332
ERB

25

এই থ্রেডটি দেখার আগে আমার একই প্রশ্ন ছিল। আমার জন্য sys.stdout.writ শুধুমাত্র তখনই কাজ করেছিল যদি আমি বাফারকে যথাযথভাবে ফ্লাশ করি

for x in range(10):
    sys.stdout.write('\r'+str(x))
    sys.stdout.flush()

ফ্লাশ না করে, ফলাফলটি কেবল স্ক্রিপ্টের শেষে প্রিন্ট করা হয়


stringvar.ljust(10,' ')পরিবর্তনশীল দৈর্ঘ্যের স্ট্রিংয়ের ক্ষেত্রে ফাঁকা জায়গাগুলির মতো বাকী স্ট্রিংগুলি পূরণ করার পক্ষেও ভাল ধারণা ।
আনারফেটেক

@ ক্রিস, ডন এট আল এটি পাইথন 2, অন্যান্য উত্তরগুলির বেশিরভাগটি পাইথন 3 Everyone প্রত্যেকেরই এখন পাইথন 3 ব্যবহার করা উচিত; পাইথন 2 2020-এ জীবনের শেষ
অবধি

18

নিউলাইনটি চাপুন এবং মুদ্রণ করুন \r

print 1,
print '\r2'

বা stdout লিখুন:

sys.stdout.write('1')
sys.stdout.write('\r2')

9

এটা চেষ্টা কর:

import time
while True:
    print("Hi ", end="\r")
    time.sleep(1)
    print("Bob", end="\r")
    time.sleep(1)

এটা আমার জন্য কাজ করে। end="\r"অংশ এটা পূর্ববর্তী লাইন ওভাররাইট করছে।

সতর্কবার্তা!

আপনি যদি প্রিন্ট আউট করেন hiতবে প্রিন্ট আউট helloব্যবহার করে \rআপনি পাবেন hilloকারণ আউটপুট আগের দুটি অক্ষরের উপরে লিখেছিল। যদি আপনি hiস্পেস দিয়ে মুদ্রণ করেন (যা এখানে প্রদর্শিত হবে না), তবে এটি আউটপুট হবে hi। এটি ঠিক করতে, ব্যবহার করে স্পেসগুলি মুদ্রণ করুন \r


1
এটি আমার পক্ষে কাজ করে না। আমি সেই কোডটি অনুলিপি করেছি, তবে আমার আউটপুট Hi BobHi BobHi BobHi BobHi Bob। পাইথন 3.7.1
পলম্যাগ

1
তবে রুবিক্রেডের উত্তর কার্যকর হয়েছিল। রহস্যময়। তারা আমার কাছে একই পদ্ধতির মতো দেখায়। কেবলমাত্র তফাতটি আমি দেখছি \rএটি শেষের পরিবর্তে শুরুতে।
পলম্যাগ

7

আইপিথনের পক্ষে কাজ করার জন্য আমি এই পৃষ্ঠায় কোনও সমাধান পেতে পারি নি , তবে @ মাইক-ডেসিমোন এর সমাধানের ক্ষেত্রে সামান্যতম পরিবর্তনটি এই কাজটি করেছে: ক্যারেজ রিটার্নের সাথে লাইনটি শেষ করার পরিবর্তে, ক্যারেজ রিটার্নের সাথে লাইনটি শুরু করুন:

for x in range(10):
    print '\r{0}'.format(x),

অতিরিক্তভাবে, এই পদ্ধতির জন্য দ্বিতীয় মুদ্রণ বিবৃতি প্রয়োজন হয় না।


এমনকি এটি পাইদেভ কনসোলেও কাজ করে না, বা মুদ্রণের () বন্ধুত্বের পরে কমাও দেয় না।
নওমেনন

আমার পক্ষে কাজ করে না, প্রক্রিয়াটি শেষ হয়ে গেলে এটি চূড়ান্ত ফলাফলটি (উদাহরণস্বরূপ: "অগ্রগতি 100% ডাউনলোড করুন") লিখে ফেলে।
আলেকজান্দ্রে

2
@ আলেকজান্দ্রে এটি আইপথন বা এর উত্তরসূরি জুপিটারে ভাল কাজ করে। আপনার বাফারটি ফ্লাশ করা দরকার। stackoverflow.com/questions/17343688/…
মার্চ হো

7
for x in range(10):
    time.sleep(0.5) # shows how its working
    print("\r {}".format(x), end="")

সময়.স্লিপ (০.০) হ'ল পূর্ববর্তী আউটপুটটি কীভাবে মুছে যায় এবং নতুন আউটপুট "\ r" মুদ্রিত হয় তা প্রিন্ট বার্তার প্রারম্ভিক সময়ে, এটি নতুন আউটপুটের পূর্বে পূর্ববর্তী আউটপুট মুছবে show



5

গৃহীত উত্তর নির্ভুল নয় । প্রথমে যে লাইনটি মুদ্রিত হয়েছিল সেগুলি সেখানেই থাকবে এবং আপনার দ্বিতীয় মুদ্রণটি যদি পুরো নতুন লাইনটি কভার করে না, আপনি আবর্জনা পাঠ্যের সাথে শেষ করবেন।

সমস্যাটি চিত্রিত করার জন্য এই কোডটি স্ক্রিপ্ট হিসাবে সংরক্ষণ করুন এবং এটি চালান (বা কেবল একবার দেখুন):

import time

n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print("Progress {:2.1%}".format(i / 100))

আউটপুটটি এরকম কিছু দেখবে:

Progress 0.0%%
Progress 1.0%%
Progress 2.0%%
Progress 3.0%%

আমার জন্য যা কাজ করে তা হ'ল স্থায়ী মুদ্রণ ছাড়ার আগে লাইনটি সাফ করা। আপনার নির্দিষ্ট সমস্যার সাথে নির্দ্বিধায় নির্দ্বিধায়:

import time

ERASE_LINE = '\x1b[2K' # erase line command
n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print(ERASE_LINE + "Progress {:2.1%}".format(i / 100)) # clear the line first

এবং এখন এটি প্রত্যাশার মতো প্রিন্ট করে:

Progress 0.0%
Progress 1.0%
Progress 2.0%
Progress 3.0%

5

এখানে একটি ক্লিনার, আরও "প্লাগ-এন্ড-প্লে", @ নাগাসাকি 45 এর উত্তরের সংস্করণ। এখানে অন্যান্য অনেক উত্তরের বিপরীতে, এটি বিভিন্ন দৈর্ঘ্যের স্ট্রিংগুলির সাথে সঠিকভাবে কাজ করে। এটি সর্বশেষ লাইনের মুদ্রিত মুদ্রণের দৈর্ঘ্যের মতোই অনেক স্পেস দিয়ে লাইন সাফ করে এটি অর্জন করে। উইন্ডোজেও কাজ করবে।

def print_statusline(msg: str):
    last_msg_length = len(print_statusline.last_msg) if hasattr(print_statusline, 'last_msg') else 0
    print(' ' * last_msg_length, end='\r')
    print(msg, end='\r')
    sys.stdout.flush()  # Some say they needed this, I didn't.
    print_statusline.last_msg = msg

ব্যবহার

কেবল এটির মতো ব্যবহার করুন:

for msg in ["Initializing...", "Initialization successful!"]:
    print_statusline(msg)
    time.sleep(1)

এই ছোট পরীক্ষাটি দেখায় যে লাইনগুলি সঠিকভাবে সাফ হয়ে যায়, এমনকি বিভিন্ন দৈর্ঘ্যের জন্যও:

for i in range(9, 0, -1):
    print_statusline("{}".format(i) * i)
    time.sleep(0.5)

5
এটি দুর্দান্ত সমাধান কারণ এটি পূর্ববর্তী আউটপুটটি পুরোপুরি পুরোপুরি পরিষ্কার করে দেয় কেবল স্বেচ্ছাসেবীর সংখ্যা নির্ধারণ না করে (যা আমি পূর্বে অবলম্বন করেছি!) ধন্যবাদ
টবি পেটি

2

আমি কিছুটা অবাক হয়েছি কেউ ব্যাকস্পেস চরিত্রটি ব্যবহার করছে না। এটি ব্যবহার করে এমন একটি এখানে।

import sys
import time

secs = 1000

while True:
    time.sleep(1)  #wait for a full second to pass before assigning a second
    secs += 1  #acknowledge a second has passed

    sys.stdout.write(str(secs))

    for i in range(len(str(secs))):
        sys.stdout.write('\b')

নিশ্চিত হয়ে নিন যে আপনি এই পদ্ধতিটি ব্যবহারের পরে ফ্লাশ করেছেন বা আপনি কোনও কিছু স্ক্রিনে মুদ্রিত নাও পেতে পারেন। sys.stdout.flush()
গ্যাব্রিয়েল ফেয়ার

2

(পাইথন 3) এটি আমার পক্ষে কাজ করেছিল। যদি আপনি কেবল 10 010 ব্যবহার করেন তবে এটি অক্ষরগুলি ছেড়ে দেবে, তাই এটি সেখানে কী রয়েছে তা ওভাররাইট হচ্ছে তা নিশ্চিত করার জন্য আমি এটি কিছুটা টুইট করি। এটি আপনাকে প্রথম মুদ্রণ আইটেমের আগে কিছু রাখার অনুমতি দেয় এবং কেবলমাত্র আইটেমটির দৈর্ঘ্য সরিয়ে দেয়।

print("Here are some strings: ", end="")
items = ["abcd", "abcdef", "defqrs", "lmnop", "xyz"]
for item in items:
    print(item, end="")
    for i in range(len(item)): # only moving back the length of the item
        print("\010 \010", end="") # the trick!
        time.sleep(0.2) # so you can see what it's doing

2

প্রচলিত উত্তরের উপর ভিত্তি করে আরও একটি উত্তর।

Pbar.py এর সামগ্রী: sys, shutil, তারিখের সময় আমদানি করুন

last_line_is_progress_bar=False


def print2(print_string):
    global last_line_is_progress_bar
    if last_line_is_progress_bar:
        _delete_last_line()
        last_line_is_progress_bar=False
    print(print_string)


def _delete_last_line():
    sys.stdout.write('\b\b\r')
    sys.stdout.write(' '*shutil.get_terminal_size((80, 20)).columns)
    sys.stdout.write('\b\r')
    sys.stdout.flush()


def update_progress_bar(current, total):
    global last_line_is_progress_bar
    last_line_is_progress_bar=True

    completed_percentage = round(current / (total / 100))
    current_time=datetime.datetime.now().strftime('%m/%d/%Y-%H:%M:%S')
    overhead_length = len(current_time+str(current))+13
    console_width = shutil.get_terminal_size((80, 20)).columns - overhead_length
    completed_width = round(console_width * completed_percentage / 100)
    not_completed_width = console_width - completed_width
    sys.stdout.write('\b\b\r')

    sys.stdout.write('{}> [{}{}] {} - {}% '.format(current_time, '#'*completed_width, '-'*not_completed_width, current,
                                        completed_percentage),)
    sys.stdout.flush()

লিপির ব্যবহার:

import time
from pbar import update_progress_bar, print2


update_progress_bar(45,200)
time.sleep(1)

update_progress_bar(70,200)
time.sleep(1)

update_progress_bar(100,200)
time.sleep(1)


update_progress_bar(130,200)
time.sleep(1)

print2('some text that will re-place current progress bar')
time.sleep(1)

update_progress_bar(111,200)
time.sleep(1)

print('\n') # without \n next line will be attached to the end of the progress bar
print('built in print function that will push progress bar one line up')
time.sleep(1)

update_progress_bar(111,200)
time.sleep(1)

1

এখানে আমার সমাধান! উইন্ডোজ 10, পাইথন 3.7.1

আমি নিশ্চিত না কেন এই কোডটি কাজ করে তবে এটি সম্পূর্ণরূপে মূল লাইনটি মুছে ফেলে। আমি পূর্ববর্তী উত্তরগুলি থেকে সংকলন করেছি। অন্যান্য উত্তরগুলি কেবল শুরুতে রেখাটি ফিরিয়ে দেবে, তবে পরে যদি আপনার একটি ছোট রেখা থাকে, তবে এটি helloপরিবর্তনের মতো গণ্ডগোল দেখাবে byelo

import sys
#include ctypes if you're on Windows
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
#end ctypes

def clearline(msg):
    CURSOR_UP_ONE = '\033[K'
    ERASE_LINE = '\x1b[2K'
    sys.stdout.write(CURSOR_UP_ONE)
    sys.stdout.write(ERASE_LINE+'\r')
    print(msg, end='\r')

#example
ig_usernames = ['beyonce','selenagomez']
for name in ig_usernames:
    clearline("SCRAPING COMPLETE: "+ name)

আউটপুট - প্রতিটি লাইন কোনও পুরানো পাঠ্য না দেখিয়েই আবার লেখা হবে:

SCRAPING COMPLETE: selenagomez

পরবর্তী লাইন (সম্পূর্ণ একই লাইনে পুনরায় লিখিত):

SCRAPING COMPLETE: beyonce

0

পুরো লাইনটি ওভাররাইট করা ভাল অন্যথায় নতুন লাইনটি যদি ছোট হয় তবে পুরানোগুলির সাথে নতুন লাইন মিশে যায়।

import time, os
for s in ['overwrite!', 'the!', 'whole!', 'line!']:
    print(s.ljust(os.get_terminal_size().columns - 1), end="\r")
    time.sleep(1)

columns - 1উইন্ডোজ ব্যবহার করতে হয়েছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.