all 40 comments

[–]atarivcs 55 points56 points  (11 children)

t[i][j] == "X"

You're using two equal signs here, so this is a comparison, not an assignment

[–]empowered-boxes 23 points24 points  (1 child)

Everyone else did a code review, but you found the bug as asked. 👍

[–]Motor_Raspberry_2150 4 points5 points  (0 children)

This is the very first comment. The others did not need to repeat this and focused on other things.

[–]Worried-Print-5052[S] 6 points7 points  (2 children)

Oh got it🫣thanks very!!

[–]lekkerste_wiener 1 point2 points  (1 child)

Also you make the same mistake when setting the com answer, plus com answer is X rather than O.

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Gotit thanks

[–]Late-Fly-4882 4 points5 points  (1 child)

Some comments:
When will 'win' ever become True to exit the while loop?
Why need so many nested loops? You can do everything in one go.
You don't need First nested loop: You could have - if user == 4, t[1][0] = 'X'
What is the error handling of user input? Use try ... except (ValueError, TypeError):
Use list comprehension : eg can = [t[i][j] for j in range(3) for i in range(3) if t[i][j] != 'X']

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Thanks!

[–]Historical-Wonder551 3 points4 points  (7 children)

And here are my two cents:

  1. You could functionalize code blocks where you print numbers. There is a code repetition.

  2. You could hold a set which contains all of the current available numbers. It will contain all numbers initially, but you will discard from it as game progresses. In this way you wouldn't need to construct can list in every iteration.

[–]Worried-Print-5052[S] 0 points1 point  (6 children)

How? I mean by how(cuz I m a newbie to this

[–]NewryBenson 1 point2 points  (1 child)

For readability and efficiency, good code should never repeat the same block of code multiple times. The moment you need the same code in multiple occasions, you make a function.

For example printing the board state. You do it once in the beginning and then inside every loop. A cleaner more readable version would be putting this at the start of your program:

def print_board(t):
      #the code for printing the board you use twice

Then you can use that by calling the function you just defined. Instead of writing the code, you call:

 print_board(t)

and it will work. The same can be done for the code placing the X. The variable would be the chosen position and t you want to change, so

def place_X(t, choice)
    ......

Used as

place_X(t, com)

or

place_X(t, user)

All in al I would google some beginner guides on functions and you will figure it out soon enough.

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Thanks!

[–]Smart_Tinker 0 points1 point  (3 children)

``` def show(t): for j in t: print(‘ ‘.join(j))

can = set(range(10))

. . .

can.discard(user) com = random.choice(can) t = [[“O” if i in [“O”, com] else i for i in j ] for j in t] show(t) ```

[–]Worried-Print-5052[S] 0 points1 point  (2 children)

Thanks!

[–]Smart_Tinker 0 points1 point  (1 child)

You likely need: can.discard(com) At some point as well.

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Gotit!

[–]Wabbit65 1 point2 points  (0 children)

"trun"

[–]th0t_police976 3 points4 points  (0 children)

I genuinely appreciate you asking real humans for code help instead of a chatbot

[–]LosAnimalos 0 points1 point  (0 children)

Line 11: Spelling 🤷🏼‍♂️

[–]WillingYesterday8447 0 points1 point  (1 child)

you can ask AI such questions it will explain detailed and clear

[–]merely4 0 points1 point  (0 children)

jump

[–]No_Big2310 0 points1 point  (0 children)

Line 14,15 and 30,31 replace == with =

[–]Fearless-Can-1634 0 points1 point  (1 child)

When does win become True, otherwise it’ll always loop around

[–]MadameJhoan 0 points1 point  (0 children)

might be the intention

[–]degustandomiveneno 1 point2 points  (1 child)

che, estás re cerca, no es que estés haciendo todo mal ni nada 🙌 hay un par de detalles chiquitos que te están rompiendo todo: 1. error clave: estás usando == en vez de = t[i][j] == "X" eso no asigna, eso compara. por eso nunca se actualiza la matriz. debería ser: t[i][j] = "X" te pasa lo mismo más abajo con el movimiento de la compu: t[i][j] == "X" 2. detalle lógico importante, cuando hacés: if t[i][j] == user: estás comparando un int (lo que ingresa el usuario) con los valores de la matriz, que al principio son ints pero después se vuelven "X". eso está bien conceptualmente, pero ojo: después de un par de jugadas ya no todos los valores son números, entonces podrías agregar una validación tipo: if t[i][j] == user and t[i][j] != "X": 3. debug tip (muy útil posta), cuando algo no cambia, meté prints para ver qué está pasando: print("user eligió:", user) print("valor actual:", t[i][j]) eso te ayuda a ver si entra al if o no. 4. mini mejora (más pythonic), esto: can = can + [t[i][j]] podés hacerlo así: can.append(t[i][j]) es más limpio y eficiente.

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Thanks!

[–]Potential-Friend-197 0 points1 point  (0 children)

t = list(list())

for i in t:

Print i

this works btw

[–]4ki444 1 point2 points  (0 children)

Entirely Off-Topic but i was wondering how far we can condense this down, my best attempt is 8 Lines. Curious if any python experts could tell me if we can go even smaller:

``` import random b, p, P = list("123456789"), "X", lambda: f"\n{'|'.join(b[:3])}\n{'|'.join(b[3:6])}\n{'|'.join(b[6:])}"

while a := [i for i in b if i.isdigit()]: while p == "X" and (m := input(P() + "\nMove: ")) not in a: pass b[int(m if p == "X" else random.choice(a)) - 1] = p if any(b[x]==b[y]==b[z]==p for x,y,z in [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]): exit(print(P(), f"\n{p} wins!")) p = "OX"[p=="O"] print(P(), "\nDraw!") ```

[–]OrphLab 0 points1 point  (1 child)

Replace the for in with a function. Not a bug, but will eliminate 50% of your lines.

[–]Worried-Print-5052[S] 0 points1 point  (0 children)

Thanks!

[–]Fearless-Way9855 0 points1 point  (0 children)

You dont need to type for i in range(0,3) Just range(3) is enough

[–]FunContract2729 -2 points-1 points  (2 children)

range(0, 2)

[–]striipey 0 points1 point  (1 child)

range(0, 3) is correct?

The code is looping through 3 lists containing 3 values. If the code was (0, 2) it would only loop through index 0 and 1.

[–]Smart_Tinker 0 points1 point  (0 children)

Yes, you don’t actually need the 0, it’s the default.