I have a number and I want to find the sum of all of its possible substrings. Since the sum may be very large, I am taking modulo 1e9+7. Here is the code I wrote for it:
n = input()
total = 0
for i in range(len(n)):
for j in range(i, len(n)):
total = (total + int(n[i:j+1]))%(1e9+7)
print(int(total))
But this gives me Overflow error:
OverflowError: int too large to convert to float
Taking modulo inside also doesn't help:
total = (total%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7)
Neither does converting total to int every step:
total = int((total%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7))
I searched online, and many people were using decimal, so I tried that too:
import decimal
n = input()
total = 0
for i in range(len(n)):
for j in range(i, len(n)):
total = decimal.Decimal((int(total)%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7))
print(int(total))
This also gave me the same error. So how can I fix it?
EDIT:
This is the input value causing the error:
630078954945407486971302572117011329116721271139829179349572383637541443562605787816061110360853600744212572072073871985233228681677019488795915592613136558538697419369158961413804139004860949683711756764106408843746324318507090165961373116110504156510362261390086415758369311946617855091322330974469225379475157034653986221430086928768825350265642050874148148762850633380318092218497923938934331494944977897218250062378381926065651168047990017214673422724320097123140849040864223795967322521445859865961967502883479331506850337535224430391571038073324911164139663006137417510539192705821435391823658411385338369730232377028300695738866310468334377735439392551346134885024889217010755804062396901380184592416137322133531990680941959600864409332647120219490414701983979339375751465609840801484592889925172867105767663865003474673877306782492180067353856493873352082672833242368295700361941406607094298524971010582848155295175876416280789802070376313832361148791530700602039387918303750966965311391574707837728570176384970704855124594407172251268098706978376090542912929344492513384183231040016207412648019561891411057151352984928184115181483534959666911309714744265773932487092170761893895469807486999330039447615795396834925983574737750806569360090695009597077440117397176004125384806886783639660621550162794222825503301866755919064102371025428970202609474167093725973377029019369542489008907399816344268271107251422642444394295031677496626574918192538987307032199141725692286015261369012945174380684144484086524852886270717368426832490990772158458075266904766542991903970407465284703623099975166486775916952691073355877964592340230731529088307662462168730966089062336436389277513929792989509527961806655782453847736236387259057358913693838332016851781407524359352813229072505380650711693049176679191021591021389372641247384964875287336650708846120446276882272810745622693709331578317206645848042706067557480758511553310824640020649394355322305550804086562784060919544289531008318716584762468479626254129440271062831239695632816441075920969278753806765451632278698182308325313693381046301850639648800754286747096420253430423489479466804681482044272737999450499555465823164480037422222367329404142745283822947899313540404366082279717101515216147594766392292429511243594117952923319141560834706050302935730124475680758933436231491685270482951411606790235850929380027076481544634203449136248177171198738003486838372217932769689898884784243826855286091288358239337707121625402050851090825870703676300673135330647766969648618275025084598123309185991065848687389917566591933063673989563554382295252021136544002390268843474613430643976640252484632736275857290476774458675146529714463940660919706163233969511685041545624837717646981487338708223589261847530514133271116906741091917303278220653192405195999010112864383206483703165777476499412818478890639921457227974733696980927826881905040085772367856544559431242332068267736163848514181227641896012840513431718789320462329400102516689122316306450427759800832003864806238880726778463445628851437837462460535312158694258263309302240517780411649608046974426356882853543894970861987774349994574781336617336532821610244134603281437218963727001383319023603953398010028490193243704729281796345148350290421966348930850029874490245386530847693496493617805444480239004190850309960252932678216332242871877009997232445612436261407704091991812835292853218055207198699990193596327522065871513324383404436885617489886675946278629169614212976734843602198938090909080423822416990482891694415707626880182335127385564845496968722502531064508236794490149037021373756875425278069621745860863912399196641388414399463171257761192133719058891540419926061937259684055960761838199081600923840918336924120526335236516500115108241855287430263809480233364084000105646409638910878994420820422552248809062853062971314598633808334114010418924133364933998209352785219452456089337721022144079478199256501302345218342858278235244199769192326879823000937772497828914123378185067698603690831733524939588396025784744225418501083799649691393873269892335315415985069239360869306287430161725433942167215211261881754762154607113521244775811112287675881463204557903372983296624502192459971356246676084633217778109344434581417296897250881570580436981350693342923679859228288541131389540894299576663507525370715066110292813780358628483132303131742983176445700582642966318721896316623598268218673189722517718549132701529540520838922283977941956346618584749724827265852568855500361230814706488134611068845316354598799199730845206624628172917488457386459633185969341459672532379007964850480186110477536989316248137632870890622881765455399233258931339410494872048786445380805620853716965362789859403153144908183575383939310217279705139721560019568071214255994974408572648841828625948484183872232281767754936910627565103682925375742419024815987856586166378115801243175559269046804610268271061187624472308223805466602642940260042682812756256714586960165383407898099487002894444062178839391272002262993374941547876859908138330758067507911277955632733866611899695647351688393078353839611712871637384462404921878353336617815170011477929312619557000783485114417555469412886951873941491122663330089140640237525839190435611147175201365580352057169422983019756479705286311737745688878300295162035783336721495176173005235943366036579342403031858371914608154767616552994518813852963325330926988565056420401996182426971074864830358200261362270644352471067742908740066312532706251619727693803689605359722994531913085746256816708333207607372464782479204187957800323115042281681129259667352353517828344865153265302260116463924808962369896134974192415072584064052318417051648079212739917316031264326241507504548923934897411859282836187869534528811502263549599774513219264816628970416773822011462914052436110107140947441642811202817152783793620844688755256396789417685977459433814911438287855016776285922198699082347185992693560300125534315526770599208589855117129892234808497648798749646357191091546146105862763759843591202631705539149848234511495065117372464217143148171544816412125072538951795020039403886647971400954941112844849901590156966236341935249533139330401618307950786879596469984119359421473188358955907773883294422386655263220117627516995224969119904423765978663514224958566699689223512229385859291888846405683717180332460248187496572144703276206259527743572333980326718238070708650626983118629971542697495485252436024567421318695854715454101364076644687730899594195633275321940815295981062932643316855398782785214003121345721054960499469768201901436790482699005065113381322434770359397558788285726356480844311358408385253074776523383477020175018046561198787369898157059096899613482593561519419424142071652533171543891165116251895092189352681035517633166882961672980048326420273966474172389658068362117989909317156664012999905834065753973024952538940459359134550258647169854000824881036941617642608336413135147747841565829503975928572807411306180458140011310004983383026486015252188390643855363612216856777424655584758055581172316113883725410980557553123430983725023598059269514271705141359723255705532679522179269076133226643135890378252461618715340762528062563692617084267038794880235151507089462270896512581989114649911930878095396167316626567923044257435256806444296060636631937672317042925789128926010875180848009703217786800815516725253240060242786574356358801695111745961187387934689215227487920216703113061886444488110070984015605138767865701169972101412815405111287993463590619141283476936740880771219789950164205754467253452729863863950188739206664510955140236732140158021974750113109733958553067094099406873014624519007182600409029981781192576220342072442404407525694905182026252480724976436388060662190514332680872481044874701969108472815273272711817597987293115253454183720993206057768497928765003643915107639254922781596562385649150660525460064354624202531015121109364122338886448890343464196409635269404582149158284742251021906623863213747664602076214326636400706220794772134432273627481233425177349936452817255847706031575002057972719912748242114947097609007914285108694438842246267149271162583225184547641087826552789896176698128504268589381137327318145707839809327397245651593444250042725815049799745201372918555659842435159140214766015206264721726961406530774240071612440812084893955728905341340722978959370951469131953687044216423231488696742678073353379700564119257217803190999447776766945656573316206535726981650249163828677908520393197985243387213795555465230391800618144495416908755212757986378350464035578468435976351162791656892497974733578066603931101486067508297960437234016531761812630581332141184120753306673976159208563797007731706257116416221162110419311205495221132895418746168121064205944498701002545540456478596919625174145565742316551390140063146675199648332585331762709727331999408582325796339606878970603814755703167837480442251068230531926699205980639895012239254327439300220930923024855090117769633765709714826339834535876565538006788679271916019685164920493416004883901394115173882206447090610228518660081719399539376075038070034810020211340293423040766585888292494537662913458772049817318437606250938129574541767841602448300145138073940696983979059415445451195212528787305894819950526282403144596367019708209116488019479785136064985877899731579692549619154770180888669752809069235496303872000398374241532650796235196695916947874428693058258893424293987791471045924421366356810359849529988292704148275922733760964828717638828532352066259757744446229184986951298617242419115550392412022848989840586920941416655818223507527601871564570641408192234786458318407574121105566577710381048872914691225665311980882110415222436817149605338657757168302854397900614706332327212921851066498300381053609841762266343669520372320628210114413639485761915162414609422533174459519006397814257737889054381038101112761472099883783780140565576787975042564664143611845913471061951575941338844337411203552878275342039192198521263603180368307831236175304268307887495444496370405314855591523212253
Convert it into Decimal
from decimal import Decimal
Decimal(630078954945407486971302572117011329116721271139829179349572383637541443562605787816061110360853600744212572072073871985233228681677019488795915592613136558538697419369158961413804139004860949683711756764106408843746324318507090165961373116110504156510362261390086415758369311946617855091322330974469225379475157034653986221430086928768825350265642050874148148762850633380318092218497923938934331494944977897218250062378381926065651168047990017214673422724320097123140849040864223795967322521445859865961967502883479331506850337535224430391571038073324911164139663006137417510539192705821435391823658411385338369730232377028300695738866310468334377735439392551346134885024889217010755804062396901380184592416137322133531990680941959600864409332647120219490414701983979339375751465609840801484592889925172867105767663865003474673877306782492180067353856493873352082672833242368295700361941406607094298524971010582848155295175876416280789802070376313832361148791530700602039387918303750966965311391574707837728570176384970704855124594407172251268098706978376090542912929344492513384183231040016207412648019561891411057151352984928184115181483534959666911309714744265773932487092170761893895469807486999330039447615795396834925983574737750806569360090695009597077440117397176004125384806886783639660621550162794222825503301866755919064102371025428970202609474167093725973377029019369542489008907399816344268271107251422642444394295031677496626574918192538987307032199141725692286015261369012945174380684144484086524852886270717368426832490990772158458075266904766542991903970407465284703623099975166486775916952691073355877964592340230731529088307662462168730966089062336436389277513929792989509527961806655782453847736236387259057358913693838332016851781407524359352813229072505380650711693049176679191021591021389372641247384964875287336650708846120446276882272810745622693709331578317206645848042706067557480758511553310824640020649394355322305550804086562784060919544289531008318716584762468479626254129440271062831239695632816441075920969278753806765451632278698182308325313693381046301850639648800754286747096420253430423489479466804681482044272737999450499555465823164480037422222367329404142745283822947899313540404366082279717101515216147594766392292429511243594117952923319141560834706050302935730124475680758933436231491685270482951411606790235850929380027076481544634203449136248177171198738003486838372217932769689898884784243826855286091288358239337707121625402050851090825870703676300673135330647766969648618275025084598123309185991065848687389917566591933063673989563554382295252021136544002390268843474613430643976640252484632736275857290476774458675146529714463940660919706163233969511685041545624837717646981487338708223589261847530514133271116906741091917303278220653192405195999010112864383206483703165777476499412818478890639921457227974733696980927826881905040085772367856544559431242332068267736163848514181227641896012840513431718789320462329400102516689122316306450427759800832003864806238880726778463445628851437837462460535312158694258263309302240517780411649608046974426356882853543894970861987774349994574781336617336532821610244134603281437218963727001383319023603953398010028490193243704729281796345148350290421966348930850029874490245386530847693496493617805444480239004190850309960252932678216332242871877009997232445612436261407704091991812835292853218055207198699990193596327522065871513324383404436885617489886675946278629169614212976734843602198938090909080423822416990482891694415707626880182335127385564845496968722502531064508236794490149037021373756875425278069621745860863912399196641388414399463171257761192133719058891540419926061937259684055960761838199081600923840918336924120526335236516500115108241855287430263809480233364084000105646409638910878994420820422552248809062853062971314598633808334114010418924133364933998209352785219452456089337721022144079478199256501302345218342858278235244199769192326879823000937772497828914123378185067698603690831733524939588396025784744225418501083799649691393873269892335315415985069239360869306287430161725433942167215211261881754762154607113521244775811112287675881463204557903372983296624502192459971356246676084633217778109344434581417296897250881570580436981350693342923679859228288541131389540894299576663507525370715066110292813780358628483132303131742983176445700582642966318721896316623598268218673189722517718549132701529540520838922283977941956346618584749724827265852568855500361230814706488134611068845316354598799199730845206624628172917488457386459633185969341459672532379007964850480186110477536989316248137632870890622881765455399233258931339410494872048786445380805620853716965362789859403153144908183575383939310217279705139721560019568071214255994974408572648841828625948484183872232281767754936910627565103682925375742419024815987856586166378115801243175559269046804610268271061187624472308223805466602642940260042682812756256714586960165383407898099487002894444062178839391272002262993374941547876859908138330758067507911277955632733866611899695647351688393078353839611712871637384462404921878353336617815170011477929312619557000783485114417555469412886951873941491122663330089140640237525839190435611147175201365580352057169422983019756479705286311737745688878300295162035783336721495176173005235943366036579342403031858371914608154767616552994518813852963325330926988565056420401996182426971074864830358200261362270644352471067742908740066312532706251619727693803689605359722994531913085746256816708333207607372464782479204187957800323115042281681129259667352353517828344865153265302260116463924808962369896134974192415072584064052318417051648079212739917316031264326241507504548923934897411859282836187869534528811502263549599774513219264816628970416773822011462914052436110107140947441642811202817152783793620844688755256396789417685977459433814911438287855016776285922198699082347185992693560300125534315526770599208589855117129892234808497648798749646357191091546146105862763759843591202631705539149848234511495065117372464217143148171544816412125072538951795020039403886647971400954941112844849901590156966236341935249533139330401618307950786879596469984119359421473188358955907773883294422386655263220117627516995224969119904423765978663514224958566699689223512229385859291888846405683717180332460248187496572144703276206259527743572333980326718238070708650626983118629971542697495485252436024567421318695854715454101364076644687730899594195633275321940815295981062932643316855398782785214003121345721054960499469768201901436790482699005065113381322434770359397558788285726356480844311358408385253074776523383477020175018046561198787369898157059096899613482593561519419424142071652533171543891165116251895092189352681035517633166882961672980048326420273966474172389658068362117989909317156664012999905834065753973024952538940459359134550258647169854000824881036941617642608336413135147747841565829503975928572807411306180458140011310004983383026486015252188390643855363612216856777424655584758055581172316113883725410980557553123430983725023598059269514271705141359723255705532679522179269076133226643135890378252461618715340762528062563692617084267038794880235151507089462270896512581989114649911930878095396167316626567923044257435256806444296060636631937672317042925789128926010875180848009703217786800815516725253240060242786574356358801695111745961187387934689215227487920216703113061886444488110070984015605138767865701169972101412815405111287993463590619141283476936740880771219789950164205754467253452729863863950188739206664510955140236732140158021974750113109733958553067094099406873014624519007182600409029981781192576220342072442404407525694905182026252480724976436388060662190514332680872481044874701969108472815273272711817597987293115253454183720993206057768497928765003643915107639254922781596562385649150660525460064354624202531015121109364122338886448890343464196409635269404582149158284742251021906623863213747664602076214326636400706220794772134432273627481233425177349936452817255847706031575002057972719912748242114947097609007914285108694438842246267149271162583225184547641087826552789896176698128504268589381137327318145707839809327397245651593444250042725815049799745201372918555659842435159140214766015206264721726961406530774240071612440812084893955728905341340722978959370951469131953687044216423231488696742678073353379700564119257217803190999447776766945656573316206535726981650249163828677908520393197985243387213795555465230391800618144495416908755212757986378350464035578468435976351162791656892497974733578066603931101486067508297960437234016531761812630581332141184120753306673976159208563797007731706257116416221162110419311205495221132895418746168121064205944498701002545540456478596919625174145565742316551390140063146675199648332585331762709727331999408582325796339606878970603814755703167837480442251068230531926699205980639895012239254327439300220930923024855090117769633765709714826339834535876565538006788679271916019685164920493416004883901394115173882206447090610228518660081719399539376075038070034810020211340293423040766585888292494537662913458772049817318437606250938129574541767841602448300145138073940696983979059415445451195212528787305894819950526282403144596367019708209116488019479785136064985877899731579692549619154770180888669752809069235496303872000398374241532650796235196695916947874428693058258893424293987791471045924421366356810359849529988292704148275922733760964828717638828532352066259757744446229184986951298617242419115550392412022848989840586920941416655818223507527601871564570641408192234786458318407574121105566577710381048872914691225665311980882110415222436817149605338657757168302854397900614706332327212921851066498300381053609841762266343669520372320628210114413639485761915162414609422533174459519006397814257737889054381038101112761472099883783780140565576787975042564664143611845913471061951575941338844337411203552878275342039192198521263603180368307831236175304268307887495444496370405314855591523212253)
The best solution to this question runs in linear time. Here's the idea:
let's look at a shorter example: 1234
consider the total sum of the substrings which end on the ith digit (0..3)
substringsum[0]: 1 (we have only a single substring)
substringsum[1]: 2 + 12 (two substrings)
substringsum[2]: 3+23+123 (three substrings)
substringsum[3]: 4 + 34+234+1234
see a pattern?
let's look at substringsum[2]:
3 + 23 + 123 = 3 + 20+3 + 120+3 = 3*3 + 20+120 = 3*3 + 10*(2+12) = 3*3 +10*substringsum[1]
in general:
substringsum[k] = (k+1)*digit[k] + 10 * substringsum[k-1]
This you can compute in linear time.
This type of ideas is called "Dynamic Programming"
The overflow error suggest that there's an undesired conversion to float, which I assume you did not intend. The conversion happens because the type of 1e9 is float. To fix this, use % int(1e9+7) instead of % 1e9+7
Related
from math import log10, exp
places = int(input('Enter the number of decimal places: '))
one = 10**places
extra = 10**4
n = 1
term = one * extra
eee = 0
count = 0
while term > 0:
eee += term
count += 1
term = term // n
n += 1
eee = eee // extra
intPart = eee // one
fracPart = eee % one
eee = str(intPart)+'.'+ '0'*(places - (int(log10(fracPart)) + 1))+str(fracPart)
print("""
Python's value of e is:\n%.15f\n
e to %d decimal places is:\n%s\n
The number of terms in the series is %d""" \
% (exp(1), places, eee, count))
Questions:
What's the reason behind using extra?
The first term of the series is 1 but why is term = one * extra?
Why is while condition term > 0 ?
Logic behind term = term // n
In short problem with understanding the whole code.
Thank you.
(1) What's the reason behind using extra?
To keep four extra, hidden decimal places for extra accuracy during the execution of the main loop. As soon as the main loop ends, the line eee = eee // extra throws the four extra places away.
(2) The first term of the series is 1 but why is term = one * extra?
This is a fixed-point calculation. What do you know about fixed point? It requires a scale, here represented by one.
(3) Why is while condition term > 0?
Because only the first several terms of the series are large enough to matter. All the late, very small terms can be ignored. Do you know what the // operator does?
Your fourth question should answer itself once the other three answers are understood.
I want to print out a list of the character '&' as many times as there are in a given number. So if the number is 10, I want the result to be '&&&&&&&&&&&'
What I have done is turned the int into a list so I can better visualize what I want to perform.
def print_list_&(size):
"""super serious docstring"""
result_1 = 1
result_2 = size + 1
result = list(range(result_1, result_2))
return result
I'm stuck on where I go from here. This is university work so I'm better off with a push in the right direction than a straight answer.
'&' * 10 will give you '&&&&&&&&&&'. Therefore it seems you just need '&' * size.
Python 2:
N = int(raw_input())
print '&' * N
Python 3:
N = int(input())
print ('&' * N)
I want to get the length of a string including a part of the string that represents its own length without padding or using structs or anything like that that forces fixed lengths.
So for example I want to be able to take this string as input:
"A string|"
And return this:
"A string|11"
On the basis of the OP tolerating such an approach (and to provide an implementation technique for the eventual python answer), here's a solution in Java.
final String s = "A String|";
int n = s.length(); // `length()` returns the length of the string.
String t; // the result
do {
t = s + n; // append the stringified n to the original string
if (n == t.length()){
return t; // string length no longer changing; we're good.
}
n = t.length(); // n must hold the total length
} while (true); // round again
The problem of, course, is that in appending n, the string length changes. But luckily, the length only ever increases or stays the same. So it will converge very quickly: due to the logarithmic nature of the length of n. In this particular case, the attempted values of n are 9, 10, and 11. And that's a pernicious case.
A simple solution is :
def addlength(string):
n1=len(string)
n2=len(str(n1))+n1
n2 += len(str(n2))-len(str(n1)) # a carry can arise
return string+str(n2)
Since a possible carry will increase the length by at most one unit.
Examples :
In [2]: addlength('a'*8)
Out[2]: 'aaaaaaaa9'
In [3]: addlength('a'*9)
Out[3]: 'aaaaaaaaa11'
In [4]: addlength('a'*99)
Out[4]: 'aaaaa...aaa102'
In [5]: addlength('a'*999)
Out[5]: 'aaaa...aaa1003'
Here is a simple python port of Bathsheba's answer :
def str_len(s):
n = len(s)
t = ''
while True:
t = s + str(n)
if n == len(t):
return t
n = len(t)
This is a much more clever and simple way than anything I was thinking of trying!
Suppose you had s = 'abcdefgh|, On the first pass through, t = 'abcdefgh|9
Since n != len(t) ( which is now 10 ) it goes through again : t = 'abcdefgh|' + str(n) and str(n)='10' so you have abcdefgh|10 which is still not quite right! Now n=len(t) which is finally n=11 you get it right then. Pretty clever solution!
It is a tricky one, but I think I've figured it out.
Done in a hurry in Python 2.7, please fully test - this should handle strings up to 998 characters:
import sys
orig = sys.argv[1]
origLen = len(orig)
if (origLen >= 98):
extra = str(origLen + 3)
elif (origLen >= 8):
extra = str(origLen + 2)
else:
extra = str(origLen + 1)
final = orig + extra
print final
Results of very brief testing
C:\Users\PH\Desktop>python test.py "tiny|"
tiny|6
C:\Users\PH\Desktop>python test.py "myString|"
myString|11
C:\Users\PH\Desktop>python test.py "myStringWith98Characters.........................................................................|"
myStringWith98Characters.........................................................................|101
Just find the length of the string. Then iterate through each value of the number of digits the length of the resulting string can possibly have. While iterating, check if the sum of the number of digits to be appended and the initial string length is equal to the length of the resulting string.
def get_length(s):
s = s + "|"
result = ""
len_s = len(s)
i = 1
while True:
candidate = len_s + i
if len(str(candidate)) == i:
result = s + str(len_s + i)
break
i += 1
This code gives the result.
I used a few var, but at the end it shows the output you want:
def len_s(s):
s = s + '|'
b = len(s)
z = s + str(b)
length = len(z)
new_s = s + str(length)
new_len = len(new_s)
return s + str(new_len)
s = "A string"
print len_s(s)
Here's a direct equation for this (so it's not necessary to construct the string). If s is the string, then the length of the string including the length of the appended length will be:
L1 = len(s) + 1 + int(log10(len(s) + 1 + int(log10(len(s)))))
The idea here is that a direct calculation is only problematic when the appended length will push the length past a power of ten; that is, at 9, 98, 99, 997, 998, 999, 9996, etc. To work this through, 1 + int(log10(len(s))) is the number of digits in the length of s. If we add that to len(s), then 9->10, 98->100, 99->101, etc, but still 8->9, 97->99, etc, so we can push past the power of ten exactly as needed. That is, adding this produces a number with the correct number of digits after the addition. Then do the log again to find the length of that number and that's the answer.
To test this:
from math import log10
def find_length(s):
L1 = len(s) + 1 + int(log10(len(s) + 1 + int(log10(len(s)))))
return L1
# test, just looking at lengths around 10**n
for i in range(9):
for j in range(30):
L = abs(10**i - j + 10) + 1
s = "a"*L
x0 = find_length(s)
new0 = s+`x0`
if len(new0)!=x0:
print "error", len(s), x0, log10(len(s)), log10(x0)
This question already has answers here:
How to make rounded percentages add up to 100%
(23 answers)
Closed 8 years ago.
I know how to round a number in Python, this is not a simple technical issue.
My issue is that rounding will make a set of percentages not adding up to 100%, when, technically, they should.
For example:
a = 1
b = 14
I want to compute the percentage of a in (a + b) and b in (a + b).
The answer should be
a/(a + b) = 1/15
b/(a + b) = 14/15
When I try to round those numbers, I got
1/15 = 6.66
14/15 = 93.33
(I was doing the flooring), which makes those two number doesn't add up to 100%.
In this case, we should do ceiling for 1/15, which is 6.67, and flooring for 14/15, which is 93.33. And now they add up to 100%. The rule in this case should be "rounding to the nearest number"
However, if we have a more complicate case, say 3 numbers:
a = 1
b = 7
c = 7
flooring:
1/15 = 6.66
7/15 = 46.66
7/15 = 46.66
Doesn't add up to 100%.
ceiling:
1/15 = 6.67
7/15 = 46.67
7/15 = 46.67
doesn't add up to 100%.
Rounding (to nearest number) is same as ceiling. Still doesn't add up to 100%.
So my question is what should I do to make sure they all add up to 100% in any cases.
Thanks in advance.
UPDATE:
Thanks for the tips from comments. I have took the "Largest Remainder" solution from the duplicate Post answer.
The code are:
def round_to_100_percent(number_set, digit_after_decimal=2):
"""
This function take a list of number and return a list of percentage, which represents the portion of each number in sum of all numbers
Moreover, those percentages are adding up to 100%!!!
Notice: the algorithm we are using here is 'Largest Remainder'
The down-side is that the results won't be accurate, but they are never accurate anyway:)
"""
unround_numbers = [x / float(sum(number_set)) * 100 * 10 ** digit_after_decimal for x in number_set]
decimal_part_with_index = sorted([(index, unround_numbers[index] % 1) for index in range(len(unround_numbers))], key=lambda y: y[1], reverse=True)
remainder = 100 * 10 ** digit_after_decimal - sum([int(x) for x in unround_numbers])
index = 0
while remainder > 0:
unround_numbers[decimal_part_with_index[index][0]] += 1
remainder -= 1
index = (index + 1) % len(number_set)
return [int(x) / float(10 ** digit_after_decimal) for x in unround_numbers]
Tested, seems work fine.
As others have commented, if your numbers are nice and round as in your example, you can use the fractions module to retain the accuracy of the rational numbers:
In [2]: from fractions import Fraction
In [5]: a = Fraction(1)
In [6]: b = Fraction(14)
In [7]: a/(a+b)
Out[7]: Fraction(1, 15)
In [8]: a/(a+b) + (b/(a+b))
Out[8]: Fraction(1, 1)
This obviously doesn't look good if you have really odd fractions.
Welcome to IEEE Floats.
The floating point numbers returned from math operations in python are approximates. On some values, the sum of percentages will be greater than 100.
You have two solutions: use the fraction or decimal modules OR, simply not want them to add up to 100%.
I get this error when using a python script that calculates pi using the Gauss-Legendre algorithm. You can only use up to 1024 iterations before getting this:
C:\Users\myUsernameHere>python Desktop/piWriter.py
End iteration: 1025
Traceback (most recent call last):
File "Desktop/piWriter.py", line 15, in <module>
vars()['t' + str(sub)] = vars()['t' + str(i)] - vars()['p' + str(i)] * math.
pow((vars()['a' + str(i)] - vars()['a' + str(sub)]), 2)
OverflowError: long int too large to convert to float
Here is my code:
import math
a0 = 1
b0 = 1/math.sqrt(2)
t0 = .25
p0 = 1
finalIter = input('End iteration: ')
finalIter = int(finalIter)
for i in range(0, finalIter):
sub = i + 1
vars()['a' + str(sub)] = (vars()['a' + str(i)] + vars()['b' + str(i)])/ 2
vars()['b' + str(sub)] = math.sqrt((vars()['a' + str(i)] * vars()['b' + str(i)]))
vars()['t' + str(sub)] = vars()['t' + str(i)] - vars()['p' + str(i)] * math.pow((vars()['a' + str(i)] - vars()['a' + str(sub)]), 2)
vars()['p' + str(sub)] = 2 * vars()['p' + str(i)]
n = i
pi = math.pow((vars()['a' + str(n)] + vars()['b' + str(n)]), 2) / (4 * vars()['t' + str(n)])
print(pi)
Ideally, I want to be able to plug in a very large number as the iteration value and come back a while later to see the result.
Any help appreciated!
Thanks!
Floats can only represent numbers up to sys.float_info.max, or 1.7976931348623157e+308. Once you have an int with more than 308 digits (or so), you are stuck. Your iteration fails when p1024 has 309 digits:
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216L
You'll have to find a different algorithm for pi, one that doesn't require such large values.
Actually, you'll have to be careful with floats all around, since they are only approximations. If you modify your program to print the successive approximations of pi, it looks like this:
2.914213562373094923430016933707520365715026855468750000000000
3.140579250522168575088244324433617293834686279296875000000000
3.141592646213542838751209274050779640674591064453125000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
In other words, after only 4 iterations, your approximation has stopped getting better. This is due to inaccuracies in the floats you are using, perhaps starting with 1/math.sqrt(2). Computing many digits of pi requires a very careful understanding of the numeric representation.
As noted in previous answer, the float type has an upper bound on number size. In typical implementations, sys.float_info.max is 1.7976931348623157e+308, which reflects the use of 10 bits plus sign for the exponent field in a 64-bit floating point number. (Note that 1024*math.log(2)/math.log(10) is about 308.2547155599.)
You can add another half dozen decades to the exponent size by using the Decimal number type. Here is an example (snipped from an ipython interpreter session):
In [48]: import decimal, math
In [49]: g=decimal.Decimal('1e12345')
In [50]: g.sqrt()
Out[50]: Decimal('3.162277660168379331998893544E+6172')
In [51]: math.sqrt(g)
Out[51]: inf
This illustrates that decimal's sqrt() function performs correctly with larger numbers than does math.sqrt().
As noted above, getting lots of digits is going to be tricky, but looking at all those vars hurts my eyes. So here's a version of your code after (1) replacing your use of vars with dictionaries, and (2) using ** instead of the math functions:
a, b, t, p = {}, {}, {}, {}
a[0] = 1
b[0] = 2**-0.5
t[0] = 0.25
p[0] = 1
finalIter = 4
for i in range(finalIter):
sub = i + 1
a[sub] = (a[i] + b[i]) / 2
b[sub] = (a[i] * b[i])**0.5
t[sub] = t[i] - p[i] * (a[i] - a[sub])**2
p[sub] = 2 * p[i]
n = i
pi_approx = (a[n] + b[n])**2 / (4 * t[n])
Instead of playing games with vars, I've used dictionaries to store the values (the link there is to the official Python tutorial) which makes your code much more readable. You can probably even see an optimization or two now.
As noted in the comments, you really don't need to store all the values, only the last, but I think it's more important that you see how to do things without dynamically creating variables. Instead of a dict, you could also have simply appended the values to a list, but lists are always zero-indexed and you can't easily "skip ahead" and set values at arbitrary indices. That can occasionally be confusing when working with algorithms, so let's start simple.
Anyway, the above gives me
>>> print(pi_approx)
3.141592653589794
>>> print(pi_approx-math.pi)
8.881784197001252e-16
A simple solution is to install and use the arbitrary-precisionmpmath module which now supports Python 3. However, since I completely agree with DSM that your use ofvars()to create variables on the fly is an undesirable way to implement the algorithm, I've based my answer on his rewrite of your code and [trivially] modified it to make use ofmpmath to do the calculations.
If you insist on usingvars(), you could probably do something similar -- although I suspect it might be more difficult and the result would definitely harder to read, understand, and modify.
from mpmath import mpf # arbitrary-precision float type
a, b, t, p = {}, {}, {}, {}
a[0] = mpf(1)
b[0] = mpf(2**-0.5)
t[0] = mpf(0.25)
p[0] = mpf(1)
finalIter = 10000
for i in range(finalIter):
sub = i + 1
a[sub] = (a[i] + b[i]) / 2
b[sub] = (a[i] * b[i])**0.5
t[sub] = t[i] - p[i] * (a[i] - a[sub])**2
p[sub] = 2 * p[i]
n = i
pi_approx = (a[n] + b[n])**2 / (4 * t[n])
print(pi_approx) # 3.14159265358979