0

How can I create a matrix by using rows and columns. when I print the matrix the output should be like this:

O X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
N X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
M X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
L X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
K X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
J X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
I X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
H X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
G X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
F X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
E X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
D X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
C X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
B X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
A X  X  X  X  X  X  X  X  X  X  X  X  X  X  X  
  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14

I think I need to use a list in a dictionary and use matrix for For "X"s to be edited later.

hall_dictionary = {}
hall_dictionary["merhaba"] = []
rows = 10
columns = 15
x = [[hall_dictionary["merhaba"] for i in range(columns)] for j in range(rows)]
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Do you need to save the row and column name in your matrix? Or it just to show when the matrix display? – Dion Saputra Dec 08 '18 at 08:45
  • @MehmetBurakYıldırım you're not answering Dion's question. Are the ABC/012 axes labels part of the matrix itself or are they just there when printing? – TrebledJ Dec 08 '18 at 08:57
  • @TrebuchetMS are they just there when printing. I think when when I want to call C3 I have to do this hall_dictionary["merhaba][2][3] – Mehmet Burak Yıldırım Dec 08 '18 at 09:01
  • But your printing is reversed, from bottom to top? And with my previous comment, it's still unclear... you're not answering my question. :| – TrebledJ Dec 08 '18 at 09:09
  • @TrebuchetMS for alphabet letters is reversed bottom to top.I guess I didn't understand what you wanted to say. I think it should be saved so I can change the empty seats in the future. – Mehmet Burak Yıldırım Dec 08 '18 at 09:20

3 Answers3

1

You can capsule the whole data-storage away into a class. It handles all the "book-keeping" and you simply use A to ... and 1 to ... to change the X.

Internally it uses a simple 1-dim list:

class Field:
    def __init__(self, rows, cols, init_piece="x"):
        self.rows = rows
        self.cols = cols
        self.field = [init_piece] * rows * cols

    def place_at(self, row, col, piece):
        """Changes one tile on the field. Does all the reverse-engineering to compute 
        1-dim place of A..?,1..? given tuple of coords."""
        def validation():
            """Raises error when out of bounds."""
            error = []
            if not (isinstance(row,str) and len(row) == 1 and row.isalpha()):
                error.append("Use rows between A and {}".format(chr(ord("A") + 
                                                                    self.rows - 1)))
            if not (0 < col <= self.cols):
                error.append("Use columns between 1 and {}".format(self.cols))
            if error:
                error = ["Invalid row/column: {}/{}".format(row,col)] + error
                raise ValueError('\n- '.join(error))
        validation()
        row = ord(row.upper()[0]) - ord("A")  
        self.field[row * self.cols + col - 1] = piece

    def print_field(self):
        """Prints the playing field."""
        for c in range(self.rows - 1,-1,-1):
            ch = chr(ord("A") + c)
            print("{:<4} ".format(ch), end = "")
            print(("{:>2} " * self.cols).format(*self.field[c * self.cols:
                                                 (c + 1) * self.cols], sep = "  "))
        print("{:<4} ".format(""), end = "")
        print(("{:>2} " * self.cols).format(*range(1,self.cols + 1)))

Then you can use it like so:

rows = 10
cols = 15
f = Field(rows,cols)
f.print_field()

# this uses A...? and 1...? to set things
for r,c in [(0,0),("A",1),("ZZ",99),("A",99),("J",15)]:
    try:
        f.place_at(r,c,"i")  # set to 'i'
    except ValueError as e:
        print(e) 
f.print_field()

Output (before):

J     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
I     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
H     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
G     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
F     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
E     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
D     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
C     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
B     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
A     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
      1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

Output (setting things && after):

Invalid row/column: 0/0
- Use rows between A and J
- Use columns between 1 and 15
Invalid row/column: ZZ/99
- Use rows between A and J
- Use columns between 1 and 15
Invalid row/column: A/99
- Use columns between 1 and 15

J     x  x  x  x  x  x  x  x  x  x  x  x  x  x  i
I     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
H     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
G     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
F     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
E     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
D     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
C     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
B     x  x  x  x  x  x  x  x  x  x  x  x  x  x  x
A     i  x  x  x  x  x  x  x  x  x  x  x  x  x  x
      1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0

Sounds like a 2-D array (similiar to answer How to define a two-dimensional array in Python), so something like this:

vertical = list(string.ascii_uppercase[0:15][::-1]) # ['O', 'N', ..., 'A']
columns = 15

hall_dictionary = {}
hall_dictionary["merhaba"] = [[x for x in range(columns)] for y in vertical]

for i in range(len(vertical)):
    for j in range(columns):
        hall_dictionary["merhaba"][i][j] = 'X'

Then you can index as desired:

hall_dictionary["merhaba"][0][1]  # Always prints 'X'

display the entire array:

for row in hall_dictionary["merhaba"]:
    print(row)

['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
... 15 rows ...

and assign, update new values:

hall_dictionary["merhaba"][0][2] = 'O'

for row in hall_dictionary["merhaba"]:
    print(row)

['X', 'X', 'O', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
... 

confirms element [0][2] has been updated.

0

If you're interested, you can use a pandas DataFrame as well.

import pandas as pd

rows = 10
columns = 15

def indexToLetter(index:int):   # This function might be a bit too verbose
    if index == 0:              #   but all this does is convert an
        return 'A'              #   integer index [0, ∞) to an
                                #   alphabetical index [A..Z, AA..ZZ, AAA...]
    ret = ''
    while index > 0:
        length = len(ret)
        letter = chr(ord('A') + index % 26 - [0, 1][length >= 1])
        ret = letter + ret
        index //= 26
    return ret

# create the row labels
rLabels = [*map(indexToLetter, range(rows))]

# create the dataframe, note that we can simplify
# [['X' for i in range(columns)] for j in range(rows)]
# to [['X'] * columns] * rows
df = pd.DataFrame([['X'] * columns] * rows, index=rLabels)
print(df)

Output:

  0  1  2  3  4  5  6  7  8  9  10 11 12 13 14
A  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
B  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
C  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
D  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
E  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
F  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
G  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
H  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
I  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
J  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X

The output looks slightly ugly, and might not be what you're looking for. But with a dataframe, it's very convenient to manipulate a matrices and tables of data.

You can access it by specifying the column then the row (unlike some other solutions).

df[1][0] = 'O'
df[1][2] = 'O'
df[1][3] = 'O'
print(df)

Output:

  0  1  2  3  4  5  6  7  8  9  10 11 12 13 14
A  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
B  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
C  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
D  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
E  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
F  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
G  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
H  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
I  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
J  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X

Say, someone wants to book the entire row 'E' of the hall.

if any(df.loc['E'] == 'O'):  # check if any seats were taken
    print('Error: some seats in Row <E> are taken.')
else:
    df.loc['E'] = 'O'

print(df)

Output:

  0  1  2  3  4  5  6  7  8  9  10 11 12 13 14
A  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
B  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
C  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
D  X  O  X  X  X  X  X  X  X  X  X  X  X  X  X
E  O  O  O  O  O  O  O  O  O  O  O  O  O  O  O
F  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
G  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
H  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
I  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X
J  X  X  X  X  X  X  X  X  X  X  X  X  X  X  X

Note: you can also do df.iloc[4] to access row E. Want to access rows B to E? Use df.loc['B':'E'] or df.iloc[1:5].

You can also do the same with columns by accessing df[<column_index>] = 'O'.

TrebledJ
  • 8,713
  • 7
  • 26
  • 48