2015-09-14 4 views
0

Предположим, у меня есть файл под названием «Продовольствие», в котором перечислены названия продуктов и их цены. Некоторые из этих предметов являются сырыми ингредиентами, а другие сделаны из разных количеств этих, например, я могу вручную перечислить цену яиц как 1 и найти, что омлет имеет цену по умолчанию 10, но затем обнаруживает, что омлет будет только нужно 5 яиц, поэтому мне понадобится программа, чтобы прочитать цену яиц, найдите линию, содержащую омлет, и замените ее «омлетом:» + str (яйца 5 *). Мне также может потребоваться добавить дополнительные ингредиенты/предметы питания, например. кучу омлетов, изготовленную из 5 омлетов. основная цель состояла бы в том, чтобы позволить просто отредактировать значение яиц, а также обновить значение омлета и пилеохоллетов. Я начал код, просто создав список строк, содержащихся в файле.Как заменить строки в файле, используя данные, содержащиеся в другом месте в том же файле?

with open("Food.txt") as g: 
    foodlist=g.readlines() 

Файл 'Food.txt' будет в следующем формате:

eggs: 5 
omelette: 20 
pileofomelettes: 120 

и т.д ... и после того, как работает код должен выглядеть

eggs: 5 
omelette: 25 
pileofomelettes: 125 

I будет закодировать отношения вручную, так как они вряд ли когда-либо изменились (и даже если бы они это сделали, было бы довольно легко войти и изменить коэффициенты)

и будет прочитан питона в списке его формат, как что-то вроде

«[» яйцо 2 \ п»,„муки 1 \ п“,„масла 1 \ п“,„сахара 3 \ п“, 'almond 5 \ n', 'cherry 8 \ n'] '

Я искал алгоритмы поиска/замены, которые могут искать определенную фразу и заменять ее другой конкретной фразой, но я не знаю, как i 'd применить его, если строка может быть изменена (пользователь может изменить значения исходного ингредиента, если он хочет обновить все связанные с ним значения). Одно из решений, о котором я могу думать, включает преобразование их в формат словаря, причем все они перечислены как пара значений целочисленного значения, так что я мог бы просто заменить целую часть пары на основе целочисленных значений, хранящихся в других парах целых целых чисел , но, будучи неопытным, я не знаю, как бы я преобразовал список (или сам необработанный файл, еще лучше) в словарь.

Любые советы о том, как выполнить действия этой программы было бы весьма признателен :)

Edit- в фактическом применении программы, это не имеет значения, в каком порядке элементы перечислены в в финале файл, поэтому, если я перечислил все исходные ингредиенты в 1 месте и все составные элементы в другом (с большим пространством между ними, если нужно добавить больше необработанных элементов), я мог бы просто переписать всю вторую половину файла в произвольном порядке без проблем - если положение строк исходных ингредиентов остается неизменным.

+0

вы могли бы включать в себя два исходных файлов ? –

+0

делает это цепь черезt? Что, если я определю кучу омлетов? – Caridorc

+0

Я сделал этот пример еды, чтобы помочь мне применить его к фактическому примеру в том же формате. И да, я бы хотел, чтобы на более позднем этапе можно было определить кучу омлетов и просто скопировать некоторый код с более ранней версии программа и просто изменить аргументы, которые она содержит, для работы с кучей омлетов – Cubbs

ответ

0

Хорошо, я хотел бы предложить создать текстовый файл, отношения, которые вы можете разобрать в случае, если подумайте, что отношения могут впоследствии измениться или просто так, что ваш код легче читать и изменять. Затем это можно проанализировать, чтобы найти необходимые отношения между сырыми ингредиентами и комплексами. Пусть это будет "relations.txt", и типа:

omelette: 5 x eggs + 1 x onions 
pileofomelettes: 6 x omelette 

Здесь вы можете поместить любое количество ингредиентов типа:

комплекс: number1 х ingredient1 + number2 х ingredient2 + ...

и так далее. И ваш food.txt содержит цены на все ингредиенты и комплексы:

eggs: 2 
onions: 1 
omelette: 11.0 
pileofomelettes: 60 

Теперь мы можем видеть, что значение pileofomlettes намеренно не отображается здесь правильно. Итак, мы запустим код ниже, а также вы можете изменить числа и увидеть результаты.

#!/usr/bin/python 
''' This program takes in a relations file and a food text files as inputs 
and can be used to update the food text file based on changes in either of these''' 

relations = {} 
foodDict = {} 

# Mapping ingredients to each other in the relations dictionary 
with open("relations.txt") as r: 
    relationlist=r.read().splitlines() 
    for relation in relationlist: 
     item, equatedTo = relation.split(': ') 
     ingredientsAndCoefficients = equatedTo.split(' + ') 
     listIngredients = [] 
     for ingredient in ingredientsAndCoefficients: 
      coefficient, item2 = ingredient.split(' x ') 
      # A list of sets of amount and type of ingredient 
      listIngredients.append((float(coefficient),item2)) 
     relations.update({item:listIngredients}) 


# Creating a food dictionary with values from food.txt and mapping to the relations dictionary 
with open("food.txt") as g: 
    foodlist=g.read().splitlines() 
    for item in foodlist: 
     food,value = item.split(': ') 
     foodDict.update({food:value}) 
    for food in relations.keys(): 
     # (Raw) Ingredients with no left hand side value in relations.txt will not change here. 
     value = 0. 
     for item2 in range(len(relations[food])): 
      # Calculating new value for complex here. 
      value += relations[food][item2][0]* float(foodDict[relations[food][item2][1]]) 
     foodDict.update({food: value }) 

# Altering the food.txt with the new dictionary values 
with open("food.txt",'w') as g: 
    for key in sorted(foodDict.keys()): 
     g.write(key + ': ' + str (foodDict[key])+ '\n') 
     print key + ': ' + str(foodDict[key]) 

И выходит быть:

eggs: 2 
onions: 1 
omelette: 11.0 
pileofomelettes: 66.0 

Вы можете изменить цену яиц до 5 в файле food.txt и

eggs: 5 
onions: 1 
omelette: 26.0 
pileofomelettes: 156.0 
+0

Я полагаю, я мог бы создать файл отношений, но так как есть проблема с некоторыми элементами, для которых может потребоваться определенное количество 1 элемента и определенное количество другого, поэтому я думаю, что я просто займусь более простой возможностью ручного кодирования. Вместо этого, если бы я хотел изменить коэффициенты, используемые для разработки обновленных значений, я думаю, что я просто зайду и отредактирую саму программу, так же быстро, как переход в отдельный .txt-файл, если я использую Ctrl + F. – Cubbs

+0

You может легко изменить это, чтобы добавить «+» для всех товаров, которые входят в вашу смесь, и проанализировать файл. Может быть, плохая идея жестко кодировать эти числа, потому что невозможно отладить ваш код! –

+0

Хотя я знаю, что это была бы плохая практика, я не буду использовать отдельный файл для отношений, я также подчеркнул, что теперь мне не нужно будет выполнять поиск и замену. Так что все, что мне действительно нужно знать как искать значения в словаре и переписывать файл на основе этого (извините, вы прошли через усилие написания этого кода :(), я снова посмотрю на это завтра и посмотрю, смогу ли я конденсировать проблему до что-то с немного меньшей двусмысленностью – Cubbs

0

Как ваша программа знает компоненты каждого элемента? Я предлагаю вам сохранить два файла: один со стоимостью атомных предметов (яйца) и другой с рецептами (омлет < = 5 яиц).

Прочтите оба файла. Храните атомные затраты, помня, сколько из них у вас есть, atomic_count. Расширьте эту таблицу из файла рецептов, по одной строке за раз. Если рецепт, который вы читаете, целиком состоит из предметов с известными затратами, затем вычислите стоимость и добавьте этот элемент в «известный» список. В противном случае добавьте рецепт в «более поздний» список и продолжите.

Когда вы достигнете конца обоих входных файлов, у вас будет список известных затрат и несколько других рецептов, которые зависят от элементов, расположенных дальше по файлу рецепта. Теперь переходите через этот «неизвестный» список, пока (а) он не будет пустым; (б) у вас нет ничего со всеми известными ингредиентами. Если случай (b), у вас что-то не так с вашим вводом: либо ингредиент без определения, либо круговая зависимость. Распечатайте оставшийся список рецептов и отлаживайте свои входные файлы.

В случае (a), теперь вы готовы распечатать список продуктов. Пройдите через свой «известный» список и выпишите один предмет или рецепт за раз. Когда вы перейдете к элементу [atomic_count], напишите второй файл, новый список рецептов. Это ваш старый список рецептов, но в полезном порядке сверху вниз. В будущем у вас не будет никаких «неизвестных» рецептов после первого прохода.

Для будущих изменений ... не беспокойтесь. У вас есть только 173 элемента, и список кажется маловероятным, чтобы он вырос до 500. Когда вы меняете или добавляете элемент, просто отредактируйте файл и перезапустите программу. Это будет быстрее, чем алгоритм замены строк, который вы пытаетесь написать.

Таким образом, я предлагаю вам выполнить только начальную задачу вычисления, что довольно просто, чем добавление обновления строки. Не делайте инкрементных обновлений; переделайте весь список с нуля. Для такого небольшого списка компьютер будет делать это быстрее, чем вы можете писать и отлаживать дополнительное кодирование.

0

Я до сих пор не совсем уверен, что вы просите, но это то, что я придумал ...

from collections import OrderedDict 

food_map = {'omelette': {'eggs': 5, 'price': None}, 'pileofomelettes': {'eggs': 25, 'price': None}, 'eggs': {'price': 5}} 

with open('food.txt', 'rb') as f: 
    data = f.read().splitlines() 

data = OrderedDict([(x[0], int(x[1])) for x in [x.split(': ') for x in data]]) 

for key, val in data.items(): 
    if key == 'eggs': 
     continue 
    food_rel = food_map.get(key, {}) 
    val = food_rel.get('eggs', 1) * food_map.get('eggs', {}).get('price', 1) 
    data[key] = val 

with open('out.txt', 'wb') as f: 
    data = '\n'.join(['{0}: {1}'.format(key, val) for key, val in data.items()]) 
    f.write(data) 
+0

Да, я думаю, что функция OrderedDict будет очень полезной - она ​​вернет что-то по линии {"eggs": 5, "omelette": 20, "pileofomelettes": 120}? Потому что, если это так, то все, что я хочу сделать, это написать много отдельных утверждений, которые просто (отношения, которые я буду жестко кодировать) обновить значения, хранящиеся в словаре – Cubbs

Смежные вопросы