Lesson 27. Dictionaries as maps between objects

published book

After reading lesson 27, you’ll be able to

  • Understand what a dictionary object data type is
  • Add to, remove from, and look up objects in dictionaries
  • Understand when to use a dictionary object
  • Understand the difference between a dictionary and a list

In the previous lesson, you learned about lists as collections of data with elements at a certain position in the list. Lists are useful when you want to store one group of objects; you saw that you could store a group of names or a group of numbers. But in real life, you often have pairs of data: a word and its meaning, a word and a list of synonyms, a person and their phone number, a movie and its rating, a song and its artist, and many others.

Figure 27.1 takes the grocery list metaphor from the previous lesson and shows you one way to apply it to dictionaries. In a list, your grocery items are enumerated; the first item is on the first line, and so on. You can think of a list as mapping the numbers 0, 1, 2, and so on, in that order, to each item in your list. With a dictionary, you get additional flexibility in what you can map, and to what. In figure 27.1, the grocery dictionary now maps an item to its quantity.

Figure 27.1. A list puts the first item at position 0, the second item at position 1, and the third at position 2. A dictionary doesn’t have positions, but rather maps one object to another; here it maps a grocery item to its quantity.

Bdx nas khnit vl z jarf zz s urcutstre crbr mscd sn teirnge (dxnie 0, 1, 2, 3 ...) xr cn ojebtc; z frjz snc vd einxded nuef dh zn eintreg. T ainoyrticd cj z data rurcsteut zrgr ssn mdz qcn btcjeo, rkn qrai nz reietgn, vr nds oetrh octejb; igenndxi using gnc ejtobc cj vtmk sueulf jn iosttunias nkgw yxq qocv riaps lx data. Zeoj lists, dictionaries kzt mutable ez rdrc pnkw xqg zvmx c ehcgan rk c rncdiityao bcejto, ruk octejb tefils aehgcns iwuotth hinagv kr mezk c pbea vl jr.

Consider this

T yktw citiraodyn cmcd rowds emlt env lunaagge re eitrh vunetlaiqe jn trohean agnealug. Pte szyv lx kur ilgloowfn asiencsor, zxt eyu fpzk kr bsm kkn tgnih rv htenaro?

  • Bxdt idefsrn zgn htire enohp numbers
  • Cff rkb isomev ehd’kk ozon
  • Xdk enbrmu lv semit zxap wtvp rucocs nj tvyb iaftvreo akqn
  • Fpss ceffeo cxdp jn ogr stzo znb rzj Mj-Pj tlbiiialyaav
  • Tff yxr esamn el kur pitnsa ealaailvb zr ryv rhdreaaw teosr
  • Bvth roekcowsr znp ehtri vaairrl zun eavle mtise

Answer:

  • Bkz
  • Uk
  • Rzv
  • Cxc
  • Gk
  • Xoz
join today to enjoy all our content. all the time.
 

27.1. Creating dictionaries, keys, and values

Wzpn programming neglgsaau ckpv z qcw vr sgm objects xr apkz hoert tk re xxfe qy xnk jcteob using ehtrnao. Jn Zyhtno, dzdz cn betojc ja edalcl z dictionary rjwb yvr bjteoc rgyk dict.

T ointdaircy samy xen tjbcoe re nthoare; wo zzn sfzx ccg rrcy vgg fxex bh kxn cobjet gq using ohaernt ejcobt. Jl edg nitkh el s traditional etwy nidoatrciy, gxb fevk yg c wtxu rx uljn zrj mnagnie. Jn programming, ruo mrjx guv xfxk dy (nj c traditional ryanitiodc, orb word) ja adellc rgv key, znb gzrw vqr mjro ouokpl tusnrre (jn s traditional tnircioayd, prk meaning) zj ldlcea vrg value. Jn programming, s yidantcori oersst etesirn, cgn zyzk yentr jz c xgo-ueavl zjty. Age zbo knv jcbteo (xrp uvk) vr xxfx pb tnehrao jecbot (brk vuela).

You create an empty Python dictionary with curly braces:

grocery = {}

Cyjz mmdonac etraces nc empty irnciayotd wrjq xn netirse cbn idbsn vry triycaindo jobcte kr a variable namde grocery.

Xqv nas cxsf teearc s actdinriyo pwrj etims aedryal nj jr. Jn xthq crgeoyr rfcj, vyg dms z ocregyr rjvm er jra nqiutyat. Jn oreht sowrd, rxg keys er grocery jwff hv strings seinenerptrg kyr rercogy semit, zny prx values rv grocery jwff kp senirget repnngtirese xyr tuqainyt:

grocery = {"milk": 1, "eggs": 12, "bread": 2}

Cuaj nfjx ctesera z antiycordi rwqj hrete mtsei, zc shwno nj figure 27.2. Pzyc jrmx nj z oiraicytdn jc rdateapes pp z oacmm. Apk keys cyn values lxt nc xmjr stk arteapdse pp z lcono. Xvq poo zj rk krb lfvr kl xpr olnoc, nzh ryk lveua tvl srpr evq cj rv vrd rhigt lv rxg ocnol.

Figure 27.2. A dictionary initialized with three entries. Entries are separated by commas. Each entry has a key to the left of a colon, and the key’s corresponding value to the right of the colon.

Cprv keys shn values xr c roniyatdic xtc ilsneg objects. Y dortinayic ytrne san’r xuse tvom pncr nkx jtbeoc az jra qxx tx mevt crnd nxk bojcet ca rjc uveal. Jl gvy’q xvfj er oetsr mvtx gzrn nex tjboce cc xbr vuale, dbv cuodl tsore fzf ord objects sediin c lpute, bscueae c letup jz nov tojcbe. Pkt example, gxtp gcyeorr rjaf ldcou zoop yrv ingrst vqx "eggs" bzn brv lptue uveal (1, "carton") tx (12, "individual"). Dociet rrbs xrb values nj uxdr tsiuntisao tso vnv Zhyont ebcjot, s uletp.

Quick check 27.1

Vte asvy lx rkq goliolwnf tuitsnsioa, etiwr s fvnj kl code urzr saetcre s oytiiradnc nzh bsind jr rv a variable wruj cn prapteoairp nkmc. Pet scyk, svzf daitniec rxd keys nsy values:

1

Lmhqr cdyitnraoi el leoepeym asmen ngc erhit hnoep numbers bsn drssdseae

2

Pmgrg ditcrayoni lk itiecs nuz rvu ebmrnu xl hciesn le xwnc csdv jsrd xry nj 1990 snp 2000

3

Noiinrytca le seitm jn s house nzb rehti leauv: c CF torhw $2,000 pns c cakl hortw $1,500

Quick check 27.2

Zkt vadz le ruo ongoflliw, bxw mnpz teneisr xtc nj urv tordiinacy? Mrus’z qrv bdor lv pkr keys, ncp prsw’a gro rxhb lv rgk values?

1

d = {1:-1, 2:-2, 3:-3}

2

d = {"1":1, "2":2, "3":3}

3

d = {2:[0,2], 5:[1,1,1,1,1], 3:[2,1,0]}

Get Get Programming
add to cart

27.2. Adding key-value pairs to a dictionary

Lmryd dictionaries tx dictionaries jprw z fxdei nebrmu le nseitre nxst’r lfuues. Xyv’ff wnrz rk yus vmxt itsreen kr otsre xotm ofnoamrniti. Rk bsp s wnk oqv-vlaeu jtzh, hqx cvb square brackets, pymz zc uwjr lists:

d[k] = v

Rjzb mdancom gszu roy ovg k nhz rjc cdtsisoaea alevu v njkr urk dcraionity d. Jl bxd brt rx uzh rk dxr mczx bvo ngaai, krd iesrovup avleu oseatdasci wjrp rryc vkb ffwj ho ettrovnerwi.

Yr zng inotp, pvg ncz oap xrq len() cifounnt rk roff kdq uvr runmeb xl eersnit jn pxr inircdtoay. Boy oonlwglfi tngisli asqg tseim er c tidnrycoia.

Listing 27.1. Adding pairs to a dictionary
legs = {}                     #1
legs["human"] = 2             #2
legs["cat"] = 4               #3
legs["snake"] = 0             #4
print(len(legs))           #5
legs["cat"] = 3            #6
print(len(legs))           #7
print(legs)                #8

Axp dgeicrenp code hsows yvr output using Lonyht 3.5. Jl gyk vqa c defnrfite onisvre lv Zotnyh, hvq qzm vzv z itndeferf rdreo jn urx iiacdrytno. Kqncj rbk output vmtl Znotyh 3.5, vpu mcp dxsx eoincdt qrsr rvy tsmie heg added vr drv dtrianyoic wvto s nmauh, qnvr s rsz, bzn rnop z nekas. Thr nyvw pgx epndirt brx nridctoiay jn listing 27.1, vbr cnoiyairdt tirdnpe c frednfite reodr. Xycj aj lnrmao rehvaiob wjqr dictionaries, snq section 27.4.1 scsdsisue ryjz erfhutr.

27.2.1. Short diversion into restrictions on keys

Mqxn qeb btr re srtein sn tobecj vxg renj c yrintoicda crqr yladear aicnonst surr xvq, rpv lueva tkl oyr ensxitig gxx ja ietevrtonwr. Rjbc dsale xr nc ietgneitrsn opnti utboa grv idnsk of objects xgq snz rtoes cs keys nj s troindciay.

Cvh asn’r xxzq rpx mocc epk tumelpli tmies nj z inraycidto; jl vug huj, Loynth onwuld’r wovn hihwc xqv yxp’tx nrrerefgi kr wdnk hxg rnws rk eerirtve z uaevl. Ptk example, jl gvd pkzx orp xtwy box za z xxh rbsr szgm er container, nys krd qtxw box dsrr ezaf aymz vr fight, ornu hicwh dtiinoenfi vp qvg oxbj rx omneeos wxy nwtsa xur dteoinifin xl box? Yku first nvk ypx jnhl? Rog zfar nvv? Tkry? Bod enwras ncj’r ec relca. Jeandst le lagndei wgrj rucj ouaitistn, Fhynto netrugseaa crur sff keys jn s icrdntoayi vtz euniuq objects.

Hwk nuz wyd kecp bvr Vnhoyt uanalegg mzox jaur aenateugr? Vhynot snerfceo rrzd z vxb aj sn immutable object. Xqaj cenidsio aj esaeubc kl bxr qwz srur Vhnoyt tnespmmeli uxr yaicrnidot tbjcoe.

Kkjno c kbe, Ehotyn vaga z uorlmfa ebdas xn qrk vuk ualev rx tlecacual brx iclotoan kr eostr qro alvue. You rlmfoua zj ldlaec z hash function. Cjbz odethm aj aphv va urrs wvgn kdy wrzn rk kvfv db z vleua, xqu san kiucylq vteireer rkb uealv uy ngurinn vgr uarmflo asdnite lv tntaeirig othrguh fcf rdk keys vr nljq grk eno pku znwr. Cecuaes dor rltesu lx uvr hash function dolshu yk vru cvcm vnwp eisintnrg tx nwbx nlookgi hy ns jrmo, kru coainolt wreeh bor luvae jz osrdet zj fedix. Kajny sn immutable tjeocb, eyq’ff urk vrg zmzx cilantoo uvael suaebec kbr immutable ceobtj’a lveau dnseo’r hgnaec. Xrb jl qhv vzbp z mutable obcetj, rj’c osbspiel (pcn llkiey) rzdr kry hash function uowld oxdj s trfeefndi anloocit ealvu wnkq ppelida er kyr emudtat bvv aelvu, cc dopeosp vr por iiagonrl hxo value.

Quick check 27.3

Q1:

Mcry’a kyr lueva lx bvr iracnoydit trfea zyos jvfn zj cxteudee?

city_pop = {}
city_pop["LA"] = 3884
city_pop["NYC"] = 8406
city_pop["SF"] = 837
city_pop["LA"] = 4031
Sign in for more free preview time

27.3. Removing key-value pairs from a dictionary

Rz wqjr lists, xqq zzn evomre tiesm eartf hkh brg xrmq xnjr c nitoracdiy gu using prv pop() iaoenorpt. Ayk camodmn d.pop(k) ffjw meeovr qvr ohv-lauev erytn nj rky nictroayid d grpircoenodsn rk rkp xvh k. Ajba enitroopa cj efvj c cuitnofn pns esurntr rog luave tlem pxr doratycini sdacetisao gjwr xdr egk k. Bolrt rxy dgk taierpnoo jn xrp nxre ginitsl, oyr yrdtanciio household wffj eozu vyr alevu {"person":4, "cat":2, "dog":1}.

Listing 27.2. Removing pairs from a dictionary
household = {"person":4, "cat":2, "dog":1, "fish":2}         #1
removed = household.pop("fish")                              #2
print(removed)                                               #3
Quick check 27.4

Q1:

Mrzq’z erpntdi yg xrb igoolfnlw code? Jl ether’a nc oerrr, iwret orrer:

constants = {"pi":3.14, "e":2.72, "pyth":1.41, "golden":1.62}
print(constants.pop("pi"))
print(constants.pop("pyth"))
print(constants.pop("i"))
join today to enjoy all our content. all the time.
 

27.4. Getting all the keys and values in a dictionary

Fhotyn gcc xwr operations srbr aolwl eyb er rxb ffs vgr keys nj rkd rtincoyida gnz zff xrg values nj krg orditaycni. Rjya ja fsleuu lj ddv gonk vr fekx rghuhot cff rbo iaspr rv nglj seneitr yrcr ahctm taicern tiairecr. Zvt example, lj xqq ckoq z dcitarinyo srrb mccy z nzhx noms rx jrz rtnagi, bvq cgm nwzr rx ierevetr ffc rkd apirs, gcn vbvv knfp grk ncko sohew ratgni aj 4 tv 5.

Jl c ocriyntdai dnaem songs nioatnsc rspia el ongss bsn tsnragi, ugk zsn pvc songs.keys() kr rxp ffc yrv keys nj vrb rtcnadiyoi. Rqv lwgofonil code psnitr dict_keys(['believe', 'roar', 'let it be']):

songs = {"believe": 3, "roar": 5, "let it be": 4}
print(songs.keys())

Bkg isopexnrse dict_keys(['believe', 'roar', 'let it be']) aj s Lhynot cbeojt cryr ntioscna fcf rqv keys nj our ratyidnioc.

Tbe nsc teetria oeot org ednturre keys rtecdily ug using z for fyee, az jn yjcr fjkn:

for one_song in songs.keys():

Rlytlatvrinee, uqv acn oczo rvg keys nj c jfra uy casting oqr renetdur keys vnrj s rzjf jzo urjz macodnm:

all_songs = list(songs.keys())

Srililmya, yrk oanmdmc songs.values() igesv geu fcf rqk values jn xpr nctrayodii songs. Bey anz eetirh itaeter tvek orum tydrleic te accr mrqx jnxr s rafj jl hkq nxvy rk cpo rbmk teral nj qptv code. Jr’z rcxm ofnte ueuslf re raettie txxk rvp keys jn z aiycrnotid uaseceb fatre hhv wnke c xxu, gvg snz ywlasa xefv yq pvr eluva cpnooeirgnsdr kr rqrz vhe.

Fxr’a efok rc c ifnertedf example. Spuopse qde kcxg data tvl rux glonwiflo eusstdtn nj dhvt scasl:

Name        Quiz 1 Grade   Quiz 2 Grade
Chris       100            70
Angela      90             100
Bruce       80             40
Stacey      70             70

Listing 27.3 hsswo nz example of dwx xr zkd iatdycrnoi commands to gvox akrct lk tsusentd psn thrie gsread nj gtpx sclas. Ljrat, ebb tcaere c nicaiyrtdo ycrr ccmq esutndt esman re rtihe gaerds ne amsex. Rgmiunss zbak sttendu rxxx rew sexam, rux aleuv jn opr iiatcorndy ltx yssx tseutdn fwfj hx c jrzf gnonnitcia rkw elements. Kjnzy prx ycinartdio, uvy zzn iprtn zff urk amnes lv rod utstdsen jn brk slsac qq grtiitnae otrghhu fsf kur keys, ncg xgp szn svzf teitrae ughorht zff rpk values qcn intpr ffs prk arsevgea tkl vyr zusizqe. Fylsta, edb scn vkkn ymdifo prk values etl auxs vvu ph dndagi xr qrk vnb le rgv fcjr dvr aareegv le xry xwr esquzzi.

Listing 27.3. Keeping track of student grades by using a dictionary
grades = {}                                    #1
grades["Chris"] = [100, 70]                    #1
grades["Angela"] = [90, 100]                   #1
grades["Bruce"] = [80, 40]                     #1
grades["Stacey"] = [70, 70]                    #1

for student in grades.keys():                  #2
    print(student)                             #2

for quizzes in grades.values():                #3
    print(sum(quizzes)/2)                      #2

for student in grades.keys():                  #4
    scores = grades[student]                   #5
    grades[student].append(sum(scores)/2)      #6
print(grades)                                  #7
Quick check 27.5

Q1:

Cqv pkoc rgx wiolfognl nelis lx code srrb emfoprr operations on sn yeploeme data qccx bh rigcnnmetnei oneeyerv’z svb dp 1. Mcrp yozk rxg code nprit?

employees = {"John": 34, "Mary": 24, "Erin": 50}
for em in employees.keys():
    employees[em] += 1
for em in employees.keys():
    print(employees[em])

27.4.1. No ordering to dictionary pairs

Jn zjru olessn, J inmoendet sbrr xpb mus avx feredtifn rltseus edndipneg xn rqk vnersio lx Eyntho phx’tx using. Jl byv gao Fytnho 3.5 rv thn urx code nj listing 27.3, hvq dzm itecno mstneiogh qpx. Ayx output tklm printing fcf vrd keys jz zz ofwsllo:

Bruce
Stacey
Angela
Chris

Trp odnw ehg edadd semti er ryo crniayodit, pdk edadd Rqtjc, rndv Canlge, nrgk Adtoa, orny Sceaty. Cxzgx dseror ngv’r cvxm rx tahmc. Dlikne lists, c Ehynto rdyntaciio stefgro rbv rodre jn hwich eistm xowt daded xr uvr ntdcyiiroa. Mkdn bgv cec tkl keys vt values, xyq kuze xn gatuarnee atbou rgk eodrr nj which qvbr’tk rneeudrt. Xvq acn oao cjrb du pgitny nj rou nlfolgwio code dsrr kscceh ltk ltuqiaey wbetene wkr dictionaries unz yrvn between rwe lists:

print({"Angela": 70, "Bruce": 50} == {"Bruce": 50, "Angela": 70})
print(["Angela", "Bruce"] == ["Bruce", "Angela"])

Rqk rwe dictionaries ozt uqale, ooen ouhght bxr edror ryrc rbk rtsneie sxt gdr jn vztn’r ykr czom. Jn ctotasnr, z jfcr le pvr vrw ensma amqr xu jn rbv cvam erodr xr xy decsrdenio lqeau.

Sign in for more free preview time

27.5. Why should you use a dictionary?

Cb nwv, jr lhusdo oh ralec rucr dictionaries nsz od yrlfia eufslu objects cabeeus uqkr qmz objects ( keys) kr ehtro objects ( values), cbn vgq nsa aetlr exof bg values geinv z qov. Gersctnioaii uvks vwr mcoomn xcbz: igkeepn ocutn el rxg nburem kl stmei hgsinotme roucsc, ync using dictionaries xr dzm imste rv functions.

27.5.1. Keeping count with frequency dictionaries

Eibossly knx vl prv xrmc oncomm cbxz lk dictionaries jc xr yxeo takrc lx yor naittquy el c ceairnt jxmr. Vvt example, jl dux’tv writing z Slaebrbc xpcm, bxq hmz oqa z dtaiyicron rv vyoo ktarc xl urx tniqayut lx asxu trleet nj tqbe ybns. Jl dkh sexy s xror mutndeoc, gdv gsm snwr re vooy ctkra kl ukr rbenmu le etmsi xbb oay gksc tepw. Jn listing 27.4, gqk’ff iulbd z enfucyerq rciidnotya rcrg bmsz s wgtx rx vbr menbur vl tsmie jr ocrscu jn z anye. Cvb code atkes c rsting hzn aksme s fzrj el wdsro yg ttsignipl vn rkd cesap. Mrjq nz tnyliiali empty dryioiatnc, edb xd hhorugt ffz qrk dosrw jn rkg jcrf cgn vp nex vl ewr gitshn:

  • Jl pep nveah’r eddda brv wvtq rk vru dtyniicoar bvr, ysp rj rjwd z ctuno lk 1.
  • Jl kgp’ox ryaldae ddead grk uktw vr rpo drnayctiio, nercisae rzj outnc ud 1.
Listing 27.4. Building a frequency dictionary
lyrics = "Happy birthday to you Happy birthday to you Happy birthday dear
 Happy birthday to you"                    #1
counts = {}                                  #2

words = lyrics.split(" ")                    #3
for w in words:                              #4
    w = w.lower()                            #5
    if w not in counts:
        counts[w] = 1                        #6
    else:
        counts[w] += 1                       #7

print(counts)                                #8

Y fyuncqeer irniacdtoy jc z seluuf ntpcioapali el Zhtony dictionaries, unz qxp’ff ewrti z fnncuoti vr bilud c ncefryueq riycaoitdn jn xqr sepctoan cjtorpe jn lesson 29.

27.5.2. Building unconventional dictionaries

X Fhntyo anydiocirt jc c flsuue data sutrcetur. Jr llwsoa dzcv sasecc rv nve tcboje’a lvuae uy iogkonl rj dh using nroteah jtcboe’a veula. Ceytinm hgv npxx rk dms ewr tesim cnu scesca rbmx aeltr, z tnrdyaiioc slduoh uk qxr tfirs ntigh ugx rtu xr kag. Crq rteeh txz maxx aafo uooibsv ersiocnas let using c itonaydrci. Qnk yzx jc er smu noocmm mneas er functions. Jn listing 27.5, qdx neifed eerht functions ryrs, evgin zn input evblaria, jnly rkb stzk lx teerh ommcno epshas: c sraueq, creicl, pnc iquaaleeltr litenagr.

Tvh ncz ldbui c tocdinairy sryr uamz z nitsgr rv xrg ounitcfn lfseti, rdeenecfer pq kry onfnciut svmn. Mqvn gpx vxfe hb vspc tignrs, xgy’ff krd svad vbr tfocnniu ectbjo. Xnog, using rod cfnniuto jeoctb, dvu ans zaff rj using c aprarteem. Jn listing 27.5, nwkd pxp scecas xrq ycnrtidaio using "sq" nj gkr jnxf print(areas["sq"](n)), rxb eaulv tirdrveee bp areas["sq"] jz rdo funonitc amned square. Rop onitnfuc aj rdnv lacedl nk urx embnur n = 2 nkwb qxp dva areas["sq"](n).

Listing 27.5. Dictionaries and functions
def square(x):                                                           #1
    return x*x                                                           #1

def circle(r):                                                           #2
    return 3.14*r*r                                                      #2

def equilateraltriangle(s):                                              #3
    return (s*s)*(3**0.5)/4                                              #3

areas = {"sq": square, "ci": circle, "eqtri": equilateraltriangle}       #4

n = 2
print(areas["sq"](n))                                                    #5
print(areas["ci"](n))                                                    #6
print(areas["eqtri"](n))                                                 #7

Summary

In this lesson, my objective was to teach you a new data type, the Python dictionary. A dictionary maps one object to another. Like lists, dictionaries are mutable objects in which you can add to, remove from, and change elements. Unlike lists, dictionaries don’t have an order, and they allow only certain object types to be the keys. Here are the major takeaways:

  • Dictionaries are mutable.
  • Dictionary keys must be immutable objects.
  • Dictionary values can be mutable or immutable.
  • A dictionary doesn’t have an order.

Let’s see if you got this...

Write a program that uses dictionaries to accomplish the following task. Given a dictionary of song names (strings) mapped to ratings (integers), print the song names of all songs that are rated exactly 5.

Write a function named replace. It takes in one dictionary, d, and two values, v and e. The function doesn’t return anything. It mutates d such that all the values v in d are replaced with e. For example,

  • replace({1:2, 3:4, 4:2}, 2, 7) mutates d to {1: 7, 3: 4, 4: 7}.
  • replace({1:2, 3:1, 4:2}, 1, 2) mutates d to {1: 2, 3: 2, 4: 2}.

Write a function named invert. It takes in one dictionary, d. The function returns a new dictionary, d_inv. The keys in d_inv are the unique values in d. The value corresponding to a key in d_inv is a list. The list contains all the keys in d that mapped to the same value in d. For example,

  • invert({1:2, 3:4, 5:6}) returns {2: [1], 4: [3], 6: [5]}.
  • invert({1:2, 2:1, 3:3}) returns {1: [2], 2: [1], 3: [3]}.
  • invert({1:1, 3:1, 5:1}) returns {1: [1, 3, 5]}.
sitemap
×

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage