global entries window tk(window title('people shelve'form frame(windowform pack(entries {for (ixlabelin enumerate(('key',fieldnames)lab label(formtext=labelent entry(formlab grid(row=ixcolumn= ent grid(row=ixcolumn= entries[labelent button(windowtext="fetch"command=fetchrecordpack(side=leftbutton(windowtext="update"command=updaterecordpack(side=leftbutton(windowtext="quit"command=window quitpack(side=rightreturn window def fetchrecord()key entries['key'get(tryrecord db[keyfetch by keyshow in gui exceptshowerror(title='error'message='no such key!'elsefor field in fieldnamesentries[fielddelete( endentries[fieldinsert( repr(getattr(recordfield))def updaterecord()key entries['key'get(if key in dbrecord db[keyupdate existing record elsefrom person import person make/store new one for key record person(name='?'age='?'evalstrings must be quoted for field in fieldnamessetattr(recordfieldeval(entries[fieldget())db[keyrecord db shelve open(shelvenamewindow makewidgets(window mainloop(db close(back here after quit or window close this script uses the widget grid method to arrange labels and entriesinstead of packas we'll see latergridding arranges by rows and columnsand so it is natural for forms that horizontally align labels with entries well we'll also see later that forms can usually be laid out just as nicely using pack with nested row frames and fixed-width labels although the gui doesn' handle window resizes well yet (that requires configuration options we'll explore later)adding this makes the grid and pack alternatives roughly the same in code size step adding gui