简体   繁体   中英

Python Printing on the same Line

The problem that I have is printing phone_sorter() and number_calls() all on the same lines. For instance it will print the two lines of phone_sorter but the number_calls will be printed right below it. I have tried the end='' method but it does not seem to work.

customers=open('customers.txt','r')
calls=open('calls.txt.','r')

def main():
    print("+--------------+------------------------------+---+---------+--------+")
    print("| Phone number | Name                         | # |Duration | Due    |")
    print("+--------------+------------------------------+---+---------+--------+")
    print(phone_sorter(), number_calls())

def time(x):
    m, s = divmod(seconds, x)
    h, m = divmod(m, x)
    return "%d:%02d:%02d" % (h, m, s)

def phone_sorter():
    sorted_no={}
    for line in customers:
        rows=line.split(";")
        sorted_no[rows[1]]=rows[0]
    for value in sorted(sorted_no.values()):
            for key in sorted_no.keys():
                if sorted_no[key] == value:
                    print(sorted_no[key],key)                            
def number_calls():
    no_calls={}
    for line in calls:
        rows=line.split(";")
        if rows[1] not in no_calls:
            no_calls[rows[1]]=1
        else:
            no_calls[rows[1]]+=1
    s={}
    s=sorted(no_calls.keys())
    for key in s:
        print(no_calls[key]) 
main()

Your key problem is that both phone_sorter and number_calls do their own printing, and return None . So, printing their return values is absurd and should just end with a None None line that makes no sense, after they've done all their own separate-line printing.

A better approach is to restructure them to return , not print , the strings they determine, and only then arrange to print those strings with proper formatting in the "orchestrating" main function.

It looks like they'll each return a list of strings (which they are now printing on separate lines) and you'll likely want to zip those lists if they are in corresponding order, to prepare the printing.

But your code is somewhat opaque, so it's hard to tell if the orders of the two are indeed corresponding. They'd better be, if the final printing is to make sense...

Added: let me exemplify with some slight improvement and one big change in phone_sorter ...:

def phone_sorter():
    sorted_no={}
    for line in customers:
        rows=line.split(";")
        sorted_no[rows[1]]=rows[0]
    sorted_keys = sorted(sorted_no, key=sorted_no.get)
    results = [(sorted_no[k], k) for k in sorted_keys]
    return results

Got it? Apart from doing the computations better, the core idea is to put together a list and return it -- it's main 's job to format and print it appropriately, in concert with a similar list returned by number_calls (which appears to be parallel).

def number_calls():
    no_calls=collections.Counter(
        line.split(';')[1] for line in calls)
    return [no_calls(k) for k in sorted(no_calls)]

Now the relationship between the two lists is not obvious to me, but, assuming they're parallel, main can do eg:

nc = no_calls()
ps = phone_sorter()
for (duration, name), numcalls in zip(ps, nc):
    print(...however you want to format the fields here...)

Those headers you printed in main don't tell me what data should be printed under each, and how the printing should be formatted (width of each field, for example). But, main , and only main , should be intimately familiar with these presentation issues and control them, while the other functions deal with the "business logic" of extracting the data appropriately. "Separation of concerns" -- a big issue in programming!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM