• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Niespodziewane zachowanie funkcji własnej

Object Storage Arubacloud
0 głosów
203 wizyt
pytanie zadane 31 października 2018 w Python przez El Lirón Obywatel (1,320 p.)
edycja 31 października 2018 przez El Lirón

Cześć! Piszę kalkulator wyborczy, czyli program do rozdzielania mandatów dla partii w zależności ile mają głosów. Stworzyłem funkcję give_the_seat(), która powinna: 1) posortować listę "wygrywających ilorazów" (win_list), 2) wybrać największy iloraz (the_b) 3) sprawdzić, czy na liście ilorazów każdej partii znajduje się największy iloraz i jeśli tak, to przydzielić tej partii miejsce w Sejmie/Radzie (funkcja get_seat()). Następnie w części głównej usunąć największy iloraz z listy i powtarzać operację tak długo, jak długo są mandaty do rozdania.

Problem polega na tym, że wszystkie partie otrzymują... tą samą ilość miejsc równą liczbie miejsc do wygrania. Co tu jest nie tak? Czy ja gdzieś pomyliłem kolejność, przeoczyłem coś? Czy cała ta funkcja jest zła? Będę wdzięczny za każdą podpowiedź.

kod główny:
 


import P

#user gives info about electoral district

hm_seats=int(input("Ile mandatów jest możliwych do zdobycia w tym okręgu? "))

hm_parties=int(input("Ile partii wzięło udział w wyborach w tym okręgu? "))

party_list=[]

x=0
while x < hm_parties:
    p=P.Party()
    party_list.append(p)
    x += 1

system = int(input("""
W jakim systemie zostaną przeliczone głosy?
d'Hondta - wybierz 1
Sainte-Lague - wybierz 2
Hare'a-Niemayera - wybierz 3 
"""))

scope=[1, 2, 3]
while system not in scope:
    system = int(input("""
Wybierz 1, 2 lub 3
d'Hondta - wybierz 1
Sainte-Lague - wybierz 2
Hare'a-Niemayera - wybierz 3 
"""))

# calculations in d'Hondt system
## creatig quotients' lists for each party

if system == 1:
    for p in party_list:
        divisor = 1

        x=0
        while x < hm_seats:
            quotient = p.votes/divisor
            p.quotients_list.append(quotient)
            divisor += 1
            x += 1

## creating list of all qoutients

    all_quotients = []

    for p in party_list:
        for quotient in p.quotients_list:
            all_quotients.append(quotient)

## looking for biggests quotients

    winning_quotients = []

    x=0
    while x < hm_seats:
        the_biggest = P.find_the_biggest(all_quotients)
        x+=1
        winning_quotients.append(the_biggest)
        all_quotients.sort(key=int, reverse=True)
        all_quotients.pop(0)

    print("test0: ", winning_quotients)
## distrubution of seats

    x=hm_seats
    while x>0:
        P.give_the_seat(party_list, p.quotients_list, winning_quotients)
        winning_quotients.sort(key=int, reverse=True)
        winning_quotients.pop(0)
        x-=1

    print("test1: ", party_list[0].seats)
    print("test2: ", party_list[1].seats)
    print("test3: ", party_list[2].seats)

Funkcje i klasy:
 


class Party(object):
    def __init__(self):
        self.ask_party_name()
        self.ask_party_votes()
        self.seats = 0
        self.quotients_list = []

    def ask_party_name(self):
        self.party_name = input("Podaj nazwę lub skrót partii: ")

    def ask_party_votes(self):
        self.votes = int(input("Podaj liczbę głosów, którą zdobyła partia " + self.party_name + ": "))

    def get_seat(self):
        self.seats += 1

def find_the_biggest(list):
    list.sort(key=int, reverse=True)
    the_b = list[0]
    return the_b

def give_the_seat(par_list, q_list, win_list):
    win_list.sort(key=int, reverse=True)
    the_b = win_list[0]
    for p in par_list:
        for q in q_list:
            if q == the_b:
                p.get_seat()

Output:

Ile mandatów jest możliwych do zdobycia w tym okręgu? 7
Ile partii wzięło udział w wyborach w tym okręgu? 3
Podaj nazwę lub skrót partii: A
Podaj liczbę głosów, którą zdobyła partia A: 100
Podaj nazwę lub skrót partii: B
Podaj liczbę głosów, którą zdobyła partia B: 200
Podaj nazwę lub skrót partii: C
Podaj liczbę głosów, którą zdobyła partia C: 400

W jakim systemie zostaną przeliczone głosy?
d'Hondta - wybierz 1
Sainte-Lague - wybierz 2
Hare'a-Niemayera - wybierz 3
1
test0:  [400.0, 200.0, 200.0, 133.33333333333334, 100.0, 100.0, 100.0]
test1:  7
test2:  7
test3:  7

Process finished with exit code 0

informacje o metodzie d'Hondt'a jeśli ktoś chce przeczytać :)
https://pl.wikipedia.org/wiki/Metoda_D%E2%80%99Hondta

1
komentarz 31 października 2018 przez adrian17 Ekspert (344,860 p.)
Wrzucisz cały kod?
komentarz 31 października 2018 przez El Lirón Obywatel (1,320 p.)
Jasne, już wrzucam. Zaraz edytuję pytanie.

1 odpowiedź

+1 głos
odpowiedź 31 października 2018 przez adrian17 Ekspert (344,860 p.)

Na oko... to nie ma sensu.

while x>0:
        give_the_seat(party_list, p.quotients_list, winning_quotients)

Przekazujesz jako argument listę współczynników jednej konkretnej partii i zawsze z nią porównujesz.

BTW, dużo kodu masz przekombinowane. Na przykład:

the_biggest = find_the_biggest(all_quotients)

to po prostu

the_biggest = max(all_quotients)

Podobnie, cała ta pętla

    x=0
    while x < hm_seats:
        the_biggest = find_the_biggest(all_quotients)
        x+=1
        winning_quotients.append(the_biggest)
        all_quotients.sort(key=int, reverse=True)
        all_quotients.pop(0)

To po prostu

    all_quotients.sort(reverse=True)
    winning_quotients = all_quotients[:hm_seats]

 

komentarz 31 października 2018 przez El Lirón Obywatel (1,320 p.)
1) Masz rację. Już zmieniłem te parametry i sprawdzę jak to działa.

2) Bardzo ciekawe, nie znałem tego :)

Dzięki za pomoc.

Podobne pytania

0 głosów
1 odpowiedź 189 wizyt
0 głosów
1 odpowiedź 111 wizyt
0 głosów
1 odpowiedź 142 wizyt

92,573 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...