CSV File Cell Slicer -- python campo con beginner campo con python-3.x campo con csv camp codereview Relacionados El problema

CSV file cell slicer


1
vote

problema

Español

Se supone que este programa encuentra y cortar cualquier celda dentro de un archivo CSV que contenga más de un número definido de caracteres.

Los archivos pueden ser bastante grandes, por lo que es un principiante que me gustaría saber si está escrito correctamente, y si podría hacerlo más eficiente. Una de las líneas también tiene más de 80 caracteres de longitud, lo que me molesta.

  import configparser, csv, sys  if len(sys.argv) < 3 :         usage = """Usage: %s [inputfile][output file] This program requires 2  arguments to function properly. [input file] is the file to clean [output fil e] is the name of the file that will be created as a result of this program """         print(usage % (sys.argv[0])) else :         #reads the config file         config = configparser.ConfigParser()         config.read('csv_cleaner.ini')         config = config['CONFIG']         encoding = config['character_encoding']         size = int(config['truncation_size'])         #opens target file and creates the receiving one         with open(sys.argv[1], 'r', newline='', encoding=encoding)as csv_file,               open(sys.argv[2],'x', newline='', encoding=encoding)as output_file:                 #helps with parsing                 if config['detect_dialect'] :                         dialect = csv.Sniffer().sniff(csv_file.read(2048))                         dialect.escapechar = '\'                         #return to beginning of file                         csv_file.seek(0)                         #creates reader and writer                         reader = csv.reader(csv_file, dialect)                         dialect.delimiter = config['delimiter_in_output']                         writer = csv.writer(output_file, dialect)                         #loops through file's lines                         for row in reader :                                 #slices cells and loops through line's columns                                 row=[col[:(size-2)]+(col[(size-2):]and'..')for col in row]                                 #writes in new file                                 writer.writerow(row)   

Este programa utiliza un archivo de configuración:

  [CONFIG] character_encoding = UTF-8 delimiter_in_output = ; #set this option to False if the file is not recognized detect_dialect = True truncation_size = 255   
Original en ingles

This program is supposed to find and slice any cell within a CSV file which contains more than a defined number of characters.

The files can be pretty large, so being a beginner I would like to know if it is written correctly, and if I could make it more efficient. One of the lines is also more than 80 characters long, which bothers me.

import configparser, csv, sys  if len(sys.argv) < 3 :         usage = """Usage: %s [inputfile][output file]\nThis program requires 2 \ arguments to function properly.\n[input file] is the file to clean\n[output fil\ e] is the name of the file that will be created as a result of this program\n"""         print(usage % (sys.argv[0])) else :         #reads the config file         config = configparser.ConfigParser()         config.read('csv_cleaner.ini')         config = config['CONFIG']         encoding = config['character_encoding']         size = int(config['truncation_size'])         #opens target file and creates the receiving one         with open(sys.argv[1], 'r', newline='', encoding=encoding)as csv_file, \              open(sys.argv[2],'x', newline='', encoding=encoding)as output_file:                 #helps with parsing                 if config['detect_dialect'] :                         dialect = csv.Sniffer().sniff(csv_file.read(2048))                         dialect.escapechar = '\\'                         #return to beginning of file                         csv_file.seek(0)                         #creates reader and writer                         reader = csv.reader(csv_file, dialect)                         dialect.delimiter = config['delimiter_in_output']                         writer = csv.writer(output_file, dialect)                         #loops through file's lines                         for row in reader :                                 #slices cells and loops through line's columns                                 row=[col[:(size-2)]+(col[(size-2):]and'..')for col in row]                                 #writes in new file                                 writer.writerow(row) 

This program uses a config file :

[CONFIG] character_encoding = UTF-8 delimiter_in_output = ; #set this option to False if the file is not recognized detect_dialect = True truncation_size = 255 
           

Lista de respuestas

1
 
vote

La mejora principal que puede obtener es separar sus inquietudes. Actualmente analizando la línea de comandos, analizando el archivo de configuración y, en realidad, truncando las columnas se trata de un poco de mezcla. En su lugar, escriba funciones cortas para cada una de estas cosas:

      public static boolean isPalindrome(String s) {         for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {             if (s.charAt(i) != s.charAt(j)) {                 return false;             }         }          return true;     } 2  

Aquí hice los siguientes cambios adicionales:

  • Según la Guía de estilo oficial de Python, pep8 , las líneas deben ser sangrado por 4 espacios. También los espacios deben rodear a los operadores y palabras clave. Las importaciones también deben estar en líneas separadas.
  • Mientras public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 3 funciona, encuentro public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 4 un poco más legible.
  • Cuando public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 5 es falso en su caso, el script no debe ejecutarse (ya que todo está anidado bajo eso si). Pero dado que el valor es una cadena, es veracente, independientemente de si pone o no public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 6 o public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 7 allí.
  • Cuando utilice una cadena de línea múltiple con las cotizaciones triples, no es necesario usar las salidas de línea explícitas y los caracteres de continuación. Lo hice una constante global aquí para evitar problemas de sangría.

Tenga en cuenta que i (o más bien, mi linter) piensa que public static boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } 8 no es un modo de archivo válido.

 

The main improvement you can get is separating your concerns. Currently parsing the commandline, parsing the config file and actually truncating the columns is all mashed up together. Instead write short functions for each of these things:

import configparser import csv import sys  USAGE = """ Usage: %s [inputfile] [output file] This program requires 2 arguments to function properly. [input file] is the file to clean [output file] is the name of the file that will be created as a result of this program """   def read_config(file_name):     config = configparser.ConfigParser()     config.read(file_name)     return config['CONFIG']   def detect_dialect_from_file(csv_file):     dialect = csv.Sniffer().sniff(csv_file.read(2048))     dialect.escapechar = '\\'     # return to beginning of file     csv_file.seek(0)     return dialect   def truncate_row(row, size):     return [col if len(col) <= size else col[:size - 2] + ".." for col in row]   def truncate_cells(csv_file_name, output_file_name, encoding, size,\                    output_delimiter, detect_dialect, **kwargs):     # opens target file and creates the receiving one     with open(csv_file_name, 'r', newline='', encoding=encoding) as csv_file,\          open(output_file_name, 'x', newline='', encoding=encoding) as output_file:         # helps with parsing         dialect = (detect_dialect_from_file(csv_file)                    if detect_dialect                    else "excel")         reader = csv.reader(csv_file, dialect)         dialect.delimiter = output_delimiter         writer = csv.writer(output_file, dialect)         # loops through file's lines         for row in reader:             # writes in new file             writer.writerow(truncate_row(row, size))   def main():     print(len(sys.argv))     if len(sys.argv) < 3:         print(usage % (sys.argv[0]))         sys.exit(1)     # reads the config file     config = read_config('csv_cleaner.ini')     config['size'] = int(config['truncation_size'])     config['detect_dialect'] = bool(config['detect_dialect'])      truncate_cells(sys.argv[1], sys.argv[2], **config)   if __name__ == "__main__":     main() 

Here I made the following additional changes:

  • According to Python's official style-guide, PEP8, lines should be indented by 4 spaces. Also spaces should surround operators and keywords. Imports should also be on separate lines.
  • While [col[:(size-2)]+(col[(size-2):]and'..')for col in row] works, I find [col if len(col) <= size else col[:size - 2] + ".." for col in row] a bit more readable.
  • When detect_dialect is false in your case, the script should not run (since it is all nested under that if). But since the value is a string, it is truthy, regardless of whether or not you put True or False there.
  • When using a multiple line string using triple-quotes, there is no need to use explicit line-breaks and line-continuation characters. I made it a global constant here to avoid indentation issues.

Note that I (or rather my linter) think that 'x' is not a valid file mode.

 
 
   
   

Relacionados problema

4  73 líneas de mayhem - analizar, ordenar y guardar en CSV en PHP CLI  ( 73 lines of mayhem parse sort and save to csv in php cli ) 
Dentro de una carpeta llamada dispatch_sync(dispatch_get_main_queue(), ^{1 Tengo 138 archivos de texto (un total de 349 MB) lleno de direcciones de correo e...

4  Vectorizamos la prueba exacta de Fisher  ( Vectorize fishers exact test ) 
Tengo dos marcos de datos / listas de datos, humanSplit 9988776655544331 , y son del formulario > ratSplit$Kidney_F_GSM1328570 ratGene ratRepli...

8  Python CSV a XML Converter  ( Python csv to xml converter ) 
Estoy creando una aplicación que se lee en los datos de un archivo CSV y crea un archivo XML usando LXML. El siguiente código funciona como se esperaba. Sin e...

24  Generando cuerdas CSV para varias utilidades de terceros  ( Generating csv strings for various 3rd party utilities ) 
Estoy generando cuerdas de CSV para varias utilidades de terceros y esta sección del código se repite en muchas clases. ¿Hay una mejor manera de generar esta ...

6  Herramientas de línea de comandos para formatear tablas  ( Command line tools to format tables ) 
Soy un gran fanático de un revestimiento usando sed awk 9988777665544332 y otras herramientas. Pero hay cosas difíciles de hacer en una sola línea, como...

5  Analice un archivo CSV y devuelva un objeto o matriz  ( Parse a csv file and return an object or array ) 
Recientemente publiqué un módulo de JavaScript para NPM que también está disponible on Github por el nombre de Rawiki-Pars-CSV. El código lleva datos RAW C...

3  Cómo pedir a un usuario a guardar y regenerar algunas entradas en un archivo  ( Prompting a user to save and regenerate some entries in a file ) 
Quiero eliminar mi goto en este código, pero no estoy seguro de cómo. Debe haber una forma más limpia de escribir mi código. Tal vez mueva la declaración "IF"...

7  La forma más rápida de escribir un archivo CSV grande en Python  ( Fastest way to write large csv file in python ) 
Soy bastante nuevo para Python y Pandas, pero tratando de mejorar con él para analizar y procesar archivos de datos grandes. Actualmente estoy trabajando en u...

3  Determinar los promedios de columnas  ( Determine column averages ) 
Estoy tratando de escribir código de TERSE PERL para calcular el promedio de cada columna en un archivo. El archivo puede tener & gt; = 1 columnas. use str...

1  Copiando CSV a SQL_Table  ( Copying csv to sql table ) 
Escribí el código que lleva CSV y expórtelo a la tabla SQL. Parece esto: output_leftBound()1 Este método creará una tabla basada en la variable de nombr...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos