পাইথনে কনসোল আউটপুট প্রতিস্থাপন করুন


106

আমি ভাবছি যে আমি কীভাবে নির্দিষ্ট সি / সি ++ প্রোগ্রামের মতো পাইথনে সেই নিফটি কনসোল কাউন্টারগুলির একটি তৈরি করতে পারি।

আমি জিনিসগুলি করতে একটি লুপ পেয়েছি এবং বর্তমান আউটপুট এর লাইনের সাথে আছে:

Doing thing 0
Doing thing 1
Doing thing 2
...

নিকটবর্তী হতে হবে কি শেষ লাইন আপডেট আছে;

X things done.

আমি এটি বেশ কয়েকটি কনসোল প্রোগ্রামে দেখেছি এবং আমি কীভাবে পাইথনে এটি করব / তা ভাবছি।


3
আপনি অভিশাপ এক নজর করা উচিত ।
বিজরন পোলেক্স

2
শুধু ব্যবহার print: stackoverflow.com/a/8436827/1959808
Ioannis Filippidis

1
@ বিজার্নপ্লেক্স, cursesএকটি ওভারকিল (গ্রহণযোগ্য উত্তর দেখুন)।
অ্যালেক্সি

উত্তর:


151

একটি সহজ সমাধান কেবল "\r"স্ট্রিংয়ের আগে লেখা এবং একটি নতুন লাইন যুক্ত করা নয়; যদি স্ট্রিংটি কখনও সংক্ষিপ্ত না হয় তবে এটি যথেষ্ট ...

sys.stdout.write("\rDoing thing %i" % i)
sys.stdout.flush()

সামান্য আরও পরিশীলিত হ'ল একটি অগ্রগতি বার ... এটি এমনটি যা আমি ব্যবহার করছি:

def startProgress(title):
    global progress_x
    sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41)
    sys.stdout.flush()
    progress_x = 0

def progress(x):
    global progress_x
    x = int(x * 40 // 100)
    sys.stdout.write("#" * (x - progress_x))
    sys.stdout.flush()
    progress_x = x

def endProgress():
    sys.stdout.write("#" * (40 - progress_x) + "]\n")
    sys.stdout.flush()

আপনাকে কল startProgressঅপারেশন বিবরণ ক্ষণস্থায়ী, তারপর progress(x)যেখানে xশতকরা হার এবং পরিশেষে হয়endProgress()


2
যদি স্ট্রিংটি আগেরটির চেয়ে কম হয়?
math2001

6
হোয়াইটস্পেস সহ @ ম্যাথ ২০০1 প্যাডিং।
felipsmartins

কোডের প্রথম প্রথম 2 লাইনের জন্য ভোট দিয়েছেন। অগ্রগতি বার অংশটি কয়েকটি ক্ষেত্রে ধীর হয়ে যাচ্ছে। যাইহোক ধন্যবাদ @ 6502
ওয়াটার রকেট 8236

কিছু প্রোগ্রাম ( restic, flatpak) কনসোল আউটপুট বিভিন্ন লাইন আপডেট করতে পারে। আপনি কীভাবে কোনও সুযোগেই জানেন যে কীভাবে এটি অর্জন করা যায়?
অ্যালেক্সি

1
@Alexey: আপনার চারপাশের কার্সার সরানোর জন্য ANSI পালাবার কোড ব্যবহার করতে পারেন, পর্দা এবং পরিবর্তন রঙের স্পষ্ট অংশ ... দেখুন en.wikipedia.org/wiki/ANSI_escape_code
6502

39

আরও মার্জিত সমাধান হতে পারে:

def progressBar(current, total, barLength = 20):
    percent = float(current) * 100 / total
    arrow   = '-' * int(percent/100 * barLength - 1) + '>'
    spaces  = ' ' * (barLength - len(arrow))

    print('Progress: [%s%s] %d %%' % (arrow, spaces, percent), end='\r')

এই ফাংশনটির সাথে কল করুন valueএবং endvalue, ফলাফল হওয়া উচিত

Progress: [------------->      ] 69 %

দ্রষ্টব্য: পাইথন 2.x সংস্করণ এখানে


আপনার উন্নততর বার এবং স্পিনারগুলির জন্য হ্যালো ব্যবহার করা উচিত ।
অরবিন্দ ভোগগু

17

ইন পাইথন 3 আপনি একই লাইনে প্রিন্ট করতে এটা করতে পারেন:

print('', end='\r')

সর্বশেষ আপডেট এবং অগ্রগতি ট্র্যাক রাখতে বিশেষভাবে দরকারী।

যদি কেউ লুপের অগ্রগতি দেখতে চায় তবে আমি এখান থেকে tqdm এর প্রস্তাবও দেব । এটি সমাপ্তির প্রত্যাশিত সময়ের সাথে অগ্রগতি বার হিসাবে বর্তমান পুনরাবৃত্তি এবং মোট পুনরাবৃত্তিগুলি মুদ্রণ করে। সুপার দরকারী এবং দ্রুত। পাইথন 2 এবং পাইথন 3 এর জন্য কাজ করে।


7

অন্য উত্তরটি আরও ভাল হতে পারে তবে আমি যা করছি তা এখানে। প্রথমত, আমি অগ্রগতি নামে একটি ফাংশন করেছি যা ব্যাকস্পেসের অক্ষরটি ছাপায়:

def progress(x):
    out = '%s things done' % x  # The output
    bs = '\b' * 1000            # The backspace
    print bs,
    print out,

তারপরে আমি এটিকে আমার মূল ফাংশনে একটি লুপে ডেকেছি:

def main():
    for x in range(20):
        progress(x)
    return

এটি অবশ্যই পুরো লাইনটি মুছে ফেলবে, তবে আপনি যা চান ঠিক তেমন করতে আপনি এটি নিয়ে গণ্ডগোল করতে পারেন। আমি এই পদ্ধতিটি ব্যবহার করে একটি অগ্রগতি বার তৈরি শেষ করেছি।


4
কাজ করে, তবে আগের লাইনে যদি পরের চেয়ে আরও বেশি অক্ষর থাকে তবে নতুন লাইন শেষ হওয়ার পরে অক্ষরগুলি পূর্ববর্তী লাইন থেকে যায়: "বানান চেকিং রেকর্ড ৪১7/70০১ [সার্ফাইস পৃষ্ঠে পরিবর্তিত হয়েছে]] যখন [uminescence] cence] shmentarianism] "
লিল 'বিট

7

যে কেউ এই বছর পরে হোঁচট খায় (যেমন আমি করেছি), আমি অগ্রগতি বারটিকে হ্রাস করার পাশাপাশি বাড়ার জন্য 6502 এর পদ্ধতিগুলি কিছুটা টুইট করেছিলাম। আরও কিছু ক্ষেত্রে কার্যকর। একটি দুর্দান্ত সরঞ্জামের জন্য 6502 ধন্যবাদ!

মূলত, শুধুমাত্র পার্থক্য হ'ল প্রতিটি সময় প্রগতি (x) বলা হলে # এবং -s এর সম্পূর্ণ লাইনটি বলা হয় এবং কার্সারটি সর্বদা বারের শুরুতে ফিরে আসে।

def startprogress(title):
    """Creates a progress bar 40 chars long on the console
    and moves cursor back to beginning with BS character"""
    global progress_x
    sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41)
    sys.stdout.flush()
    progress_x = 0


def progress(x):
    """Sets progress bar to a certain percentage x.
    Progress is given as whole percentage, i.e. 50% done
    is given by x = 50"""
    global progress_x
    x = int(x * 40 // 100)                      
    sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41)
    sys.stdout.flush()
    progress_x = x


def endprogress():
    """End of progress bar;
    Write full bar, then move to next line"""
    sys.stdout.write("#" * 40 + "]\n")
    sys.stdout.flush()

1
যদিও আমি খুঁজে পেয়েছি, কোড দ্বারা এটি খুব ঘন ঘন বলা হয়ে থাকলে এটি কিছুটা
ধীরগতির

6

যদি আমি ভাল করে বুঝতে পারি (নিশ্চিত না) আপনি কি ব্যবহার করে মুদ্রণ করতে চান <CR>এবং না <LR>?

যদি এটি সম্ভব হয়, ততক্ষণ কনসোল টার্মিনাল এটির অনুমতি দেয় (আউটপুট যখন কোনও ফাইলে পুনঃনির্দেশিত হয় তখন এটি ভেঙে যায়)।

from __future__ import print_function
print("count x\r", file=sys.stdout, end=" ")

5

যদি আমরা print()ফাংশনটি দেখি তবে সিস লাইব্রেরি ব্যবহার না করেই এটি করা যায়

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

আমার কোডটি এখানে:

def update(n):
    for i in range(n):
        print("i:",i,sep='',end="\r",flush=True)
        #time.sleep(1)

5

আমি এটি কিছুক্ষণ আগে লিখেছিলাম এবং এটিতে সত্যই খুশি। এটি বিনামূল্যে নির্দ্বিধায়।

এটি একটি সময় লাগে indexএবং totalএবং ঐচ্ছিকরূপে titleবা bar_length। একবার হয়ে গেলে, ঘন্টা গ্লাসটিকে একটি চেক-চিহ্ন দিয়ে প্রতিস্থাপন করে।

⏳ Calculating: [████░░░░░░░░░░░░░░░░░░░░░] 18.0% done

✅ Calculating: [█████████████████████████] 100.0% done

আমি একটি উদাহরণ অন্তর্ভুক্ত করেছি যা এটি পরীক্ষা করার জন্য চালানো যেতে পারে।

import sys
import time

def print_percent_done(index, total, bar_len=50, title='Please wait'):
    '''
    index is expected to be 0 based index. 
    0 <= index < total
    '''
    percent_done = (index+1)/total*100
    percent_done = round(percent_done, 1)

    done = round(percent_done/(100/bar_len))
    togo = bar_len-done

    done_str = '█'*int(done)
    togo_str = '░'*int(togo)

    print(f'\t⏳{title}: [{done_str}{togo_str}] {percent_done}% done', end='\r')

    if round(percent_done) == 100:
        print('\t✅')


r = 50
for i in range(r):
    print_percent_done(i,r)
    time.sleep(.02)

আমি shutil.get_terminal_size()আগ্রহী যদি এটি ব্যবহার করে টার্মিনাল প্রস্থের উপর নির্ভর করে প্রতিক্রিয়াশীল অগ্রগতি বার সহ একটি সংস্করণও রাখি ।


4

অরবিন্দ ভোগগুর উদাহরণে আরও কিছুটা কার্যকারিতা যুক্ত হয়েছে :

def progressBar(name, value, endvalue, bar_length = 50, width = 20):
        percent = float(value) / endvalue
        arrow = '-' * int(round(percent*bar_length) - 1) + '>'
        spaces = ' ' * (bar_length - len(arrow))
        sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\
                         name, width, arrow + spaces, int(round(percent*100))))
        sys.stdout.flush()
        if value == endvalue:     
             sys.stdout.write('\n\n')

এখন আপনি আগেরটি প্রতিস্থাপন না করে একাধিক প্রগতিবার তৈরি করতে সক্ষম।

আমি nameএকটি নির্দিষ্ট প্রস্থ সহ একটি মান হিসাবে যুক্ত করেছি ।

দুটি লুপ এবং দু'বারের progressBar()জন্য ফলাফলের ব্যবহার দেখতে পাবেন:

অগ্রগতি বার অ্যানিমেশন


-1

কোডের নীচে বার্তাটি 0 থেকে 137 পর্যন্ত গণনা করা হবে প্রতিটি পূর্ববর্তী সংখ্যা প্রতিস্থাপন করে প্রতি ০.৩০ সেকেন্ড।

ব্যাকস্টেজে প্রতীক সংখ্যা = সংখ্যাগুলির সংখ্যা।

stream = sys.stdout
for i in range(137):
    stream.write('\b' * (len(str(i)) + 10))
    stream.write("Message : " + str(i))
    stream.flush()
    time.sleep(0.3)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.