Python con palabras clave alternativas -- python campo con python-2.x campo con language-design camp codereview Relacionados El problema

Python with alternative keywords


11
vote

problema

Español

hace un tiempo, un usuario en Rompecabezas y código de programación Golf tuvo una idea:

¿Qué tal un idioma donde todos los comandos principales son los nombres de usuario de PPCG? - Helka HOMBA

Se hizo una lista de pares de nombre de usuario / (palabra clave | Función incorporada), pero nadie realmente quería hacer el código, por lo que un poco se sujetó.

Recientemente (lee: ayer) otro usuario sugirió usando el módulo 9988777665544330 , Así que lo hice. Con su ayuda, Terminé un código PY2 para reemplazar los nombres . < / p>

Aquí está mi código:

  import tokenize import ast import sys    def handle_token(type, token, (srow, scol), (erow, ecol), line):     # Return the info about the tokens, if it's a NAME token then replace it      if tokenize.tok_name[type] == "NAME":         token = token_names.get(token, token)     return (type, token, (srow, scol), (erow, ecol), line)   def run(assignments="assignments.txt",open_from="peoples.txt"):     with open(assignments, "r") as f:         # Read the replacements into token_names         global token_names         token_names = ast.literal_eval(f.read())      with open(open_from) as source:         # Get the tokenized version of the input, replace it, and untokenize into pretty output         tokens = tokenize.generate_tokens(source.readline)         handled_tokens = (handle_token(*token) for token in tokens)          output = tokenize.untokenize(handled_tokens)      with open(open_from[:-4]+"-output.txt",'w') as outfile:         # Write to the output file         outfile.write(output)      return output   if __name__ == "__main__":     if len(sys.argv) > 1:         if len(sys.argv) > 2:             try:exec run(assignments=sys.argv[1],open_from=sys.argv[2])             except:pass         else:             try:exec run(assignments=sys.argv[1])             except:pass     else:         try:exec run()         except:pass   

Este es el contenido de main.py . Utiliza assignments.txt , que es un archivo que contiene un dict de Python de los pares de reemplazo.

  {"Martin":"False", "Geobits":"None", "Dennis":"True", "adnan":"and", "rainbolt":"as", "buttner":"assert", "flawr":"break", "aditsu":"class", "katenkyo":"continue", "quill":"def", "nathan":"del", "hobbies":"elif", "helkahomba":"else", "irk":"except", "ender":"finally", "peter":"for", "conor":"from", "gnibbler":"global", "calvins":"if", "obrien":"import", "taylor":"in", "fryamtheeggman":"is", "starman":"lambda", "sp3000":"nonlocal", "phinotpi":"not", "xnor":"or", "maltysen":"pass", "mego":"raise", "alex":"return", "easterly":"try", "molarmanful":"while", "minxomat":"with", "optimizer":"yield", "mbomb007":"abs", "digital":"all", "trauma":"any", "asciionly":"ascii", "zyabin":"bin", "bkul":"bool", "chris":"chr", "jesteryoung":"classmethod", "elendia":"enumerate", "gcampbell":"eval", "fatalize":"filter", "sandbox":"help", "zgarb":"id", "phase":"input", "loovjo":"int", "minibits":"issubclass", "lynn":"len", "doorknob":"map", "upgoat":"max", "briantompsett":"memoryview", "downgoat":"min", "jimmy23013":"open", "destructiblewatermelon":"ord", "ninjabearmonkey":"pow", "you":"print", "djmcmayhem":"range", "qwerpderp":"round", "orlp":"sorted", "timmyd":"staticmethod", "muddyfish":"sum", "balint":"super", "trichoplax":"tuple", "quartata":"zip"}   

un ejemplo peoples.txt :

  peter i taylor djmcmayhem(10):     you(list(set(i)))   

debe emitir:

  for i in range(10):     print(list(set(i)))   

¿Qué hace el código? Se necesita en un archivo de entrada (por defecto peoples.txt

en el mismo directorio main.py ) y lo traduce de "Python de la gente" a Python estándar, y ejecuta el resultado. También escribe el código "normal" compilado en import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 0 , de forma predeterminada import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 1

Ejecute como import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 2 ( import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 3 es el código Python Pople's y 99887766555443314 es el DICT de las asignaciones que está utilizando)

En términos de estilo, ¿cómo puedo mejorar esto?

Las cosas que doy cuenta:

  • probablemente podríamos más comentarios más.

  • Reemplace import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 5 Con otro método que no implica usarlo NYNESE EVAL. Sin estar seguro si esto es incluso posible. ¿La mejor práctica diría para incluir el diccionario masivo en import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 6 ?

  • está usando en blanco import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 7 s sin un error especial (I.E. import tokenize import ast import sys def handle_token(type, token, (srow, scol), (erow, ecol), line): # Return the info about the tokens, if it's a NAME token then replace it if tokenize.tok_name[type] == "NAME": token = token_names.get(token, token) return (type, token, (srow, scol), (erow, ecol), line) def run(assignments="assignments.txt",open_from="peoples.txt"): with open(assignments, "r") as f: # Read the replacements into token_names global token_names token_names = ast.literal_eval(f.read()) with open(open_from) as source: # Get the tokenized version of the input, replace it, and untokenize into pretty output tokens = tokenize.generate_tokens(source.readline) handled_tokens = (handle_token(*token) for token in tokens) output = tokenize.untokenize(handled_tokens) with open(open_from[:-4]+"-output.txt",'w') as outfile: # Write to the output file outfile.write(output) return output if __name__ == "__main__": if len(sys.argv) > 1: if len(sys.argv) > 2: try:exec run(assignments=sys.argv[1],open_from=sys.argv[2]) except:pass else: try:exec run(assignments=sys.argv[1]) except:pass else: try:exec run() except:pass 8 ) ¿Está bien en esta situación?

Original en ingles

A while ago, a user on Programming Puzzles and Code Golf had an idea:

How about a language where all of the core commands are PPCG usernames? -- Helka Homba

A list was made of username/(keyword|builtin function) pairs, but nobody really wanted to actually make the code, so it kinda went on hold.

Recently (read: yesterday) another user suggested using the tokenize module, so I did. With his help, I finished some py2 code for replacing the names.

Here is my code:

import tokenize import ast import sys    def handle_token(type, token, (srow, scol), (erow, ecol), line):     # Return the info about the tokens, if it's a NAME token then replace it      if tokenize.tok_name[type] == "NAME":         token = token_names.get(token, token)     return (type, token, (srow, scol), (erow, ecol), line)   def run(assignments="assignments.txt",open_from="peoples.txt"):     with open(assignments, "r") as f:         # Read the replacements into token_names         global token_names         token_names = ast.literal_eval(f.read())      with open(open_from) as source:         # Get the tokenized version of the input, replace it, and untokenize into pretty output         tokens = tokenize.generate_tokens(source.readline)         handled_tokens = (handle_token(*token) for token in tokens)          output = tokenize.untokenize(handled_tokens)      with open(open_from[:-4]+"-output.txt",'w') as outfile:         # Write to the output file         outfile.write(output)      return output   if __name__ == "__main__":     if len(sys.argv) > 1:         if len(sys.argv) > 2:             try:exec run(assignments=sys.argv[1],open_from=sys.argv[2])             except:pass         else:             try:exec run(assignments=sys.argv[1])             except:pass     else:         try:exec run()         except:pass 

This is the content of main.py. It uses assignments.txt, which is a file containing a python dict of the replacement pairs.

{"Martin":"False", "Geobits":"None", "Dennis":"True", "adnan":"and", "rainbolt":"as", "buttner":"assert", "flawr":"break", "aditsu":"class", "katenkyo":"continue", "quill":"def", "nathan":"del", "hobbies":"elif", "helkahomba":"else", "irk":"except", "ender":"finally", "peter":"for", "conor":"from", "gnibbler":"global", "calvins":"if", "obrien":"import", "taylor":"in", "fryamtheeggman":"is", "starman":"lambda", "sp3000":"nonlocal", "phinotpi":"not", "xnor":"or", "maltysen":"pass", "mego":"raise", "alex":"return", "easterly":"try", "molarmanful":"while", "minxomat":"with", "optimizer":"yield", "mbomb007":"abs", "digital":"all", "trauma":"any", "asciionly":"ascii", "zyabin":"bin", "bkul":"bool", "chris":"chr", "jesteryoung":"classmethod", "elendia":"enumerate", "gcampbell":"eval", "fatalize":"filter", "sandbox":"help", "zgarb":"id", "phase":"input", "loovjo":"int", "minibits":"issubclass", "lynn":"len", "doorknob":"map", "upgoat":"max", "briantompsett":"memoryview", "downgoat":"min", "jimmy23013":"open", "destructiblewatermelon":"ord", "ninjabearmonkey":"pow", "you":"print", "djmcmayhem":"range", "qwerpderp":"round", "orlp":"sorted", "timmyd":"staticmethod", "muddyfish":"sum", "balint":"super", "trichoplax":"tuple", "quartata":"zip"} 

An example peoples.txt:

peter i taylor djmcmayhem(10):     you(list(set(i))) 

Should output:

for i in range(10):     print(list(set(i))) 

What does the code do? It takes in an input file (by default peoples.txt in the same dir as main.py) and translates it from "People's Python" to standard python, and executes the result. It also writes the compiled "normal" code into <input_file_name>-output.txt, by default peoples-output.txt

Run as python main.py custom/assignments.txt path/to/inputfile.txt (inputfile.txt is the People's Python code and assignments.txt is the dict of assignments you're using)

In terms of style, how can I improve this?

The things I notice:

  • Probably could some more comments.

  • Replace ast.literal_eval with another method that doesn't involve using any eval. Not sure if this is even possible though. Would best practice say to just include the massive dictionary in main.py?

  • Is using blank except:s with no special error (i.e. except SyntaxError:) okay in this situation?

        
   
   

Lista de respuestas

9
 
vote
vote
La mejor respuesta
 

Algunas reflexiones sobre excepciones

(1) ¡Nunca pase cada excepción!

Básicamente lo estás absorbiendo todas las posibles excepciones sin utilidad. Normalmente, para evitar accidentes de tiempo de ejecución, hago esto con mi excepto cuando quiero coger todo:

      //Creating the main sudoku board     int sudokuGraph[][] = new int[9][9]; 8  

... lo que pondrá un mensaje mejor. Por supuesto, puede ampliar esto definiendo diferentes tipos para capturar en los bloques, excepto. Puede haber casos para esto, pero como este no es un desafío de código de golf, puede hacer esto aquí en su lugar.

(2) "en blanco" //Creating the main sudoku board int sudokuGraph[][] = new int[9][9]; 9 bloques

Hay una regla de pulgar que respeto: "En la mayoría de los casos, siempre debe intentar atrapar la excepción más estrecha que espera terminar al ver en un 99887776655443340 / public boolean attemptAssignValue(int leftIndex, int upIndex){ //Attempt to assign a value to the specified cell for(int x = 0; x < 10 ; x++){ if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 1 Bloque, con un bloque de "captura" definitivo más tarde para manejar cualquier excepción inesperada ". Eso básicamente significa que si estoy tratando de capturar un error "Invalid JSON" cuando se ejecuta public boolean attemptAssignValue(int leftIndex, int upIndex){ //Attempt to assign a value to the specified cell for(int x = 0; x < 10 ; x++){ if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 2 (verá por qué menciono esto más tarde), haría algo así:

      public boolean attemptAssignValue(int leftIndex, int upIndex){         //Attempt to assign a value to the specified cell         for(int x = 0; x < 10 ; x++){             if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 3  

En efecto, hacemos algo diferente con un public boolean attemptAssignValue(int leftIndex, int upIndex){ //Attempt to assign a value to the specified cell for(int x = 0; x < 10 ; x++){ if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 4 (podríamos pasar, o simplemente podríamos dejar de fumar, o podemos imprimir un buen mensaje como este), pero para todos los demás public boolean attemptAssignValue(int leftIndex, int upIndex){ //Attempt to assign a value to the specified cell for(int x = 0; x < 10 ; x++){ if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 5 no los capturará y aumentará la excepción que intentara aumentar. Sin embargo, digamos, esto fue en una función 998877766555443346655443346, y yo llamo a la función 998877766655443347 de una manera como lo hace en su código:

      public boolean attemptAssignValue(int leftIndex, int upIndex){         //Attempt to assign a value to the specified cell         for(int x = 0; x < 10 ; x++){             if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 8  

Dado que la mayoría de los errores heredan de la excepción, esto captura todos los demás errores, pero no las advertencias, esto le permitirá capturar excepciones no controladas y "manejarlas" como una "opción final", tipo de intento / excepto bloque, para cuando están 't Manejo en otros bloques debajo public boolean attemptAssignValue(int leftIndex, int upIndex){ //Attempt to assign a value to the specified cell for(int x = 0; x < 10 ; x++){ if(notContainedInRow(leftIndex, x) && notContainedInColumn(upIndex, x) && notContainedInSubGrid(leftIndex, upIndex, x)){ 9 directamente.

Siempre hay casos raros en los que desea hacerlo nada cuando sucede una excepción, por lo que puede usar leftIndex0 en esos casos, pero en el 99% de todos los casos, Debe no ser simplemente 'permitiendo que las excepciones pasen sin recaudar cierto aviso'.


reemplazar leftIndex1 con leftIndex2 en lugar

Los datos JSON son básicamente un 99887766555443353 . Dado que está almacenando un 99887766655443354 y cumple con el archivo JSON más básico, podemos analizar su archivo 998877766655443355 como JSON en su lugar, y retire el leftIndex6 y leftIndex7 . Esto lo requiere en leftIndex8 en lugar de leftIndex9 , pero este es un enfoque más sano:

  upIndex0  

De esta manera, no tenemos que preocuparnos por upIndex1 y tener una evaluación literal que podría causar el mal en el futuro. Esto también nos permite errores con una excepción si no tenemos un archivo de asignaciones válidas. (Y podemos manejarlo con mensajes de error personalizados si lo deseamos).

En cuanto al almacenamiento del 'dict masivo' en main.py, si es probable que se expanda en el futuro, déjelo en su propio archivo, y continúe cargándolo como un objeto JSON como lo ha hecho mi sugerencia aquí.


¡Esto no es código golf! Whitespace es algo bueno!

Su código es difícil de leer cuando intenta / excepto los bloques y todos están de golf para eliminar el espacio en blanco. Añadir espacios en blanco para la legibilidad.


No necesita que muchos intente / acepten bloques alrededor de las llamadas 'Ejecutar', y no necesita upIndex2 ¡Tampoco!

Tiene cuatro cuadras de intento separado / excepto, sin embargo, todo lo que hacen es silenciosamente deja que las excepciones pasen las excepciones. Teniendo en cuenta No sugiero usar 'Pass' en excepciones que podrían ser importantes, podemos simplemente tomar una página de mi libro y cambiar su código para tener un intento / excepto bloque envuelto alrededor de todos El upIndex3 Llamadas, y maneja excepciones siempre que surjan, sin tener intentos individuales / excepto bloques solo para cada llamada.

También no necesita el upIndex4 Llamadas que tiene aquí.

Entonces, en última instancia, ahorras algún código:

  upIndex5  

Sección de nitpicking

Aquí estoy poco aquí con algunos de su código, y trae más sugerencias que sean de naturaleza menor / estética, en lugar de fundamentales. Estas sugerencias se reflejan a continuación a continuación.

upIndex6 es en realidad una incorporada, use un Nombre diferente en upIndex7

Este es bastante obvio, pero upIndex8 es en realidad un incorporado. Sombreado incorporado es malo si eventualmente podría usar una versión incorporada, así que reemplace upIndex9 con row0 en row1 , para deshacerse de la " Sombras Problemas incorporados 'tipo' ".

paréntesis innecesario en 'retorno' en row2

No necesita los paréntesis alrededor del objeto 'retorno'. Devolverá todos los objetos que especifique como una tupla de todos modos, y opere a medida que lo esperamos.

she-bang line: row3 y row4 son idénticos

Nota: cuando esta respuesta fue escrita, el código aún no se había actualizado para reflejar la eliminación de la línea de SHEBANC. La línea de Shebang funciona, pero necesita ajustada según esta parte de la revisión; Se ha agregado nuevamente para este código, en consecuencia, porque es parte del código original , pero necesitaba un cambio de ajustes. Consulte el historial de revisiones para la pregunta original para más.

En la mayoría de los casos, las directrices actuales que row5 es Python 2 y 99887766555443376 es Python 3 de Python Upstream todavía está en juego. Considere cualquier sistema Linux: row77 es el intérprete de Python 3, pero una llamada a 99887776655443378 Cuando se instalan Python 2 y 3 es una llamada a Python 2.7. Debido a que row9 puede no existir en la ENV, está sano llamar column0 en lugar de column1 . Alternativamente, elimine la línea SHEBANG para que no pueda llamar al programa como un script directamente y tiene para invocar el archivo a través de una llamada a column2 con column3 .

USO DE UN column4 PERO NO DEFINIRLO EN EL NIVEL DE MÓDULO

Esto es más o menos que me agarró sobre Pycharm (mi IDE) siendo molesto. Informa que su uso de column5 no se define en el nivel del módulo. Si bien, en última instancia, esto no tiene un efecto real en la ejecución de su programa, puede evitar este aviso fácilmente solo poniendo column6 en el bloque antes de la prueba / excepto el bloque. Y hice esto, solo para suprimir la alerta IDE. (No afecta a la ejecución aparentemente, y todavía funciona como debería)



Este es su código con todas mis sugerencias desde arriba:

  column8 

 

Some Musings about Exceptions

(1) NEVER pass on every single exception!

You're basically absorbing every possible exception without usefulness. Normally, to prevent runtime crashes, I do this with my excepts when I want to catch all:

try:     # some code here... except Exception as e:     print "An exception has occurred:\n%s" % str(e) 

... which will put a nicer message. Of course, you can expand this by defining different types to capture in the except blocks. There may be cases for this, but since this isn't a code golf challenge, you can do this here instead.

(2) "Blank" except blocks

There's a rule of thumb that I abide by: "In most cases, you should always try and catch the most narrow exception that you expect to end up seeing in a try/except block, with an ultimate "catch-all" block later to handle any unexpected exceptions." That basically means that if I'm trying to catch an "Invalid JSON" error when running json.load (you'll see why I mention this later), I'd do something like this:

with open('jsondata.json', 'r') as f:     try:         data = json.load(f)     except ValueError:         print "Could not properly parse JSON data, is the file 'jsondata.json' comprised of actual JSON data?" 

In effect, we do something different with a ValueError (we could pass, or we could simply quit, or we can print a nice message like this does), but for all other Exceptions will not capture them and will raise whatever exception it was trying to raise. Let's say, though, this was in a run() function, and I call the run function in a manner like you do in your code:

if __name__ == "__main__":     try:         run()     except Exception as e:         print "An unhandled exception has occurred:\n%s" % str(e) 

Since most errors inherit from Exception this captures all other errors, but not warnings, this will allow for us to capture unhandled exceptions and 'handle' them as a "final option" type of try/except block, for when they aren't handled in other blocks below run directly.

There are always rare cases where you want to do nothing when an exception happens, so you can use pass in those cases, but in 99% of all cases, you should not be simply 'allowing exceptions to pass on without raising some notice'.


Replace ast with json instead

JSON data is basically a structured dict. Since you're storing a dict and it meets the most basic JSON formatting, we can just parse your assignments file as JSON instead, and remove the literal_eval and import ast. This does require you to import json instead of import ast but this is a more sane approach:

with open(assignments, "r") as f:     # Read the replacements into token_names     global token_names     token_names = json.load(f) 

This way, we don't have to worry about ast and having a literal evaluation that could cause evil in the future. This also permits us to error out proper with an exception if we don't have a valid assignments file. (And we can handle it with customized error messages if we wish).

As for storing the 'massive dict' in main.py, if it's likely to expand in the future leave it in its own file, and continue to load it as a JSON object as my suggestion here has.


This isn't code golf! Whitespace is a good thing!

Your code is hard to read when your try/except blocks and such are all golfed to remove whitespace. Add whitespace for readability.


You don't need that many try/accept blocks around your 'run' calls, and you don't need exec either!

You have four separate try/except blocks, yet all they do is silently let exceptions go by. Taking into account I don't suggest using 'pass' on exceptions that could be important, we can just simply take a page from my book, and change your code to have one try/except block wrapped around all the run calls, and handle exceptions whenever they come up, without having individual try/except blocks just for each call.

You also don't need the exec calls you have in here.

So, ultimately, you save some code:

if __name__ == "__main__":     try:         if len(sys.argv) > 1:             if len(sys.argv) > 2:                 run(assignments=sys.argv[1], open_from=sys.argv[2])              else:                 run(assignments=sys.argv[1])         else:                 run()     except Exception as e:         print "An exception has occurred:\n%s" % str(e) 

Nitpicking Section

I'mma nitpick a little here with some of your code, and bring more suggestions that are minor/aesthetic in nature, rather than code-critical. These suggestions are reflected below though.

type is actually a builtin, use a different name in handle_token

This one's fairly obvious, but type is actually a built-in. Shadowing built-ins is bad if you eventually could use a builtin, so let's replace type with type_ in handle_token, to get rid of the "Shadows built-in 'type'" problems.

Unnecessary parentheses on 'return' in handle_token

You don't need the parentheses around the 'return' object. It'll return all the objects you specify as a tuple anyways, and operate as we expect it to.

She-bang line: python2 and python are identical

NOTE: When this answer was written, the code had not yet been updated to reflect OP's removal of the shebang line. The shebang line works, but it needs tweaked as per this part of the review; it's added back in for this code, accordingly, because it's part of the original code, but needed a tweak. Refer to the revision history for the original question for more.

In most cases, the current guidelines that python is Python 2 and python3 is Python 3 from Python upstream are still in play. Consider any Linux system - python3 is the Python 3 interpreter, but a call to python when both Python 2 and 3 are installed is a call to Python 2.7. Because python2 may not exist in the env either, it's sane to call python instead of python2. Alternatively, remove the shebang line so you can't call the program as a script directly and have to invoke the file via a call to python with python main.py [args].

Use of a global but not defining it at the Module level

This is more or less me griping about PyCharm (my IDE) being annoying. It reports that your use of global token_names is not defined at the module level. While ultimately this has no real effect on the execution of your program, you can easily avoid this notice by just putting token_names = None in the if __name__ == "__main__": block right before the try/except block. And I did this, just to suppress the IDE alert. (It doesn't affect execution apparently, and still works as it should)



This is your code with all my suggestions from above:

#!/usr/bin/env python  import tokenize import sys import json   def handle_token(type_, token, (srow, scol), (erow, ecol), line):     # Return the info about the tokens, if it's a NAME token then replace it      if tokenize.tok_name[type_] == "NAME":         token = token_names.get(token, token)     return type_, token, (srow, scol), (erow, ecol), line   def run(assignments="assignments.txt", open_from="peoples.txt"):     with open(assignments, "r") as f:         # Read the replacements into token_names         global token_names         token_names = json.load(f)      with open(open_from) as source:         # Get the tokenized version of the input, replace it, and untokenize into pretty output         tokens = tokenize.generate_tokens(source.readline)         handled_tokens = (handle_token(*token) for token in tokens)          output = tokenize.untokenize(handled_tokens)      with open(open_from[:-4]+"-output.txt", 'w') as outfile:         # Write to the output file         outfile.write(output)      return output   if __name__ == "__main__":     token_names = None     try:         if len(sys.argv) > 1:             if len(sys.argv) > 2:                 exec run(assignments=sys.argv[1], open_from=sys.argv[2])              else:                 run(assignments=sys.argv[1])         else:                 run()     except Exception as e:         print "An exception has occurred:\n%s" % str(e) 
 
 
     
     

Relacionados problema

8  Implementación de programas de múltiples archivos en Vitsy  ( Implementing multi file programs in vitsy ) 
Soy el orgulloso propietario de la lenguaje de programación de Vitsy , con el que he estado trabajando para algún tiempo (excepto recientemente, porque la es...

4  Lexer con un combinador de analistas  ( Lexer with a parser combinator ) 
Un seguimiento a Mi pregunta anterior que estaba en la biblioteca de token que este lexer produce una corriente de. Ver el proyecto completo , la biblio...

16  Jediscript - Que el 4 sea contigo  ( Jediscript may the 4th be with you ) 
En honor al Día de Star Wars, he reunido este pequeño programa Python, estoy llamando a Jediscript. Jediscript es esencialmente una versión desechada de Brain...

22  Golf algún código con a-ray  ( Golf some code with a ray ) 
Para algunos de los en el 2nd monitor , sabes que estaba creando un nuevo Idioma de golf. Para uno o dos (@quill), ha escuchado de mí lo difícil que es. a-...

8  LINNY: un lenguaje de programación interpretado  ( Linny an interpreted programming language ) 
Hay una pregunta de seguimiento aquí . He realizado el proyecto de crear mi propio idioma de programación, Linny . Es un lenguaje muy, muy simple, con sol...

3  Lenguaje de scripting con clases genéricas  ( Scripting language with generic classes ) 
Estoy creando un dialecto de ActionScript 3.0 y ahora tiene un verificador de trabajo o verificador "Símbolo de símbolos". La lengua actualiza a ActionScript ...

5  LINNY: Desarrollo de idiomas continuo  ( Linny continued language development ) 
Una pregunta anterior con respecto a linny existe aquí . Después de una maravillosa respuesta en mi Pregunta previa con respecto a mi lenguaje de progr...

5  Gramática para un lenguaje personalizado llamado elegancia  ( Grammar for a custom language called elegance ) 
Estoy trabajando en mi propio idioma personalizado llamado elegancia. Esta es mi primera gramática, y estoy buscando ayuda con: legibilidad Código de exp...

4  Biblioteca de tokens de idioma  ( Language tokens library ) 
Esto puede parecer un poco pequeño , pero en realidad es una caja autocontenida en mi proyecto. Esta caja contiene definiciones para los tokens de origen e...

6  Parser complejo en C #  ( Complex parser in c ) 
La última vez Pedí una revisión de mi tokenizador , y me gustaría Agradecer por todos los comentarios! Esta vez escribí un analizador para mi idioma. El anal...




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