Jak bardzo Pythonowy jest mój kod

0

Proszę o ocenę mego kodu, wcześniej kodziłem trochę w C++:

import random
import getpass

rock = "rock"
paper = "paper"
scissors = "scissors"

single_player = "single player"
multiplayer = "multiplayer"

synonyms = {"rock": rock,
            "paper": paper,
            "scissors": scissors,
            "stone": rock,
            "vellum": paper,
            "shears": scissors,
            "kamien": rock,
            "papier": paper,
            "nozyce": scissors,
            "r": rock,
            "p": paper,
            "s": scissors
            }

modes = {"single": single_player,
         "multi": multiplayer,
         "singleplayer": single_player,
         "multiplayer": multiplayer,
         "single player": single_player,
         "s": single_player,
         "m": multiplayer
         }


chosen_single_player = "You Chosen The Game With a Computer" 

chosen_multi_player = "You Chosen The Game With An Another Player"


game_is_draw = "Game is a Draw"

playerA_wins = "Player A Wins"

playerB_wins = "Player B Wins"


transitions = {(null, null): both_players_must_choose,
               (null, rock): playerA_must_choose,
               (null, paper): playerA_must_choose,
               (null, scissors): playerA_must_choose,
               (rock, null): playerB_must_choose,
               (rock, rock): game_is_draw,
               (rock, paper): playerB_wins,
               (rock, scissors): playerA_wins,
               (paper, null): playerB_must_choose,
               (paper, rock): playerA_wins,
               (paper, paper): game_is_draw,
               (paper, scissors): playerB_wins,
               (scissors, null): playerB_must_choose,
               (scissors, rock): playerB_wins,
               (scissors, paper): playerA_wins,
               (scissors, scissors): game_is_draw
               }
               

playerA_choice = ' '
playerB_choice = ' '
mode_choice = ' '

# Main 
print("You are playing Rock Paper Scisscors")
print("Choose a mode: single player or mutliplayer?" )
while mode_choice not in modes:
    mode_choice = input("Enter The Game Mode: ")

if modes[mode_choice] == single_player:
    while playerA_choice not in synonyms:
        playerA_choice = input("Enter Your Choice: ")
            
    playerB_choice = random.choice(list(synonyms.keys()))
    #print(playerB_choice)

    print(transitions[synonyms[playerA_choice], synonyms[playerB_choice]])

elif modes[mode_choice] == multiplayer:
    while playerA_choice not in synonyms:
        playerA_choice = getpass.getpass("Player A: Enter Your Choice: ")

    while playerB_choice not in synonyms: 
        playerB_choice = getpass.getpass("Player B: Enter Your Choice: ")
   
    print("The Player A Choose '{}' And The Player B Choose '{}'".format(playerA_choice, playerB_choice)) 
    print(transitions[synonyms[playerA_choice], synonyms[playerB_choice]])
0

"playerA_must_choose" --- gdzie deklarujesz te zmienne? Odpala ci się ten kod i nie rzuca błędem?

Pozostałość po starym koncepcie. Ta opcja nie występuje, nie ma szans jej wywołać.

0

Pomijając fakt, że się nie uruchamia bo brak wielu zmiennych:

Z pythonowych rzeczy to bym nazwał dużymi literami stałe,
czyli elementy, którym nie jest zmieniana wartość
np.

ROCK = "rock"
PAPER = "paper"
SCISSORS = "scissors"

Z rzeczy już niepythonowych to zamiast wartości tekstowych
przypisał bym im wartości liczbowe - i tak ich nie wypisujesz
a liczby szybciej komputerowi porównać
choć przy tak małej grze to nie ma takiego znaczenia

ROCK = 1
PAPER = 2
SCISSORS = 3

Przy wyborze trybu gry i symbolu wolałbym jednak wybierać cyfrę 1, 2 lub pojedynczyą literę
niż pisać całe słowo więc taka możliwość wydaje mi się zbyteczna.

0

Może pisz bardziej obiektowo niż strukturalnie?

1

nie widzę ani jednego słowa kluczowego def co dla mnie jest oznaką, że jest bardzo źle (jak używałeś C++ to też musiało być jeszcze bardziej nieczytelnie).

6

Wyobraź sobie, że ktoś chciałby użyć np. jakiejś stałej z twojego kodu. Importuje sobie więc: from nazwa_modulu import transitions. Chyba ostatnie, czego w tym momencie się spodziewa, to wyświetlenie dwóch tekstów w konsoli i czekanie na input użytkownika, a tak niestety się dzieje po zaimportowaniu twojego modułu. Żeby się przed tym uchronić otaczamy wykonywalny kod w takiego ifa:

if __name__ == '__main__':
    pass  # wykonywalny kod tutaj

Generalnie robimy tak zawsze, gdy wiemy, że kod może być odpalany bezpośrednio, a nie tylko importowany. Więcej o tym tutaj.

Jak najbardziej zgadzam się z @MarekR22, musisz wydzielić z tego czytelne funkcje. Linijek będzie więcej, ale wracając do tego po kilku miesiącach skumasz znacznie szybciej o co chodzi. Może to nie jest widoczne przy dosyć prostym kodzie, ale kilkanaście linijek więcej i nie wiedziałbyś co się tu dzieje. Staraj się, żeby funkcje miały maksymalnie jeden stopień zagłębienia i były krótkie, a nazwy sensowne. Wtedy taki kod się czyta jak książkę ;)

Natomiast nie zgadzam się ze @Spine, nie widzę tutaj potrzeby wsadzania żadnych klas. Python to nie Java i nie chodzi o to, że nie piszę się w nim obiektowo, tylko, że nie zawsze konieczne jest opakowywanie wszystkiego w to słowo kluczowe, a kod nadal może zostać "obiektowy". W Pythonie moduły są obiektami, więc przestrzeń nazw mamy. Dalej - jako, że instancja gry byłaby i tak singletonem, to na jedno wychodzi, dodalibyśmy po prostu kolejny niepotrzebny poziom pseudo-abstrakcji. W Pythonie nie ma nacisku na enkapsulację, dodanie klasy nic w tym nie zmienia. Wniosek: jest okej. Inna rzecz przy bardziej rozbudowanej grze, gdzie takich obiektów byłoby znacznie więcej, ale nawet wtedy stawiałbym głównie na takie rzeczy jak namedtuple czy słowniki, gdzie tylko się da.

1

Powtarzająca się logika. Najpierw masz tutaj coś takiego:

 while playerA_choice not in synonyms:
        playerA_choice = getpass.getpass("Player A: Enter Your Choice: ")

a potem prawie to samo, tylko dla gracza B:

    while playerB_choice not in synonyms: 
        playerB_choice = getpass.getpass("Player B: Enter Your Choice: ")

To przeciez można włożyć funkcję (czyli zgadza się to, o czym @MarekR22 mówił, że nie ma żadnej funkcji zdefiniowanej) nazwać np. get_player_choice i wywoływać tak:



get_player_choice(playerB)

nie prościej?

Poza tym... po co playerA, playerB? To nie jest skalowalne, bo 3 gracz już nie dojdzie. Lepiej już zrobić listę graczy, np.

[
{'name': 'Marcin', 'last_choice': None},
{'name': 'Genowefa', 'last_choice': None},
]

(używam literału obiektu dla prostoty, chociaż zapewne taką listę będziesz tworzył inaczej, bardziej dynamicznie, wczytując najpierw od usera liczbę graczy i ich imiona)

Dalej mamy niepotrzebne w tym przypadku rozróżnienie na singleplayer i multiplayer. Są gry, gdzie rozgrywka na jedną osobę i drugą jest zupełnie inna, i takie rozróżnienie miałoby sens. Ale tutaj rozgrywka jest dokładnie taka sama. Ludzie po kolei dokonują wyborów i potem nastąpi przeliczenie punktów.

Więc to zrobiłeś:

if modes[mode_choice] == single_player:
....
elif modes[mode_choice] == multiplayer:

Jest słabe. Z powodu nieumiejętności wydzielenia abstrakcji poszedłeś na łatwiznę i zrobiłeś kopiuj-wklej.

A przecież zobacz. Czym się różni tryb single i multiplayer?
Tylko tym:

 playerB_choice = random.choice(list(synonyms.keys())

A wystarczy, żebyś w danych gracza dodał flagę czy dany gracz jest człowiekiem czy komputerem:

[
{'name': 'Marcin', 'last_choice': None, 'is_human': True }
{'name': 'Genowefa', 'last_choice': None, 'is_human': False},
]

a potem sprawdzać coś w rodzaju tego:

if player['is_human']:
    player['choice'] = get_player_choice(player)
else: 
    player['choice'] = random.choice(list(synonyms.keys())

Podsumując - twój kod jest bardzo imperatywny, brak większych abstrakcji, dużo powtórzeń tych samych idiomów etc.
Bardziej jakbyś w assemblerze pisał, niż w pythonie... ;)

Tym niemniej wydaje mi się, że pytanie jest źle zadane. Nie jest kwestia tego, czy kod jest pythonowy czy nie, tylko raczej czy umiesz dostrzec i zaimplementować odpowiednie abstrakcje. Ale to można ćwiczyć. Tylko trzeba zwracać uwagę na

  • elastyczność programu (twój program nie jest elastyczny, bo 3 gracz nie dojdzie)

  • prostotę kodu (twój program nie jest prosty, bo powtarzasz to samo dla trybu single i multi, zamiast mieć w jednym miejscu tę logikę)

  • czytelność (twój kod przez to, że nie ma żadnych abstrakcji tylko ciurkiem wszystko leci zbyt czytelny nie jest).

  • strukturę danych / model (Tutaj o ile częściowo o tym myślałeś (transitions) to np. o tym, żeby wsadzić dane gracza w jakiś słownik, obiekt czy jakąkolwiek inną strukturę danych (ew. nadać mu ID i rozpoznawac go po identyfikatorze, tak jak jest to w bazach danych), już kompletnie nie pomyślałeś tylko piszesz zmienne luzem playerA_choice, playerB_wins etc. Czyli koncepcja Gracz w ogóle nie istnieje w twoim programie. Robisz grę bez graczy, jedynie z "wyborami graczy" czy z "wygranymi graczy".)

Oczywiście z abstrakcjami też można przesadzić. Jakiś programista Javy do tego co robisz pewnie porobiłby 15 różnych klas, implementując 30 różnych interfejsów i 10 różnych wzorców projektowych - co byłoby mocno przekombinowane ;)

0

Powołując się na python zen:

Simple is better than complex

Myślę, że tutaj trafiono w samo sedno. Kod jest nadal prosty i zrozumiały. Co prawda można sugerować Ci sztuczki z pythona bądź podział na funkcje, klasy czy też inne praktyki (testy, wzorce), ale przy tak prostych zadaniach to nie jest konieczne. W każdym razie jeśli na tym etapie zaczniesz przejmować się samą formą niż treścią to w niedługim czasie zobaczymy tutaj Twoje metaprogramowanie :-)

0

Hej, dzięki za liczne odpowiedzi ;) Można na was liczyć. Spróbuje się odnieść do niektórych zarzutów, zaprezentuję nowy kod i przedstawię listę pytań.
@Wizzie: przyznam, że pierwszego i ostatniego akapitu twego postu po prostu nie zrozumiałem. Ale też nie poświecałem zbytnio czasu na to. Po prostu nie miałem kiedy. Ale dzięki, szczególnie za to o zasadności stosowania funkcji

@LukeJL: bardzo fajnie i zwięźle wypunktowałeś co jest źle. Dzięki.

Wrzucam nowy kod. Troszkę go rozbudowałem o dodatkowe funkcje (dodawanie graczy, zarządzanie dodanymi już graczmi, generowanie imion graczy według potrzeby, kamień, papier, nożyce, jaszczurka i Spock :), rundy).

import random
import time
import getpass

players_list = []

def generate_player_name():
    names = ['Plaska Dziewica', 'Zbutwialy Piernik', 'Mistrz Wegorza', 'Zjadacz Sedesow',
             'Stanikowy Deszcz', 'Smetny Pierd', 'Sprzedam Seata', 'Zimna Warka',
             'Jacek Maly Wacek', 'Waleczny Mlot', 'Szalony Ziemniak', 'Sheldon'
             'Waz Rzeczny', 'Tururu Tururu', 'Jest Niebezpieczny' ]
    
    decision = ' '
    possible_decision = ('Y', 'N')
    while decision not in possible_decision:
        player_name = random.choice(names)
        decision = input('>> Do The Name ' + player_name + " Is OK With You? If Not I Will Draw Again [Y/N] ").upper()

        if(decision == 'Y'):
            print('>> Great then!', player_name)
            return player_name
        elif decision == 'N':
            decision = ' '


def create_player(decision, possible_decisions):
    flag = ' '
    possible_flags = {'C': 'is_computer', 'H': 'is_human'}
    while(flag not in possible_flags):
        flag = input('>> Will The Player Be Controlled By [H]uman or [C]omputer? ').upper()

    if(decision == 'M'):
        player_name = input('>> Type The Name:')  
    elif(decision == 'A'):
        player_name = generate_player_name()

    players_list.append( {'player_name': player_name,
                         'player_flag': possible_flags[flag],
                         'player_decision': None,
                         'player_points': 0}
                        )


def add_player():
    list_status = len(players_list)
    decision = ' '

    while decision != 'B':
        decision = input(">> Do You Want To Create New Player [M]anualy Or Should I Do It [A]utomaticly (I'll Generate The Name)?\n   [B]ack To Main Menu ").upper()

        possible_decisions = ['A', 'M']
        if(decision in possible_decisions):
            create_player(decision, possible_decisions)

            decision = ' '
            possible_decisions = ['Y', 'N']
            while decision not in possible_decisions:
                decision = input('>> You Just Added The Player! Do You Want To Add Another One? [Y/N] ' ).upper()

                if(decision == 'N'):
                    decision = 'B'
                    break

        if(decision == 'B'):
            print('>> You Just Added:',  len(players_list) - list_status, 'Players')


def play():
    print(">> We Will Play In That Order:", end = ': ')
    for player in players_list:
        print(player['player_name'], end = ', ')
    print() # newline

    number = 99
    while not number <= 5 or number <= 0:
        number = int(input('>> Before You Start Type How Many Rounds Do You Want To Play?\n   The Maximum Number Of Rounds Is Five '))

        if number > 5:
            print('As I Said You Cannot Play More Rounds Than Five')
        elif number == 0:
            print('In This Case I Predict The Score. NOBODY WON AND NOBODY LOST')
        elif number < 0:
            print("I Won't Comment On That. Just Type Once Again")

        for rounds in range(0, number):
            print('\n>> Round', rounds + 1)
            make_choice()
            give_points()

    decide_winner()
    clean_points()


def make_choice():
    options = {1: 'rock', 2: 'paper', 3: 'scissors', 4: 'lizard', 5: 'Spock'}

    for player in players_list:
        if(player['player_flag'] == 'is_computer'):
            print('>> It Is {player_name} Turn! The Player Is Controled By The Computer'.format(player_name = player['player_name']))
            for i in range(1, 4):
                print('>> {i}... '.format(i = i))
                time.sleep(1)

            player_decision = random.randint(1, 5)

        elif(player['player_flag'] == 'is_human'):
            player_decision = 2
            while player_decision < 1 and player_decision > 5: 
                player_decision = int(getpass.getpass(">> It Is {player_name} Turn! The possible choices:\n   1: 'rock', 2: 'paper', 3: 'scissors', 4: 'lizard', 5: 'Spock' ".format(player_name = player['player_name'])))
        
        print('>> {player_name} Made a Choice!\n'.format(player_name = player['player_name']));    
        player['player_decision'] = options[player_decision]


def give_points():
    results = {('rock', 'rock'): 'game_is_draw',
               ('rock', 'paper'): 'playerB_wins',
               ('rock', 'scissors'): 'playerA_wins',
               ('rock', 'lizard'): 'playerA_wins',
               ('rock', 'Spock'): 'playerB_wins',
               ('paper', 'rock'): 'playerA_wins',
               ('paper', 'paper'): 'game_is_draw',
               ('paper', 'scissors'): 'playerB_wins',
               ('paper', 'lizard'): 'playerB_wins',
               ('paper', 'Spock'): 'playerA_wins',
               ('scissors', 'rock'): 'playerB_wins',
               ('scissors', 'paper'): 'playerA_wins',
               ('scissors', 'scissors'): 'game_is_draw',
               ('scissors', 'lizard'): 'playerA_wins',     
               ('scissors', 'Spock'): 'playerB_wins',
               ('lizard', 'rock'): 'playerB_wins',
               ('lizard', 'paper'): 'playerA_wins',
               ('lizard', 'scissors'): 'playerB_wins',
               ('lizard', 'lizard'): 'game_is_draw',
               ('lizard', 'Spock'): 'playerA_wins',
               ('Spock', 'rock'): 'playerA_wins',
               ('Spock', 'paper'): 'playerB_wins',
               ('Spock', 'scissors'): 'playerA_wins',
               ('Spock', 'lizard'): 'playerB_wins',
               ('Spock', 'Spock'): 'game_is_draw'
              }

    print('Results:')
    i = 1
    for playerA in players_list:
        for playerB in players_list[i:]:
            result = results[playerA['player_decision'], playerB['player_decision']]

            if result == 'game_is_draw':
                playerA['player_points'] += 0.5
                playerB['player_points'] += 0.5
                print('  - Players {playerA_name} And {playerB_name} Has Drawn. Each Of Them Got 0.5 Point'
                      .format(playerA_name = playerA['player_name'], playerB_name = playerB['player_name']))

            elif result == 'playerA_wins':
                playerA['player_points'] += 1
                print('  - Player {playerA_name} Won With {playerB_name}. Players {playerA_name} Got 1 Point'
                      .format(playerA_name = playerA['player_name'], playerB_name = playerB['player_name']))

            elif result == 'playerB_wins':
                playerB['player_points'] += 1
                print('  - Player {playerB_name} Won With {playerA_name}. Players {playerB_name} Got 1 Point'
                      .format(playerA_name = playerA['player_name'], playerB_name = playerB['player_name']))

        i += 1


def decide_winner():
    sorted_list = sorted(players_list, key=lambda k: k['player_points'], reverse=True)

    i = 0
    while sorted_list[i]['player_points'] == sorted_list[i + 1]['player_points']:
        i += 1

    print('\n>> The Winner Is...', end = ' ')
    time.sleep(2)
    if i == 0:
        print(sorted_list[0]['player_name'].upper(), '!!!')
    elif i > 0:
        print('There Is a Draw Between ', end = '')
        for j in range (0, i + 1):
            print(sorted_list[j]['player_name'], end = ', ')

        print() #newline

    print('>> Congratulations! You Have Got', sorted_list[0]['player_points'], 'Points')

    print('>> Results:')
    for player in sorted_list:
        print('  ', player['player_name'], player['player_points'])

    print() #newline


def managment_players():
    print('>> The List Of Players: ')
    for player in players_list:
        print('   - {player_name} is controled by {player_flag}'. format(player_name = player['player_name'], player_flag = player['player_flag'][3:]))
    
    possible_decision = ('D', 'B')
    decision = ' '
    while decision not in possible_decision:
        decision = input('>> Do You Want To [D]elete a Player? [B]ack To Main Menu ').upper()

        if decision == 'D':
            number = 99
            while not number < len(players_list) + 1:
                number = int(input(">> What Player Do You Want To Delete? Give Me a Number "))

                if number > len(players_list) + 1:
                    print('>> The Player With {number} Number Does Not Exist'.format(number = number)) 

                else:
                    possible_decision = ('Y', 'N')
                    while decision not in possible_decision:
                        decision = input('>> Are You Sure You Want To Delete {player_name} Player? [Y/N] '.format(player_name = players_list[number - 1]['player_name'])).upper()

                        if decision == 'Y':
                            del players_list[number - 1]
                            print('>> You Just Removed The Player!')
                            break
                    
                    possible_decision = ('D', 'B')
                            

def clean_points():
    for player in players_list:
        player['player_points'] = 0
         
    sorted_list = []                       


''' for tests
players_list.append( {'player_name': 'Marek',
                        'player_flag': 'is_human',
                        'player_decision': None,
                        'player_points': 0}
                    )

players_list.append( {'player_name': 'Karolinka',
                        'player_flag': 'is_computer',
                        'player_decision': None,
                        'player_points': 0}
                    )

players_list.append( {'player_name': 'Sraromir',
                        'player_flag': 'is_computer',
                        'player_decision': None,
                        'player_points': 0}
                    )

players_list.append( {'player_name': 'Smutna Julka',
                        'player_flag': 'is_computer',
                        'player_decision': None,
                        'player_points': 0}
                    )
'''

print(">> Welcome To Rock-Paper-Scissors-Lizard-Spock Game. All Rights Reserved. Enjoy! ")
decision = input('>> Before You [P]lay, Remeber To [A]dd Players. You Can [M]anage The List Of Participants At Any Time.\n   When You Get Tired Of The Game, Just [E]xit ').upper()

while(decision != 'E'):
    if(decision == 'E'):
       print('>> Have a Nice Day! ')

    elif(decision == 'P'):
        if not players_list:
            print('>> At First You Need To Add Players. Do It And I Will Let You Play')
        else:
            play()

    elif(decision == 'A'):
        add_player()

    elif(decision == 'M'):
       if not players_list:
            print(">> You Moron! You Didn't Add Any Players Yet!")
       else:
            managment_players()

    decision = input('>> So What Do You Want To Do Now? [P]lay, [A]dd a New Player, [M]anage Already Added Players, Or Just [E]xit? ').upper()

A teraz pytania ode mnie dla was:

  1. Jak powinien wyglądać główny blok kodu? Jaka jest konwencja? Czy powinienem go zamknąć w main() i po prostu go wywołać czy tak jak zrobiłem też jess OK?
  2. Jak wygląda dobrze napisany odpowiednik Switch: case w pythonie za pomocą if'ów?
  3. Czy jest jakiś lepszy sposób na wymuszeniu na użytkowniku odpowiedniego znaku przy wybiorze niż zastosowane przeze mnie:
possible_decision = ['option1', 'option2']
decision = ' '
while decision not in possible_decision:
       decision = input()
  1. Jak brzmią dobrze nazwane funkcje? :)
  2. Czy nie robię bardzo źle że używam zmiennej globalnej (players_list = [])?
  3. Co dostrzegacie gdzieś powtarzającą się logikę o której wspomniał @LukeJL?
2
jaSwiezak napisał(a):

@Wizzie: przyznam, że pierwszego i ostatniego akapitu twego postu po prostu nie zrozumiałem

  1. Jak powinien wyglądać główny blok kodu? Jaka jest konwencja? Czy powinienem go zamknąć w main() i po prostu go wywołać czy tak jak zrobiłem też jess OK?

Tego właśnie dotyczył mój pierwszy akapit. W Pythonie, w momencie gdy ktoś chce zaimportować twoją bibliotekę, cały kod w niej jest po prostu wykonywany. Na przykład weźmy taki kod w pliku o nazwie super_obliczenia.py:

def area_of_rectangle(a, b):
    return a * b

area = area_of_rectangle(5, 10)
test = area == 50
print(area)
print(test)

Czyli jakaś prosta funkcja do liczenia pola prostokąta i 4 linijki prymitywnego testu. Pokazałeś ten kod swojemu szwagrowi Markowi. Marek stwierdził: ta funkcja do liczenia pola jest zajebista! Zaimportuje on sobie tą ją w taki sposób:

from super_obliczenia import area_of_rectangle

Funkcja ładnie się zaimportowała, wszystko działa jak należy, Marek się cieszy. Ale nagle patrzy do konsoli, a tu dwie linijki jakiegoś tekstu. Markowi to bardzo nie pasuje, bo to może wprowadzić w zakłopotanie użytkowników jego programu. W rezultacie tego Marek popada w depresję, sięga do butelki i stacza się na niziny społeczne. W jaki sposób możemy podać rękę Markowi i wyciągnąć go z tej trudnej sytuacji?

A no okazuje się, że można w bardzo prosty sposób. Jeśli uruchamiasz swój program za pomocą komendy python super_obliczenia.py to wszystko działa jak należy, tak? Problem pojawia się, jeśli ktoś importuje twój program z innego modułu. Rozwiązanie to rozgraniczenie tych dwóch rzeczy. Robimy to wykorzystując magiczną zmienną __name__, znajdującą się w każdym module jaki napiszemy. Jeśli uruchamiamy nasz program bezpośrednio (z konsoli), to zmienna __name__ będzie miała wartość __main__. Więc przerabiamy nasz kod w taki sposób:

def area_of_rectangle(a, b):
    return a * b

if __name__ == '__main__':
    area = area_of_rectangle(5, 10)
    test = area == 50
    print(area)
    print(test)

W tym momencie Marek zapisuje się do AA, powoli wychodzi z dołka i wszystko wraca do normy, a nawet jest lepiej, bo Marek jest bogatszy o naszą wspaniałą funkcję. A nasz program działa identycznie jak wcześniej.


Czy powinienem go zamknąć w main()

W twoim przypadku tak, bo jest go dużo. W powyższym przypadku niekoniecznie, bo to tylko 4 linijki.

0

@Wizzle: okej, już wiem o co chodzi. Rozumiem, że dodanie warunku

if __name__ == '__main__':

jest po prostu dobrym nawykiem, tak? Korzystając z okazji: polecacie jakąś dobrą stronkę z dobrze napisanymi kodami w pythonie? Oczywiście na poziomie laika.

Dzięki za zobrazowanie mi tego ;) doceniam.

1

robisz za duże funkcję. Szczególnie managment_players jest zbyt skomplikowane (za dużo funkcji sterujących), dziel to na mniejsze funkcje.
Żadna funkcja nie powinna mięcej więcej niż dwie pętle. A 3-4 instrukcje warunkowe (wliczając w to pętle) to też jest już dużo.

0

W moim kodzie potrzebowałem porównać wartość elementu jednego słownika z wartością elementu zawartego w kolejnym słowniku tej samej listy. Zrobiłem to w ten sposób:

i = 0
    while sorted_list[i]['player_points'] == sorted_list[i + 1]['player_points']:
        i += 1

Czy istnieje bardziej elegancki sposób na rozwiązanie tego? Dodam, że w tym przypadku potrzebuję skorzystać ze zmiennej i poza pętlą

0

Obstawiam, że masz posortowanych playerów po pointsach malejąco i że chcesz coś takiego robić, żeby wyciągnąć graczy, którzy zajmują względem punktacji (gdzie gracz z maksymalną liczbą punktów wygrywa) pierwsze miejsce. Można to pewnie zrobić też tak (uważam, że to ładniejsze):

first_place_winners = [x for x in filter(lambda p: p['player_points'] == sorted_list[0]['player_points'], sorted_list)]

Ale nie wiem. Może chodzi Ci o coś innego ;-)

PS. No i odnoszę wrażenie, że Twój kod się sypnie dla listy takiej, że każdy gracz ma taką samą liczbę punktów.
PS1. Mój zaś sypnie się gdy lista będzie pusta ;-) (Mój się nie sypie, pomyłka.)

1 użytkowników online, w tym zalogowanych: 0, gości: 1