Как изменить последнее значение строки в файле .csv - PullRequest
0 голосов
/ 11 июля 2019

Я создаю список дел, используя CLI, и я хочу изменить последнее значение строки, т. Е. Статус с «Incomplete» на «Complete»

Я знаю, что мы не можем так просто отредактировать CSV-файл, поэтому нам нужно прочитать его, изменить значение и перезаписать существующий файл. вот CSV-файл: https://drive.google.com/open?id=1fqc79mtVmZGZ_pb_2zrzDGVDmyMFWi6C Я попробовал это:

import csv
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-o', '--option', metavar='', help='-o <option> write either you want to add or view')
parser.add_argument('-l', '--select', metavar='', help='-l <used to select the task for modification')
args = parser.parse_args()


    def modify():
        select = args.select
        with open('csv.csv', 'r+', newline='') as file:
            lines = list(file)
            lines[int(select)][7] = 1
        with open('csv.csv', 'w+', newline='') as ifile:
            writer = csv.writer(ifile)
            writer.writerows(lines)

Я хочу, чтобы, когда мы запустили это:

python todoarg.py -o modify -l 2

изменяет статус 2-й строки с 'Incomplete' на 'Complete'

Ответы [ 2 ]

1 голос
/ 12 июля 2019

Я нашел способ сделать это и без панд:

    def modify():
        with open("csv.csv", 'r+') as f:
            lines = f.readlines()
            f.seek(0)

            task = args.select

            for line in lines:
                if not task in line.split(',')[0]:
                    f.write(line)
            for line in lines:
                if task in line.split(',')[0]:
                    #what we do here is print existing values using their index
                    #with split function and adding 'Complete' instead of
                    #6th index which was 'Incomplete'
                    f.write('\n' + line.split(',')[0] + ',' + line.split(',')[1] + ',' + line.split(',')[2] + ','
                            + line.split(',')[3] + ',' + line.split(',')[4] + ','
                            + line.split(',')[5] + ',' + 'Complete')

            f.truncate()

Я знаю, что это новый способ, но он отлично работает LOL

0 голосов
/ 11 июля 2019

Вы были близки, я посмотрел на ваш CSV и, так как у вас есть строка заголовка, я думаю, что будет полезно использовать ваш S.No в качестве уникального идентификатора задачи:

import pandas as pd
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-o', '--option', metavar='', help='-o <option> write either you want to add or view')

# Here I added the action="append"
parser.add_argument('-l', '--select', metavar='', help='-l <used to select the task for modification', action="append")
args = parser.parse_args()


def modify(filename, taskids):
    taskids = list(map(int, taskids))  # just to change from str to int for your taskids
    df = pd.read_csv(filename, sep=";")
    df.loc[df["S.No"].isin(taskids), "Status"] = "complete"
    df.to_csv(filename, sep=";", index=False)

modify("csv.csv", args.select)

Я использую фрейм данных Pandas, чтобы упростить его. Строка df.loc[...] предназначена для выбора каждой строки, где S.No - это один из идентификаторов вашей задачи, указанных в командной строке, и для изменения столбца Status на «complete».

Также я внес небольшое изменение, которое, я думаю, может вас заинтересовать: я просто добавил небольшой action="append" в ваш парсер для опции select. Это означает, что вы сможете изменить несколько задач одновременно, выполнив что-то вроде:

python todoarg.py -o modify -l 2 -l 6 -l 3

Для вашего параметра option я могу порекомендовать вам использовать аргумент choices в анализаторе:

parser.add_argument(
    "-o", "--option",
    type    = str,
    choices = [
        "modify",
        "add",
        "cook_a_turkey"
    ],
    default = "modify",  # you can even use a default choice if the parameter is not given
    metavar = "",
    help    = "some help"
)

И для того, чтобы выбрать, какой метод использовать на основе значения, данного параметру option, я не думаю, что у меня есть хороший способ сделать это, но, возможно, что-то подобное может работать:

my_methods = {
    "modify": modify,  # they keys are the same as provided in the choices in the argument parser
    "add": add_task,
    "cook_a_turkey": cook_that_turkey,
}
# And you can call the function like this: However you will have to change a bit your functions to parse the arguments in each of them.
my_methods[parser.option]("csv", args)

# For instance the modify will become:
def modify(filename, args):
    taskids = list(map(int, args.select))
    # ...
def add_task(filename, args):
    # do stuff
def cook_that_turkey(filename, args):
    # your grandma recipe
...