2017-09-01 21 views
2

我有一個非常簡單的程序,我正在爲班級編寫計算基於固定門票價格的收入。將它乘以用戶提供的許多票據後,首先用千位上的逗號將其格式化,然後在其前面添加一個美元符號,最後將其作爲字符串返回以在列中列出在頂部固定標題。如何計算多個數字的位數,然後以表格形式對其進行格式化?

我想知道的是,如果有一種方法可以首先統計最後生成的字符串中的數字位數(包括美元符號和逗號),並根據該數字調整列的寬度如果這是有意義的,那麼空格的長度要比正確顯示列標題的最小空格數要長。

就像一個參考,腳本已經輸出了項目所需的結果,我只是想進一步擴展我自己的理解。另外,我知道這可能不是全部是構建這一計劃的最好方式,所以任何建議將受到歡迎:

# Define ticket prices 

SILVER_TIC_PRICE = 35 
GOLD_TIC_PRICE = 55 
PLATINUM_TIC_PRICE = 85 

# Create Functions 

# Validate tickets sold as an interger 

def tickets_sold(message): 
    while True: 
     try: 
      user_input = int(input(message)) 
     except ValueError: 
      print('\nERROR : \nInvalid entry \nPlease use a number\n') 
      continue 
     try: 
      assert user_input >= 0 
     except AssertionError: 
      print('\nERROR : \nInvalid entry \nPlease use a positive number\n') 
      continue 
     else: 
      return user_input 
      break 

# Reusable line function 

def print_line(ticket_class, tickets_sold, ticket_revenue): 
    print(format(ticket_class, " >8"), format(tickets_sold, " >7"), format(ticket_revenue, " <7"), sep=' ') 

# Format Function 

# def format_final() 

# Get the number of tickets sold by type 
# But first a blank line for readability 

print(' ') 

# Get Silver tickets sold 

silver_tickets_sold = tickets_sold ('Enter the number of Silver tickets sold: ') 

# Get Gold tickets sold 

gold_ticket_sold = tickets_sold('Enter the number of Gold tickets sold: ') 

# Get Platinum tickets sold 

platinum_ticket_sold = tickets_sold('Enter the number of Platinum tickets sold: ') 

# calculate revenue 

silver_initial = int(silver_tickets_sold * SILVER_TIC_PRICE) 
gold_initial = int(gold_ticket_sold * GOLD_TIC_PRICE) 
platinum_initial = int(platinum_ticket_sold * PLATINUM_TIC_PRICE) 

silver_final = "{:,}".format(silver_initial) 
gold_final = "{:,}".format(gold_initial) 
platinum_final = "{:,}".format(platinum_initial) 

silver_revenue = '$' + str(silver_final) 
gold_revenue = '$' + str(gold_final) 
platinum_revenue = '$' + str(platinum_final) 

# calculate totals 

total_tickets = int(silver_tickets_sold + gold_ticket_sold + platinum_ticket_sold) 
total_initial = int(silver_initial + gold_initial + platinum_initial) 

total_final = "{:,}".format(total_initial) 

total_revenue = '$'+str(total_final) 

# display results 

print(' ') 
print_line('Section','Tickets','Revenue') 
print_line('--------','-------','-------') 
print_line('Silver', silver_tickets_sold, silver_revenue) 
print_line('Gold', gold_ticket_sold,gold_revenue) 
print_line('Platinum', platinum_ticket_sold, platinum_revenue) 
print_line('========','=======','=======') 
print_line('Total', total_tickets, total_revenue) 
print(' ') 

我知道已經有這個問題的答案的這一部分問題,但我無法找到任何東西以某種方式將各部分結合起來,這樣我就可以將我的大腦包裹起來。

+0

使用一些已經爲你實現的表格包(按照依賴複雜度的增加順序),可以想到'tabulate','pandas','astropy.table'。 – MSeifert

+1

還請包括當前行爲和*期望*行爲,以便我們知道實際上你想要解決的問題是什麼:) – MSeifert

+0

當前我只能將字段長度設置爲固定值(在可重用行中函數),我想要做的是計算每個輸出中的數字,如果它們長於正確顯示標題所需的最小數量,請將格式的長度調整爲最長。即如果出售的門票數量乘以成本結果的字符串長度超過8個字符,則將格式調整爲該數字(如果它們均不是這樣),請將其保留在顯示列標題所需的數量上。這有幫助嗎? – richwoo

回答

0

好了,讓我先了解一下代碼審查:

第一個功能是相當不錯的。它正確使用while Truebreak,直到給出一個有效的號碼。然而,有一定的提升空間:

def tickets_sold(message): 
    while True: 
     try: 
      user_input = int(input(message)) 
     except ValueError: 
      print('\nERROR : \nInvalid entry \nPlease use a number\n') 
      continue 
     if user_input < 0: # better to use an if instead of "try: assert" 
      print('\nERROR : \nInvalid entry \nPlease use a positive number\n') 
      continue 
     return user_input # just return all other cases already "continue"d 

但是那有很多重複的開始,我會放,要求取票密碼,然後返回門票和收入的數量。通過將它的一些進入功能重複了很多(不是全部)可以簡單地迴避:

def get_tickets_and_revenue(name, tic_price): 
    n_tickets_sold = tickets_sold('Enter the number of {} tickets sold: '.format(name)) 
    revenue = int(n_tickets_sold * tic_price) 
    return n_tickets_sold, revenue 


silver_tickets_sold, silver_revenue = get_tickets_and_revenue('Silver', SILVER_TIC_PRICE) 
gold_ticket_sold, gold_revenue = get_tickets_and_revenue('Gold', GOLD_TIC_PRICE) 
platinum_ticket_sold, platinum_revenue = get_tickets_and_revenue('Platinum', PLATINUM_TIC_PRICE) 

total_tickets = silver_tickets_sold + gold_ticket_sold + platinum_ticket_sold 
total_revenue = silver_revenue + gold_revenue + platinum_revenue 

def format_number_according_to_spec(num): 
    return '${:,}'.format(num) 

# only now convert them to strings! 
silver_revenue = format_number_according_to_spec(silver_revenue) 
gold_revenue = format_number_according_to_spec(gold_revenue) 
platinum_revenue = format_number_according_to_spec(platinum_revenue) 
total_revenue = format_number_according_to_spec(total_revenue) 

下一部分或許可以通過保持值iterables被縮短,但它也可以用硬編碼:

def find_column_length(*column_values): 
    # using "len(str(sth))" you can determine the length! 
    return max(len(str(value)) for value in column_values) 

# The row formatter is formatted twice, once with the length values and once 
# with the actual values. So we need to escape the outer {} by doubling them. 
row_formatter = '{{:>{}}} {{:>{}}} {{:>{}}}' 
column_lengths = [find_column_length('Section', 
            'Silver', 
            'Gold', 
            'Platinum', 
            'Total'), 
        find_column_length('Tickets', 
            silver_tickets_sold, 
            gold_ticket_sold, 
            platinum_ticket_sold, 
            total_tickets), 
        find_column_length('Revenue', 
            silver_revenue, 
            gold_revenue, 
            platinum_revenue, 
            total_revenue)] 
row_formatter = row_formatter.format(*column_lengths) 
placeholder1 = '{} {} {}'.format('-'*column_lengths[0], 
            '-'*column_lengths[1], 
            '-'*column_lengths[2]) 
placeholder2 = '{} {} {}'.format('='*column_lengths[0], 
            '='*column_lengths[1], 
            '='*column_lengths[2]) 

print(' ') 
print(row_formatter.format('Section','Tickets','Revenue')) 
print(placeholder1) 
print(row_formatter.format('Silver', silver_tickets_sold, silver_revenue)) 
print(row_formatter.format('Gold', gold_ticket_sold,gold_revenue)) 
print(row_formatter.format('Platinum', platinum_ticket_sold, platinum_revenue)) 
print(placeholder2) 
print(row_formatter.format('Total', total_tickets, total_revenue)) 
print(' ') 

例如:

Enter the number of Silver tickets sold: 200000000 
Enter the number of Gold tickets sold: 1 
Enter the number of Platinum tickets sold: 20 

Section Tickets   Revenue 
-------- --------- -------------- 
    Silver 200000000 $7,000,000,000 
    Gold   1    $55 
Platinum   20   $1,700 
======== ========= ============== 
    Total 200000021 $7,000,001,755 

Enter the number of Silver tickets sold: 2 
Enter the number of Gold tickets sold: 5 
Enter the number of Platinum tickets sold: 1 

Section Tickets Revenue 
-------- ------- ------- 
    Silver  2  $70 
    Gold  5  $275 
Platinum  1  $85 
======== ======= ======= 
    Total  8  $430 
0

如果這個數字和你只對量級感興趣,那麼它就是十位數。

import math 
math.ceil(math.log(n,10)) 

應該工作。 或者你可以使用任何一種:

len(str(n)) 

len(str(n).replace(".","")) 
0

我已經把一個小的代碼,這將使你的數字數的計數中,最後一個字符串TOTAL_REVENUE。

# Initialize the counter 
count_number = 0 

# Get the count of numbers 
for c in total_revenue: 
    if(c.isdigit()): 
     count_number += 1 

# Display the count 
print(count_number) 
相關問題