2015-07-09 72 views
4

我完全不熟悉編程。這是我的第一個「適當」項目,將被其他人使用。在文件中的某個點追加,每次增加一個值

該程序提出了各種問題,然後寫入一個新的商店入口文件。對於一個空文件,我大部分都可以工作,但成品需要將條目插入現有文件中的特定點。

2問題已經我百思不得其解:

如何插入新開店項目到文件之前,「返回:」我如何增加「InventoryLocation:」通過各1項被添加

時間該文件被附加到具有這種結構:

# shop 1 
SuperSpaceSquids: 
    RewardType: playercommand 
    PriceType: free 
    Reward: 
    - ewarp Shop-SuperSpaceSquids 
    MenuItem: 
    - type:SKULL_ITEM 
    - playerhead:MHF_Squid 
    - durability:3 
    - amount:1 
    - name:&5SuperSpaceSquids 
    - 'lore:&6&o"Squid Shop From Space!"' 
    Message: '' 
    InventoryLocation: 38 
    ExtraPermission: '' 
# shop 2 
HadesKitty: 
    RewardType: playercommand 
    PriceType: free 
    Reward: 
    - ewarp Shop-HadesKitty 
    MenuItem: 
    - type:SKULL_ITEM 
    - playerhead:Turtle_Em 
    - durability:3 
    - amount:1 
    - name:&5HadesKitty 
    - 'lore:&6&o"our prices are fair!..."' 
    Message: '' 
    InventoryLocation: 39 # This value needs to be incremented by 1 each time 
    ExtraPermission: '' 
>> insert new shops here << 
Back: 
    RewardType: shop 
    PriceType: free 
    Reward: Shop_Menu 
    MenuItem: 
    - type:REDSTONE 
    - amount:1 
    - name:&cBack 
    - lore:&8Back to Shop Menu 
    InventoryLocation: 54 

這是寫入到文件中的功用:

def write(shop, id, data, desc, skull): 
    f = open('file.yml', 'w') 
    f.write(" %s:" % shop) 
    f.write("\n RewardType: playercommand") 
    f.write("\n PriceType: free") 
    f.write("\n Reward:") 
    f.write("\n - ewarp shop-%s" % shop) 
    f.write("\n MenuItem:") 
    if skull: 
     f.write("\n - Type:SKULL_ITEM") 
     f.write("\n - playerhead:%s" % skull) 
     f.write("\n - durability:3") 
    if not skull: 
     f.write("\n - id:%s" % id) 
    if data: 
     f.write("\n - durability:%s" % data) 
    f.write("\n - amount:1") 
    f.write("\n - name:&5%s" % shop) 
    f.write("\n - 'lore:&6&o\"%s\"'" % desc) 
    f.write("\n Message:") 
    f.write("\n InventoryLocation:") 
    f.write("\n ExtraPermission: ''") 
    f.flush() 
    print "\nAll done." 
    print "\nHit Return to quit or 1 to add more shops." 

    while True: 
     choice = raw_input(prompt) 
     if choice == "": 
      print "\nGoodbye!" 
      f.close() 
      time.sleep(2) 
      exit(0) 
     elif choice == "1": 
      os.system('cls' if os.name == 'nt' else 'clear') 
      input() 
     else: 
      print "I dont understand that." 
+0

我想指出你的設計存在一些嚴重的問題,這些問題太廣泛而無法在本網站上得到解答。你應該研究數據庫理論,並習慣使用幾個不同的數據庫(我建議SQLite啓動,後來Postgres)。實施它你自己*會*搞砸了。 – o11c

回答

1

這是一個很好的問題。我寫了兩個功能,爲您提供:

insert_before_back(列表,列表)

insert_before_back需要在文件和所有你想要Back:之前添加行的列表的行的列表,那麼這個返回一個列表,其中的項目添加在正確的索引中。

add_inventory(列表,字符串)

add_inventory需要的文件和店鋪名稱,其庫存要增加的行的列表。然後它通過並將該數字遞增1,並將列表中的值重置爲新遞增的值。它返回新行的列表。

您可以使用這些來修改您讀入的行的列表,然後只是遍歷列表中所有新修改的項目,並將每個項目寫入具有相同名稱的文件。

繼承人使用這兩個功能我的一個例子:

def insert_before_back(lines, thingsToAdd): 
    backIndex = lines.index('Back:\n') 
    for item in reversed(thingsToAdd): 
     lines.insert(backIndex, item) 
    return lines 

def add_inventory(lines, shopName): 
    shopFound = 0 
    for i in range(len(lines)): 
     if shopName in lines[i]: 
      shopFound = 1 
     if 'InventoryLocation:' in lines[i] and shopFound: 
      shopFound = 0 
      lineSplit = lines[i].split(': ') 
      incrementInventory = str(int(lineSplit[-1]) + 1) 
      lineSplit[-1] = incrementInventory + '\n' 
      lines[i] = ': '.join(lineSplit) 


newLines = [] 
with open('input.txt', 'r') as f: 
    inputLines = f.readlines() 
    newLines = insert_before_back(inputLines, ['Hello\n', 'From\n', 'heinst\n']) 
    add_inventory(newLines, 'HadesKitty') 

with open('output.txt', 'w') as f: 
    for line in newLines: 
     f.write(line) 
+0

謝謝!我很難確切地確定代碼的功能,因爲它對我而言並不熟悉,但我相信我會最終弄明白。 – cyclo

+0

@cyclo你究竟在遇到什麼麻煩?並且不要忘記接受正確的答案! :) – heinst

-1

據我所知,我們不能修改一個文件的中間。

你只要有2種選擇:

  1. 讀取所有的文件到內存中的列表,然後修改列表,然後寫所有的列表文件。

  2. (推薦)使用xml文件保存信息,但不是普通文件。因此,您可以使用很多工具來編寫或讀取它。

1

這是一個有趣的問題,heinst提供了一個很好的解決方案。不過我對這個架構有一些保留。以下是我看到的問題,如果這是一個非常小的項目,並且預計在有限的時間內使用,則可以忽略這些問題。

併發性和並行性問題: 如果多個用戶同時嘗試讀取和更新清單,我們需要一個不同的解決方案。數據庫可以輕鬆支持庫存中的多個同時事務,而不是將文件系統作爲持久性存儲。

可擴展性問題: 隨着事務總數隨着時間增加,文件大小不斷增加,讀取整個文件並更新文件的規模也不會很好。事務將不得不使用某種方案在多個文件之間分割。

+1

根據我的經驗,絕不應該使用「非常小」和「有限時間」的藉口,因爲有人*最終會使用它比您計劃的時間更長。 – o11c

+0

我無法使用平面文件以外的任何類型的數據庫。我發佈的yaml文件由不支持其他類型存儲選項的minecraft插件使用。 至於文件變得過大,當'InventoryLocation'達到52時,將創建一個新文件,因爲遊戲庫存只能處理54個插槽。插槽53將成爲「下一頁」命令,該命令在遊戲中打開新的庫存窗口並加載新文件。槽54返回到前一個菜單。 – cyclo

+0

@Ramana Kandimalla這是我同時進行文件編輯的業餘解決方案: http://pastebin.com/gKahzqVM – cyclo