Как читать строку по одной букве за раз в Python

Мне нужно преобразовать строку, введенную пользователем в азбуку Морзе. Наш профессор хочет, чтобы мы это делали, читая из файла morseCode.txt, разделяя буквы из morseCode в два списка, а затем преобразовывая каждую букву в код Морзе (вставляя новую строку, если есть пробел).

У меня есть начало. Он читает файл morseCode.txt и разделяет буквы в список [A, B, ... Z], а коды - в список ['- -., - - \n', '. -. -. - \ п"...].

Мы еще не изучили "наборы", поэтому я не могу это использовать. Как мне тогда взять строку, которую они ввели, пройти по буквам и преобразовать ее в азбуку Морзе? Я немного нагнал Вот что у меня сейчас (совсем немного...)

РЕДАКТИРОВАТЬ: завершил программу!

# open morseCode.txt file to read
morseCodeFile = open('morseCode.txt', 'r') # format is <letter>:<morse code translation><\n>   
# create an empty list for letters
letterList = []    
# create an empty list for morse codes
codeList = []
# read the first line of the morseCode.txt
line = morseCodeFile.readline()    
# while the line is not empty
while line != '':        
    # strip the \n from the end of each line
    line = line.rstrip()        
    # append the first character of the line to the letterList        
    letterList.append(line[0])           
    # append the 3rd to last character of the line to the codeList
    codeList.append(line[2:])        
    # read the next line
    line = morseCodeFile.readline()        
# close the file    
morseCodeFile.close()


try:
    # get user input
    print("Enter a string to convert to morse code or press <enter> to quit")    
    userInput = input("")  
    # while the user inputs something, continue   
    while userInput:
        # strip the spaces from their input
        userInput = userInput.replace(' ', '')
        # convert to uppercase
        userInput = userInput.upper()

        # set string accumulator
        accumulateLetters = ''
        # go through each letter of the word
        for x in userInput:            
            # get the index of the letterList using x
            index = letterList.index(x)
            # get the morse code value from the codeList using the index found above
            value = codeList[index]
            # accumulate the letter found above
            accumulateLetters += value
        # print the letters    
        print(accumulateLetters)
        # input to try again or <enter> to quit
        print("Try again or press <enter> to quit")
        userInput = input("")

except ValueError:
    print("Error in input. Only alphanumeric characters, a comma, and period allowed")
    main()   

9 ответов

Почему бы просто не перебрать строку?

a_string="abcd"
for letter in a_string:
    print letter

возвращается

a
b
c
d

Итак, в псевдо-коде я бы сделал это:

user_string = raw_input()
list_of_output = []
for letter in user_string:
   list_of_output.append(morse_code_ify(letter))

output_string = "".join(list_of_output)

Обратите внимание morse_code_ify функция является псевдокодом.

Вы определенно хотите составить список символов, которые вы хотите вывести, а не просто конкатенировать их в конце какой-либо строки. Как указано выше, это O(n^2): плохо. Просто добавьте их в список, а затем используйте "".join(the_list),

В качестве примечания: почему вы убираете пробелы? Почему бы просто не иметь morse_code_ify(" ") вернуть "\n"?

Пара вещей для тебя:

Загрузка будет "лучше", как это:

with file('morsecodes.txt', 'rt') as f:
   for line in f:
      line = line.strip()
      if len(line) > 0:
         # do your stuff to parse the file

Таким образом, вам не нужно закрывать, и вам не нужно вручную загружать каждую строку и т. Д., И т. Д.

for letter in userInput:
   if ValidateLetter(letter):  # you need to define this
      code = GetMorseCode(letter)  # from my other answer
      # do whatever you want

Я не могу оставить этот вопрос в таком состоянии, когда этот окончательный код в вопросе висит над мной...

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

  • Есть только два комментария - и даже второй действительно не нужен для тех, кто знаком с Python, они поймут, что NL удаляется. Пишите комментарии только там, где это добавляет ценность.

  • with оператор (рекомендуется в другом ответе) устраняет необходимость закрытия файла через обработчик контекста.

  • Используйте словарь вместо двух списков.

  • Генератор понимания ((x for y in z)) используется для перевода в одну строку.

  • Оберните как можно меньше кода в try/except блок, чтобы уменьшить вероятность получения исключения, которое вы не хотели.

  • Использовать input() аргумент, а не print()сначала - используйте '\n' чтобы получить новую строку, которую вы хотите.

  • Не пишите код в несколько строк или с такими промежуточными переменными просто ради этого:

    a = a.b()
    a = a.c()
    b = a.x()
    c = b.y()
    

    Вместо этого напишите эти конструкции следующим образом, объединяя вызовы так, как это совершенно правильно:

    a = a.b().c()
    c = a.x().y()
    

code = {}
with open('morseCode.txt', 'r') as morse_code_file:
    # line format is <letter>:<morse code translation>
    for line in morse_code_file:
        line = line.rstrip()  # Remove NL
        code[line[0]] = line[2:]

user_input = input("Enter a string to convert to morse code or press <enter> to quit\n")
while user_input:
    try:
        print(''.join(code[x] for x in user_input.replace(' ', '').upper()))
    except KeyError:
        print("Error in input. Only alphanumeric characters, a comma, and period allowed")

    user_input = input("Try again or press <enter> to quit\n")
# Retain a map of the Morse code
conversion = {}

# Read map from file, add it to the datastructure
morseCodeFile = file('morseCode.txt')
for line in moreCodeFile:
    conversion[line[0]] = line[2:]
morseCodeFile.close()

# Ask for input from the user
s = raw_input("Please enter string to translate")
# Go over each character, and print it the translation.
# Defensive programming: do something sane if the user 
# inputs non-Morse compatible strings.    
for c in s:
    print conversion.get(c, "No translation for "+c)

Используйте "индекс".

def GetMorseCode(letter):
   index = letterList.index(letter)
   code = codeList[index]
   return code

Конечно, вы захотите проверить правильность введенного вами письма (при необходимости преобразуйте его регистр, убедитесь, что оно находится в списке, проверив этот индекс!= -1), но это должно помочь вам в этом.

Для фактической обработки я оставляю строку готового продукта и перебираю каждую букву в строке, которую они ввели. Я бы вызвал функцию для преобразования буквы в азбуку Морзе, а затем добавил ее в строку существующего азбуки Морзе.

finishedProduct = []
userInput = input("Enter text")
for letter in userInput:
    finishedProduct.append( letterToMorseCode(letter) )
theString = ''.join(finishedProduct)
print(theString)

Вы можете проверить наличие места в цикле или в вызываемой функции.

# Open the file
f = open('morseCode.txt', 'r')

# Read the morse code data into "letters" [(lowercased letter, morse code), ...]
letters = []
for Line in f:
    if not Line.strip(): break
    letter, code = Line.strip().split() # Assuming the format is <letter><whitespace><morse code><newline>
    letters.append((letter.lower(), code))
f.close()

# Get the input from the user
# (Don't use input() - it calls eval(raw_input())!)
i = raw_input("Enter a string to be converted to morse code or press <enter> to quit ") 

# Convert the codes to morse code
out = []
for c in i:
    found = False
    for letter, code in letters:
        if letter == c.lower():
            found = True
            out.append(code)
            break

    if not found: 
        raise Exception('invalid character: %s' % c)

# Print the output
print ' '.join(out)

Сначала создайте таблицу поиска:

morse = [None] * (ord('z') - ord('a') + 1)
for line in moreCodeFile:
    morse[ord(line[0].lower()) - ord('a')] = line[2:]

Затем конвертируйте, используя таблицу:

for ch in userInput:
    print morse[ord(ch.lower()) - ord('a')]

Вот простой пример: эта программа вычисляет, сколько пробелов в предложении.

      # get an input from the user  
inp = input("Write a sentence: ")
spaces = 0
for i in inp:
#print each letter the user have typed
     if(i == " ")
          spaces += 1
print(spaces)
    
Другие вопросы по тегам