How to search nested list grid and give lettered c

2019-03-02 02:38发布

I'm new to python and struggling quite a bit to get this going. This is my task:

The Six-Letter Cipher is a method of encoding a secret message that involves both substitution and transposition. The encryption starts by randomly filling a 6  6 grid with the alphabet letters from A to Z and the digits from 0 to 9 (36 symbols in total). This grid must be known to both the sender and receiver of the message. The rows and columns of the grid are labelled with the letters A, B, C, D, E, F.

Write a Python program that implements the six-letter cipher method. Your program should: 1. Create a 6x6 grid and fill it randomly with letters and numbers as described in the first paragraph, then prompt the user to enter a secret message. 2. Display the 6x6 grid and the generated ciphertext, after the user enters the secret message. 3. Prompt the user to enter the ciphertext to display the original message. It is OK to ask the user to separate every two letters of the ciphertext with a space or comma.

The bit I am struggling with is how do I search through the nested lists for the randomly placed letter that has been entered and give the coordinates. Also won't the coordinates be given in numbers i.e. 0,1, rather than letters i.e. A,B I think I could manage the encoding and decoding once I have the ideas of how to use this nested list.

Here is my code so far:

grid = [["Z","9","G","Q","T","3"],
    ["Y","8","F","P","S","2"],
    ["X","7","E","O","R","1"],
    ["W","6","D","N","M","0"],
    ["V","5","C","L","K","U"],
    ["J","4","B","I","H","A"]]

def main():
    print("Welcome to the sixth cipher")
    print("Would you like to (E)Encode or (D)Decode a message?")
    operation = input()

    if(operation == "E"):
        encodecipher()
    elif(operation == "D"):
        decodecipher()
    else:
        print("Sorry, input not recognised")

def encodecipher():
    print("Please enter a message to encode:")
    messagetoencode = input()



def decodecipher():
    print("Decode Test")
    rowcolumn()


def rowcolumn():
    pass

main()

3条回答
混吃等死
2楼-- · 2019-03-02 03:07

This is a simple way to get the co-ordinates of a character in the grid :

def find_pos(s):
    for i, j in enumerate(grid):
        try:
            return i, j.index(s)
        except ValueError:
            continue
    raise ValueError("The value {0!r} was not found.".format(s))


>>> find_pos("O")
(2, 3)
查看更多
Summer. ? 凉城
3楼-- · 2019-03-02 03:17

I realise you're doing this for learning/homework purposes, but I'll point this out for something for you to bear in mind later. It's easier to think of what you have as something of 36-items (that just happens to be representable as a 6x6) - or more explicity - you have a character -> coord, and a dict is very useful to do this, and reverse it...

from string import ascii_uppercase, digits
from random import shuffle
from itertools import product

# build 36 items list and randomise it
chars = list(ascii_uppercase + digits)
shuffle(chars)

# alternatively, use your existing grid:
from itertools import chain
chars = list(chain.from_iterable(grid))
# ...


# Create char -> (coords)
lookup = dict(zip(chars, product('ABCDEF', repeat=2)))
# Swap over so (coords) -> char
rev_lookup = {v: k for k,v in lookup.iteritems()}
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-03-02 03:19

You can use Python's enumerate to iterate over values and provide an index position of each value as you go:

grid = [["Z","9","G","Q","T","3"],
    ["Y","8","F","P","S","2"],
    ["X","7","E","O","R","1"],
    ["W","6","D","N","M","0"],
    ["V","5","C","L","K","U"],
    ["J","4","B","I","H","A"]]

search = 'D'

for rownum, row in enumerate(grid):
    for colnum, value in enumerate(row):
       if value == search:
           print "Found value at (%d,%d)" % (rownum, colnum)

You can adapt this into your chosen function structure, such as the following (if values in your grid are unique):

def findvalue(grid, value):
    for rownum, row in enumerate(grid):
        for colnum, itemvalue in enumerate(row):
            if itemvalue == value:
                return (rownum, colnum)
    raise ValueError("Value not found in grid")

As this will raise a ValueError if the value isn't found, you'll have to handle this in your calling code.

If you then need to map between 0-indexed row and column numbers to the letters A...F you can do something like:

def numbertoletter(number):
    if number >= 0 and number <= 26:
        return chr(65 + number)
    else:
        raise ValueError('Number out of range')

Which will give you the following:

>>> numbertoletter(0)
'A'
>>> numbertoletter(1)
'B'

Putting it all together gives you:

value = 'B'
row, col = map(numbertoletter, findvalue(grid, value))
print "Value '%s' found at location (%s, %s)" % (value, row, col)
查看更多
登录 后发表回答