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

Niespodziewane zachowanie funkcji własnej

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
249 wizyt
pytanie zadane 31 października 2018 w Python przez El Lirón Obywatel (1,350 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 Mentor (350,120 p.)
Wrzucisz cały kod?
komentarz 31 października 2018 przez El Lirón Obywatel (1,350 p.)
Jasne, już wrzucam. Zaraz edytuję pytanie.

1 odpowiedź

+1 głos
odpowiedź 31 października 2018 przez adrian17 Mentor (350,120 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,350 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ź 328 wizyt
0 głosów
1 odpowiedź 136 wizyt
0 głosów
1 odpowiedź 162 wizyt

93,109 zapytań

142,087 odpowiedzi

321,610 komentarzy

62,450 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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...