[pastacode lang=”python” manual=”%22%22%22%0AScript%20by%20Jessel%20Serrano%0A2016-05-15%0ASimple%20GUI%20that%20imports%20CSV%20files%20to%20SQLite%20Database%20and%20outputs%20to%20a%20text%20area%0AComes%20with%20several%20buttons%2C%205%20of%20which%20have%20pre-programmed%20SQL%20queries%20to%20fetch%20data%20from%20tables%20’Members’%20and%20’Stores’%0A%22%22%22%0Aimport%20Tkinter%20as%20tki%0Afrom%20Tkinter%20import%20*%0Aimport%20os%2C%20csv%2C%20sqlite3%0Afrom%20tkFileDialog%20import%20askopenfilename%0A%0Aclass%20App(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.root%20%3D%20tki.Tk()%0A%0A%20%20%20%20%23%20create%20Frame%20for%20buttons%0A%20%20%20%20%20%20%20%20toolbar%20%3D%20tki.Frame(self.root%2C%20width%3D1280%2C%20height%3D50)%0A%20%20%20%20%20%20%20%20toolbar.pack(fill%3D%22both%22%2C%20expand%3DFalse)%0A%20%20%20%20%20%20%20%20toolbar.grid_propagate(False)%0A%20%20%20%20%20%20%20%20toolbar.grid_rowconfigure(0%2C%20weight%3D1)%0A%20%20%20%20%20%20%20%20toolbar.grid_columnconfigure(0%2C%20weight%3D1)%0A%0A%20%20%20%20%23%20create%20a%20Frame%20for%20the%20Text%20and%20Scrollbar%0A%20%20%20%20%20%20%20%20txt_frm%20%3D%20tki.Frame(self.root%2C%20width%3D1280%2C%20height%3D720)%0A%20%20%20%20%20%20%20%20txt_frm.pack(fill%3D%22both%22%2C%20expand%3DTrue)%0A%20%20%20%20%23%20ensure%20a%20consistent%20GUI%20size%0A%20%20%20%20%20%20%20%20txt_frm.grid_propagate(False)%0A%20%20%20%20%23%20implement%20stretchability%0A%20%20%20%20%20%20%20%20txt_frm.grid_rowconfigure(0%2C%20weight%3D1)%0A%20%20%20%20%20%20%20%20txt_frm.grid_columnconfigure(0%2C%20weight%3D1)%0A%0A%20%20%20%20%23%20create%20a%20Text%20widget%0A%20%20%20%20%20%20%20%20self.txt%20%3D%20tki.Text(txt_frm%2C%20borderwidth%3D3%2C%20relief%3D%22sunken%22)%0A%20%20%20%20%20%20%20%20self.txt.config(font%3D(%22consolas%22%2C%2010)%2C%20undo%3DTrue%2C%20wrap%3D%22none%22%2C%20state%3D%22disabled%22)%0A%20%20%20%20%20%20%20%20self.txt.grid(row%3D0%2C%20column%3D0%2C%20sticky%3D%22nsew%22%2C%20padx%3D2%2C%20pady%3D2)%0A%20%20%20%20%20%20%20%20self.txt.tag_configure(%22stderr%22%2C%20foreground%3D%22%23b22222%22)%0A%0A%20%20%20%20%23%20create%20a%20Scrollbar%20and%20associate%20it%20with%20txt%0A%20%20%20%20%20%20%20%20scrollb%20%3D%20tki.Scrollbar(txt_frm%2C%20orient%3DHORIZONTAL%2C%20command%3Dself.txt.xview)%0A%20%20%20%20%20%20%20%20scrollb.grid(row%3D1%2C%20column%3D0%2C%20sticky%3D’nsew’)%0A%20%20%20%20%20%20%20%20self.txt%5B’xscrollcommand’%5D%20%3D%20scrollb.set%0A%0A%20%20%20%20%20%20%20%20scrolly%20%3D%20tki.Scrollbar(txt_frm%2C%20orient%3DVERTICAL%2C%20command%3Dself.txt.yview)%0A%20%20%20%20%20%20%20%20scrolly.grid(row%3D0%2C%20column%3D1%2C%20sticky%3D’nsew’)%0A%20%20%20%20%20%20%20%20self.txt%5B’yscrollcommand’%5D%20%3D%20scrolly.set%0A%0A%20%20%20%20%23%20Import%20CSV%20File%20Button%0A%20%20%20%20%20%20%20%20self.importCSV%20%3D%20tki.Button(self.root%2C%20text%3D%22ImportCSV%22%2C%20command%3Dself.importCSVFile)%0A%20%20%20%20%20%20%20%20self.importCSV.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Button%20A%3A%20List%20of%20alphabetized%20member%20names%20with%20all%20available%20data%0A%20%20%20%20%20%20%20%20self.BtnA%20%3D%20tki.Button(self.root%2C%20text%3D%22A)%20All%20Members%20%2B%20Data%22%2C%20command%3Dself.buttonA)%0A%20%20%20%20%20%20%20%20self.BtnA.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Button%20B%3A%20List%20of%20all%20members%20with%20zip%20code%2022101%20who%20have%20paid%20dues%20during%20January%0A%20%20%20%20%20%20%20%20self.BtnB%20%3D%20tki.Button(self.root%2C%20text%3D%22B)%20January%20Members%20%2B%20’22101’%20Zip%22%2C%20command%3Dself.buttonB)%0A%20%20%20%20%20%20%20%20self.BtnB.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Button%20C%3A%20List%20of%20all%20members%20who%20have%20joined%20since%201999-07-01%20and%20live%20in%20VA%0A%20%20%20%20%20%20%20%20self.BtnC%20%3D%20tki.Button(self.root%2C%20text%3D%22C)%20Virginia%20Members%20%2B%20July%201999%22%2C%20command%3Dself.buttonC)%0A%20%20%20%20%20%20%20%20self.BtnC.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Button%20D%3A%20List%20of%20names%20of%20all%20members%20and%20the%20names%20of%20their%20favorite%20store%20and%20its%20location%0A%20%20%20%20%20%20%20%20self.BtnD%20%3D%20tki.Button(self.root%2C%20text%3D%22D)%20Members’%20Favorite%20Stores%22%2C%20command%3Dself.buttonD)%0A%20%20%20%20%20%20%20%20self.BtnD.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Button%20E%3A%20List%20of%20names%20of%20all%20members%20whose%20favorite%20store%20is%20Total%20Wine%0A%20%20%20%20%20%20%20%20self.BtnE%20%3D%20tki.Button(self.root%2C%20text%3D%22E)%20Total%20Sommeliers%22%2C%20command%3Dself.buttonE)%0A%20%20%20%20%20%20%20%20self.BtnE.pack(in_%3Dtoolbar%2C%20side%3D%22left%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20QUIT%20Button%0A%20%20%20%20%20%20%20%20self.QUIT%20%3D%20tki.Button(self.root%2C%20text%3D%22Quit%22%2C%20fg%3D%22red%22%2C%20command%3Dself.root.quit)%0A%20%20%20%20%20%20%20%20self.QUIT.pack(in_%3Dtoolbar%2C%20side%3D%22right%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Clear%20Button%0A%20%20%20%20%20%20%20%20self.clear%20%3D%20tki.Button(self.root%2C%20text%3D%22Clear%22%2C%20command%3Dself.clearText)%0A%20%20%20%20%20%20%20%20self.clear.pack(in_%3Dtoolbar%2C%20side%3D%22right%22%2C%20padx%3D10%2C%20pady%3D10)%0A%0A%20%20%20%20%23%20Change%20print%20options%20so%20that%20App%20prints%20in%20GUI%0A%20%20%20%20%20%20%20%20sys.stdout%20%3D%20TextRedirector(self.txt%2C%20%22stdout%22)%0A%20%20%20%20%20%20%20%20sys.stderr%20%3D%20TextRedirector(self.txt%2C%20%22stderr%22)%0A%0A%20%20%20%20%23%20Button%20A%3A%20List%20of%20alphabetized%20member%20names%20with%20all%20available%20data%0A%20%20%20%20def%20buttonA(self)%3A%0A%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%20%20%20Last_Name%20%7C%7C%20’%2C%20’%20%7C%7C%20First_Name%20as%20Name%2C%20Member_id%2C%20Street_Address%2C%20City%2C%20State%2C%20Zip_Code%2C%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%20%20%20Phone%2C%20Favorite_Store%2C%20Date_Joined%2C%20Dues_Paid%2C%20a.*%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22FROM%20stores%20a%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22JOIN%20members%20b%20ON%20a.Store_id%20%3D%20b.Favorite_Store%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ORDER%20BY%20Last_Name%2C%20First_Name%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%20%3D%20%5Bf%5B0%5D%20for%20f%20in%20cur.description%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20output%20in%20readable%20format%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0A%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20Button%20B%3A%20List%20of%20all%20members%20with%20zip%20code%2022101%20who%20have%20paid%20dues%20during%20January%0A%20%20%20%20def%20buttonB(self)%3A%0A%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20Last_Name%20%7C%7C%20’%2C%20’%20%7C%7C%20First_Name%20as%20Name%2C%20Zip_Code%2C%20Dues_Paid%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22FROM%20members%20WHERE%20Zip_Code%20%3D%20’22101’%20AND%20strftime(‘%25m’%2C%20Dues_Paid)%20%3D%20’01’%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%20%3D%20%5Bf%5B0%5D%20for%20f%20in%20cur.description%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20output%20in%20readable%20format%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0A%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20Button%20C%3A%20List%20of%20all%20members%20who%20have%20joined%20since%201999-07-01%20and%20live%20in%20VA%0A%20%20%20%20def%20buttonC(self)%3A%0A%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20Last_Name%20%7C%7C%20’%2C%20’%20%7C%7C%20First_Name%20as%20Name%2C%20Date_Joined%2C%20State%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22FROM%20members%20WHERE%20date(Date_Joined)%20%3E%3D%20date(‘1999-07-01′)%20AND%20State%20%3D%20’VA’%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%20%3D%20%5Bf%5B0%5D%20for%20f%20in%20cur.description%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20output%20in%20readable%20format%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0A%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20Button%20D%3A%20List%20of%20names%20of%20all%20members%20and%20the%20names%20of%20their%20favorite%20store%20and%20its%20location%0A%20%20%20%20def%20buttonD(self)%3A%0A%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20Last_Name%20%7C%7C%20’%2C%20’%20%7C%7C%20First_Name%20as%20Name%2C%20Store_name%2C%20Location%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22FROM%20members%20a%20JOIN%20stores%20b%20ON%20a.Favorite_Store%20%3D%20b.Store_id%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%20%3D%20%5Bf%5B0%5D%20for%20f%20in%20cur.description%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20output%20in%20readable%20format%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0A%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20Button%20E%3A%20List%20of%20names%20of%20all%20members%20whose%20favorite%20store%20is%20Total%20Wine%0A%20%20%20%20def%20buttonE(self)%3A%0A%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20Last_Name%20%7C%7C%20’%2C%20’%20%7C%7C%20First_Name%20as%20Name%2C%20Store_name%2C%20Location%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22FROM%20members%20a%20JOIN%20stores%20b%20ON%20a.Favorite_Store%20%3D%20b.Store_id%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22WHERE%20Store_name%20%3D%20’Total%20Wine’%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fieldnames%20%3D%20%5Bf%5B0%5D%20for%20f%20in%20cur.description%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20output%20in%20readable%20format%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0A%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20Function%20to%20clear%20textbox%20in%20GUI%0A%20%20%20%20def%20clearText(self)%3A%0A%20%20%20%20%20%20%20%20self.txt.configure(state%3D%22normal%22)%0A%20%20%20%20%20%20%20%20self.txt.delete(1.0%2C%20END)%0A%20%20%20%20%20%20%20%20self.txt.configure(state%3D%22disabled%22)%0A%0A%20%20%20%20%23%20This%20function%20will%20prompt%20the%20user%20for%20a%20file.%20If%20it%20is%20a%20CSV%2C%20it%20will%20upload%20the%20contents%20to%20sommelier.db%0A%20%20%20%20def%20importCSVFile(self)%3A%0A%20%20%20%20%20%20%20%20filepath%20%3D%20askopenfilename()%0A%20%20%20%20%20%20%20%20if%20not%20filepath%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20%22No%20file%20selected%22%0A%20%20%20%20%20%20%20%20elif%20os.path.splitext(filepath)%5B1%5D%20!%3D%20%22.csv%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Please%20select%20a%20CSV%20file%5Cn%22)%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Dynamic%20naming%20of%20table%20based%20on%20name%20of%20CSV%20file%0A%20%20%20%20%20%20%20%20%20%20%20%20tablename%20%3D%20os.path.splitext(os.path.basename(filepath))%5B0%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fileCSV%20%3D%20open(filepath%2C%20’r’)%0A%20%20%20%20%20%20%20%20%20%20%20%20reader%20%3D%20csv.DictReader(fileCSV)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Create%20Table%20and%20Insert%20Into%20Table%20SQL%20Statements%0A%20%20%20%20%20%20%20%20%20%20%20%20create_sql%20%3D%20’CREATE%20TABLE%20’%20%2B%20tablename%20%2B%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20′(‘%20%2B%20’%2C’.join(reader.fieldnames).replace(%22%20%22%2C%20%22_%22).replace(%22%23%22%2C%20%22id%22)%20%2B%20′)’%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20insert_sql%20%3D%20’insert%20into%20’%20%2B%20tablename%20%2B%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20’%20(‘%20%2B%20’%2C’.join(reader.fieldnames).replace(%22%20%22%2C%20%22_%22).replace(%22%23%22%2C%20%22id%22)%20%2B%20′)%20VALUES%20(‘%20%2B%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20’%2C’.join(%5B’%3F’%5D%20*%20len(reader.fieldnames))%20%2B%20′)’%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Extract%20values%20from%20CSV%0A%20%20%20%20%20%20%20%20%20%20%20%20values%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20reader%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row_values%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20field%20in%20reader.fieldnames%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row_values.append(row%5Bfield%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20values.append(row_values)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Connect%20to%20SQL%20database%20and%20execute%20queries%0A%20%20%20%20%20%20%20%20%20%20%20%20con%20%3D%20sqlite3.connect(%22sommelier.db%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20cur%20%3D%20con.cursor()%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(create_sql)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20con.commit()%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cur.executemany(insert_sql%2C%20values)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20con.commit()%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Select%20everything%20from%20the%20imported%20table%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cur.execute(%22SELECT%20distinct%20*%20FROM%20%22%20%2B%20tablename)%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20sqlite3.Error%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sys.stderr.write(%22Error%3A%20%22%20%2B%20e.args%5B0%5D%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20cur.fetchall()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Print%20results%20in%20readable%20format%20despite%20success%20of%20insert%0A%20%20%20%20%20%20%20%20%20%20%20%20row_format%20%3D%20%22%7B%3A%3C25%7D%22%20*%20(len(reader.fieldnames)%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*reader.fieldnames)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20row_format.format(%22%22%2C%20*row)%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20”%0A%0Aclass%20TextRedirector(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20widget%2C%20tag%3D%22stdout%22)%3A%0A%20%20%20%20%20%20%20%20self.widget%20%3D%20widget%0A%20%20%20%20%20%20%20%20self.tag%20%3D%20tag%0A%0A%20%20%20%20def%20write(self%2C%20str)%3A%0A%20%20%20%20%20%20%20%20self.widget.configure(state%3D%22normal%22)%0A%20%20%20%20%20%20%20%20self.widget.insert(%22end%22%2C%20str%2C%20(self.tag%2C))%0A%20%20%20%20%20%20%20%20self.widget.configure(state%3D%22disabled%22)%0A%0Aapp%20%3D%20App()%0Aapp.root.mainloop()” message=”WineClub” highlight=”” provider=”manual”/]