0

I am trying to make a function that will extract data from a .txt in the format 'Sample 1: 1, 2, 7' and then replace the first value, pushing the other two along and removing the last one. When I input '4', I would expect the following output: 'Sample 1: 4, 1, 2', however the data does not change. I am not searching for a value, as the code iterates through each line in the file and changes a specific part of it. It does not replace the whole line.

Here is my code:

f = open("task3.txt")

lines = f.readlines()
print(lines)

for i in lines:
    splitlines = i.split(":")
    print(splitlines)
    splitnums = splitlines[1].split(", ")
    print(splitnums)
    for i in splitnums:
        i = int(i)
    edit = input('Would you like to edit this entry?')
    if edit == "Yes":
        valueNew = input("Which new value would you like to add?")
        del(splitnums[2])
        splitnums.append(splitnums[1] + "\n")
        splitnums[1] = splitnums[0]
        splitnums[0] = valueNew
        print(splitnums)
        numstring = ''.join(splitnums)
        splitlines.append(splitlines[1])
        splitlines[1] = ": "
        newval = ''.join(splitlines)
        newval = str(newval)
        i = str(i)
        print(newval)
        i.replace(i, newval)
    else:
        print("Okay.")

f.close

Also, the text in the file is not replaced. Thanks for any help you can offer.

lagy159
  • 5
  • 3
  • possible duplicate of [Search and replace a line in a file in Python](http://stackoverflow.com/questions/39086/search-and-replace-a-line-in-a-file-in-python). The thing is you're currently just manipulating local variables (and in the case of `i.replace(i, newval)` not even that because python strings are immutable. Finally you need to actually write the data out in order for the change to take place. – Scis Mar 25 '15 at 09:00
  • What exactly do you want as output? I have tested this code and get `['4', '1', '2\n']`. The file does not get changed because you are not doing anything to write to it. – Stuart Mar 25 '15 at 09:02

3 Answers3

0

You're creating numstring on line 21 (numstring = ''.join(splitnums)) but are not using that to create splitlines. Furthermore, what you seem to be implementing looks like a fixed-length LIFO collection. Typically a deque is suitable for that task.

When it comes to editing a file in place, having a look at the fileinput module might help you out! A snippit to get you started:

import fileinput

def process(line):
    return 'Replaced line with static text'

with fileinput.input(files=('task3.txt'), inplace=True) as f:
    for line in f:
        print(process(line))
Joost
  • 4,094
  • 3
  • 27
  • 58
0

There is no need for all the string and integer conversion in your code, and you are not doing anything to write the data back to the file. You can add the new value to the line with something like [new_value] + numbers[:-1], and then use .format to write this back to the file in the correct format.

with open('task3.txt') as f:
    lines = f.readlines()

with open('task3.txt', 'w') as output:
    for line in lines:
        edit = input('Would you like to edit this entry?').lower()
        if edit == 'yes':
            heading, data = line.split(':')
            numbers = data.split(', ')
            new_value = input('Which new value would you like to add?')
            numbers = [new_value] + numbers[:-1]
            output.write('{}: {}\n'.format(heading, ', '.join(numbers)))
        else:
            output.write(line + '\n')
Stuart
  • 9,597
  • 1
  • 21
  • 30
0

Do not use same variable name.

In code variable i is assign in two places. In for i in lines: and for i in splitnums: , So i is store value of latest. So Avoid this.


Use string lower() method.

As we are asking User to enter Yes word for processing, so better to strip and convert to lower case.

Demo

>>> edit = raw_input("Enter Yes to process:").strip().lower()
Enter Yes to process:             YES
>>> edit
'yes'

Algo: 1. Iterate every line from the lines. 2. Ask user to edit values or not by raw_input() method. 3. If yes, then ask user to enter digit string. 4. Split line by : and get two different part, first is before : and second is after : 5. Create list of second part by split of , and list compression to remove white spaces. 6. Remove second item from the step 5 list 7. Insert user value in to step 5 list. 8. Create new line.

Sample Code:

lines = ["Sample 1: 1, 2, 7", "Sample 1: 11, 12, 17" ]
new_lines = []

for line in lines:
    edit = raw_input('Would you like to edit this entry, Yes/No?').strip().lower()
    if edit== "yes":
        valueNew = raw_input("Which new value would you like to add?")
        #- Split line by :
        splitlines = line.split(":")
        print "\nDebug 1: Split Line by ':' - ", splitlines
        #- Get numners part and remove white spaces.
        splitnums = [i.strip() for i in splitlines[1].split(",")]
        print "Debug 2: Split Numbers -", splitnums
        #- Remove second element.
        del splitnums[2]
        splitnums.insert(0, valueNew)
        print "Debug 3: After adding New Number -",splitnums 
        new_line = splitlines[0]+ ":"+ ', '.join(splitnums)
        print "Debug 4: New Line -", new_line
        new_lines.append(new_line)
    else:
        new_lines.append(line)


print "\nFinal New Lines:", new_lines

Output:

infogrid@infogrid-vivek:~/workspace/vtestproject/study$ python test1.py
Would you like to edit this entry, Yes/No?yes
Which new value would you like to add?77

Debug 1: Split Line by ':' -  ['Sample 1', ' 1, 2, 7']
Debug 2: Split Numbers - ['1', '2', '7']
Debug 3: After adding New Number - ['77', '1', '2']
Debug 4: New Line - Sample 1:77, 1, 2
Would you like to edit this entry, Yes/No?no

Final New Lines: ['Sample 1:77, 1, 2', 'Sample 1: 11, 12, 17']

Note: Use raw_input() for Python 2.x

Use input() for Python 3.x

Vivek Sable
  • 9,938
  • 3
  • 40
  • 56
  • Given that you're noting a difference between Python 2 and 3, don't you think it would be appropriate to use Python 3 throughout the suggested code? Py3k was _6 years ago_. – Joost Mar 25 '15 at 13:10