Niepoprawne obliczenia w nawiasie

0

Żeby obliczyć ile % całości stanowi int(x[0]) trzeba podzielić int(x[0]) przez sumę całości wziętą w nawias i pomnożyć * 100. Na kalkulatorze wychodzi około 18%. W Pythonie dodanie nawiasu przed int powoduje nieprawidłowe wyniki. Przykład poniżej to tylko uproszczenie, w moim prawdziwym programie nie da się przekonwertować na typ int, muszę przed każdym wyrażeniem dodać typ int. Jak można zmusić program żeby poprawnie obliczył to wyrażenie?

x = ["338","836","736"]

print int(x[0])/(int(x[0])+int(x[1])+int(x[2]))*100
0

float!

2

W Python 2 dzielenie liczby całkowitej przez całkowitą zostaje zaokrąglone do liczby całkowitej.
Musisz jedną z liczb przed dzieleniem zamienić na liczbę rzeczywistą za pomoca float()
(lub ewentualnie mnożąć przez liczbę rzeczywistą 1.0)

Swoją drogą to mógłbyś najpierw wszystkie teksty zamienić na wartości liczbowe
aby nie robić tych samych obliczeń wiele razy.
Przez to i sam zapis obliczenia byłby czytelniejszy.

x = ["338","836","736"]
 
x = map(int, x)

print float(x[0]) / (x[0]+x[1]+x[2]) * 100

Tutaj można nawet zastosować sum()

x = ["338","836","736"]
 
x = map(int, x)

print float(x[0]) / sum(x) * 100

Ostatecznie wynik będzie liczbą rzeczywistą 17.6963350785
i jak chcesz zaokrąglenia to użyj np. round()
i otrzymasz liczbę rzeczywistą 18.0
Jak chcesz aby wynik znów był liczbą całkowitą to użyj int()

x = ["338","836","736"]
 
x = map(int, x)

wynik = float(x[0]) / sum(x) * 100

print round(wynik) # rzeczywista 18.0
print int(round(wynik)) # calkowita 18

**EDIT: **

Co do dzielenia można też zamienić kolejność działań
i zamienić całkowite 100 na rzeczywiste 100.0
aby najpierw nastąpiło mnożenie rzeczywistej i całkowitej co da rzeczywistą
a dopiero potem aby dzieliło rzeczywistą przez całkowitą co da rzeczywistą.

x = ["338","836","736"]
 
x = map(int, x)

wynik = 100.0 * x[0] / sum(x)

print round(wynik) # rzeczywista 18.0
print int(round(wynik)) # calkowita 18

--

Najłatwiejszym rozwiązaniem jest jednak zaimportowanie z "przyszłości"
dzielenia takiego jak jest w Python 3

from __future__ import division

print 1/2  # 0.5
print 1//2 # 0  zaokrąglenie do całkowitych

i od teraz wszystkie dzielenia dają wynik rzeczywisty.

0

Napisałem to jednak w zbytnim uproszczeniu. W moim prawdziwym przykładzie nie bardzo mogę użyć map() bo to jest tupla, której pierwszy element składa się tylko z liter. Na razie udało mi się napisać taki prosty wzór:

import re

x = "xwhatevert67364646a83746554b3623"
for name in re.findall('x(whatever)t(\d+)a(\d+)b(\d+)', x):
    print name[0], int(round(float(name[1])/(int(name[1])+int(name[2])+int(name[3]))*100))

i nawet on działa, ale czasami powoduje bugi.

1

moja propozycja

import re

for name in re.findall('x(whatever)t(\d+)a(\d+)b(\d+)', x):
    a = map(lambda y: y.isdigit() and int(y) or y, name)
    print a[0], 100. * a[1] / sum(a[1:])
1

Zawsze można pobrać wycinek tupli lub listy bez pierwszego elementu.

import re
 
x = "xwhatevert67364646a83746554b3623"

for name in re.findall('x(whatever)t(\d+)a(\d+)b(\d+)', x):

    liczby = map(int, name[1:]) # bez pierwszego elementu

    print name[0], int(round( float(liczby[0]) / sum(liczby) * 100 ))

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