Есть ли более элегантный способ рефакторинга этого очень линейного блока кода?

#python #refactoring

#python #рефакторинг

Вопрос:

Я создал это решение для назначения класса. По сути, это шифр caesar, который принимает файл в качестве входных данных, а также значение сдвига и выводит ‘encrypted.txt ‘. Это ОЧЕНЬ элементарно и не включает проверку входных данных.

Прямо сейчас это просто серия списков, заполняющих и преобразующих элемент за элементом.

 dir = input("What is your file titled?: ")
shift = int(input("Enter a shift number for document: "))
doc = open(dir, "r")
encrypted_doc = open("encrypted.txt","w")

#split document into list of characters
doc_list=[]
with doc as fileobj:
    for line in fileobj:
        for ch in line:
            doc_list.append(ch)
doc.close()

ord_list = []
for char in doc_list:
    ord_list.append(int(ord(char)))

cipher_ord_list = []
for ord in ord_list:
    cipher_ord_list.append(ord   shift)

#convert cipher list back into characters, then string
cipher_list = []
for ord in cipher_ord_list:
    cipher_list.append(chr(ord))

ciphered_string = "".join(cipher_list)

encrypted_doc.write(ciphered_string)
encrypted_doc.close()
  

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

Комментарии:

1. Я бы опубликовал это на codereview.stackexchange.com

2. вам могло бы понадобиться некоторое понимание списка для сжатия вашего кода

Ответ №1:

Вы можете сократить это:

  • используйте with open(...) as f: ... синтаксис и удалите .close()
  • создайте таблицу подстановочного перевода, используя словарь или str.translate()
  • и использовать встроенную функциональность:

 import string
import os

# Looks for the first .py file in the current dir and translates it:
for root,dirs,files in os.walk("./"):
    filename = [f for f in files if f.endswith(".py")][0]

shift = 2222 # int(input("Enter a shift number for document: "))

shift_by = shift % len(string.printable) # so it works for shifts of 10000
mapper = str.maketrans( string.printable, 
                        string.printable[shift_by:]   string.printable[:shift_by])

revmap = str.maketrans( string.printable[shift_by:]   string.printable[:shift_by],
                        string.printable )

# translate documents
doc_list=[]
with open(filename) as f:
    ciphered_string = f.read().translate(mapper)

with open("encrypted.txt","w") as encrypted_doc: 
    encrypted_doc.write(ciphered_string)

# output cipher and reversed cipher
with open("encrypted.txt") as f:
    t = f.read()
    print(t)
    print(t.translate(revmap))
  

Смотрите:

Вывод print(t) :

 EILKNPgOPNEJCiEILKNPgKOii]g(KKGOgBKNgPDAgBENOPg
LUgBEHAgEJgPDAgyQNNAJPgzENgwJzgPNwJOHwPAOgEPiBKNgNKKP   zENO    BEHAOgEJgKO
SwHG|
}iggggBEHAJwIAg2g6BgBKNgBgEJgBEHAOgEBgB
AJzOSEPD|
LU}86m8iiODEBPg2goooog]gEJP|EJLQP|!JPANgwgODEBPgJQIxANgBKNgzKyQIAJPg}}iiODEBPaxUg2gODEBPg_gHAJ|OPNEJC
LNEJPwxHA}g]gOKgEPgSKNGOgBKNgODEBPOgKBgnmmmmiIwLLANg2gOPN
IwGAPNwJO|gOPNEJC
LNEJPwxHA   giggggggggggggggggggggggggOPNEJC
LNEJPwxHA6ODEBPaxU8g gOPNEJC
LNEJPwxHA6ODEBPaxU8}iiNARIwLg2gOPN
IwGAPNwJO|gOPNEJC
LNEJPwxHA6ODEBPaxU8g gOPNEJC
LNEJPwxHA6ODEBPaxU8 iggggggggggggggggggggggggOPNEJC
LNEJPwxHAg}ii]gPNwJOHwPAgzKyQIAJPOizKyaHEOP268iSEPDgKLAJ|BEHAJwIA}gwOgBiggggyELDANAzaOPNEJCg2gB
NAwz|}
PNwJOHwPA|IwLLAN}iiSEPDgKLAJ|AJyNULPAz
PTP    S}gwOgAJyNULPAzazKygiggggAJyNULPAzazKy
SNEPA|yELDANAzaOPNEJC}ii]gKQPLQPgyELDANgwJzgNARANOAzgyELDANiSEPDgKLAJ|AJyNULPAz
PTP}gwOgBiggggPg2gB
NAwz|}iggggLNEJP|P}iggggLNEJP|P
PNwJOHwPA|NARIwL}}
  

Вывод print(t.translate(revmap)) :

 import string
import os

# Looks for the first -py file in the current dir and translates it:
for root,dirs,files in os-walk("-/"):
    filename = [f for f in files if f-endswith("-py")][0]

shift = 2222 # int(input("Enter a shift number for document: "))

shift_by = shift % len(string-printable) # so it works for shifts of 10000
mapper = str-maketrans( string-printable, 
                        string-printable[shift_by:]   string-printable[:shift_by])

revmap = str-maketrans( string-printable[shift_by:]   string-printable[:shift_by],
                        string-printable )

# translate documents
doc_list=[]
with open(filename) as f:
    ciphered_string = f-read()-translate(mapper)

with open("encrypted-txt","w") as encrypted_doc: 
    encrypted_doc-write(ciphered_string)

# output cipher and reversed cipher
with open("encrypted-txt") as f:
    t = f-read()
    print(t)
    print(t-translate(revmap))