Text Shift function in Python

后端 未结 5 422
陌清茗
陌清茗 2020-12-03 15:50

I\'m writing code so you can shift text two places along the alphabet: \'ab cd\' should become \'cd ef\'. I\'m using Python 2 and this is what I got so far:

         


        
相关标签:
5条回答
  • 2020-12-03 16:10

    It's easier to write a straight function shifttext(text, shift). If you want a prompt, use Python's interactive mode python -i shift.py

    > shifttext('hello', 2)
    'jgnnq'
    
    0 讨论(0)
  • 2020-12-03 16:19

    Tried with Basic python. may useful for someone.

    # Caesar cipher
    import sys
    
    text = input("Enter your message: ")
    
    cipher = ''
    try:
      number = int(input("Enter Number to shift the value : "))
    except ValueError:
      print("Entered number should be integer. please re0enter the value")
      try:
        number = int(input("Enter Number to shift the value : "))
      except:
        print("Error occurred. please try again.")
        sys.exit(2)
      
    for char in text:
        if not char.isalpha():
          flag = char
        elif char.isupper():
          code = ord(char) + number
          if 64 < code <= 90:
            flag = chr(code)
          elif code > 90:
            flag = chr((code - 90) + 64)
            
        elif char.islower():
          code = ord(char) + number
          if 96 < code <= 122:
            flag = chr(code)
          elif code > 122:
            flag = chr((code - 122) + 96)
        
        else:
          print("not supported value by ASCII")
        
        cipher += flag
    
    print(cipher)
    
    0 讨论(0)
  • 2020-12-03 16:22

    Martijn's answer is great. Here is another way to achieve the same thing:

    import string
    
    def shifttext(text, shift):
        shift %= 26 # optional, allows for |shift| > 26 
        alphabet = string.lowercase # 'abcdefghijklmnopqrstuvwxyz' (note: for Python 3, use string.ascii_lowercase instead)
        shifted_alphabet = alphabet[shift:] + alphabet[:shift]
        return string.translate(text, string.maketrans(alphabet, shifted_alphabet))
    
    print shifttext(raw_input('Input text here: '), 3)
    
    0 讨论(0)
  • 2020-12-03 16:28

    Looks you're doing cesar-cipher encryption, so you can try something like this:

    strs = 'abcdefghijklmnopqrstuvwxyz'      #use a string like this, instead of ord() 
    def shifttext(shift):
        inp = raw_input('Input text here: ')
        data = []
        for i in inp:                     #iterate over the text not some list
            if i.strip() and i in strs:                 # if the char is not a space ""  
                data.append(strs[(strs.index(i) + shift) % 26])    
            else:
                data.append(i)           #if space the simply append it to data
        output = ''.join(data)
        return output
    

    output:

    In [2]: shifttext(3)
    Input text here: how are you?
    Out[2]: 'krz duh brx?'
    
    In [3]: shifttext(3)
    Input text here: Fine.
    Out[3]: 'Flqh.'
    

    strs[(strs.index(i) + shift) % 26]: line above means find the index of the character i in strs and then add the shift value to it.Now, on the final value(index+shift) apply %26 to the get the shifted index. This shifted index when passed to strs[new_index] yields the desired shifted character.

    0 讨论(0)
  • 2020-12-03 16:30

    You are looping over the list of characters, and i is thus a character. You then try to store that back into data using the i character as an index. That won't work.

    Use enumerate() to get indexes and the values:

    def shifttext(shift):
        input=raw_input('Input text here: ')
        data = list(input)
        for i, char in enumerate(data):
            data[i] = chr((ord(char) + shift) % 26)
        output = ''.join(data)
        return output
    

    You can simplify this with a generator expression:

    def shifttext(shift):
        input=raw_input('Input text here: ')
        return ''.join(chr((ord(char) + shift) % 26) for char in input)
    

    But now you'll note that your % 26 won't work; the ASCII codepoints start after 26:

    >>> ord('a')
    97
    

    You'll need to use the ord('a') value to be able to use a modulus instead; subtracting puts your values in the range 0-25, and you add it again afterwards:

        a = ord('a')
        return ''.join(chr((ord(char) - a + shift) % 26) + a) for char in input)
    

    but that will only work for lower-case letters; which might be fine, but you can force that by lowercasing the input:

        a = ord('a')
        return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in input.lower())
    

    If we then move asking for the input out of the function to focus it on doing one job well, this becomes:

    def shifttext(text, shift):
        a = ord('a')
        return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in text.lower())
    
    print shifttext(raw_input('Input text here: '), 3)
    

    and using this on the interactive prompt I see:

    >>> print shifttext(raw_input('Input text here: '), 3)
    Input text here: Cesarsalad!
    fhvduvdodgr
    

    Of course, now punctuation is taken along. Last revision, now only shifting letters:

    def shifttext(text, shift):
        a = ord('a')
        return ''.join(
            chr((ord(char) - a + shift) % 26 + a) if 'a' <= char <= 'z' else char
            for char in text.lower())
    

    and we get:

    >>> print shifttext(raw_input('Input text here: '), 3)
    Input text here: Ceasarsalad!
    fhdvduvdodg!
    
    0 讨论(0)
提交回复
热议问题