#!/usr/bin/env python3 import sys import curses from operator import itemgetter import time # Number of top items to be displayed N = 10 def gen_output(item_dict, N=10): """ Generate a formatted output string for the top N items in item_dict. :param item_dict: A dictionary containing items and their counts :param N: The number of top items to be displayed :return: A generator yielding formatted strings for each of the top N items """ top_items = dict(sorted(item_dict.items(), key=itemgetter(1), reverse=True)[:N]) count_length = len(str(max(top_items.values()))) for i, key in enumerate(top_items): yield i, f'{i + 1:3} : [{top_items[key]:{count_length}}] {key}' def main(screen): """ Main function to read input lines, maintain a count of each unique line, and periodically display the top N lines with the highest counts using curses. :param screen: A curses window object """ if not sys.stdin.isatty(): # Check if the input comes from a pipe # Initialize an empty dictionary to store unique input lines and their counts toplist = {} # Set the next screen update time t_update = time.time() + 1 for line in sys.stdin: line = line.strip() # Increment the count for each unique input line if line in toplist: toplist[line] += 1 else: toplist[line] = 1 # Periodically update the screen with the top N lines if time.time() > t_update: for idx, line in gen_output(toplist): screen.addstr(idx, 0, line) screen.refresh() t_update = time.time() + 1 # Clean up the curses environment and print the final top N lines curses.endwin() for idx, line in gen_output(toplist): print(line) else: print("Usage: cat input_file.txt | ./top_lines.py") print("Or: ./top_lines.py < input_file.txt") # Initialize the curses library, run the main function, and restore the terminal state curses.wrapper(main)