web-dev-qa-db-fra.com

TypeError: élément de séquence 0: chaîne attendue, aucun type trouvé

J'essaie d'améliorer un jeu de cuirassés. La version originale fonctionne correctement sans erreur. J'ai écrit du code pour aider à surmonter le fait que la première version place les navires au même endroit à chaque fois, donc j'ai commencé avec un navire (constitué de deux carrés). J'ai fait cela en créant deux fonctions: la première génère une coordonnée aléatoire ... 

 # Destroyer (2 squares)
def Deploy_Destroyer_1(Player):
    Rand_col_1 = randint(0,11)
    if Rand_col_1 <= 5:
        Rand_row_1 = randint(0,11)
    else:
        Rand_row_1 = randint(6,11)
    return Rand_col_1
    return Rand_row_1
    if Player[Rand_row_1][Rand_col_1] == 'X':
        Deploy_Destroyer_1(Player)
    else:
        Deploy_Destroyer_2(Player)

et les deuxièmes essais correspondent aux conditions (s’il tient sur le tableau et quelle rotation il peut être placé). 

def Deploy_Destroyer_2(Player):
    if Rand_col_1 == 5 and Rand_row_1 == 6:
        #can be 1, 2, 3 or 4... in that order below
        Rand_position_1 = randint(1,4)
        if Rand_position_1 == 1:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 4:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif Rand_col_1 in range(1,4) and Rand_row_1 in range(1,10):
        #can be any 1, 2, 3 or 4... in that order below
        Rand_position_1 = randint(1,4)
        if Rand_position_1 == 1:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 4:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif Rand_col_1 in range(5,10) and Rand_row_1 in range(7,10):
        #can be any 1, 2, 3 or 4... in that order below
        Rand_position_1 = randint(1,4)
        if Rand_position_1 == 1:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 4:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif Rand_col_1 == 0 and Rand_row_1 == 0:
        #can be any 1, 2, 3 or 4... in that order below
        Rand_position_1 = randint(1,4)
        if Rand_position_1 == 1:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 4:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif (Rand_col_1 == 5 and Rand_row_1 == 0) or (Rand_col_1 == 11 and Rand_row_1 ==6):
        #can be one or four
        #check brackets and booleans here
        Rand_position_1 = randint(1,2)
        if Rand_position_1 == 1: #position 1
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2: #position 4
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif Rand_col_1 == 0 and Rand_row_1 == 11:
        #can be 2 or 3
        Rand_position_1 = randint(2,3)
        if Rand_position_1 == 2: #position 2
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3: #position 3
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
    Elif Rand_col_1 == 11 and Rand_row_1 == 11:
        #can be 2 or 4
        Rand_position_1 = randint(1,2)
        if Rand_position_1 == 1: #position 2
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 2: #position 4
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif (Rand_row_1 == 0 and Rand_col_1 in range(1,4)) or (Rand_row_1 == 6 and Rand_col_1 in range(6,10)):
        #can be 1, 3 or 4
        #check brackets and booleans here
        Rand_position_1 = randint(1,3)
        if Rand_position_1 == 1: #position 1
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2: #position 3
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 3: #position 4
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif (Rand_col_1 == 5 and Rand_row_1 in range(1,5)) or (Rand_col_1 == 11 and Rand_row_1 in range(7,10)):
        #can be 1, 2 or 4
        #check brackets and booleans here
        Rand_position_1 = randint(1,3)
        if Rand_position_1 == 1: #position 1
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2: #position 2
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3: #position 4
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2
    Elif Rand_col_1 == 0 and Rand_row_1 in range(1,10):
        #can be 1, 2 or 3... in that order below
        Rand_position_1 = randint(1,3)
        if Rand_position_1 == 1:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 + 1][Rand_col_1] = 2
        if Rand_position_1 == 2:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3:
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
    Elif Rand_col_1 in range(1,10) and Rand_row_1 == 11:
        #can be 2, 3 or 4
        Rand_position_1 = randint(1,3)
        if Rand_position_1 == 2: #position 2
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1 - 1][Rand_col_1] = 2
        if Rand_position_1 == 3: #position 3
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 + 1] = 2
        if Rand_position_1 == 4: #position 4
            Player[Rand_row_1][Rand_col_1] = 2
            Player[Rand_row_1][Rand_col_1 - 1] = 2

Après avoir appliqué mon code, j'obtiens cette erreur.

    Traceback (most recent call last):
  File "<stdin>", line 310, in <module>
  File "<stdin>", line 15, in PrintBoards
TypeError: sequence item 0: expected string, NoneType found

et voici la fonction PrintBoards

def PrintBoards(Player,Opponent):
    print ' '*10, 'PLAYER', ' '*30, 'OPPONENT'
    letters = ['A','B','C','D','E','F','G','H','I','J','K','L']
    for x in range(6):
        print letters[x],"  ".join(map(DisplayChar,Player[x]))," "*18,"| ","  ".join(map(DisplayChar,Opponent[x]))
    for x in range(6,12):
        print letters[x],"  ".join(map(DisplayChar,Player[x]))," | ","  ".join(map(DisplayChar,Opponent[x]))
    print " ","  ".join(map(str,range(1,10)))," 10 11 12","  ","  ".join(map(str,range(1,10)))," 10 11 12"

et voici la fonction DisplayChar

def DisplayChar(x):
    if x==0: 
        return '?'
    Elif x==1:
        return ' '
    Elif x==2:
        return 'X'
    Elif x==3:
        return ' '
    Elif x==4:
        return '*'

J'ai essayé de modifier la fonction ci-dessus pour cela ...

def DisplayChar(x):
        if x==0: 
            return '?'
        Elif x==2:
            return 'X'
        Elif x==4:
            return '*'
        else:
            return ' '

Cependant il m'a donné cette erreur à la place

Traceback (most recent call last):
  File "<stdin>", line 309, in <module>
  File "<stdin>", line 15, in PrintBoards
TypeError: argument 2 to map() must support iteration

J'ai également essayé d'imprimer les listes Player et Opponent après la fonction PrintBoards pour s'assurer qu'elles contenaient des 0 et des 1 (en référence à la fonction DisplayChar), ce qu'elles font (lorsqu'elles sont insérées dans l'original, pas lorsque je mets mon nouveau et très long code)

Ce bit suivant est une réponse à Michael

PLAYER                                OPPONENT
[[1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1], [1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
[0, 0, 0, 0, 0, 0]
A                                                       |  ?  ?  ?  ?  ?  ?
<function Deploy_Destroyer_1 at 0x1c2634>
[0, 0, 0, 0, 0, 0]
B
Traceback (most recent call last):
  File "<stdin>", line 314, in <module>
  File "<stdin>", line 17, in PrintBoards
TypeError: argument 2 to map() must support iteration

MODIFIER

Après que quelqu'un a gentiment fait remarquer que j'avais assigné la fonction au lieu de l'appeler, j'ai constaté qu'une autre erreur s'était produite (je ne pense pas que Python m'aime bien)

Traceback (most recent call last):
  File "<stdin>", line 313, in <module>
  File "<stdin>", line 17, in PrintBoards
TypeError: argument 2 to map() must support iteration

Ci-dessous, j'ai également indiqué où j'ai appelé la fonction au cas où je ferais une bêtise.

Player, Opponent = InitBoards()
Player = DeployFleet(Player), Deploy_Destroyer_1(Player)
PrintBoards(Player,Opponent)

EDIT 2

Je l'ai changé en ce que Micheal0x2a a dit et il s'est déroulé sans erreur, mais le navire que le code place a disparu: s 

D'après ce que j'ai compris, la fonction PrintBoards imprime le tableau pour la Player en mappant les éléments de la liste à la fonction DisplayChar (si 2 est un élément de la liste, il imprime X, etc.). Ainsi, mes connaissances de novice me disent que la fonction Deploy_Destroyer_1 doit être appelée dans Player = dans la fonction Main (incluse ci-dessus) pour garantir que l'élément de la liste est modifié. Le caractère imprimé doit donc être modifié. 

Je suppose qu'il y a quelque chose qui ne va pas dans mon nouveau code (Deploy_Destroyer_1) qui ne le fait pas correctement (soit ne change pas l'élément de la liste et n'imprime donc pas le caractère correct, ou quelque chose d'autre que je peux ». ne pense pas à). 

Cependant, il y a aussi une grande chance que je me suis confus :)

Je n'ai appris le python que depuis quelques semaines, donc si quelqu'un a besoin de plus de détails pour m'aider, merci de demander 

12
BLeeM

Si vous êtes arrivé ici parce que vous recherchiez la cause première de "TypeError: sequence item 0: expected string, NoneType found", cela peut venir de faire quelque chose dans ce sens ...

','.join([None])
70
Noel Evans

Votre fonction DisplayChar n'a pas de valeur par défaut. Cela ne ferait aucun mal si vous gérez tous les cas possibles pour x, mais apparemment, vous ne l'êtes pas. Essayer

def DisplayChar(x):
    if x == 0: 
        return '?'
    Elif x == 2:
        return 'X'
    Elif x == 4:
        return '*'
    else:
        return ' '

mais cela donnera probablement des chaînes vierges où vous ne les attendez pas.

En général, je vous recommande de commencer par un bon tutoriel sur Python. Tout votre code ci-dessus peut être grandement simplifié. 

1
Johannes Charra

Le problème se situe probablement dans ces 4 lignes:

for x in range(6):
    print letters[x],"  ".join(map(DisplayChar,Player[x]))," "*18,"| ","  ".join(map(DisplayChar,Opponent[x]))
for x in range(6,12):
    print letters[x],"  ".join(map(DisplayChar,Player[x]))," | ","  ".join(map(DisplayChar,Opponent[x]))

Dans ces lignes, vous avez utilisé plusieurs fois une instruction join. L'instruction join requiert une liste de chaînes pour fonctionner. Toutefois, lorsque vous mappez DisplayChar à Player[x], la fonction DisplayChar renvoie la valeur None au lieu d'une chaîne quelconque.

Si vous examinez la fonction DisplayChar, elle ne traite que les valeurs de 0 à 4. Les listes que vous utilisez contiennent probablement des chiffres ou des caractères supplémentaires. Si x se trouve être quelque chose comme 5, DisplayChar se terminera et renverra simplement la valeur None. N'oubliez pas que les fonctions renvoient la valeur None par défaut.

Vous devez soit gérer ces numéros supplémentaires dans DisplayChar, soit modifier DisplayChar pour contenir une instruction else afin de renvoyer une chaîne vide, comme suit:

def DisplayChar(x):
    if x==0: 
        return '?'
    Elif x==1:
        return ' '
    Elif x==2:
        return 'X'
    Elif x==3:
        return ' '
    Elif x==4:
        return '*'
    else:
        return ' '

Modifier:

Ok, je pense que je pourrais savoir ce qui se passe, compte tenu des nouvelles modifications.

Notez que lorsque vous imprimiez Player[x], il imprimait <function Deploy_Destroyer_1 at 0x1c2634> la deuxième fois?

Cela signifie que quelque part, enfoui au plus profond de votre code, vous avez agi comme suit: Player[row] = Deploy_Destroyer_1 (remarquez la parenthèse manquante!). Au lieu d'appeler la fonction, vous avez assigné la fonction. 

La recherche et l'ajout de parenthèses manquantes devraient probablement résoudre le problème. 

Edit 2:

Je pense que votre problème est avec cette ligne: Player = DeployFleet(Player), Deploy_Destroyer_1(Player)

Si vous essayez de faire un print Player immédiatement après, je pense que vous verrez probablement une grande liste de nombres, suivie de None.

En effet, la fonction DeployFleet renvoie la table (je pense?) Alors que la fonction Deploy_Destroyer_1 ne renvoie rien. Au lieu de cela, il ne fait que transformer la table Player.

Pour résoudre ce problème, essayez ceci:

Player = DeployFleet(Player)
Deploy_Destroyer_1(Player)

... ou modifiez Deployer_Destroyer_1 pour qu'il renvoie Player une fois terminé, afin que vous puissiez le faire:

Player = DeployFleet(Player)
Deploy_Destroyer_1(Player)
0
Michael0x2a