Сохранение нескольких CSV-файлов с разными именами, которые меняются в зависимости от значения переменной - python - PullRequest
0 голосов
/ 28 марта 2020

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

Моя программа будет постоянно получать автомобильные данные, и я хочу сохранить их в несколько файлов CSV. Я хочу сэкономить на каждом круге. Так что для Lap1 у меня будет что-то вроде car_data_1.csv, для второго круга car_data_2.csv и так далее.

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

Итак, в приведенном ниже коде, когда я создаю строку with open ('car_data_(LapNumber).csv', 'w') as csv_file:, я хочу, чтобы программа создала файл с именем car_data_1, поскольку я начну на 1-м круге. Итак, LapNumber (внутри парантеза в этой строке просто чтобы показать вам) это имя моей переменной, которая будет меняться, и я хотел бы сохранить каждый CSV с данными, соответствующими каждому кругу.

import socket
import csv

'''UDP SET UP'''

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
UDP_IP = 'IP'
UDP_PORT = Port

sock.bind((UDP_IP, UDP_PORT))

'''CSV SET UP'''

fieldnames = ["On","Time","LapNumber","Engine","Speed","Power","BestLap","Distance"]

LapNumber=1

with open(f'car_data_{LapNumber}.csv','w') as csv_file:
    csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
    csv_writer.writeheader()

while True:

    data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
    values = struct.unpack("<iIffffff",data)

    LapNumber = values[2]

    with open(f'car_data_{LapNumber}.csv','a') as csv_file:
        csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
        #csv_writer.writeheader()

        info = {
            "On"    :values[0],
            "Time"  :values[1],
            "LapNumber" :values[2],
            "Engine"    :values[3],
            "Speed" :values[4],
            "Power" :values[5],
            "BestLap"   :values[6],
            "Distance"  :values[7],         
        }

        csv_writer.writerow(info)

Я понимаю, что, возможно, мне придется изменить структуру, потому что я думаю, что мне придется создать CSV внутри условного while или что-то в этом роде, потому что, если я создаю CSV и приложение значения внутри while будут постоянно перезаписывать значения в CSV, а я получу только последний набор значений (до пересечения линии для следующего круга).

Какие у вас предложения? Я думал добавить несколько for и if, поэтому дайте мне знать, что вы, ребята, считаете лучшим вариантом. Этот проект является недавним, и я делаю шаг за шагом, чтобы убедиться, что все работает, и теперь я хочу улучшить программу.

Спасибо за вашу помощь, пожалуйста, дайте мне знать, если вам нужна дополнительная информация , Я использую windows, python 3.8 и pycharm.

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Вам необходимо использовать переменную формата в имени файла

with open('car_data_{}.csv'.format(LapNumber),'w')

Теперь переменная LapNumber подставляется в строку вместо {}

или, если вы используете Python 3,6 или более поздней версии, используйте f-строки

with open(f'car_data_{LapNumber}.csv','w')

Ваш текущий подход создает имя файла 'car_data_ (LapNumber.csv)' и фактически не подставьте переменную в строку.

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

Что-то вроде;

# Initialise writing_lap to lap number 1
writing_lap = 1
while True:

    data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
    values = struct.unpack("<iIffffff",data)

    # Read the current lap
    current_lap = values[2]

    with open(f'car_data_{writing_lap}.csv','a') as csv_file:
        csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
        if current_lap > writing_lap:
             # If the current_lap has increased, write the headers
             csv_writer.writeheader()
             # And remember to update the writing_lap variable
             writing_lap = current_lap

        info = {
            "On"    :values[0],
            "Time"  :values[1],
            "LapNumber" :values[2],
            "Engine"    :values[3],
            "Speed" :values[4],
            "Power" :values[5],
            "BestLap"   :values[6],
            "Distance"  :values[7],         
        }

        csv_writer.writerow(info)

0 голосов
/ 28 марта 2020

Поскольку wstk ответил на ваш первый вопрос, ваш второй в комментарии касается добавления заголовка в новый файл. (Я не могу комментировать, потому что у меня недостаточно репутации)

Чтобы добавить заголовок к каждому новому CSV-файлу, вы можете проверить, когда меняется LapNumber, и добавить заголовок прямо здесь.

Например, , внутри while l oop:

#LapNumber = values[2] --> you just need to move this line as below
#instead of putting LapNumber inside {}, you can just put values[2], and use 
#LapNumber for checking the condition of writing the header

with open(f'car_data_{values[2]}.csv','a') as csv_file:
    csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
    if values[2] != LapNumber:
        csv_writer.writeheader()
        LapNumber = values[2]

Теперь ваш скрипт пишет заголовок только при создании нового файла.

...