Taking the average of two years, written as [1858-60] - python

There are a few cases where the date is written as 'created ca. 1858-60', where a human reader would understand it as 'created ca 1858-1860.'
As such, imagine two integers representing years.
a = 1858
b = 60
I want to be able to get a+b == 1859.
I could parse them to strings, take the first two characters ('18'), concatinate the shorter string and parse them back to numbers, sure, but..that seems a bit round-a-bound.
What would be the Pythonic way to deal with this?

I think you're going about this wrong. The easier approach is to add the century to b, then use them as normal numbers now that they're equatable.
def add_century(n: int, from_century=1900) -> int:
"""add_century turns a two-digit year into a four-digit year.
takes a two-digit year `n` and a four-digit year `from_century` and
adds the leading two digits from the latter to the former.
"""
century = from_century // 100 * 100
return century + n
Then you can do:
a, b = 1858, 60
b = add_century(b, from_century=a)
result = (a + b) / 2
Treating the numbers this way provides two benefits.
First of all, you clarify the edge case you might have. Explicitly adding the century from one onto the ending years from the other makes it very clear what's happened if the code should return the wrong result.
Secondly, transforming objects into equatable terms isn't just a good idea, it's required in languages that are, shall we say, less accepting than Python is. A quick transformation so two items are equatable is an easy way to make sure you're not confusing things down the road.

This version works entirely with integers and handles cross-century boundaries:
def year_range_average(a, b):
return a + (b - (a % 100) + 100) % 100 // 2
>>> year_range_average(1858, 60)
1859
>>> year_range_average(1858, 61)
1859
>>> year_range_average(1858, 62)
1860
>>> year_range_average(1898, 2)
1900

try this:
a = 1858
b = 60
def average_year(a,b):
c = int(str(a)[:2]) * 100
a1 = int(str(a)[2:])
return c + (b + a1)/2
print average_year(a,b)
> 1859

Parse the string with a regex such as (dd) to get groups XXYY-ZZ those will be stored as g1 g2 and g3.
result = int(g1) * 1000 + (int(g2) + int(g3))/2
This of course assumes the prefix is always the same. So 1890-10 would break...
It also assumes the prefix is always there.
Overall doing the string concat and average seems better...

Mm if you don't want to convert to strings... Let's do some maths :
a = 1858
b = 60
cent = 0
s = 0
if a < 2000:
s = a - 1000
c, y = divmod(s, 100)
cent = 1000
else:
s = a - 2000
cent = 2000
c, y = divmod(s, 100)
avg = (b + y) / 2
result = cent + (c*100) + avg

Related

Python OverflowError: int too large to convert to float

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

Brute forcing the private key

I need to find x from the below equation
h = pow(g,x,p)
I have the values of
h = 400 digit number
g = 400 digit number
p = 400 digit number
I need to find the value of x.
All the values are very big.
I have incomplete x with 10 missing digits in it and they are not continuous missing digits.Index of all the missing digits is different.
I am using 10 for loops
to replace that value every time to get H.It is taking too much time in python to do that.Is there anyway in which I can do it faster.
Don't call pow() ten billion times. Instead, use it to calculate the first value of h, and then calculate each successive value by multiplying the previous value by g (or g raised to the appropriate power of 10 in the case where the missing digits are not at the end of x).
Here's a worked example that finds 7 missing digits in just a few seconds. It should give an answer for ten missing digits in a few hours. But as others have noted, you will get better performance by porting this code to another language like C.
h = 27029080272084173153635398406622455117429159185281491773519587480106092289627
g = 26376362132555166607008315364046996472951702119314003469217622667073785183917
p = 81593331324697655999776287731387256090095437693547587289127550085992860325943
x = 31952256647378403805884540140134925446045889939629675712565170000000381638216
# The missing digits (3897858): ^^^^^^^
z = pow(g, x, p) # Initial value of h
d = pow(g, 10**9, p) # Multiplier to get next value of h
while z != h:
z = (z * d) % p
x += 10**9 # Increment x at position of last unknown digit
print(x)
EDIT:
If the missing digits are not consecutive, then you can still use a similar approach, but instead of incrementing x by the same amount each time, you'll need to keep tabs on which digits are changing at each step. For example given a number .0.....0...0.., where 0 represents a missing digit and . represents a known digit, you'll need to add 100 when incrementing the last unknown digit, 9999100 when the last unknown digit has reached 9, and 999990999100 when the last two unknown digits are both 9. It shouldn't be too hard to figure out the correct increments for any pattern of unknown digits.
.0.....0...0.. + 100
.0.....0...1.. + 100
.0.....0...2.. + 100
: : :
.0.....0...8.. + 100
.0.....0...9.. + 9999100
.0.....1...0.. + 100
.0.....1...1.. + 100
: : :
.0.....1...9.. + 9999100
.0.....2...0.. + 100
: : :
.0.....9...9.. + 999990999100
.1.....0...0.. + 100
: : :
This should run in a feasible amount of time with 10 unknown digits, but for a much faster solution, use the meet-in-the-middle approach suggested by James K Polk in the comments below.

Python Percentage Rounding [duplicate]

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%.

Most pythonic way to pad a float left of the decimal point

What I'm trying to accomplish
-12.345 -> -012.345
Where left of decimal can be -999->999 (for my specific need) and n-amount of decimal digits
I came up with two methods to do this:
def pad(num, pad):
pad = pow(10,pad)
if num > 0:
return "%s" % str(num + pad)[1:]
else:
return "-%s" % str(num - pad)[2:]
def pad(num, pad):
import math
mag = 1 + int(math.log10(abs(num)))
sz = len(str(num))
return str(num).zfill(pad+sz-mag)
but this seems rather obtuse for being python. I saw a previous similar question but didn't like the answer ...
>>> "%06.2f"%3.3
'003.30'
because it assumes you already know where your decimal point is and how many decimal digits you have.
This seems like a common situation, so is there an existing better/cleaner/single fncall, way to go about this in python 2.7?
I think you have found a corner case. It's easy to specify digits to the left and to the right of the decimal place; it's also easy to specify total number of digits; it's not very easy to specify digits to the left and leave digits to the right completely unspecified.
I suggest that the cleanest thing to do is to just take the integer portion of the float and format that, then take the fraction and format that (not specifying a length).
Here's a tested function that does what you asked for, and also works correctly for negative numbers.
import math
def float_lformat(f, width):
neg = f < 0.0
fraction, n = math.modf(abs(f)) # get fraction and integer parts of f
if neg and width > 0:
width -= 1
s = "%0*d" % (width, n) + str(fraction)[1:]
if neg:
s = '-' + s
return s
Not sure if this is pythonic. It just pad integer and concat the decimal.
def pad(x, p):
return ('%0'+str(p+(x<0 and 1 or 0))+'d%s') % (x,str(x-int(x))[x<0 and 2 or 1:])
tests
pad(-3,3) -> -003
pad(3,3) -> 003
pad(-3.3,3) -> -003.3
pad(3.3,3) -> 003.3
Fixed vs. dynamic fractions:
>>> "{:08}".format(-12.345)
'-012.345'
>>> a,b=str(x).split('.');a=int(a);"{}{:03}.{}".format('-' if a<0 else"",abs(a),b)
'-012.345'
Cleaned up:
def pad(x):
a, b = str(x).split('.')
a = int(a)
return '{}{:03}.{}'.format('-' if a < 0 else ' ', abs(a), b)
for x in [12.0, 12.345, -12.345, -12.3456]:
print('{:>8} -> {}'.format(x, pad(x)))
Output:
12.0 -> 012.0
12.345 -> 012.345
-12.345 -> -012.345
-12.3456 -> -012.3456

A number out of digits [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I want to know what is the biggest number you can make from multiplying digits entered by the user like this:
5*6*7*2 OR 567*2 OR 67*25 ...etc
so 5/6/7/2 should be entered by the user as variables, but how do I tell python to form a number from two variables (putting the two digits next to each other and treating the outcome as a number by itself).
how do I tell python to form a number from two variables (putting the two digits next to each other and treating the outcome as a number by itself)
Provided the two digits are stored in integer variables, the following will do it:
In [1]: v1 = 5
In [2]: v2 = 6
In [3]: v1 * 10 + v2
Out[3]: 56
This can be generalized to a sequence of digits:
In [7]: l = (1, 2, 6, 3)
In [8]: reduce(lambda x,y: x * 10 + y, l)
Out[8]: 1263
I feel you have posted a mistake in your question. You ask for permutations? Are you sure?
If so, see #mbeckish's answer. It's pretty simple, and not a very good exercise in programming.
(it is, however, a good exercise in trick questions with riddle-like "gotchas" for solutions)
A better approach is to ditch the permutations requirement, so that the order of the input can actually affect the answer. For that approach, we get a much more interesting solution:
def largest_product(*args):
numbers = ''.join(map(str, args))
results = []
for i in range(1, len(numbers) - 1):
multicand = int(numbers[:i])
multiplier = int(numbers[i:])
m, n = multicand, multiplier
results.append(( m * n, "%s * %s" % (m, n)))
return max(results)
>>> largest_product(*range(8))
(827115, '12345 * 67')
so 5/6/7/2 should be entered by the user as variables, but how do I tell python to form a number from two variables (putting the two digits next to each other and treating the outcome as a number by itself).
Seems the root of your problem is capturing data from the user, combining it, and converting it:
>>> a = raw_input()
8
>>> b = raw_input()
3
>>> a
'8'
>>> b
'3'
>>> a + b
'83'
>>> int(a+b)
83
It's that easy.
Now as far as biggest number you can make from multiplying digits entered goes... we can prove that with math if you'd like so you don't have a pile of combinations to try:
We can sort the digits a >= b >= c >= d
First let's look at splitting the digits 3 and 1. We need to compare a * bcd, b * acd, c * abd, d * abc.
Comparing a * bcd = 100ab + 10ac + ad with b * acd = 100ab + 10bc + bd we see the former is larger because a >= b. A similar argument will show that a * bcd beats the others.
Similarly we can compare ac * bd = 100ab + 10(ad+bc) + bd with ad * bc = 100ab + 10(ac+bd) + cd. We would rather have more copies of the big a, so the second wins.
Finally we need to compare a * bcd = 100ab + 10ac + ad with ad * bc = 100ab + 10(ac+bd) + cd. The second is the winner.
You probably took the input in a loop as an array, so if you have:
(a) arr[0] = '5' arr[0] = '7'
(b) arr[1] = '6' sort em => arr[1] = '6'
(c) arr[2] = '7' arr[2] = '5'
(d) arr[3] = '2' arr[3] = '2'
The largest would be:
int(arr[0] + arr[3]) * int(arr[1] + arr[2]) = 4680
Any solution that has you trying all permutations of digits will be horribly inefficient, running in O(n!). Just 14 digits (and the multiply operator) would give around 1 trillion combinations!
An O(n lg n) solution would be:
Sort the digits from high to low.
Concatenate them into one string.
Print the string.
If you must multiply at least one digit, then
Sort.
Take the highest digit and multiply by the concatenation of the remaining digits.
Print the result.
If you must multiply at least one digit, then you might need to try all permutations (see #Mike's answer).
I assume you get the numbers as string, so you can simply strip them, join and translate to int:
string = "5*6*7*2"
value = int( "".join(string.split('*')) )
# value == 5672

Categories