From steve at pearwood.info Thu Jan 1 00:57:36 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 1 Jan 2015 10:57:36 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> Message-ID: <20141231235736.GH24472@ando.pearwood.info> On Tue, Dec 30, 2014 at 05:40:04PM -0500, wolfrage8765 at gmail.com wrote: > On Tue, Dec 30, 2014 at 2:37 PM, Danny Yoo wrote: > > If that's the case, then none of this requires linked list storage. > > > > Instead, we can represent this as a list of rows. Each row element > > would be itself a list of tiles. In short, a matrix. See: > > https://docs.python.org/2/faq/programming.html#how-do-i-create-a-multidimensional-list > > True, I could use a multidimensional list. And originally I was using > a 2D list. But I wanted the ability to QUICKLY search across a row or > up and down a column and so the added benefit of the linked list was > that it simply requires me to access the next node reference. [emphasis added] Trust me on this, there is no linked list code you can write in Python that will be faster than using a list of lists. Even in C, traversing a linked list is slower than array access, and Python is not C. > > And finding neighboring tiles also wouldn't be too bad: Given a tile > > at (i, j), we can find its neighbors through arithmetic (i plus or > > minus one, j plus or minus one). > > From a coding perspective the linked list seemed simplier, because my > other 2D list implementation required me to have a function that could > map from any position to North, South, East, & West, plus it needed to > perform bounds checking. Of course having the list now be doubly > linked has added complexity. Bounds checking is easy: cell [i, j] is in bounds if this is true: (0 <= i < NUM_ROWS) and (0 <= j < NUM_COLS) Fast access to any cell is possible: array[i][j] gives you access to the cell [i, j] effectively instantly, two array accesses, which is much, much faster than having to traverse a linked list: cell = array for x in range(i): cell = cell.next_row for x in range(j): cell = cell.next_col (or whatever scheme you use for linking to the next row/column). As far as memory consumption goes, I don't think there is any comparison. Here is a doubly-linked list of strings: class Cell: __slots__ = ['data', 'next', 'prev'] def __init__(self, data): self.data = data self.next = self.prev = None x = y = Cell('alpha0') for i in range(1, 10): y.next = Cell('alpha' + str(i)) y.next.prev = y y = y.next Now let's see how much memory it uses: from sys import getsizeof size = 0 y = x while y is not None: size += getsizeof(y) + getsizeof(y.data) y = y.next On my system, that gives size of 630 bytes. Let's do the same for a list. This only takes two lines of code: x = ['alpha' + str(i) for i in range(0, 10)] size = getsizeof(x) + sum(getsizeof(s) for s in x) On my system, that gives a size of 406 bytes, considerably smaller. -- Steven From steve at pearwood.info Thu Jan 1 01:18:44 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 1 Jan 2015 11:18:44 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> Message-ID: <20150101001844.GI24472@ando.pearwood.info> On Tue, Dec 30, 2014 at 09:41:33PM -0800, Alex Kleider wrote: > In the process of doing so I discovered that list multiplication does > not at all behave the way I expected (as demonstrated by the > 'bad_flip_2_D' function.) Well, don't keep us in suspense. How did you expect it to behave, and how does it actually behave? My guess is that you expected this: py> grid = [[0]*5]*4 # make a 4x5 grid py> print(grid) [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] Looks good so far! But: py> grid[1][1] = 99 # Adjust a single cell. py> print(grid) [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] while you expected: [[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] Am I right? The problem is that you guessed that list multiplication *copies* the items. It does not. It just repeats them. So: [a, b]*3 returns [a, b, a, b, a, b] but NOT [copy(a), copy(b), copy(a), copy(b), copy(a), copy(b)] If the list items are immutable, like ints or strings, the difference doesn't matter. You can't modify immutable objects in-place, so you never notice any difference between copying them or not. Aside: the copy module actually implements copying for some immutable objects by returning the original! py> import copy py> x = 2.3456 py> y = copy.copy(x) py> y is x True py> x = [] py> y = copy.copy(x) py> y is x False Floats are immutable and cannot be modified, so there is nothing you can do to change float x. Making an actual copy is a waste of time, so copy.copy just returns the same float object. But lists are mutable and can be modified, so copy.copy has to actually build a new list. But I digress. Back to list multiplication. Since list multiplication doesn't *copy* the items, it just repeats them, we can see what is happening if we expand the code a little with a temporary variable: Before: grid = [[0]*5]*4 # make a 4x5 grid grid[1][1] = 99 # Adjust a single cell. Expanded: x = [0]*5 # Make a single list of five immutable integers. grid = [x]*4 # Like [x, x, x, x] So here we have a list of four references to the same list, not four different lists! If you change any one of those references, or indeed the original "x" reference *in-place*, they all change. They all change because in fact there is no "all", there is only one! grid[1][1] = 99 print(x) -> prints [0, 99, 0, 0, 0] The solution to this is not to use list multiplication unless you know the items are immutable. Instead, a list comprehension solves the problem nicely: py> grid = [[0]*5 for i in range(4)] py> grid[1][1] = 99 py> print(grid) [[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] -- Steven From shreya11234 at gmail.com Thu Jan 1 15:06:19 2015 From: shreya11234 at gmail.com (Vedhi Shreya Marwaha) Date: Thu, 1 Jan 2015 19:36:19 +0530 Subject: [Tutor] Fwd: pickle module error in source code In-Reply-To: References: Message-ID: Hi! My name is Shreya Marwaha. I?m class 12th student in India. I?m using 2.7.5 python version [MSC v.1500 64 bit (AMD64)] on win32 as instructed by CBSE (central board of secondary education). I?ve been having problem in using pickle module. It keeps on showing error in the source code. I?ve attached two files: 1. Prax.py file with error1.txt 2. Video.py file with error.txt Prax.py file is a simple problem, the first program I tried with pickle module. Video.py is my project which I?ll be submitting at the end of my year at school i.e. February 2015. I?ve attached two text documents in which both are showing the error occurring in both the problems. The errors in both the programs are similar. Please help me in this context. -Shreya Marwaha -------------- next part -------------- # File name: ...\\Source_XII\Project\Video.py import os from pickle import load, dump import datetime import string MFile = "Master.dat" File1 = "Cassettes.dat" File2 = "Balance.dat" File3 = "Customer.dat" Cdate = datetime.datetime.now() # Current date and time # Class for date class Cast_Date: def __init__(self): self.dd = Cdate.day self.mm = Cdate.month self.yy = Cdate.year class Master: # Constructor def __init__(self): self.Cast_Code = 0 # cassette/CD code - (Like, 1, 2, 3, etc.) self.Cast_Name = " " # Title of the cassette/CD self.Cast_Comp = " " # cassette/CD company self.Cast_Price = 0 # Price per cassette/CD def Check_Code(self, C_Code): MList = list() TRec = list() Flag = False # To check if Cast_Code is in Master.dat or not if os.path.isfile(MFile): Mobj = open(MFile, 'rb') try: while True: MRec = [] # For extracting Master.dat records MRec = load(Mobj) if (C_Code == MRec[0]): TRec = MRec MList.append(MRec[0]) except EOFError: pass for i in range(len(MList)): if (C_Code == MList[i]): Flag = True break Mobj.close() # Flag for Master data entry and TRec for Cassette data entry return Flag, TRec # For Master data entry def Master_Entry(self): TRec = list() # A temporary list to store master record print("Add Master Cassette/CD"); ch ='Y' while ch=='Y': while True: self.Cast_Code = int(input("Cassette/CD Code (1/2/3...) # ")) Flag, TRec = self.Check_Code(self.Cast_Code) if (Flag == False): while True: self.Cast_Name = input("Cassette/CD Name : ") if (self.Cast_Name == 0 or len(self.Cast_Name) > 25): print("Cassette/CD Name should not greater than 25") else: break while True: self.Cast_Comp = input("Company Name : ") if (self.Cast_Comp == 0 or len(self.Cast_Comp) > 25): print("Company Name should not greater than 25") else: break while True: self.Cast_Price = float(input("Individual Cassette/CD price : ")) if (self.Cast_Price <= 0): print("Enter valid price for Cassette/CD") else: break; with open(MFile, 'ab+') as Mobj: if not Mobj: print (MFile, "does not created") else: # Appends data into a sequnce object MList = list() MList.append(self.Cast_Code) MList.append(self.Cast_Name) MList.append(self.Cast_Comp) MList.append(self.Cast_Price) # Write data into binary file dump(MList, Mobj) else: print ("Code", self.Cast_Code, "is already in 'Master.dat' file") ch = input("Add new Cassette/CD code? : ") ch = ch.upper() if ch=='Y': continue else: break def Master_Display(self): if not os.path.isfile(MFile): print (MFile, "file does not exist") else: Mobj = open(MFile, 'rb') print ("\nCassette/CD Master Report") print ("=" * 25) print ("{0:<7} {1:<30} {2:<20} {3:>8}".format(" Code", "Cassette/CD Name", "Company Name", "Price")) print ("-" * 70) try: while True: MRec = [] MRec = load(Mobj) print ("{0:<7} {1:<30} {2:<20} {3:>8.2f}" .format(' '+str(MRec[0]), MRec[1], MRec[2], MRec[3])) except EOFError: pass print ("-" * 70) Mobj.close() class Cassettes: # Constructor def __init__(self): self.Cast_Code = 0 # cassette/CD code - (Like, 1, 2, 3, etc.) self.Tot_Cast = 0 # Total cassette/CD purchased self.dd = self.mm = self.yy = 0 # Cassette/CD purchase date # For cassettes/CDs entry into the cassettes.dat data file def New_Cassettes(self): M = Master() B = Balance() CDt = Cast_Date() self.dd = CDt.dd self.mm = CDt.mm self.yy = CDt.yy print("Add New Stock cassette/CD"); ch ='Y' while ch=='Y': TRec = list() # A temporary list to store master record Flag = False # To check if Cast_Code is in Master.dat or not print("Date: %s-%s-%s" % (CDt.dd, CDt.mm, CDt.yy)) while True: self.Cast_Code = int(input("Cassette/CD Code (1/2/3/...) # ")) # Function call to check cassette/CD code in Master.dat Flag, TRec = M.Check_Code(self.Cast_Code) if (Flag == True): self.Cast_Name = TRec[1] # Title of the cassette/CD self.Cast_Comp = TRec[2] # cassette/CD company self.Cast_Price = TRec[3] # Price per cassette/CD print("Cassette/CD Name :", self.Cast_Name) print("Company Name : ", self.Cast_Comp) print("Individual Cassette/CD price : ",self.Cast_Price) while True: self.Tot_Cast = int(input("Enter new stock cassettes/CDs purchased (Stock): ")) if (self.Tot_Cast <= 0): print("Enter valid Cassette/CD number"); else: break ch = input("Do you want to save the record : ") if ch == 'y' or ch == 'Y': CList = list() with open(File1, 'ab') as Cobj: if not Cobj: print (File1, "does not created") else: # Appends data into a sequnce object CList.append(self.Cast_Code) CList.append(self.Tot_Cast) CList.append(self.dd) CList.append(self.mm) CList.append(self.yy) # Write data into binary file dump(CList, Cobj) #B.Add_to_File(self.Cast_Code, self.Tot_Cast, self.Cast_Price, self.dd, self.mm, self.yy) B.AddUpdateBalance(CList, self.Cast_Price) print("Record saved") ch = input("Stock more cassette/CD record? : ") ch = ch.upper() if ch=='Y': continue else: break # For cassettes/CDs entry into the cassettes.dat data file def Display_Cassettes(self): M = Master() if not os.path.isfile(File1): print (File1, "file does not exist") else: Cobj = open(File1, 'rb') print ("\nCassette/CD entry Register") print ("=" * 26) print ("{0:>5} {1:<25} {2:<20} {3:>10} {4:>8} {5:<12}" .format("Code", "Name", "Company Name", "Quantity", "Price", "Date")) print ("-" * 85) try: while True: CRec = [] CRec = load(Cobj) TRec = list() Flag, TRec = M.Check_Code(CRec[0]) nDt = Set_DateFormat(CRec[2], CRec[3], CRec[4]) if (Flag == True): print ("{0:>5} {1:<25} {2:<20} {3:>10} {4:>8.2f} {5:<12}" .format(CRec[0], TRec[1], TRec[2], CRec[1], TRec[3], nDt)) except EOFError: pass print ("-" * 85) Cobj.close() # Function to set the date as: DD-MM-YYYY def Set_DateFormat(d1, m1, y1): fDt = '' d11 = str(d1) m11 = str(m1) y11 = str(y1) if (len(d11)==1): d11 = '0'+d11 if (len(m11)==1): m11 = '0'+m11 fDt = d11+'-'+m11+'-'+y11 return fDt class Balance: def __init__(self): # Instance attributes of Balance.dat data file self.Cast_Code = 0 # cassette/CD code to be balance self.Cast_Bal = 0 # Total number of cassettes/CDs in balance self.Cast_Price = 0 # Unit price of cassettes/CDs on code wise self.dd = self.mm = self.yy = 0 # Balance date def Give_Balance(self, C_Code): Tbalance = 0 if not os.path.isfile(File2): # When file does not exit return False else: Brec = list() # A list to extract record from Balance.dat Tbalance = 0 Bobj = open(File2, 'rb') try: while True: BRec = load(Bobj) if (C_Code == BRec[0]): Tbalance = BRec[1] # E.g. Cast_Bal break; except EOFError: pass Bobj.close() return Tbalance def AddUpdateBalance(self, CList, CPrice): # To know the balance cassette in 'Balance.dat' Cbalance = Balance.Give_Balance(self, CList[0]) if (Cbalance == False): # If file does not exist, add the record for first time BRec = list() with open(File2, 'ab') as Bobj: BRec.append(CList[0]) # Cast_Code BRec.append(CList[1]) # Cast_Bal BRec.append(CPrice) # Cast_Price BRec.append(CList[2]) # Day BRec.append(CList[3]) # Month BRec.append(CList[4]) # Year dump(BRec, Bobj) elif (Cbalance >= 0): Bobj = open(File2, 'rb') Tobj = open("Temp.dat", 'wb') try: while True: BRec = list() # A list to extract record from Balance.dat BRec = load(Bobj) if (CList[0] != BRec[0]): # Write data into Temp.dat file dump(BRec, Tobj) else: BRec[1] = Cbalance + CList[1] #self.Cast_Bal = self.Cast_Bal + Cbalance dump(BRec, Tobj) except EOFError: pass Tobj.close() Bobj.close() os.remove("Balance.dat") os.rename("Temp.dat", "Balance.dat") def UpdateBalance(self, CList): Bobj = open(File2, 'rb') Tobj = open("Temp.dat", 'wb') try: while True: BRec = list() # A list to extract record from Balance.dat BRec = load(Bobj) if (CList[0] != BRec[0]): # Write data into Temp.dat file dump(BRec, Tobj) else: BRec[1] = BRec[1] - CList[4] dump(BRec, Tobj) except EOFError: pass Tobj.close() Bobj.close() os.remove("Balance.dat") os.rename("Temp.dat", "Balance.dat") print('Balance.dat updated') def Balance_Cassettes(self): M = Master() if not os.path.isfile(File2): print (File2, "file does not exist") else: TAmount = 0 print ("\nBalance Stock Register (Cassette/CD)") print ("=" * 35) Bobj = open(File2, 'rb') print ("{0:>5} {1:<26} {2:<20} {3:>10} {4:>8} {5:>10}" .format("Code", "Name", "Company Name", "Quantity", "Price", "Amount")) print ("-" * 86) try: while True: BRec = [] BRec = load(Bobj) TRec = list() Flag, TRec = M.Check_Code(BRec[0]) if (Flag == True): Amount = BRec[1] * BRec[2] TAmount = TAmount + Amount print ("{0:>5} {1:<26} {2:<20} {3:>10} {4:>8.2f} {5:>10.2f}" .format(BRec[0], TRec[1], TRec[2], BRec[1], BRec[2], Amount)) except EOFError: pass print ("-" * 86) print ("%s Total Amount: %s %.2f" % (' ' * 56, ' ' * 4, TAmount)) Bobj.close() class Customer: def __init__(self): # Instance attributes of Customer.dat data file self.Cast_Code = 0 # cassette/CD code self.C_Name = '' # Customer name self.C_Address = '' # Customer address self.C_MPhone = 0 # Customer mobile no. self.No_Of_Cast = 0 # Number of Cassette/CD self.dd = self.mm = self.yy = 0 # Sale date def Cassette_Sale(self): M = Master() B = Balance() CDt = Cast_Date() self.dd = CDt.dd self.mm = CDt.mm self.yy = CDt.yy Cbalance = 0 print("Customer sales cassette/CD"); ch ='Y' while ch=='Y': TRec = list() # A temporary list to store master record Flag = False # To check if Cast_Code is in Master.dat or not print("Date: %s-%s-%s" % (CDt.dd, CDt.mm, CDt.yy)) while True: self.Cast_Code = int(input("Cassette/CD Code (1/2/3/...) # ")) # Function call to check cassette/CD code in Master.dat Flag, TRec = M.Check_Code(self.Cast_Code) Cbalance = B.Give_Balance(self.Cast_Code) if (Flag == True): self.Cast_Name = TRec[1] # Title of the cassette/CD self.Cast_Comp = TRec[2] # cassette/CD company self.Cast_Price = TRec[3] # Price per cassette/CD print("Cassette/CD Name :", self.Cast_Name) print("Company Name : ", self.Cast_Comp) print("Individual Cassette/CD price : ",self.Cast_Price) print('\nEnter Customer details') self.C_Name = input("Customer name: ").upper() self.C_Address = input("Customer addres: ") self.C_MPhone = int(input("Customer mobile no.: ")) while True: self.No_Of_Cast = int(input("Enter sales cassettes/CDs nos.: ")) if (self.No_Of_Cast > Cbalance): print("Out of Stock"); else: break ch = input("Sales confirm : ").upper() if ch == 'Y': CustList = list() with open(File3, 'ab') as CustObj: if not CustObj: print (File3, "does not created") else: # Appends data into a sequnce object CustList.append(self.Cast_Code) CustList.append(self.C_Name) CustList.append(self.C_Address) CustList.append(self.C_MPhone) CustList.append(self.No_Of_Cast) CustList.append(self.dd) CustList.append(self.mm) CustList.append(self.yy) B.UpdateBalance(CustList) dump(CustList, CustObj) ch = input("More sale? : ") ch = ch.upper() if ch!='Y': break # Function to search individual customer on mobile no. def Return_CustomerName(self, Mno): M = Master() CName = '' if not os.path.isfile(File2): print (File3, "file does not exist") else: CustObj = open(File3, 'rb') try: while True: CustRec = [] CustRec = load(CustObj) if Mno == CustRec[3]: CName = CustRec[1] break except EOFError: pass CustObj.close() return CName # Function to display Sales report for a particular month in a calender year. def MonthlySales_Report(self): M = Master() if not os.path.isfile(File2): print (File3, "file does not exist") else: monthNo = int(input('Enter month no.: ')) yearNo = int(input('Enter year: ')) CDt = Cast_Date() self.dd = CDt.dd self.mm = CDt.mm self.yy = CDt.yy if (monthNo <= 12 and monthNo <= self.mm and yearNo <= self.yy): # Function call for a character month MonthName = Month_Name(monthNo) TAmount = 0 # Function called to set the date as DD-MM-YYYY nDt = Set_DateFormat(self.dd, self.mm, self.yy) print ("\nCustomer Sales Status Report - Date:", nDt) print ("For the month of", MonthName, yearNo) print ("=" * 27) CustObj = open(File3, 'rb') print ("{0:<20} {1:<12} {2:<25} {3:^10} {4:>5} {5:>12} {6:>8}" .format("Name", "Mobile No.", "Cassette/CD Cide & Name", "Date", "Qty", "Unit Price", "Amount")) print ("-" * 100) try: while True: CustRec = [] CustRec = load(CustObj) TRec = list() Flag, TRec = M.Check_Code(CustRec[0]) UPrice = TRec[3] Amount = (UPrice + (UPrice * 0.20)) * CustRec[4] # An additional 20% of Unit price nDt = Set_DateFormat(CustRec[5], CustRec[6], CustRec[7]) if (monthNo == CustRec[6] and yearNo == CustRec[7]): Clength = str(CustRec[0])+'-'+TRec[1] nName = '' for i in range(len(Clength)): # Extracts only 24 characters nName = nName + Clength[i] if i == 23: break print ("{0:20} {1:<12} {2:<25} {3:>10} {4:>5.0f} {5:>12.2f} {6:>8.2f}" .format(CustRec[1], CustRec[3], nName, nDt, CustRec[4], UPrice, Amount)) except EOFError: pass print ("-" * 100) print('Note. Amount is calculated as 20% extra on unit price.') #print ("%s Total Amount: %s %.2f" % (' ' * 50, ' ' * 4, TAmount)) CustObj.close() else: print ("Month no. and year is not valid") # Function to display cose wise monthly sales report. def CodeWiseMonthlySales_Report(self): M = Master() TRec = list() # A temporary list to store master record Flag = False # To check if Cast_Code is in Master.dat or not if not os.path.isfile(File2): print (File3, "file does not exist") else: CCode = int(input("Cassette/CD Code (1/2/3/...) # ")) monthNo = int(input('Enter month no.: ')) yearNo = int(input('Enter year: ')) CDt = Cast_Date() self.dd = CDt.dd self.mm = CDt.mm self.yy = CDt.yy # Function call to check cassette/CD code in Master.dat Flag, TRec = M.Check_Code(CCode) if (monthNo <= 12 and monthNo <= self.mm and yearNo <= self.yy and Flag == True): CName = TRec[1] # Title of the cassette/CD CComp = TRec[2] # cassette/CD company CPrice = TRec[3] # Price per cassette/CD # Function call for a character month MonthName = Month_Name(monthNo) TAmount = 0 # Function called to set the date as DD-MM-YYYY nDt = Set_DateFormat(self.dd, self.mm, self.yy) print ("\nCode wise Sales Report - Date:", nDt) print ("For the month of", MonthName, yearNo) print ("Cassette/CD Code: %d Name: %s" % (CCode, CName)) print ("=" * 40) CustObj = open(File3, 'rb') print ("{0:<20} {1:<12} {2:^10} {3:>5} {4:>12} {5:>8}" .format("Customer Name", "Mobile No.", "Date", "Qty", "Unit Price", "Amount")) print ("-" * 74) ctr = 0 try: while True: CustRec = [] CustRec = load(CustObj) TRec = list() Flag, TRec = M.Check_Code(CustRec[0]) UPrice = TRec[3] Amount = (UPrice + (UPrice * 0.20)) * CustRec[4] # An additional 20% of Unit price nDt = Set_DateFormat(CustRec[5], CustRec[6], CustRec[7]) if (monthNo == CustRec[6] and yearNo == CustRec[7] and CCode == CustRec[0]): ctr += 1 print ("{0:20} {1:<12} {2:>10} {3:>5.0f} {4:>12.2f} {5:>8.2f}" .format(CustRec[1], CustRec[3], nDt, CustRec[4], UPrice, Amount)) except EOFError: pass print ("-" * 74) if (ctr == 0): print('No record found on such Code No., Month and Year') else: print('Note. Amount is calculated as 20% extra on unit price.') #print ("%s Total Amount: %s %.2f" % (' ' * 50, ' ' * 4, TAmount)) CustObj.close() else: print ("Either Code not found or Month no. and year is not valid") # Function to search individual customer on mobile no. def CustomerWithMobileSearch(self): M = Master() if not os.path.isfile(File2): print (File3, "file does not exist") else: MobileNo = int(input('\nEnter customer mobile no.: ')) Cust_Name = self.Return_CustomerName(MobileNo) TAmount = 0 CDt = Cast_Date() self.dd = CDt.dd self.mm = CDt.mm self.yy = CDt.yy # Function called to set the date as DD-MM-YYYY nDt = Set_DateFormat(self.dd, self.mm, self.yy) print ("\nDate:", nDt) print ("Customer name:", Cust_Name, '& Mobile No.:', MobileNo) print ("=" * 40) CustObj = open(File3, 'rb') print ("{0:<30} {1:^10} {2:>5} {3:>12} {4:>8}" .format("Cassette/CD", "Date", "Qty", "Unit Price", "Amount")) print ("-" * 70) ctr = 0 try: while True: CustRec = [] CustRec = load(CustObj) TRec = list() Flag, TRec = M.Check_Code(CustRec[0]) UPrice = TRec[3] Amount = (UPrice + (UPrice * 0.20)) * CustRec[4] # An additional 20% of Unit price nDt = Set_DateFormat(CustRec[5], CustRec[6], CustRec[7]) if (MobileNo == CustRec[3]): ctr += 1 Clength = str(CustRec[0])+'-'+TRec[1] nName = '' for i in range(len(Clength)): # Extracts only 24 characters nName = nName + Clength[i] if i == 23: break print ("{0:<30} {1:>10} {2:>5.0f} {3:>12.2f} {4:>8.2f}" .format(nName, nDt, CustRec[4], UPrice, Amount)) except EOFError: pass print ("-" * 70) if (ctr == 0): print('No record found on such mobile no.') else: print('Note. Amount is calculated as 20% extra on unit price.') #print ("%s Total Amount: %s %.2f" % (' ' * 50, ' ' * 4, TAmount)) CustObj.close() # Function to find a character month on against a month no. def Month_Name(mNo): mDict = {1:'January', 2:'February', 3:'March', 4:'April', 5:'May', 6:'June', 7:'July', 8:'August', 9:'September', 10:'October', 11:'November', 12:'December'} mName = '' for key, value in mDict.items(): if (key == mNo): mName = value break return mName def main(): opt = '' M = Master() CS = Cassettes() BL = Balance() Cust = Customer() while True: print() print ("\n Video Library Main Menu") print ("-" * 30) print ("| 1 - > Master Cassettes/CDs |") print ("| 2 - > Stock Cassettes/CDs |") print ("| 3 - > Customer Sales |") print ("| 4 - > Exit |") print ("-" * 30) print ("Enter your choice: ") opt = input() if opt == 1: ch = '' while True: print() print ("\n\tMaster Cassette Menu") print ("-" * 35) print ("| 1 - > Cassettes/CDs Stock Entry |") print ("| 2 - > View Cassettes/CDs |") print ("| 3 - > Exit |") print ("-" * 35) print ("Enter your choice: ") ch = input() if ch == 1: M.Master_Entry() elif ch == 2: M.Master_Display() elif ch == 3: break if opt == 2: ch = '' while True: print() print ("\n\tStock Cassette Menu") print ("-" * 33) print ("| 1 - > Cassette/CD Stock entry |") print ("| 2 - > Display Cassette/CD |") print ("| 3 - > Stock/Balance Cassettes |") print ("| 4 - > Exit |") print ("-" * 33) print ("Enter your choice: ") ch = input() if ch == 1: CS.New_Cassettes() elif ch == 2: CS.Display_Cassettes() elif ch == 3: BL.Balance_Cassettes() elif ch == 4: break elif opt == 3: ch = '' while True: print() print ("\n\tCustomer Sales Menu") print ("-" * 34) print ("| 1 - > Sales Entry |") print ("| 2 - > Monthly Sales Report |") print ("| 3 - > Code Wise Monthly Sales |") print ("| 4 - > Customer Mobile No. Wise |") print ("| 5 - > Exit |") print ("-" * 34) print ("Enter your choice: ") ch = input() if ch == 1: Cust.Cassette_Sale() elif ch == 2: Cust.MonthlySales_Report() elif ch == 3: Cust.CodeWiseMonthlySales_Report() elif ch == 4: Cust.CustomerWithMobileSearch() elif ch == 5: break elif opt == 4: break if __name__ == "__main__": main() -------------- next part -------------- Traceback (most recent call last): File "C:\Users\Home\Desktop\Project\Video.py", line 678, in main() File "C:\Users\Home\Desktop\Project\Video.py", line 627, in main M.Master_Display() File "C:\Users\Home\Desktop\Project\Video.py", line 109, in Master_Display MRec = load(Mobj) File "C:\Python27\lib\pickle.py", line 1378, in load return Unpickler(file).load() File "C:\Python27\lib\pickle.py", line 858, in load dispatch[key](self) File "C:\Python27\lib\pickle.py", line 886, in load_proto raise ValueError, "unsupported pickle protocol: %d" % proto ValueError: unsupported pickle protocol: 3 -------------- next part -------------- class student: __rollno=0 __name="" __marks=0 __subject="" def no(self): return student.__rollno def mar(self): return student.__marks def input(self): student.__rollno=input("enter your rollno=") student.__name=raw_input("enter your name=") student.__marks=input("enter your marks=") student.__subject=raw_input("enter your subject=") def output(self): print 'roll no=',student.__rollno print 'name=',student.__name print 'marks=',student.__marks print 'subject=',student.__subject import pickle a=student() f=open("student.log","wb+") "a.input()" "pickle.dump(a,f)" a=pickle.load(f) a.output() f.close() -------------- next part -------------- Traceback (most recent call last): File "C:\Users\Home\Downloads\prax.py", line 25, in a=pickle.load(f) File "C:\Python27\lib\pickle.py", line 1378, in load return Unpickler(file).load() File "C:\Python27\lib\pickle.py", line 858, in load dispatch[key](self) File "C:\Python27\lib\pickle.py", line 880, in load_eof raise EOFError EOFError From tgmiller5 at hotmail.com Thu Jan 1 18:31:28 2015 From: tgmiller5 at hotmail.com (Tammy Miller) Date: Thu, 1 Jan 2015 12:31:28 -0500 Subject: [Tutor] Tutor Digest, Vol 130, Issue 47 In-Reply-To: References: Message-ID: This is regarding the Python drop-down list response. I would like to create a GUI that has a drop down list containing the data and displayed based on the stats of the list contents. I am interested in using Tkinter, wxPython or PyGTK. My data is coming from a csv file. I am using Python 2.79 and have Windows 8 as an operating system Thank you, > From: tutor-request at python.org > Subject: Tutor Digest, Vol 130, Issue 47 > To: tutor at python.org > Date: Wed, 31 Dec 2014 20:00:28 +0100 > > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Convert string to bytes (shweta kaushik) > 2. Help on Python drop-down list options (Tammy Miller) > 3. Re: Help on Python drop-down list options (WolfRage) > 4. Re: Convert string to bytes (WolfRage) > 5. Re: Help on Python drop-down list options (Alan Gauld) > 6. Re: Convert string to bytes (Alan Gauld) > 7. Re: Convert string to bytes (Alan Gauld) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 31 Dec 2014 15:38:05 +0530 > From: shweta kaushik > To: Tutor at python.org > Subject: [Tutor] Convert string to bytes > Message-ID: > > Content-Type: text/plain; charset=UTF-8 > > Hi all, > > I need help on this problem. > > I have one message packet in form of string s = '0xFE, 0x01, 0x01, 0x22, > 0xFE, 0x02'. I have to send this data to MSP430 microcontroller, but it is > not taking data if it is string. If I am passing this as hardcoded value s1 > = 0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02 then board is responding. I want to > convert s as s1 using python. > > Please help me out to convert string in normal format for microcontroller > to respond. > > Thanks in advance. > > Regards, > Shweta > > > ------------------------------ > > Message: 2 > Date: Wed, 31 Dec 2014 08:49:17 -0500 > From: Tammy Miller > To: "tutor at python.org" > Subject: [Tutor] Help on Python drop-down list options > Message-ID: > Content-Type: text/plain; charset="iso-8859-1" > > Hello All, > > > > I need help on the > following: I have a created a project from a csv file to calculate the > mean and standard deviation. > > However, I would like to > create a drop-down list and display the mean and standard deviation? Is there a module > for that? > > > > Thank you, > > > > Tammy > > > > > > > > > > > > ------------------------------ > > Message: 3 > Date: Wed, 31 Dec 2014 11:31:14 -0500 > From: WolfRage > To: tutor at python.org > Subject: Re: [Tutor] Help on Python drop-down list options > Message-ID: <54A424D2.20709 at gmail.com> > Content-Type: text/plain; charset=windows-1252; format=flowed > > What is the user interface that your program is using, currently? IE: > QT, GTK, Tkinter, Curses, Kivy, Pygame, Or None? > What is the target system on which your program runs? > How are you currently viewing the mean and standard deviation results? > What version of Python are you using and what is your OS? > > On 12/31/2014 08:49 AM, Tammy Miller wrote: > > Hello All, > > > > > > > > I need help on the > > following: I have a created a project from a csv file to calculate the > > mean and standard deviation. > > > > However, I would like to > > create a drop-down list and display the mean and standard deviation? Is there a module > > for that? > > > > > > > > Thank you, > > > > > > > > Tammy > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > > ------------------------------ > > Message: 4 > Date: Wed, 31 Dec 2014 11:34:35 -0500 > From: WolfRage > To: tutor at python.org > Subject: Re: [Tutor] Convert string to bytes > Message-ID: <54A4259B.2000005 at gmail.com> > Content-Type: text/plain; charset=windows-1252; format=flowed > > I wrote a program to help me break out hex strings awhile ago. It was > written to communicate with a Atmega 168. This is written for Python 3. > Here is a snippet, see if this helps you. > > s4 = "28 40 7A 7C 05 00 00 34" > hex_array = bytearray.fromhex(s4) > print(s4) > print(list(hex_array)) > print(hex_array) > for byte in list(hex_array): > print(hex(byte)) > print(bytes([byte])) > > > On 12/31/2014 05:08 AM, shweta kaushik wrote: > > Hi all, > > > > I need help on this problem. > > > > I have one message packet in form of string s = '0xFE, 0x01, 0x01, 0x22, > > 0xFE, 0x02'. I have to send this data to MSP430 microcontroller, but it is > > not taking data if it is string. If I am passing this as hardcoded value s1 > > = 0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02 then board is responding. I want to > > convert s as s1 using python. > > > > Please help me out to convert string in normal format for microcontroller > > to respond. > > > > Thanks in advance. > > > > Regards, > > Shweta > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > > ------------------------------ > > Message: 5 > Date: Wed, 31 Dec 2014 17:51:25 +0000 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] Help on Python drop-down list options > Message-ID: > Content-Type: text/plain; charset=windows-1252; format=flowed > > On 31/12/14 13:49, Tammy Miller wrote: > > > I need help on the > > following: I have a created a project from a csv file to calculate the > > mean and standard deviation. > > I assume that means you read the data from the CSV file > and display the stats? > > > However, I would like to > > create a drop-down list and display the mean and standard deviation? > > I assume you mean you want to create a GUI that has a "drop down list" > containing data and you want to display the stats based on the list > contents? > > If so you need to decide what kind of UI you want to use. > Your choices are: > 1) CLI using curses (Not on windows) > 2) Web UI based on HTML/Javascript > 3) Desktop GUI using Tkinter/WxPython/PyGTK > (or some other toolkit) > > And once you decide your option you need to design what the UI > looks like - how does the output appear? Is it in a label? a text > widget? a pop-up dialog? > > > Is there a module for that? > > Yes, for all of the above. > > Option 1 uses the curses module > > Option 2 uses standard HTML linked to a CGI(standard library) > or a web framework(several third-party options) > > Option 3: the standard library includes Tkinter, > the others are third-party downloads. > > We can't help much until you make the choices above. > It will help if you tell us which python version and > which OS you use. > > And once you choose an option which tookkit you want > to go with (or at least which option and we can advise > on toolkits based on your experience and your UI visual > design) > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > > ------------------------------ > > Message: 6 > Date: Wed, 31 Dec 2014 17:57:33 +0000 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] Convert string to bytes > Message-ID: > Content-Type: text/plain; charset=windows-1252; format=flowed > > On 31/12/14 10:08, shweta kaushik wrote: > > > I have one message packet in form of string s = '0xFE, 0x01, 0x01, 0x22, > > 0xFE, 0x02'. I have to send this data to MSP430 microcontroller, but it is > > not taking data if it is string. If I am passing this as hardcoded value s1 > > = 0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02 then board is responding. I want to > > convert s as s1 using python. > > I'm pretty sure you don;t need that, you only need the integer values of > the hex strings. You can then write those integers directly to your > controller. Assuming I'm right this should work (Python v2.7): > > >>> s = '0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02' > >>> [int(h,16) for h in s.split(',')] > [254, 1, 1, 34, 254, 2] > >>> > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > > ------------------------------ > > Message: 7 > Date: Wed, 31 Dec 2014 18:53:25 +0000 > From: Alan Gauld > To: shweta kaushik > Cc: tutor at python.org > Subject: Re: [Tutor] Convert string to bytes > Message-ID: <54A44625.3070707 at btinternet.com> > Content-Type: text/plain; charset=utf-8; format=flowed > > On 31/12/14 18:03, shweta kaushik wrote: > > I also did the same thing and its working... but i dint use this. I > > just did this and it is similar to what you said. > > > > >>> s = '0xFE, 0x01, 0x01, 0x22, 0xFE, 0x02' > > >>> packet = eval(s) > > (254, 1, 1, 34, 254, 2) > > >>> > > this is tuple, which my microcontroller is able to recognize and > > respond back. > It works with a fixed string input but using eval() is a big security risk, > especially if you read the input from a file or network or even a user. > You could potentially find your hard disk being formatted or similar damage. > > An explicit conversion using int() is much safer. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 130, Issue 47 > ************************************** From __peter__ at web.de Thu Jan 1 20:06:09 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 01 Jan 2015 20:06:09 +0100 Subject: [Tutor] pickle module error in source code References: Message-ID: Vedhi Shreya Marwaha wrote: > Hi! My name is Shreya Marwaha. I?m class 12th student in India. Welcome! > I?m using > 2.7.5 python version [MSC v.1500 64 bit (AMD64)] on win32 as instructed by > CBSE (central board of secondary education). I?ve been having problem in > using pickle module. It keeps on showing error in the source code. I?ve > attached two files: 1. Prax.py file with error1.txt 2. Video.py file > with error.txt Prax.py file is a simple problem, the first program I > tried with pickle module. Video.py is my project which I?ll be submitting > at the end of my year at school i.e. February 2015. I?ve attached two text > documents in which both are showing the error occurring in both the > problems. The errors in both the programs are similar. Please help me in > this context. -Shreya Marwaha I'm sorry I am not prepared to read this much code. It is both courteous and helpful to reduce a problem to the smallest amount of code that still shows the bug. Read http://sscce.org/ for the details. On the positive side, thank you for providing version info and tracebacks! > Traceback (most recent call last): > File "C:\Users\Home\Desktop\Project\Video.py", line 678, in > main() > File "C:\Users\Home\Desktop\Project\Video.py", line 627, in main > M.Master_Display() > File "C:\Users\Home\Desktop\Project\Video.py", line 109, in Master_Display > MRec = load(Mobj) > File "C:\Python27\lib\pickle.py", line 1378, in load > return Unpickler(file).load() > File "C:\Python27\lib\pickle.py", line 858, in load > dispatch[key](self) > File "C:\Python27\lib\pickle.py", line 886, in load_proto > raise ValueError, "unsupported pickle protocol: %d" % proto > ValueError: unsupported pickle protocol: 3 This one leads me to believe that you ran some of your code with Python 3 and thus have accidentally created a pickle file that cannot be read by Python 2. Delete your existing pickle files and try again. If it doesn't work out come back with a smaller more focused example. From alan.gauld at btinternet.com Thu Jan 1 23:05:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 01 Jan 2015 22:05:07 +0000 Subject: [Tutor] Drop-down list [was: Re: Tutor Digest, Vol 130, Issue 47] In-Reply-To: References: Message-ID: On 01/01/15 17:31, Tammy Miller wrote: > This is regarding the Python drop-down list response. Thanks, but please do not send the entire digest contents. Delete what is not relevant, then you wouldn't need to tell us, and those who pay by the byte would not have such big bills. Also change the subject to what is relevant. > I would like to create a GUI that has a drop down list > containing the data and displayed based on the stats > of the list contents. > I am interested in using Tkinter, wxPython or PyGTK. OK, Since Tkinter is included with python I'll look at that. Actually I recommend looking at Tix which also has a Combo box object, which if you have a lot of data to enter manually might be more useful. There are several Tkinter tutorials on the web, mine is here: http://www.alan-g.me.uk/tutor/tutgui.htm Assuming you read and understand that (if not respond here with more questions) then the next thing to do is look at the documentation for the Listbox object, here: http://effbot.org/tkinterbook/listbox.htm and a more technical but complete specification here: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/listbox.html > My data is coming from a csv file. I'll leave extracting the data from the CSV file as an exercise. I assume you have discovered the csv module to help with that? HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Thu Jan 1 23:18:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 01 Jan 2015 22:18:39 +0000 Subject: [Tutor] Fwd: pickle module error in source code In-Reply-To: References: Message-ID: On 01/01/15 14:06, Vedhi Shreya Marwaha wrote: > Hi! My name is Shreya Marwaha. I?m class 12th student in India. I?m using > 2.7.5 python version [MSC v.1500 64 bit (AMD64)] on win32 as instructed by > CBSE (central board of secondary education). I?ve been having problem in > using pickle module. OK, welcome. > It keeps on showing error in the source code. I?ve > attached two files If the files are short its better to just paste the contents into your mail. Not everyone can (or is allowed to) read attachments. : 1. Prax.py file with error1.txt 2. Video.py file > with error.txt Prax.py file is a simple problem, the first program I > tried with pickle module. OK, Let's stick with that initially. The error says: > Traceback (most recent call last): > File "C:\Users\Home\Downloads\prax.py", line 25, in > a=pickle.load(f) > File "C:\Python27\lib\pickle.py", line 1378, in load > return Unpickler(file).load() > File "C:\Python27\lib\pickle.py", line 858, in load > dispatch[key](self) > File "C:\Python27\lib\pickle.py", line 880, in load_eof > raise EOFError > EOFError The relevant code is: > import pickle > a=student() > f=open("student.log","wb+") In general, don;t use the + modifier with files. It usually creates more confusion. Just open the file for reading after you finish writing. And try very hard not to mix reading and writing to the same file. > a.input() > pickle.dump(a,f) Here you have written your data to the file. The file 'cursor' is now pointing at the end of the file. > a=pickle.load(f) Here you try to read from the file but the cursor is already at the end, so you get an end of file error. To make it work you could rewind the cursor to the beginning of the file using seek(). But it would be much safer to simply close the file after the dump() and then reopen the file for reading. That avoids a whole bunch of potential complexity and bugs just waiting to bite. Also, consider using the 'with' structure for handling files, it is generally safer than open/close: with open('student.log','wb') as f: a.input() pickle.dump(a,f) with open('student.log','rb') as f: a = pickle.load() 'with' ensures the files are closed after use. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Fri Jan 2 02:03:18 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 01 Jan 2015 17:03:18 -0800 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <20150101001844.GI24472@ando.pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> Message-ID: <4836cd95c7abd9180c69abbb3f05c353@sonic.net> On 2014-12-31 16:18, Steven D'Aprano wrote: > py> grid[1][1] = 99 # Adjust a single cell. > py> print(grid) > [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, > 0]] > > while you expected: > > [[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] > > > Am I right? Yes, although perhaps not so much 'expected' as 'hoped.' > > > The problem is that you guessed that list multiplication *copies* the > items. It does not. It just repeats them. So: I don't think I understand the distinction between 'copies' and 'repeats'. I think I understand the difference between copy and deep copy and I think that is the issue here but it isn't yet clear. I hope I'm not trying your patience too much: Do I have the correct explanations for these behaviours? (python3 on ubuntu14.04) >>> s_grid = [[0]*5 for i in range(4)] # So for each iteration of the list comprehension, # a brand new, ?immutable? object ( a list of zeros) is created. # Immutable by virtue of the fact that there is no reference to it # and therefore it can't be changed????? >>> s_grid [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] >>> s_grid[1][1] = 99 >>> s_grid [[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # :-) >>> l = [0]*5 >>> l [0, 0, 0, 0, 0] >>> grid = [l for i in range(4)] # In this form, the list comprehension is encountering a mutable # object by virtue of the fact that there is a reference to it? >>> grid[1][1] = 99 >>> grid [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] # ;-( # Is the crux of the matter that l is mutable (because it is a reference,) # while [0]*5 is not (because it is an expression?) >>> my_grid = [[0, 0, 0, 0] for i in range(4)] >>> my_grid [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> my_grid[1][1] = 99 >>> my_grid [[0, 0, 0, 0], [0, 99, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> another_grid = [[0]*5]*4 # The explanations above don't seem to explain things here. >>> another_grid [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] >>> another_grid[1][1] = 99 >>> another_grid [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] >>> My interpretation is that we appear to be getting a deep copy at the inner level of a multiplication but a not deep copy at the outer level. List comprehension provides us with a deep copy but only if we give it a literal (as opposed to a reference.) Thanks, Steven, for your efforts to help. It's very much appreciated. alex From alan.gauld at btinternet.com Fri Jan 2 02:35:48 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 01:35:48 +0000 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <4836cd95c7abd9180c69abbb3f05c353@sonic.net> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> Message-ID: On 02/01/15 01:03, Alex Kleider wrote: > I don't think I understand the distinction between 'copies' and 'repeats'. copy creates a new object with the same attributes as the original original = [1,2,3] copy = original[:] # slicing creates a copy copy == original -> True copy is original -> False Repeats replicates the reference to the object but does not create a new object. reference = original # both refer to same object reference = original -> True reference is original -> True > I think I understand the difference between copy and deep copy and I > think that is the issue here but it isn't yet clear. Deep copy is not an issue here. >>>> s_grid = [[0]*5 for i in range(4)] > # So for each iteration of the list comprehension, > # a brand new, ?immutable? object ( a list of zeros) is created. > # Immutable by virtue of the fact that there is no reference to it > # and therefore it can't be changed????? It's not immutable. Whether a reference to it exists or not has no bearing on whether it has the potential to be changed. In fact each object created has a reference: s_grid[0], s_grid[1], etc... You have 5 objects, each a list of 5 zeros. All 5 lists are mutable and all 5 are equal but not identical (ie. not the same object). >>>> s_grid > [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] >>>> s_grid[1][1] = 99 >>>> s_grid > [[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # And as expected changing one object has no impact on the others. And by changing it you demonstrate that the objects are not immutable - you just mutated it! >>>> l = [0]*5 >>>> l > [0, 0, 0, 0, 0] You now have one list object containing 5 zeros and a reference to it from 'l' >>>> grid = [l for i in range(4)] Now you have 4 more references to the same object 'l' refers to. > # In this form, the list comprehension is encountering a mutable > # object by virtue of the fact that there is a reference to it? No, the reference is irrelevant. It is mutable by virtue of being a list. >>>> grid[1][1] = 99 >>>> grid > [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] You modified the object so all references (including the original 'l') will reflect the change > # Is the crux of the matter that l is mutable (because it is a reference,) No the objects are mutable in both examples. mutable means you can change them. It has nothing to do with whether there is a reference or not. (Although, if there were truly no references the object would be destyroyed by the garbage collector) > # while [0]*5 is not (because it is an expression?) [0]*5 is an expression that yields a list object. The list object is mutable. You proved that by changing one of them. >>>> my_grid = [[0, 0, 0, 0] for i in range(4)] >>>> my_grid > [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] Now you have created another list of 5 objects. Again each object has 4 zeros and they are equal but not identical. They are all mutable. They are all referenced via my_grid. (my_grid[0],...) >>>> my_grid[1][1] = 99 >>>> my_grid > [[0, 0, 0, 0], [0, 99, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] Again you changed(mutated) one of the objects. The others remain untouched. >>>> another_grid = [[0]*5]*4 Here you create a list of 4 references to the list produced by [0]*5 One list object, 4 references. > # The explanations above don't seem to explain things here. >>>> another_grid > [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] >>>> another_grid[1][1] = 99 >>>> another_grid > [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] Again there is only one list object, so when you change it via any of the references all the references reflect that change. > My interpretation is that we appear to be getting a deep copy at the > inner level of a multiplication but a not deep copy at the outer level. No copying is going on at any point. > List comprehension provides us with a deep copy but only if we give it a > literal (as opposed to a reference.) No, list comprehensions (and generator expressions in general) return a sequence made up of whatever object the first expression evaluates to. That could be an existing object (like the one referenced by 'l' above) or a newly created (possibly literal) object like [0, 0, 0, 0]. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 2 02:57:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 01:57:44 +0000 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> Message-ID: On 02/01/15 01:35, Alan Gauld wrote: > Repeats replicates the reference to the object but > does not create a new object. > > reference = original # both refer to same object > > reference = original -> True Oops, typo, should be: reference == original -> True > reference is original -> True -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From wolfrage8765 at gmail.com Fri Jan 2 05:48:18 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Thu, 01 Jan 2015 23:48:18 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <20141231235736.GH24472@ando.pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> Message-ID: <54A62312.2090905@gmail.com> Final Code Using 2d List instead of Doubly Linked List. class GameTile(): def __init__(self, id, **kwargs): # id is (X,Y) self.id = id class GameGrid(): def __init__(self, **kwargs): self.cols = 7 self.rows = 8 # grid is 2d array as y, x ie [y][x]. self.grid = [[None] * self.rows for i in range(self.cols)] def make_grid(self): for row in range(0, self.rows): for col in range(0, self.cols): self.grid[col][row] = GameTile(id=str(row) + ',' + str(col)) def print_by_row(self): for col in range(0, self.cols): for row in range(0, self.rows): print(self.grid[col][row].id) def print_by_col(self): for row in range(0, self.rows): for col in range(0, self.cols): print(self.grid[col][row].id) def check_bounds(self, x, y): if (0 <= x < self.rows) and (0 <= y < self.cols): return True return False def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[y][x] def draw_grid(self): for col in range(0, self.cols): print(end='| ') for row in range(0, self.rows): print(self.grid[col][row].id, end=' | ') print() temp = GameGrid() temp.make_grid() temp.draw_grid() Any feedback for my code is appreciated. Thank you. On 12/31/2014 06:57 PM, Steven D'Aprano wrote: > Trust me on this, there is no linked list code you can write in Python > that will be faster than using a list of lists. Even in C, traversing > a linked list is slower than array access, and Python is not C. OK. I do trust you. > Bounds checking is easy: cell [i, j] is in bounds if this is true: > > (0 <= i < NUM_ROWS) and (0 <= j < NUM_COLS) > > Fast access to any cell is possible: > > array[i][j] Implemented both. > from sys import getsizeof Thanks I forgot about getsizeof. From davea at davea.name Fri Jan 2 06:28:38 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 00:28:38 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A62312.2090905@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> Message-ID: <54A62C86.30606@davea.name> On 01/01/2015 11:48 PM, WolfRage wrote: > Final Code Using 2d List instead of Doubly Linked List. > > Please don't top-post. Instead, post your comments inline with the parts of the previous message to which you're responding. Is there a reason you doublespaced the whole thing? And why did you retype it instead of just copy/pasting it? And why lose the indentation, so nobody can actually try it without guessing at your indentation? > class GameTile(): > > def __init__(self, id, **kwargs): > > # id is (X,Y) > > self.id = id > > > class GameGrid(): > > def __init__(self, **kwargs): > > self.cols = 7 > > self.rows = 8 These two would more generally have been parameters, and you'd create the grid by specifying the sizes to be used. > > # grid is 2d array as y, x ie [y][x]. > > self.grid = [[None] * self.rows for i in range(self.cols)] > If you always call make_grid immediately after constructing the grid, then why not combine __init__ with make_grid? It'd be much shorter. > > > def make_grid(self): > > for row in range(0, self.rows): > > for col in range(0, self.cols): > > self.grid[col][row] = GameTile(id=str(row) + ',' + str(col)) > > > > def print_by_row(self): > > for col in range(0, self.cols): > > for row in range(0, self.rows): > > print(self.grid[col][row].id) > This could be better written as: for col in self.grid: for row in col print row.id > > > def print_by_col(self): > > for row in range(0, self.rows): > > for col in range(0, self.cols): > > print(self.grid[col][row].id) > likewise, but it's a bit trickier. > > def check_bounds(self, x, y): > > if (0 <= x < self.rows) and (0 <= y < self.cols): > > return True > > return False This could be simplified to just: return (0 <= x < self.rows) and (0 <= y < self.cols) > > > def lookup_node(self, x, y): > > if not self.check_bounds(x, y): > > return False > > return self.grid[y][x] > > > def draw_grid(self): > > for col in range(0, self.cols): > > print(end='| ') > > for row in range(0, self.rows): > > print(self.grid[col][row].id, end=' | ') > > print() > > > > temp = GameGrid() > temp = GameGrid(8, 7) > temp.make_grid() > > temp.draw_grid() > -- DaveA From steve at pearwood.info Fri Jan 2 07:50:28 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 2 Jan 2015 17:50:28 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A62C86.30606@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> Message-ID: <20150102065028.GE15262@ando.pearwood.info> On Fri, Jan 02, 2015 at 12:28:38AM -0500, Dave Angel wrote: > On 01/01/2015 11:48 PM, WolfRage wrote: > >Final Code Using 2d List instead of Doubly Linked List. [...] > Is there a reason you doublespaced the whole thing? And why did you > retype it instead of just copy/pasting it? And why lose the > indentation, so nobody can actually try it without guessing at your > indentation? I think the reason can be spelled: "Bloody Gmail" Wolfrage, you will have a lot fewer problems if you can get your Gmail to send "plain text" rather than "rich text", "formatted text" or whatever they call it these days. (It's actually HTML code, like websites use.) Otherwise your code gets screwed up by Gmail: class GameTile(): def __init__(self, id, **kwargs): # id is (X,Y) self.id = id instead of: class GameTile(): def __init__(self, id, **kwargs): # id is (X,Y) self.id = id -- Steven From steve at pearwood.info Fri Jan 2 08:21:56 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 2 Jan 2015 18:21:56 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A62312.2090905@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> Message-ID: <20150102072156.GF15262@ando.pearwood.info> Fixing the mangled formatting, as best as I am able (and can be bothered). On Thu, Jan 01, 2015 at 11:48:18PM -0500, WolfRage wrote: class GameTile(): def __init__(self, id, **kwargs): # id is (X,Y) self.id = id What is the purpose of the **kwargs? It doesn't get used, it just silently ignores them. Actually, what is the purpose of this GameTile class? It has no methods apart from the constructor. That is a sign of a class that isn't pulling its weight, its not doing anything. All the other code in your program looks inside the GameTile and accesses self.id directly. This is a sure sign of a class that doesn't need to exist. It may be better to give this at least a __str__ method, so if nothing else you can print it without looking inside: class GameTile(): def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "%d, %d" % (self.x, self.y) class GameGrid(): def __init__(self, **kwargs): self.cols = 7 self.rows = 8 # grid is 2d array as y, x ie [y][x]. self.grid = [[None] * self.rows for i in range(self.cols)] Why do you have GameTiles use X,Y but the grid uses the opposite order, Y,X? This is going to cause confusion. I'm already confused! def make_grid(self): for row in range(0, self.rows): for col in range(0, self.cols): self.grid[col][row] = GameTile(id=str(row) + ',' + str(col)) No need to write range(0, Whatever), since range defaults to 0. Better to write range(Whatever). Why does the GameTile record the coordinates as strings? I would prefer something like this: def make_grid(self): for row in range(self.rows): for col in range(self.cols): self.grid[col][row] = GameTile(row, col) although it looks strange due to the backwards ordering of col/row. Your __init__ method should automatically call make_grid. That is: def __init__(self, **kwargs): self.cols = 7 self.rows = 8 # grid is 2d array as y, x ie [y][x]. self.grid = [[None] * self.rows for i in range(self.cols)] self.make_grid() Actually, even better will be to move the self.grid = ... line out of the __init__ method, and make it part of make_grid. Since it is part of making the grid. def print_by_row(self): for col in range(0, self.cols): for row in range(0, self.rows): print(self.grid[col][row].id) This now becomes: def print_by_row(self): for col in range(0, self.cols): for row in range(0, self.rows): print(self.grid[col][row]) since GameTiles now know how to print themselves. Likewise for this: def print_by_col(self): for row in range(0, self.rows): for col in range(0, self.cols): print(self.grid[col][row]) Another simplification here: def check_bounds(self, x, y): return (0 <= x < self.rows) and (0 <= y < self.cols) Your lookup_node method returns a GameTile or False on failure: def lookup_node(self, x, y, ): if not self.check_bounds(x, y): return False return self.grid[y][x] I'm not sure about that design. I wonder whether it would be better to return None, or raise an exception. You have a lookup_node method that checks the bounds, but you don't seem to use it anywhere. Why does it exist? def draw_grid(self): for col in range(0, self.cols): print(end='| ') for row in range(0, self.rows): print(self.grid[col][row].id, end=' | ') print() I'm not sure if I have reconstructed the indentation correctly here. A few changes: no need to call range(0, ...). GameTile instances now know how to print themselves, so you can call: print(self.grid[col][row], end=' | ') This could be improved: temp = GameGrid() temp.make_grid() temp.draw_grid() Creating a GameGrid should automatically create the game grid, hence what I said above about having __init__ call make_grid. Then use a more meaningful name, and we have: grid = GameGrid() grid.draw_grid() # Maybe this could be just called "draw"? -- Steven From brandontdr at gmail.com Fri Jan 2 11:25:12 2015 From: brandontdr at gmail.com (Brandon Dorsey) Date: Fri, 2 Jan 2015 05:25:12 -0500 Subject: [Tutor] multiple objects with one assignment? Message-ID: I know there is are easier ways to assign multiple objects to a variable, but why, does the following code work? Why does it return a tuple versus a list? I know it has something to do with the semi-colon, but I didn't know it wouldn't raise an error. greetings = "hello,", "what's", "your", "name?" print(greetings) x = 1, 2, 3, 4, 5, 6, 7 print(x) I assumed that you could only assign one object per assignment without the presence of tuples, list, or dictionaries. From ben+python at benfinney.id.au Fri Jan 2 12:08:48 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 02 Jan 2015 22:08:48 +1100 Subject: [Tutor] multiple objects with one assignment? References: Message-ID: <857fx5zbgf.fsf@benfinney.id.au> Brandon Dorsey writes: > I know there is are easier ways to assign multiple objects to a > variable, Not really. Every name binds to exactly one value. Values can themselves be collections of other values, which might be what you're thinking of. > Why does it return a tuple versus a list? I know it has something to > do with the semi-colon, but I didn't know it wouldn't raise an error. > > greetings = "hello,", "what's", "your", "name?" The value defined on the right-hand side of the assignment operation (the ?=?) is a literal tuple. That one value then gets the name ?greetings? bound to it. > print(greetings) The ?print? function implicitly creates a string representation of its parameter; the string representation of a tuple shows all the values in that tuple. > x = 1, 2, 3, 4, 5, 6, 7 Another literal tuple is created on the right-hand side, and the name ?x? is bound to that tuple. > I assumed that you could only assign one object per assignment without > the presence of tuples, list, or dictionaries. I don't really understand that statement. Does it help you to understand if I clarify that a tuple is one value? That a list is one value? That a dict is one value? Each of those types implements a collection; a tuple value (and likewise a list value, a dict value) itself contains other values. But those values are only *contained in*, not identical to, the collection. -- \ ?Laurie got offended that I used the word ?puke?. But to me, | `\ that's what her dinner tasted like.? ?Jack Handey | _o__) | Ben Finney From davea at davea.name Fri Jan 2 12:27:15 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 06:27:15 -0500 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: References: Message-ID: <54A68093.6060904@davea.name> On 01/02/2015 05:25 AM, Brandon Dorsey wrote: > I know there is are easier ways to assign multiple objects to a variable, > but why, does the following code work? Why does it return a tuple versus a > list? I know it has something to do with the semi-colon, but I didn't know > it wouldn't raise an error. > > greetings = "hello,", "what's", "your", "name?" > print(greetings) > > x = 1, 2, 3, 4, 5, 6, 7 > print(x) > > I assumed that you could only assign one object per assignment without the > presence of tuples, list, or dictionaries. Ben's description is very good. But I think the main thing you're missing is that a tuple is created by the comma, not by parentheses. In some contexts, parentheses need to be added to make it non-ambiguous, since comma is overloaded. a = 1, 2, 3 1,2,3 is a tuple. This statement is identical to: a = (1, 2, 3) Likewise when you say: return 1, 2 you are returning a tuple. If you are passing a (literal) tuple as an argument to a function, you would need parens, since the function call also uses commas to separate the arguments: myfunc(val1, (21, 22, 23), val3) Here the function is being called with 3 arguments: val1 the tuple val3 -- DaveA From steve at pearwood.info Fri Jan 2 12:34:58 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 2 Jan 2015 22:34:58 +1100 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: References: Message-ID: <20150102113458.GG15262@ando.pearwood.info> On Fri, Jan 02, 2015 at 05:25:12AM -0500, Brandon Dorsey wrote: > I know there is are easier ways to assign multiple objects to a variable, > but why, does the following code work? Why does it return a tuple versus a > list? I know it has something to do with the semi-colon, but I didn't know > it wouldn't raise an error. > > greetings = "hello,", "what's", "your", "name?" There is no semi-colon involved. The thing to remember is that *commas*, not parentheses, are used for making tuples. The round brackets are just for grouping. So these are exactly the same: x = "hello", "world" # tuple of two strings y = ("hello", "world") # also a tuple of two strings So you can make a tuple of a single item: x = 23, # same as x = (23,) The exception is the empty tuple: y = () -- Steven From wolfrage8765 at gmail.com Fri Jan 2 15:47:34 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 09:47:34 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A62C86.30606@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> Message-ID: <54A6AF86.2090206@gmail.com> On 01/02/2015 12:28 AM, Dave Angel wrote: > On 01/01/2015 11:48 PM, WolfRage wrote: >> Final Code Using 2d List instead of Doubly Linked List. >> >> > > Please don't top-post. Instead, post your comments inline with the > parts of the previous message to which you're responding. I did reply in-line, but it appears even though I selected plan-text only. Thunderbird still messed it up. Not much I can do about that. Sorry I am used to top posting. But the rest of my response was in-line even if Thunderbird messed it up. > > Is there a reason you doublespaced the whole thing? And why did you > retype it instead of just copy/pasting it? And why lose the > indentation, so nobody can actually try it without guessing at your > indentation? No I did not double-space it, not in what I sent or was shown by Thunderbird. I definitely did not re-type it, I copy and pasted. But it seems that Thunderbird has a real hard time when also replying in-line to quotes. As far as the rest I will repost with just the code so that hopefully it is not messed up as I imagine that made it incredibly hard to read. From wolfrage8765 at gmail.com Fri Jan 2 15:49:30 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 09:49:30 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. Message-ID: <54A6AFFA.7050001@gmail.com> import sys class GameTile(): def __init__(self, id, **kwargs): # id is (X,Y) self.id = id class GameGrid(): def __init__(self, **kwargs): self.cols = 8 self.rows = 8 # grid is 2d array as y, x ie [y][x]. self.grid = [[None] * self.rows for i in range(self.cols)] def make_grid(self): for row in range(0, self.rows): for col in range(0, self.cols): self.grid[col][row] = GameTile(id=str(row) + ',' + str(col)) def print_by_row(self): for col in range(0, self.cols): for row in range(0, self.rows): print(self.grid[col][row].id) def print_by_col(self): for row in range(0, self.rows): for col in range(0, self.cols): print(self.grid[col][row].id) def check_bounds(self, x, y): if (0 <= x < self.rows) and (0 <= y < self.cols): return True return False def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[y][x] def draw_grid(self): for col in range(0, self.cols): print(end='| ') for row in range(0, self.rows): print(self.grid[col][row].id, end=' | ') print() temp = GameGrid() temp.make_grid() temp.draw_grid() print(sys.getsizeof(temp.grid)) #The above code shows fine to me with indentation preserved. Plain-Text was selected in Thunderbird. From wolfrage8765 at gmail.com Fri Jan 2 16:11:22 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 10:11:22 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <20150102072156.GF15262@ando.pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> Message-ID: <54A6B51A.9020104@gmail.com> On 01/02/2015 02:21 AM, Steven D'Aprano wrote: > Fixing the mangled formatting, as best as I am able (and can be > bothered). > > On Thu, Jan 01, 2015 at 11:48:18PM -0500, WolfRage wrote: > > class GameTile(): > def __init__(self, id, **kwargs): > # id is (X,Y) > self.id = id > > What is the purpose of the **kwargs? It doesn't get used, it just > silently ignores them. These are Kivy Buttons, when GameTile is written as a whole. But I broke it out in order to solve this specific problem. > > Actually, what is the purpose of this GameTile class? It has no methods > apart from the constructor. That is a sign of a class that isn't pulling > its weight, its not doing anything. All the other code in your program > looks inside the GameTile and accesses self.id directly. This is a sure > sign of a class that doesn't need to exist. It manages the on_press, on_release, and the image currently being displayed on the displayed tiles. But that is all that it does. But I still think I have to have it, since it is a button which inherits from Kivy's Button class. > > It may be better to give this at least a __str__ method, so if > nothing else you can print it without looking inside: Excellent idea, I will add this __str__ method so that I can print it directly. > > > class GameTile(): > def __init__(self, x, y): > self.x = x > self.y = y > def __str__(self): > return "%d, %d" % (self.x, self.y) > > > > class GameGrid(): > def __init__(self, **kwargs): > self.cols = 7 > self.rows = 8 > # grid is 2d array as y, x ie [y][x]. > self.grid = [[None] * self.rows for i in range(self.cols)] > > Why do you have GameTiles use X,Y but the grid uses the opposite order, > Y,X? This is going to cause confusion. I'm already confused! Well my lack of understanding as to how to implement the 2d list resulted in the row and col count being opposite, but I see now simply re-arranging those would fix this problem and the resulting hacks in the rest of the code, as it goes back and forth. > > > def make_grid(self): > for row in range(0, self.rows): > for col in range(0, self.cols): > self.grid[col][row] = GameTile(id=str(row) + ',' + str(col)) > > No need to write range(0, Whatever), since range defaults to 0. Better > to write range(Whatever). Good point. > > Why does the GameTile record the coordinates as strings? > > I would prefer something like this: > > def make_grid(self): > for row in range(self.rows): > for col in range(self.cols): > self.grid[col][row] = GameTile(row, col) I did this when I was writing the previous Kivy code, the coordinates actually serve as the id which is a Kivy variable that I am able to quickly lookup via there method, but I have mostly replaced this lookup with the new 2d list lookup now and so it is no longer necessary (At least I think, I will have to see how much of my previous code relied on this functionality and then weed it out). http://kivy.org/docs/api-kivy.uix.widget.html#kivy.uix.widget.Widget.id > > > although it looks strange due to the backwards ordering of col/row. > > > Your __init__ method should automatically call make_grid. That is: > > def __init__(self, **kwargs): > self.cols = 7 > self.rows = 8 > # grid is 2d array as y, x ie [y][x]. > self.grid = [[None] * self.rows for i in range(self.cols)] > self.make_grid() > > > Actually, even better will be to move the self.grid = ... line out of > the __init__ method, and make it part of make_grid. Since it is part of > making the grid. The making of the grid was put in the update because of Kivy, literally. I did not want to delay the display of the next screen while I was building my linked list. The previous linked list code was even bigger than what I posted initially and the execution of this code took around 1-2 seconds which caused the previous screen to hang. To prevent that I called update as a task to happen after the screens had flipped. But now that the grid creation is so fast, I can do this and no delay will be experienced. > > > def print_by_row(self): > for col in range(0, self.cols): > for row in range(0, self.rows): > print(self.grid[col][row].id) > > This now becomes: > > def print_by_row(self): > for col in range(0, self.cols): > for row in range(0, self.rows): > print(self.grid[col][row]) That is a cool feature with the __str__ method. haven't really learned to use the "Magic" or "special" methods yet. But will definitely start too now. > > > since GameTiles now know how to print themselves. Likewise for this: > > def print_by_col(self): > for row in range(0, self.rows): > for col in range(0, self.cols): > print(self.grid[col][row]) > > > Another simplification here: > > > def check_bounds(self, x, y): > return (0 <= x < self.rows) and (0 <= y < self.cols) > > > > Your lookup_node method returns a GameTile or False on failure: > > def lookup_node(self, x, y, ): > if not self.check_bounds(x, y): > return False > return self.grid[y][x] > > I'm not sure about that design. I wonder whether it would be better to > return None, or raise an exception. > > You have a lookup_node method that checks the bounds, but you don't seem > to use it anywhere. Why does it exist? Both are very good questions. What is the best speed wise way to handle error returns consistently, but I can return an exception or else I would have to catch it, because I do not want the game crashing on the player. This lookup method is used when finding nodes to the North, South, East, and West of a selected tile. However searching the entire grid for matches is so fast now, that I don't need to isolate my search area, so this functionality is likely to be removed like you say. > > > > def draw_grid(self): > for col in range(0, self.cols): > print(end='| ') > for row in range(0, self.rows): > print(self.grid[col][row].id, end=' | ') > print() > > > I'm not sure if I have reconstructed the indentation correctly here. A > few changes: no need to call range(0, ...). GameTile instances now know > how to print themselves, so you can call: > > print(self.grid[col][row], end=' | ') > > > > This could be improved: > > temp = GameGrid() > temp.make_grid() > temp.draw_grid() > > > Creating a GameGrid should automatically create the game grid, hence > what I said above about having __init__ call make_grid. Then use a more > meaningful name, and we have: > > > grid = GameGrid() > grid.draw_grid() # Maybe this could be just called "draw"? Thank you! Sorry about the indentation. I am checking the web version of the tutor archives now to see if my code reposted correctly. > > > From wolfrage8765 at gmail.com Fri Jan 2 16:14:45 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 10:14:45 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A62C86.30606@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> Message-ID: <54A6B5E5.3060606@gmail.com> Dave or Steve, what mail program do you use? It appears Thunderbird is still posting the code all messed up. Which makes it impossible to communicate effectively with the list. From steve at pearwood.info Fri Jan 2 16:17:02 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 02:17:02 +1100 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: References: <20150102113458.GG15262@ando.pearwood.info> Message-ID: <20150102151702.GH15262@ando.pearwood.info> On Fri, Jan 02, 2015 at 06:51:16AM -0500, Brandon Dorsey wrote: > On Fri, Jan 2, 2015 at 6:34 AM, Steven D'Aprano wrote: > > > The thing to remember is that *commas*, not parentheses, are used for > > making tuples. The round brackets are just for grouping. > > > > That's what I was confused about. I didn't realize commas defined tuples, > not parentheses. Is this the case > for list and dictionaires as well? No. x = 1, 2 y = 1, 2 cannot make a tuple for x and a list for y. How would the compiler know which you wanted? The syntax for lists: [a, b, c, ... ] requires the square brackets. You must have a comma between items, and optionally after the last item. That makes it easy to add new items to large lists without worrying about keeping the last item special. Here's an example from some code of mine: PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, ] Now I can add or remove lines without bothering to remove the comma from the very last line. If there are no items, you can't use a comma: x = [,] is a syntax error. Likewise for dicts, and in Python 3, sets: d = {1:'a', 2:'b'} s = {1, 2, 3} # set syntax is Python 3 only It is the curly brackets { } that tell Python you're creating a dict or set, not the commas. The commas separate items, that is all. -- Steven From steve at pearwood.info Fri Jan 2 16:34:08 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 03 Jan 2015 02:34:08 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6B5E5.3060606@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> Message-ID: <54A6BA70.50809@pearwood.info> On 03/01/15 02:14, WolfRage wrote: > Dave or Steve, what mail program do you use? It appears Thunderbird is still posting the code all messed up. Which makes it impossible to communicate effectively with the list. I normally use mutt, but for this post I've used Thunderbird. It is an old version though, 24.6.0, whereas I see you are using a more recent version: User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 You might like to try updating to the most recent version of Thunderbird your distro provides. If you are using Ubuntu or Debian, try either of these: sudo aptitude install thunderbird sudo apt-get install thunderbird If you are using Fedora or Centos, try: sudo yum install thunderbird Here is a test of indentation: def function(): pass # uses four spaces def function(): pass # uses a tab You should see no blank likes between the header "def function" and the pass, a pair of blank lines between the two functions, and both pass lines indented. -- Steve From alan.gauld at btinternet.com Fri Jan 2 16:37:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 15:37:20 +0000 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6AFFA.7050001@gmail.com> References: <54A6AFFA.7050001@gmail.com> Message-ID: On 02/01/15 14:49, WolfRage wrote: > class GameTile(): > > def __init__(self, id, **kwargs): > > # id is (X,Y) > > self.id = id Still showing double spaced and without indent to me, on Thunderbird... I use Thunderbird for posting too, and nobody has complained yet about my code layout. My account settings are: Composition&Addressing Compose in HTML - OFF Auto quote original then "START REPLY BELOW QUOTE" My Tbird prefs are: Composition->General tab-> Send Options button Text Format set to "Convert to plain text" Plain Text domains tab -> includes python.org and gmane.org And in my Address book I have the python tutor list entry set to Prefers messages formatted as PLAIN TEXT HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From brandontdr at gmail.com Fri Jan 2 12:51:16 2015 From: brandontdr at gmail.com (Brandon Dorsey) Date: Fri, 2 Jan 2015 06:51:16 -0500 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: <20150102113458.GG15262@ando.pearwood.info> References: <20150102113458.GG15262@ando.pearwood.info> Message-ID: On Fri, Jan 2, 2015 at 6:34 AM, Steven D'Aprano wrote: > The thing to remember is that *commas*, not parentheses, are used for > making tuples. The round brackets are just for grouping. > That's what I was confused about. I didn't realize commas defined tuples, not parentheses. Is this the case for list and dictionaires as well? -- From brandontdr at gmail.com Fri Jan 2 12:51:31 2015 From: brandontdr at gmail.com (Brandon Dorsey) Date: Fri, 2 Jan 2015 06:51:31 -0500 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: <857fx5zbgf.fsf@benfinney.id.au> References: <857fx5zbgf.fsf@benfinney.id.au> Message-ID: On Fri, Jan 2, 2015 at 6:08 AM, Ben Finney wrote: > Does it help you to understand if I clarify that a tuple is one value? > That a list is one value? That a dict is one value? > Well I knew that those data structures represent one value that can hold "x" amount of objects, but what I didn't realize was that commas are used for making tuples, not parentheses. Thank you for the clarification. -- From brandontdr at gmail.com Fri Jan 2 12:52:55 2015 From: brandontdr at gmail.com (Brandon Dorsey) Date: Fri, 2 Jan 2015 06:52:55 -0500 Subject: [Tutor] multiple objects with one assignment? In-Reply-To: <54A68093.6060904@davea.name> References: <54A68093.6060904@davea.name> Message-ID: On Fri, Jan 2, 2015 at 6:27 AM, Dave Angel wrote: Ben's description is very good. But I think the main thing you're missing > is that a tuple is created by the comma, not by parentheses. In some > contexts, parentheses need to be added to make it non-ambiguous, since > comma is overloaded. That's what I was baffled about. -- From steve at pearwood.info Fri Jan 2 16:40:39 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 03 Jan 2015 02:40:39 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6B5E5.3060606@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> Message-ID: <54A6BBF7.5060908@pearwood.info> On 03/01/15 02:14, WolfRage wrote: > Dave or Steve, what mail program do you use? It appears Thunderbird is still posting the code all messed up. Which makes it impossible to communicate effectively with the list. Another test. This time I have re-enabled HTML posting for my account, but set Thunderbird to automatically send "plain text" when sending to python.org. My prediction is that the indentation and spacing will be lost. def test(): pass # pressed tab, but the HTML editor inserted four spaces def test(): pass # pressed space four times. -- Steven From steve at pearwood.info Fri Jan 2 16:43:46 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 03 Jan 2015 02:43:46 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6B5E5.3060606@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> Message-ID: <54A6BCB2.5070809@pearwood.info> On 03/01/15 02:14, WolfRage wrote: > Dave or Steve, what mail program do you use? It appears Thunderbird is still posting the code all messed up. Which makes it impossible to communicate effectively with the list. One last test. I've removed python.org from the "Plain text only" domains, so this post should contain both a HTML and a plain text part. (Sorry Dave :-) def test(): pass # four spaces def test(): pass -- Steve From steve at pearwood.info Fri Jan 2 16:46:24 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 02:46:24 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6BBF7.5060908@pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> <54A6BBF7.5060908@pearwood.info> Message-ID: <20150102154623.GI15262@ando.pearwood.info> On Sat, Jan 03, 2015 at 02:40:39AM +1100, Steven D'Aprano wrote: > On 03/01/15 02:14, WolfRage wrote: > >Dave or Steve, what mail program do you use? It appears Thunderbird is > >still posting the code all messed up. Which makes it impossible to > >communicate effectively with the list. > > Another test. This time I have re-enabled HTML posting for my account, but > set Thunderbird to automatically send "plain text" when sending to > python.org. > > My prediction is that the indentation and spacing will be lost. > > def test(): > pass # pressed tab, but the HTML editor inserted four spaces > > def test(): > pass # pressed space four times. Well, so much for my prediction. Looks like this version of Thunderbird (24.6) correctly converts HTML to plain text without losing the indentation or spacing. -- Steven From wolfrage8765 at gmail.com Fri Jan 2 16:53:35 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 10:53:35 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: References: <54A6AFFA.7050001@gmail.com> Message-ID: <54A6BEFF.6080205@gmail.com> On 01/02/2015 10:37 AM, Alan Gauld wrote: > > I use Thunderbird for posting too, and nobody has complained yet about > my code layout. > My account settings are: > > Composition&Addressing > Compose in HTML - OFF > Auto quote original then "START REPLY BELOW QUOTE" > > My Tbird prefs are: > Composition->General tab-> Send Options button > Text Format set to "Convert to plain text" > Plain Text domains tab -> includes python.org and gmane.org > > And in my Address book I have the python tutor list entry set to > > Prefers messages formatted as PLAIN TEXT > > HTH Using Alan's settings above I can already see the difference in the composition window. Reposting my code to see if it comes out correctly now. I am still applying Steve's suggestions. import sys class GameTile(): def __init__(self, col, row, **kwargs): # id is (X,Y) self.id = str(row) + ',' + str(col) self.col = col self.row = row def __str__(self): return '%d, %d' % (self.col, self.row) class GameGrid(): def __init__(self, **kwargs): self.cols = 8 self.rows = 8 self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [[None] * self.cols for i in range(self.rows)] for row in range(self.rows): for col in range(self.cols): self.grid[row][col] = GameTile(row=row, col=col) def print_by_row(self): for col in range(self.cols): for row in range(self.rows): print(self.grid[row][col]) def print_by_col(self): for row in range(self.rows): for col in range(self.cols): print(self.grid[row][col]) def check_bounds(self, x, y): if (0 <= x < self.rows) and (0 <= y < self.cols): return True return False def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[x][y] def draw_grid(self): for col in range(self.cols): print(end='| ') for row in range(self.rows): print(self.grid[row][col], end=' | ') print() grid = GameGrid() grid.draw() print(sys.getsizeof(grid.grid)) From davea at davea.name Fri Jan 2 16:57:02 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 10:57:02 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6BEFF.6080205@gmail.com> References: <54A6AFFA.7050001@gmail.com> <54A6BEFF.6080205@gmail.com> Message-ID: <54A6BFCE.4050506@davea.name> On 01/02/2015 10:53 AM, WolfRage wrote: > On 01/02/2015 10:37 AM, Alan Gauld wrote: > >> >> I use Thunderbird for posting too, and nobody has complained yet about >> my code layout. >> My account settings are: >> >> Composition&Addressing >> Compose in HTML - OFF >> Auto quote original then "START REPLY BELOW QUOTE" >> >> My Tbird prefs are: >> Composition->General tab-> Send Options button >> Text Format set to "Convert to plain text" >> Plain Text domains tab -> includes python.org and gmane.org >> >> And in my Address book I have the python tutor list entry set to >> >> Prefers messages formatted as PLAIN TEXT >> >> HTH > Using Alan's settings above I can already see the difference in the > composition window. > > Reposting my code to see if it comes out correctly now. I am still > applying Steve's suggestions. > > import sys > > > class GameTile(): > def __init__(self, col, row, **kwargs): > # id is (X,Y) > self.id = str(row) + ',' + str(col) > self.col = col > self.row = row > > def __str__(self): > return '%d, %d' % (self.col, self.row) > > Looks great to me. -- DaveA From davea at davea.name Fri Jan 2 16:58:25 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 10:58:25 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6BF8B.8040008@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> <54A6BCB2.5070809@pearwood.info> <54A6BF8B.8040008@davea.name> Message-ID: <54A6C021.40507@davea.name> On 01/02/2015 10:55 AM, Dave Angel wrote: > On 01/02/2015 10:43 AM, Steven D'Aprano wrote: >> On 03/01/15 02:14, WolfRage wrote: >>> Dave or Steve, what mail program do you use? It appears Thunderbird is >>> still posting the code all messed up. Which makes it impossible to >>> communicate effectively with the list. >> >> One last test. I've removed python.org from the "Plain text only" >> domains, so this post should contain both a HTML and a plain text part. > > No html part, text only. And I've given up on using the tablet for the > moment. I'm currently using Thunderbird on the laptop till the tablet > software works better. > > >> (Sorry Dave :-) >> >> def test(): >> pass # four spaces >> >> def test(): >> pass >> >> >> > > -- DaveA From wolfrage8765 at gmail.com Fri Jan 2 17:37:12 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 11:37:12 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <20150102072156.GF15262@ando.pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> Message-ID: <54A6C938.1010709@gmail.com> On 01/02/2015 02:21 AM, Steven D'Aprano wrote: > What is the purpose of the **kwargs? It doesn't get used, it just > silently ignores them. Hopefully you got the answer for this from the previous message. > > Why does the GameTile record the coordinates as strings? Hopefully you got the answer for this from the previous message. > > Your lookup_node method returns a GameTile or False on failure: > > def lookup_node(self, x, y, ): > if not self.check_bounds(x, y): > return False > return self.grid[y][x] > > I'm not sure about that design. I wonder whether it would be better to > return None, or raise an exception. What would you suggest this code does on error, when the Node looked up is out of bounds? Latest copy of the code. I think I got every ones suggestion. import sys class GameTile(): def __init__(self, col, row, **kwargs): # id is (X,Y) self.id = str(row) + ',' + str(col) self.col = col self.row = row def __str__(self): return '%d, %d' % (self.col, self.row) class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): self.cols = cols self.rows = rows self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [[None] * self.cols for i in range(self.rows)] for row in range(self.rows): for col in range(self.cols): self.grid[row][col] = GameTile(row=row, col=col) def print_by_row(self): for col in self.grid: for row in col: print(row) def print_by_col(self): for row in self.grid: for col in row: print(col) def check_bounds(self, x, y): return (0 <= x < self.rows) and (0 <= y < self.cols) def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[x][y] def draw(self): for col in self.grid: print(end='| ') for row in col: print(row, end=' | ') print() grid = GameGrid(3, 3) grid.draw() print(sys.getsizeof(grid.grid)) From davea at davea.name Fri Jan 2 18:08:13 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 12:08:13 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6C938.1010709@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> Message-ID: <54A6D07D.4090405@davea.name> On 01/02/2015 11:37 AM, WolfRage wrote: > On 01/02/2015 02:21 AM, Steven D'Aprano wrote: >> What is the purpose of the **kwargs? It doesn't get used, it just >> silently ignores them. > > Hopefully you got the answer for this from the previous message. >> >> Why does the GameTile record the coordinates as strings? > > Hopefully you got the answer for this from the previous message. >> >> Your lookup_node method returns a GameTile or False on failure: >> >> def lookup_node(self, x, y, ): >> if not self.check_bounds(x, y): >> return False >> return self.grid[y][x] >> >> I'm not sure about that design. I wonder whether it would be better to >> return None, or raise an exception. > What would you suggest this code does on error, when the Node looked up > is out of bounds? > > Latest copy of the code. I think I got every ones suggestion. > > import sys > > > class GameTile(): > def __init__(self, col, row, **kwargs): > # id is (X,Y) > self.id = str(row) + ',' + str(col) > self.col = col > self.row = row > > def __str__(self): > return '%d, %d' % (self.col, self.row) > > > class GameGrid(): > def __init__(self, cols=8, rows=7, **kwargs): You probably want to reverse the order of the parameters; you've got almost everything else row-major > self.cols = cols > self.rows = rows > self.make_grid() > > def make_grid(self): > # grid is 2d array as x, y ie [x][y]. > self.grid = [[None] * self.cols for i in range(self.rows)] > for row in range(self.rows): > for col in range(self.cols): > self.grid[row][col] = GameTile(row=row, col=col) Since both stages are being done in the same method, you don't need the part which initializes to None. try something like: def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): self.grid.append([]) for col_num in range(self.cols): self.grid[-1].append(GameTile(row=row_num, col=col_num)) or even def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): self.grid.append( [GameTile(row=row_num, col=col_num) for col_num in range(self.cols)] ) > > def print_by_row(self): > for col in self.grid: > for row in col: > print(row) This cannot work. The items in self.grid are rows. Calling one of them col doesn't make it so. In other words, the method as written will do exactly what print_by_col() does. Try the following: def print_by_row(self): for col_number in range(self.cols): for row in self.grid: print(row[col_number]) > > def print_by_col(self): > for row in self.grid: > for col in row: > print(col) This one should work fine. But one of the names could be improved: def print_by_col(self): for row in self.grid: for tile in row: print(tile) > > def check_bounds(self, x, y): > return (0 <= x < self.rows) and (0 <= y < self.cols) > > def lookup_node(self, x, y): > if not self.check_bounds(x, y): > return False > return self.grid[x][y] > > def draw(self): > for col in self.grid: > print(end='| ') > for row in col: > print(row, end=' | ') > print() > > > grid = GameGrid(3, 3) > grid.draw() > print(sys.getsizeof(grid.grid)) > All code untested. i hope it helps. -- DaveA From akleider at sonic.net Fri Jan 2 18:57:29 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 02 Jan 2015 09:57:29 -0800 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> Message-ID: <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> On 2015-01-01 17:35, Alan Gauld wrote: > Repeats replicates the reference to the object but > does not create a new object. This part I can understand but, as Steven has pointed out, this behaviour changes if the object being repeated is immutable. Why would one get a new object (rather than a new reference to it) just because it is immutable? It's this difference in behaviour that depends on mutability that I still don't understand even though Steven did try to explain it to me: """ If the list items are immutable, like ints or strings, the difference doesn't matter. You can't modify immutable objects in-place, so you never notice any difference between copying them or not. """ From davea at davea.name Fri Jan 2 19:40:19 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 13:40:19 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> Message-ID: <54A6E613.5020602@davea.name> On 01/02/2015 12:57 PM, Alex Kleider wrote: > On 2015-01-01 17:35, Alan Gauld wrote: > >> Repeats replicates the reference to the object but >> does not create a new object. > > This part I can understand but, as Steven has pointed out, > this behaviour changes if the object being repeated is immutable. > Why would one get a new object (rather than a new reference to it) > just because it is immutable? It's this difference in behaviour > that depends on mutability that I still don't understand even though > Steven did try to explain it to me: > """ > If the list items are immutable, like ints or strings, the difference > doesn't matter. You can't modify immutable objects in-place, so you > never notice any difference between copying them or not. > """ You have it backwards. The behavior doesn't change between mutable and immutable, the visibility of the behavior changes. If the object is immutable, you can't tell it hasn't been copied. An "assignment" does not create a new object, immutable or not. it simply binds the left side to the object on the right. a = x does not copy x, no matter what type it may be. It simply binds a to the object. -- DaveA From wolfrage8765 at gmail.com Fri Jan 2 19:56:17 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 13:56:17 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6D07D.4090405@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> Message-ID: <54A6E9D1.1050707@gmail.com> On 01/02/2015 12:08 PM, Dave Angel wrote: >> class GameGrid(): >> def __init__(self, cols=8, rows=7, **kwargs): > > You probably want to reverse the order of the parameters; you've got > almost everything else row-major > You are right, a lot of inconsistency that will lead to errors latter on. I need to make everything column-major. So that the grid (x,y) are the same to grid (col,row). I have too much confusion throughout my code, so I will correct the code. > Since both stages are being done in the same method, you don't need the > part which initializes to None. > > def make_grid(self): > # grid is 2d array as x, y ie [x][y]. > self.grid = [] > for row_num in range(self.rows): > self.grid.append( [GameTile(row=row_num, col=col_num) for > col_num in range(self.cols)] ) > Implemented the second version. >> >> def print_by_row(self): >> for col in self.grid: >> for row in col: >> print(row) > > This cannot work. The items in self.grid are rows. Calling one of them > col doesn't make it so. In other words, the method as written will do > exactly what print_by_col() does. Good point, I did not read the output thoroughly enough to catch this. > > Try the following: > > def print_by_row(self): > for col_number in range(self.cols): > for row in self.grid: > print(row[col_number]) > Implemented. > > This one should work fine. But one of the names could be improved: > > > def print_by_col(self): > for row in self.grid: > for tile in row: > print(tile) > Thanks, improved. > All code untested. i hope it helps. > Definitely. Thanks. I have updated the code and I realized that all of my earlier confusion was even greater, so I have also added comments to make things make sense. Now the print_by_ methods work as I envision and in accordance with the comments. import sys class GameTile(): def __init__(self, col, row, **kwargs): # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row def __str__(self): return '%d, %d' % (self.col, self.row) class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): self.cols = cols self.rows = rows self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): self.grid.append([GameTile(col=col_num, row=row_num) for col_num in range(self.cols)]) def print_by_col(self): # As in going down the column assuming we started at the top. for col_num in range(self.cols): for row in self.grid: print(row[col_num]) def print_by_row(self): # As in going right across the row assuming we started at the left. for row in self.grid: for node in row: print(node) def check_bounds(self, x, y): return (0 <= x < self.rows) and (0 <= y < self.cols) def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[x][y] def draw(self): for col in self.grid: print(end='| ') for row in col: print(row, end=' | ') print() grid = GameGrid(3, 3) grid.draw() print(sys.getsizeof(grid.grid)) print() grid.print_by_row() print() grid.print_by_col() From wolfrage8765 at gmail.com Fri Jan 2 20:03:29 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 14:03:29 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6D07D.4090405@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> Message-ID: <54A6EB81.1010505@gmail.com> Tutors, on my next iteration I am going to add more of the game code. Since I am no longer using Doubly Linked Lists, should I create a new thread? Or should I continue with this thread to continue with the established context? From d at davea.name Fri Jan 2 16:55:55 2015 From: d at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 10:55:55 -0500 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6BCB2.5070809@pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <54A62C86.30606@davea.name> <54A6B5E5.3060606@gmail.com> <54A6BCB2.5070809@pearwood.info> Message-ID: <54A6BF8B.8040008@davea.name> On 01/02/2015 10:43 AM, Steven D'Aprano wrote: > On 03/01/15 02:14, WolfRage wrote: >> Dave or Steve, what mail program do you use? It appears Thunderbird is >> still posting the code all messed up. Which makes it impossible to >> communicate effectively with the list. > > One last test. I've removed python.org from the "Plain text only" > domains, so this post should contain both a HTML and a plain text part. No html part, text only. And I've given up on using the tablet for the moment. I'm currently using Thunderbird on the laptop till the tablet software works better. > (Sorry Dave :-) > > def test(): > pass # four spaces > > def test(): > pass > > > -- DaveA From rohan0495 at gmail.com Fri Jan 2 19:21:04 2015 From: rohan0495 at gmail.com (Rohan Ds) Date: Fri, 2 Jan 2015 23:51:04 +0530 Subject: [Tutor] Fwd: Newbie In-Reply-To: References: Message-ID: ---------- Forwarded message ---------- From: "Rohan Ds" Date: 2 Jan 2015 23:46 Subject: Newbie To: Cc: Hello everybody :) I am Rohan from India. I'm new to Python. I have a basic understanding as to how Python works. I want to contribute to PSF. The information available on the site didn't really answer my questions. If anyone here could tell me, how I should get started with it, I'd be really grateful to you. Also, with GSoC coming up, if i keep contributing dedicatedly to PSF, will I have a shot at GSoC? Someone please reply asap. From alan.gauld at btinternet.com Fri Jan 2 20:15:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 19:15:37 +0000 Subject: [Tutor] Fwd: Newbie In-Reply-To: References: Message-ID: On 02/01/15 18:21, Rohan Ds wrote: > Hello everybody :) Hi, welcome. > I am Rohan from India. I'm new to Python. I have a basic understanding as > to how Python works. I want to contribute to PSF. The information available > on the site didn't really answer my questions. It will help if you tell us which information you looked at (there may be better pages) and what exactly your questions are. > If anyone here could tell me, how I should get started with it, I'd be > really grateful to you. What do you want to start doing? There are bugs to fix, documents to update, PEPs to implement. What do you want to do? > Also, with GSoC coming up, if i keep contributing > dedicatedly to PSF, will I have a shot at GSoC? Someone please reply asap. I know nothing about GSoC. Maybe the main list would be a better place to ask about GSoC, maybe even the PSF work too, since its not really about learning Python, which is what this list is for. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 2 20:19:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 19:19:36 +0000 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6EB81.1010505@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A6EB81.1010505@gmail.com> Message-ID: On 02/01/15 19:03, WolfRage wrote: > Tutors, on my next iteration I am going to add more of the game code. > Since I am no longer using Doubly Linked Lists, should I create a new > thread? Or should I continue with this thread to continue with the > established context? Since you are now just looking for general advice on your game I'd suggest a new thread to go with the new code. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From ranceh at gmail.com Fri Jan 2 21:17:05 2015 From: ranceh at gmail.com (Rance Hall) Date: Fri, 2 Jan 2015 14:17:05 -0600 Subject: [Tutor] threading in python2.7 Message-ID: I bought myself a pcduino 3 nano development board for Christmas and started picking up python again after a long forced hiatus. The board runs Ubuntu Precise Working with development boards has me navigating the inner working of python threading and I find myself at a loss. My current project is a simulated emergency vehicle warning system (otherwise known as a police siren) I started my project by writing the lighting and the sound portions of the program separately and tweaking them till I got each part working as desired. Now to get them to start simultaneously and exit cleanly. I started with some basic python like this: import needed stuff global variable declarations def setup_hardware(): do stuff here to setup hardware and gpio sytem def lights(): control the red and blue LEDs to simulate warning lights def sound(): control the sound to simulate a warning siren def cleanup(): exit cleanly and cleanup def main(): setup() try: # individually starting either lights or sound works as expected except: # catch keyboard interrupt and call cleanup I've read many threading tutorials from the old thread module to the new threading module and I've found several different ways of starting both lights and sound in their own threads. The issue I have is exiting the program. All of the tutorials suggest having a global variable to indicate when to exit the threads. so I used a global variable called exitFlag and begin the program with it set to 0 Each of the lights and sound functions are placed in a "while not exitFlag:" loop I think I'm running into some variable scoping issues related to threads, but I'm not sure exactly. Based on the debugging messages I've added to my code, the changes to the exitFlag variable made in the either the main loop or the cleanup loop are never seen by the lights and sound loop threads. The net effect of this is that once the threads are started, they are uncontrollable and I have to quit the terminal to get the threads to stop. Could someone please point me in the direction of a good tutorial or sample code that works that I could use as study tool? I've not bothered posting the code since its custom to this board and will fail on another python instance unless it has the the same hardware control modules my board does. Thanks all for your help. From alan.gauld at btinternet.com Fri Jan 2 22:18:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 02 Jan 2015 21:18:49 +0000 Subject: [Tutor] threading in python2.7 In-Reply-To: References: Message-ID: On 02/01/15 20:17, Rance Hall wrote: > I bought myself a pcduino 3 nano development board for Christmas and > started picking up python again after a long forced hiatus. The board runs > Ubuntu Precise Snap!(ish), I got an arduino Uno and RaspberryPi. As I understand it the pcDuino is just a PC and duino on a single board, right? > Working with development boards has me navigating the inner working of > python threading and I find myself at a loss. You realise the 'duino processor is strictly single threaded? So you need a stateless event handler and keep the threading all within Python. > My current project is a simulated emergency vehicle warning system > (otherwise known as a police siren) > > I started my project by writing the lighting and the sound portions of the > program separately and tweaking them till I got each part working as > desired. How are you writing the code? Are you writing 'duino stuff in C and control stuff in Python? How does the pcduino communicate between the controller and PC sections? Do you still use the 'duino IDE? In my set up I'd write the light/sound controller stuff and have the event loop read signals from the Python code via the USB link. Is it similar on the pcduino? > > def setup_hardware(): > do stuff here to setup hardware and gpio sytem > > def lights(): > control the red and blue LEDs to simulate warning lights > > def sound(): > control the sound to simulate a warning siren > > def cleanup(): > exit cleanly and cleanup > > def main(): > setup() > try: > # individually starting either lights or sound works as expected > except: > # catch keyboard interrupt and call cleanup > > Where is the event loop? You need something to manage the events. > Each of the lights and sound functions are placed in a "while not > exitFlag:" loop So the thread control is in two separate loops. And each loop can set the flag? > exitFlag variable made in the either the main loop or the cleanup loop are > never seen by the lights and sound loop threads. How many loops do you have? You have a light loop, a sound loop, a setup lop and a cleanup loop? Sounds too many. > The net effect of this is that once the threads are started, they are > uncontrollable and I have to quit the terminal to get the threads to stop. > > Could someone please point me in the direction of a good tutorial or sample > code that works that I could use as study tool? You should probably try the Ardiuino/PCduino forums > I've not bothered posting the code since its custom to this board and will > fail on another python instance But your skeleton is too skeletal for us to suggest anything. You don't even show us where the threading happens, or how. You could replicate the code structure using a pseudo API that just prints or returns values from a list... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Fri Jan 2 22:57:38 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 08:57:38 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> Message-ID: <20150102215737.GA27426@ando.pearwood.info> On Fri, Jan 02, 2015 at 09:57:29AM -0800, Alex Kleider wrote: > On 2015-01-01 17:35, Alan Gauld wrote: > > >Repeats replicates the reference to the object but > >does not create a new object. > > This part I can understand but, as Steven has pointed out, > this behaviour changes if the object being repeated is immutable. > Why would one get a new object (rather than a new reference to it) > just because it is immutable? It's this difference in behaviour > that depends on mutability that I still don't understand even though > Steven did try to explain it to me: > """ > If the list items are immutable, like ints or strings, the difference > doesn't matter. You can't modify immutable objects in-place, so you > never notice any difference between copying them or not. > """ No, you misunderstood what I was trying to say. Let's create a list with one mutable and one immutable object, then double it: py> a = [{}, 999] py> b = a*3 py> print(b) [{}, 999, {}, 999, {}, 999] The list b has 6 items, but only two different objects inside b: there is a dict, repeated three times, and an int, repeated three times. We can check this by printing the IDs of each item: py> print([hex(id(x)) for x in b]) ['0xb7bf1aec', '0xb7b6c580', '0xb7bf1aec', '0xb7b6c580', '0xb7bf1aec', '0xb7b6c580'] If you study them carefully, you will see only two distinct IDs: '0xb7bf1aec', '0xb7b6c580' The exact values you get will differ, of course. On some versions of Python, you might see something like: ['0x1', '0x2', '0x1', '0x2','0x1', '0x2'] depending on what values the compiler uses for the IDs. But the important thing is there are only two of them. We can let Python check for duplicates by using a set: py> print(set([hex(id(x)) for x in b])) {'0xb7b6c580', '0xb7bf1aec'} Go back to our list b. Naturally, we can modify *the list* directly: py> b[2] = {'a': 1} py> b[3] = 23 py> print(b) [{}, 999, {'a': 1}, 23, {}, 999] Notice that when we assign to a list item, it replaces whatever assignment was there: position 2 used to refer to an empty dict, now it refers to a different dict; position 3 used to refer to an int, now it refers to a different int. We can change the list, because lists are mutable. We can change dicts *in place* too: py> b[0]['c'] = 3 py> print(b) [{'c': 3}, 999, {'a': 1}, 23, {'c': 3}, 999] Because we have modified the dict object, not re-assigned it, the change shows up in both position 0 and position 4. It doesn't show up in position 2, because it is a different dict there now. But there is no way to change ints in place! Because they are immutable, there's nothing we can do to change that int 999 into a different value. It will always be 999. The only way to change an int is to replace it with a different object, and we've seen that the way to do that in Python is by assigning to the list index. Even something that at first glance looks like "increment" is actually "add 1 and re-assign": py> b[1] += 1 py> print(b) [{'c': 3}, 1000, {'a': 1}, 23, {'c': 3}, 999] py> print([hex(id(x)) for x in b]) ['0xb7bf1aec', '0xb7b6c600', '0xb7afb70c', '0x823c160', '0xb7bf1aec', '0xb7b6c580'] Now there are five distinct IDs. With mutable objects, identity can be important. There is a difference between: a = [] b = [] and a = [] b = a In the first case, a and b are distinct lists. In the second case, a and b are the same list. But with immutable objects, there is nothing you can do (except check the IDs) that will reveal the difference between having one or two distinct objects: a = 123 b = 123 *may or may not* set a and b to distinct objects. Because when it comes to immutable objects, it makes no difference. -- Steven From joseph.lee22590 at gmail.com Fri Jan 2 21:39:36 2015 From: joseph.lee22590 at gmail.com (Joseph Lee) Date: Fri, 2 Jan 2015 12:39:36 -0800 Subject: [Tutor] threading in python2.7 In-Reply-To: References: Message-ID: <005801d026cc$39c351b0$ad49f510$@gmail.com> Hi, Answers are below. -----Original Message----- From: Tutor [mailto:tutor-bounces+joseph.lee22590=gmail.com at python.org] On Behalf Of Rance Hall Sent: Friday, January 2, 2015 12:17 PM To: tutor Subject: [Tutor] threading in python2.7 Each of the lights and sound functions are placed in a "while not exitFlag:" loop I think I'm running into some variable scoping issues related to threads, but I'm not sure exactly. JL: Each thread has its own context and local variables unless you want to bring in the exit flag from the module itself. A good place to do it is right before you enter the while loop. Original: Based on the debugging messages I've added to my code, the changes to the exitFlag variable made in the either the main loop or the cleanup loop are never seen by the lights and sound loop threads. The net effect of this is that once the threads are started, they are uncontrollable and I have to quit the terminal to get the threads to stop. JL: Could someone please point me in the direction of a good tutorial or sample code that works that I could use as study tool? JL: There are plenty of projects online which uses threads. A toy project might be to implement a long running counter that stops when you set some variable to False, like: Pseudocode: import threading import time stop = False def count(upto): global stop for i in xrange(upto): if stop: return print i time.sleep(0.5) def main(): t = threading.Thread(count, args=(someNumber)) t.run() Essentially, this guy runs two threads: the main thread, and the counter thread. If the stop value is set, the counter thread will stop running. As for placing the value check at the top of the loop, it was done that way to make sure the thread dies when it is true and to do it as early as possible for performance. Threads introduce interesting issues. For instance, due to Python's global interpreter lock (GIL), only one thread can run at a given time. You'll also need to make sure that values modified by one thread is not misinterpreted in other threads, and that two or more threads doesn't write to same location at the same time and cause problems (the way to mitigate this is using what's called "critical region" where only one thread at a time can mess with an important variable or do some critical activity, quite beyond the scope I think). Original: I've not bothered posting the code since its custom to this board and will fail on another python instance unless it has the the same hardware control modules my board does. JL: If you are writing for an embedded board and want to really make sure your code will work as intended, try starting from your desktop - write a module that "simulates" the board (that is, write a console script) and test it on your computer before porting to your board. Good luck. Please let us know if you need more help. Cheers, Joseph _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From wolfrage8765 at gmail.com Fri Jan 2 23:35:23 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 17:35:23 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A6D07D.4090405@davea.name> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> Message-ID: <54A71D2B.8070406@gmail.com> First an explanation of how the game works: The game is a simple matching game but with a twist. Instead of matching a straight 3 in a row, we have some rules that only certain combinations will result in an elimination. In general 2 of the same value in a row with with 1 of 2 other possible values will eliminate all three nodes. Eliminations can occur either horizontally or vertically but not diagonally. Each tile has a value now, that value is used when evaluating the rules. Currently there are only 5 allowed values of 0-4 although more could be added later, so any solution needs to be expandable. These are the basic rules that allow for an elimination to occur(values are put in quotes to distinguish values): 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. 2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes. 2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes. 2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes. 2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes. 2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes. 2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes. 2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes. 2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes. 2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes. The main focus of the code is the find_eliminations method. I think its implementation is smart since it uses a math trick, but then again I wrote it. My math trick works by first finding 2 matching nodes next to each other out of every 3 nodes, then adding the values of all 3 nodes together and checking for specific totals. None of the possible totals overlap. Here is the code: import random class GameTile(): def __init__(self, value, col, row, **kwargs): # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row self.value = value self.eliminated = False def __str__(self): #return '%d, %d' % (self.col, self.row) if len(str(self.value)) == 1: return ' ' + str(self.value) return str(self.value) class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): self.cols = cols self.rows = rows self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): self.grid.append([GameTile(value=random.choice([5, 6, 11, 19, 20]), col=col_num, row=row_num) for col_num in range(self.cols)]) def print_by_col(self): # As in going down the column assuming we started at the top. for col_num in range(self.cols): for row_list in self.grid: print(row_list[col_num]) def print_by_row(self): # As in going right across the row assuming we started at the left. for row in self.grid: for node in row: print(node) def check_bounds(self, x, y): return (0 <= x < self.rows) and (0 <= y < self.cols) def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[x][y] def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def find_eliminations(self): # I define 3 variables for holding the 3 nodes/tiles that I am # currently checking to see if an elimination possibility exists. # It uses a math trick to check for elimination by adding the values # and checking for specific totals. None of the possible totals overlap. #First Down the columns. for col_num in range(self.cols): first = None second = None third = None for row_list in self.grid: if row_list[col_num].row == 0: first = row_list[col_num] elif row_list[col_num].row == 1: second = row_list[col_num] elif row_list[col_num].row == 2: third = row_list[col_num] else: first = second second = third third = row_list[col_num] if third is not None: self.check_total_and_eliminate(first, second, third) # Now across the rows. for row in self.grid: first = None second = None third = None for node in row: if node.col == 0: first = node elif node.col == 1: second = node elif node.col == 2: third = node else: first = second second = third third = node if third is not None: self.check_total_and_eliminate(first, second, third) # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total_and_eliminate(self, first, second, third): total = None if first.value == second.value: total = first.value + second.value + third.value elif second.value == third.value: total = first.value + second.value + third.value if total == 17 or total == 21 or total == 28 or total == 29 or \ total == 31 or total == 42 or total == 45 or total == 46 \ or total == 49 or total == 58: first.eliminated = True second.eliminated = True third.eliminated = True grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() # END CODE After this part has been improved, I then need to search the columns backwards to be able to drop any floating values. Any none zero values should not have a zero value below it. That is what I mean by drop floating values. I think this will be simple by just using range method to count backwards. I will be working on coding that in the meantime. From davea at davea.name Fri Jan 2 23:51:04 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 17:51:04 -0500 Subject: [Tutor] thread-breaing In-Reply-To: <54A71D2B.8070406@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> Message-ID: <54A720D8.3040105@davea.name> On 01/02/2015 05:35 PM, WolfRage wrote: > First an explanation of how the game works: The game is a simple > matching game but with a twist. Instead of matching a straight 3 in a You forgot to start a new thread. A new thread isn't changing the subject in the middle of a deeply nested thread. A new thread starts with a new message which stands on its own, and is not a reply to anything. Send a message directly to tutor at python.org, without using reply. Make sure the query makes sense without reference to any earlier message. So you include the python version in the query, along with any other context. -- DaveA From ranceh at gmail.com Sat Jan 3 02:26:40 2015 From: ranceh at gmail.com (Rance Hall) Date: Fri, 2 Jan 2015 19:26:40 -0600 Subject: [Tutor] threading in python2.7 In-Reply-To: <005801d026cc$39c351b0$ad49f510$@gmail.com> References: <005801d026cc$39c351b0$ad49f510$@gmail.com> Message-ID: First, thanks Joseph for taking the time to reply. My comments interspersed below: On Fri, Jan 2, 2015 at 2:39 PM, Joseph Lee wrote: > Hi, > Answers are below. > > -----Original Message----- > From: Tutor [mailto:tutor-bounces+joseph.lee22590=gmail.com at python.org] On > Behalf Of Rance Hall > Sent: Friday, January 2, 2015 12:17 PM > To: tutor > Subject: [Tutor] threading in python2.7 > > Each of the lights and sound functions are placed in a "while not > exitFlag:" > loop > > I think I'm running into some variable scoping issues related to threads, > but I'm not sure exactly. > > JL: Each thread has its own context and local variables unless you want to > bring in the exit flag from the module itself. A good place to do it is > right before you enter the while loop. > Exactly what I suspected was happening, but was unsure how to address the issue. > > Original: > Based on the debugging messages I've added to my code, the changes to the > exitFlag variable made in the either the main loop or the cleanup loop are > never seen by the lights and sound loop threads. > > The net effect of this is that once the threads are started, they are > uncontrollable and I have to quit the terminal to get the threads to stop. > > JL: > > Could someone please point me in the direction of a good tutorial or sample > code that works that I could use as study tool? > > JL: There are plenty of projects online which uses threads. A toy project > might be to implement a long running counter that stops when you set some > variable to False, like: > > Pseudocode: > import threading > import time > > stop = False > > def count(upto): > global stop > for i in xrange(upto): > if stop: return > print i > time.sleep(0.5) > > def main(): > t = threading.Thread(count, args=(someNumber)) > t.run() > > This failed the first time I tried it, but see below: > Essentially, this guy runs two threads: the main thread, and the counter > thread. If the stop value is set, the counter thread will stop running. As > for placing the value check at the top of the loop, it was done that way to > make sure the thread dies when it is true and to do it as early as possible > for performance. > > Threads introduce interesting issues. For instance, due to Python's global > interpreter lock (GIL), only one thread can run at a given time. You'll > also > need to make sure that values modified by one thread is not misinterpreted > in other threads, and that two or more threads doesn't write to same > location at the same time and cause problems (the way to mitigate this is > using what's called "critical region" where only one thread at a time can > mess with an important variable or do some critical activity, quite beyond > the scope I think). > > Original: > I've not bothered posting the code since its custom to this board and will > fail on another python instance unless it has the the same hardware control > modules my board does. > > JL: If you are writing for an embedded board and want to really make sure > your code will work as intended, try starting from your desktop - write a > module that "simulates" the board (that is, write a console script) and > test > it on your computer before porting to your board. > > Really good advice here. I'll craft something new that has the flow I want without respect to the board specifics and see where that goes. > Good luck. Please let us know if you need more help. > Cheers, > Joseph > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > From wolfrage8765 at gmail.com Sat Jan 3 03:00:22 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 02 Jan 2015 21:00:22 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning Message-ID: <54A74D36.5090308@gmail.com> Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, Windows, Linux, OSX). First an explanation of how the game works: The game is a simple matching game but with a twist. Instead of matching a straight 3 in a row, we have some rules that only certain combinations will result in an elimination. In general 2 of the same value in a row with with 1 of 2 other possible values will eliminate all three nodes. Eliminations can occur either horizontally or vertically but not diagonally. Each tile has a value now, that value is used when evaluating the rules. Currently there are only 5 allowed values of 0-4 although more could be added later, so any solution needs to be expandable. These are the basic rules that allow for an elimination to occur(values are put in quotes to distinguish values): 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. 2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes. 2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes. 2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes. 2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes. 2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes. 2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes. 2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes. 2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes. 2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes. The main focus of the code is the find_eliminations method. I think its implementation is smart since it uses a math trick, but then again I wrote it. My math trick works by first finding 2 matching nodes next to each other out of every 3 nodes, then adding the values of all 3 nodes together and checking for specific totals. None of the possible totals overlap. Here is the code: import random class GameTile(): def __init__(self, value, col, row, **kwargs): # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row self.value = value self.eliminated = False def __str__(self): #return '%d, %d' % (self.col, self.row) if len(str(self.value)) == 1: return ' ' + str(self.value) return str(self.value) class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): self.cols = cols self.rows = rows self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): self.grid.append([GameTile(value=random.choice([5, 6, 11, 19, 20]), col=col_num, row=row_num) for col_num in range(self.cols)]) def print_by_col(self): # As in going down the column assuming we started at the top. for col_num in range(self.cols): for row_list in self.grid: print(row_list[col_num]) def print_by_row(self): # As in going right across the row assuming we started at the left. for row in self.grid: for node in row: print(node) def check_bounds(self, x, y): return (0 <= x < self.rows) and (0 <= y < self.cols) def lookup_node(self, x, y): if not self.check_bounds(x, y): return False return self.grid[x][y] def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def find_eliminations(self): # I define 3 variables for holding the 3 nodes/tiles that I am # currently checking to see if an elimination possibility exists. # It uses a math trick to check for elimination by adding the values # and checking for specific totals. None of the possible totals overlap. #First Down the columns. for col_num in range(self.cols): first = None second = None third = None for row_list in self.grid: if row_list[col_num].row == 0: first = row_list[col_num] elif row_list[col_num].row == 1: second = row_list[col_num] elif row_list[col_num].row == 2: third = row_list[col_num] else: first = second second = third third = row_list[col_num] if third is not None: self.check_total_and_eliminate(first, second, third) # Now across the rows. for row in self.grid: first = None second = None third = None for node in row: if node.col == 0: first = node elif node.col == 1: second = node elif node.col == 2: third = node else: first = second second = third third = node if third is not None: self.check_total_and_eliminate(first, second, third) # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total_and_eliminate(self, first, second, third): total = None if first.value == second.value: total = first.value + second.value + third.value elif second.value == third.value: total = first.value + second.value + third.value if total == 17 or total == 21 or total == 28 or total == 29 or \ total == 31 or total == 42 or total == 45 or total == 46 \ or total == 49 or total == 58: first.eliminated = True second.eliminated = True third.eliminated = True grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() # END CODE After this part has been improved, I then need to search the columns backwards to be able to drop any floating values. Any none zero values should not have a zero value below it. That is what I mean by drop floating values. I think this will be simple by just using range method to count backwards. I will be working on coding that in the meantime. Dave sorry for not posting a new thread correctly, I did not realize the list was so smart. What is "breaing"? Google didn't have much of anything. Also the delay in reposting was due to me thinking there was an error in the code I posted. Does this post now stand-alone? From steve at pearwood.info Sat Jan 3 03:05:21 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 13:05:21 +1100 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <54A6C938.1010709@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> Message-ID: <20150103020521.GC27426@ando.pearwood.info> On Fri, Jan 02, 2015 at 11:37:12AM -0500, WolfRage wrote: > On 01/02/2015 02:21 AM, Steven D'Aprano wrote: > >Your lookup_node method returns a GameTile or False on failure: > > > > def lookup_node(self, x, y, ): > > if not self.check_bounds(x, y): > > return False > > return self.grid[y][x] > > > >I'm not sure about that design. I wonder whether it would be better to > >return None, or raise an exception. > > What would you suggest this code does on error, when the Node looked up > is out of bounds? In my opinion, the right thing to do is to raise an exception. In a bug-free program, your users should never see an exception raised. Either you avoid triggering the exception, or you catch it and recover. (If you cannot recover, there is no point in catching it.) But if a bug does exist in your program, then it is probably better to fail hard, as soon as possible, and provide good diagnostics that you (not your users!) can use to fix this problem. That is, raise an exception and print a stacktrace. That means something like this: def lookup_node(self, x, y, ): if not self.check_bounds(x, y): raise ValueError("out of bounds: %s, %s" % (x, y)) return self.grid[y][x] Then have to actually use this method, otherwise it is dead code and pointless. -- Steve From alan.gauld at btinternet.com Sat Jan 3 03:38:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 02:38:23 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A74D36.5090308@gmail.com> References: <54A74D36.5090308@gmail.com> Message-ID: On 03/01/15 02:00, WolfRage wrote: > Dave sorry for not posting a new thread correctly, I did not realize the > list was so smart. Take a look at the mail headers (More actions->View source in TBird) Specifically the References header. It links each message to all those above it in the thread. If you change the subject that doesn't change the references header which maintains the thread structure. This is not a tutor list thing but is supported by most mailing list servers. > What is "breaing"? I think he meant breaking > Does this post now stand-alone? Yes -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From davea at davea.name Sat Jan 3 03:57:55 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 21:57:55 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <54A74D36.5090308@gmail.com> Message-ID: <54A75AB3.6050804@davea.name> On 01/02/2015 09:38 PM, Alan Gauld wrote: > On 03/01/15 02:00, WolfRage wrote: > > >> What is "breaing"? > > I think he meant breaking > I'm afraid some keys currently stick, and 'k' is one of them. Every so often I lose a key. -- DaveA From davea at davea.name Sat Jan 3 04:21:11 2015 From: davea at davea.name (Dave Angel) Date: Fri, 02 Jan 2015 22:21:11 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A74D36.5090308@gmail.com> References: <54A74D36.5090308@gmail.com> Message-ID: <54A76027.3090801@davea.name> On 01/02/2015 09:00 PM, WolfRage wrote: > Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, > Windows, Linux, OSX). > > First an explanation of how the game works: The game is a simple > matching game but with a twist. Instead of matching a straight 3 in a > row, we have some rules that only certain combinations will result in an > elimination. In general 2 of the same value in a row with with 1 of 2 > other possible values will eliminate all three nodes. Eliminations can > occur either horizontally or vertically but not diagonally. Each tile > has a value now, that value is used when evaluating the rules. Currently > there are only 5 allowed values of 0-4 although more could be added > later, so any solution needs to be expandable. > These are the basic rules that allow for an elimination to occur(values > are put in quotes to distinguish values): > 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. > 2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes. > 2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes. > 2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes. > 2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes. > 2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes. > 2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes. > 2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes. > 2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes. > 2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes. > > The main focus of the code is the find_eliminations method. I think its > implementation is smart since it uses a math trick, but then again I > wrote it. > My math trick works by first finding 2 matching nodes next to each other > out of every 3 nodes, then adding the values of all 3 nodes together and > checking for specific totals. None of the possible totals overlap. > > Here is the code: > > import random > > > class GameTile(): > def __init__(self, value, col, row, **kwargs): > # id is grid (X,Y) which is equal to grid (col,row) > self.id = str(col) + ',' + str(row) > self.col = col > self.row = row > self.value = value > self.eliminated = False > > def __str__(self): > #return '%d, %d' % (self.col, self.row) > if len(str(self.value)) == 1: > return ' ' + str(self.value) > return str(self.value) > > > class GameGrid(): > def __init__(self, cols=8, rows=7, **kwargs): > self.cols = cols > self.rows = rows > self.make_grid() > > def make_grid(self): > # grid is 2d array as x, y ie [x][y]. > self.grid = [] > for row_num in range(self.rows): > self.grid.append([GameTile(value=random.choice([5, 6, 11, > 19, 20]), col=col_num, > row=row_num) for col_num in range(self.cols)]) > > def print_by_col(self): > # As in going down the column assuming we started at the top. > for col_num in range(self.cols): > for row_list in self.grid: > print(row_list[col_num]) > > def print_by_row(self): > # As in going right across the row assuming we started at the > left. > for row in self.grid: > for node in row: > print(node) > > def check_bounds(self, x, y): > return (0 <= x < self.rows) and (0 <= y < self.cols) > > def lookup_node(self, x, y): > if not self.check_bounds(x, y): > return False > return self.grid[x][y] > > def draw(self): > for col in self.grid: > print(end='| ') > for node in col: > print(node, end=' | ') > print() > > def find_eliminations(self): > # I define 3 variables for holding the 3 nodes/tiles that I am > # currently checking to see if an elimination possibility exists. > # It uses a math trick to check for elimination by adding the > values > # and checking for specific totals. None of the possible totals > overlap. > #First Down the columns. > for col_num in range(self.cols): > first = None > second = None > third = None > for row_list in self.grid: > if row_list[col_num].row == 0: > first = row_list[col_num] > elif row_list[col_num].row == 1: > second = row_list[col_num] > elif row_list[col_num].row == 2: > third = row_list[col_num] > else: > first = second > second = third > third = row_list[col_num] This code is way too complex for what it accomplishes. See below. > if third is not None: > self.check_total_and_eliminate(first, second, third) > # Now across the rows. > for row in self.grid: > first = None > second = None > third = None > for node in row: > if node.col == 0: > first = node > elif node.col == 1: > second = node > elif node.col == 2: > third = node > else: > first = second > second = third > third = node If the self.rows is 3, this is equivalent to just: first, second, third = row If the self.rows is larger, it's equivalent to: first, second, third = row[p: p+3] for some value of p > if third is not None: > self.check_total_and_eliminate(first, second, third) But even better, let the method check_total_and_eliminate take a slice as its argument. self.check-total_and_eliminate(row[p: p+3]) > # Set all eliminated nodes to a value of 0. > for col in self.grid: > for node in col: > if node.eliminated is True: > node.eliminated = False > node.value = 0 > > def check_total_and_eliminate(self, first, second, third): > total = None > if first.value == second.value: > total = first.value + second.value + third.value > elif second.value == third.value: > total = first.value + second.value + third.value > if total == 17 or total == 21 or total == 28 or total == 29 or \ > total == 31 or total == 42 or total == 45 or total == 46 \ > or total == 49 or total == 58: > first.eliminated = True > second.eliminated = True > third.eliminated = True > This doesn't come close to implementing the test you describe above. For example, a total of 29 could be your first case, 5,5,19. But it could also be 4,4,21. Or 6,6,17. Etc. I suggest instead that you compare the values against a table of interesting values. If you make your table a list of 3-tuples, it can be searched simply by: if tuple(nodes) in table: do-something So you don't need the separate variables first, second, and third at all. > > > grid = GameGrid(4, 8) > grid.draw() > grid.find_eliminations() > print('After Eliminations') > grid.draw() > > > # END CODE > > After this part has been improved, I then need to search the columns > backwards to be able to drop any floating values. Any none zero values > should not have a zero value below it. That is what I mean by drop > floating values. I think this will be simple by just using range method > to count backwards. I will be working on coding that in the meantime. > for what you've described so far, it might be convenient to store the board and its transposed equivalent. Then search the one for columns, and the other for rows. That's a later optimization, but it might save time getting the more complicated parts figured out. -- DaveA From ranceh at gmail.com Sat Jan 3 05:42:22 2015 From: ranceh at gmail.com (Rance Hall) Date: Fri, 2 Jan 2015 22:42:22 -0600 Subject: [Tutor] threading in python2.7 In-Reply-To: References: Message-ID: On Fri, Jan 2, 2015 at 3:18 PM, Alan Gauld wrote: > On 02/01/15 20:17, Rance Hall wrote: > >> I bought myself a pcduino 3 nano development board for Christmas and >> started picking up python again after a long forced hiatus. The board >> runs >> Ubuntu Precise >> > > Snap!(ish), I got an arduino Uno and RaspberryPi. > As I understand it the pcDuino is just a PC and > duino on a single board, right? > Yes, you are correct. Arduino Uno headers on the board, and a full pc on chip. For $40 (US) its was a no brainer for me. The OS is on an onboard 4GB Nand, and there is a mini sd card slot and a place to plug in a conventional sata hd. Not as many gpio controls on the board as a Pi, but with the easy addition of some arduino uno hardware that can be resolved. > > Working with development boards has me navigating the inner working of >> python threading and I find myself at a loss. >> > > You realise the 'duino processor is strictly single threaded? > Yes, I did, but it is a dual core cpu. > So you need a stateless event handler and keep the threading all within > Python. > > My current project is a simulated emergency vehicle warning system >> (otherwise known as a police siren) >> >> I started my project by writing the lighting and the sound portions of the >> program separately and tweaking them till I got each part working as >> desired. >> > > How are you writing the code? > Are you writing 'duino stuff in C and control stuff in Python? > How does the pcduino communicate between the controller and PC sections? > Do you still use the 'duino IDE? > > So far all the code is python. The good folks at LinkSprite have python modules that are board specific so I can get all the gpio controls by installing the board modules for python and doing a "import gpio" > In my set up I'd write the light/sound controller stuff and have > the event loop read signals from the Python code via the USB link. > Is it similar on the pcduino? > Mine isn't that fancy yet. I have three gpio pins one attached to a red led, and a second attached to a blue one. The third is controlling a buzzer. > > >> > > def setup_hardware(): >> do stuff here to setup hardware and gpio sytem >> >> def lights(): >> control the red and blue LEDs to simulate warning lights >> >> def sound(): >> control the sound to simulate a warning siren >> >> def cleanup(): >> exit cleanly and cleanup >> >> def main(): >> setup() >> try: >> # individually starting either lights or sound works as expected >> except: >> # catch keyboard interrupt and call cleanup >> >> >> > > Where is the event loop? > You need something to manage the events. > This is where my mistake happened. Sorry I wasn't clear here. The skeleton code I posted was from the working but not threaded starter attempt. My main looks like this def main(): setup() #thread management stuff here #start lights thread #start sound thread The idea here being that the lights and sounds can pulse on different frequencies/patterns independent of each other, but both loops running at what the user feels is "the same time. > > Each of the lights and sound functions are placed in a "while not >> exitFlag:" loop >> > > So the thread control is in two separate loops. > And each loop can set the flag? > > exitFlag variable made in the either the main loop or the cleanup loop are >> never seen by the lights and sound loop threads. > > > How many loops do you have? You have a light loop, a sound loop, a setup > lop and a cleanup loop? Sounds too many. > Got the word loop on the brain. Sorry about this. The main function and cleanup function are not loops just procedures. The loops are the light and sound loops and either the main or cleanup function should be able to set the criteria by which both the light and sound loops exit. > > The net effect of this is that once the threads are started, they are >> uncontrollable and I have to quit the terminal to get the threads to stop. >> >> Could someone please point me in the direction of a good tutorial or >> sample >> code that works that I could use as study tool? >> > > You should probably try the Ardiuino/PCduino forums > > I've not bothered posting the code since its custom to this board and will >> fail on another python instance >> > > But your skeleton is too skeletal for us to suggest anything. You don't > even show us where the threading happens, or how. You could replicate the > code structure using a pseudo API that just prints or returns values from a > list... > I'll work up an example that is not board specific and post it. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From akleider at sonic.net Sat Jan 3 07:51:17 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 02 Jan 2015 22:51:17 -0800 Subject: [Tutor] Making Doubly Linked List with Less Lines of Code. In-Reply-To: <20150102215737.GA27426@ando.pearwood.info> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20150101001844.GI24472@ando.pearwood.info> <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <9e68ac5c8572fd99a82084c0bb7569a2@sonic.net> <20150102215737.GA27426@ando.pearwood.info> Message-ID: <2817d347c3b48cc98c81cf21554dc7fa@sonic.net> On 2015-01-02 13:57, Steven D'Aprano wrote: > On Fri, Jan 02, 2015 at 09:57:29AM -0800, Alex Kleider wrote: >> On 2015-01-01 17:35, Alan Gauld wrote: >> >> >Repeats replicates the reference to the object but >> >does not create a new object. >> >> This part I can understand but, as Steven has pointed out, >> this behaviour changes if the object being repeated is immutable. >> Why would one get a new object (rather than a new reference to it) >> just because it is immutable? It's this difference in behaviour >> that depends on mutability that I still don't understand even though >> Steven did try to explain it to me: >> """ >> If the list items are immutable, like ints or strings, the difference >> doesn't matter. You can't modify immutable objects in-place, so you >> never notice any difference between copying them or not. >> """ > > No, you misunderstood what I was trying to say. Yes, Steven, I did but you've set that straight and I thank you for it. Here's what finally helped me figure it out: >>> a = [{}, 999] >>> b = a*3 >>> b [{}, 999, {}, 999, {}, 999] >>> b[2] = 'hello' >>> b [{}, 999, 'hello', 999, {}, 999] >>> b[4]["a"] = 1 >>> b [{'a': 1}, 999, 'hello', 999, {'a': 1}, 999] >>> b[4] = 1 >>> b [{'a': 1}, 999, 'hello', 999, 1, 999] Again, my compliments to this list for the admirable way it fulfils its mission! Alex > But with immutable objects, there is nothing you can do (except check > the IDs) that will reveal the difference between having one or two > distinct objects: > > a = 123 > b = 123 > > *may or may not* set a and b to distinct objects. Because when it comes > to immutable objects, it makes no difference. From steve at pearwood.info Sat Jan 3 08:45:24 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 18:45:24 +1100 Subject: [Tutor] Fwd: Newbie In-Reply-To: References: Message-ID: <20150103074523.GD27426@ando.pearwood.info> On Fri, Jan 02, 2015 at 11:51:04PM +0530, Rohan Ds wrote: > Hello everybody :) > I am Rohan from India. I'm new to Python. I have a basic understanding as > to how Python works. I want to contribute to PSF. The information available > on the site didn't really answer my questions. What sort of things do you wish to contribute? The PSF is responsible for protecting the Python so-called intellectual property, such as trademarks and copyright. The PSF also looks for sponsors, provides funds for Python user-groups, helps set up conventions, and (sometimes) manages the infrastructure. What it doesn't do is maintain Python the language. If you want to work on Python the language, you should start with the bug tracker. Look for some easy bugs, or bugs that interest you, and create a patch. Instructions for contributing patches are here: https://docs.python.org/devguide/ and the bug tracker is here: http://bugs.python.org/ > If anyone here could tell me, how I should get started with it, I'd be > really grateful to you. Also, with GSoC coming up, if i keep contributing > dedicatedly to PSF, will I have a shot at GSoC? Someone please reply asap. What's the rush? :-) I'm afraid I don't know much about the GSoC. -- Steven From steve at pearwood.info Sat Jan 3 09:00:22 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 3 Jan 2015 19:00:22 +1100 Subject: [Tutor] threading in python2.7 In-Reply-To: <005801d026cc$39c351b0$ad49f510$@gmail.com> References: <005801d026cc$39c351b0$ad49f510$@gmail.com> Message-ID: <20150103080022.GE27426@ando.pearwood.info> On Fri, Jan 02, 2015 at 12:39:36PM -0800, Joseph Lee wrote: > Threads introduce interesting issues. For instance, due to Python's global > interpreter lock (GIL), only one thread can run at a given time. I'd like to make a technical correction here. The GIL is not a *language* requirement, it is an *implementation* requirement. Consequently, there are Python implementations without a GIL, namely IronPython, Jython and possibly PyPy depending on which garbage collection system it is using. -- Steven From davea at davea.name Sat Jan 3 12:58:34 2015 From: davea at davea.name (Dave Angel) Date: Sat, 03 Jan 2015 06:58:34 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A76027.3090801@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> Message-ID: <54A7D96A.6040606@davea.name> On 01/02/2015 10:21 PM, Dave Angel wrote: > On 01/02/2015 09:00 PM, WolfRage wrote: >> Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, >> Windows, Linux, OSX). >> >> First an explanation of how the game works: The game is a simple >> matching game but with a twist. Instead of matching a straight 3 in a >> row, we have some rules that only certain combinations will result in an >> elimination. In general 2 of the same value in a row with with 1 of 2 >> other possible values will eliminate all three nodes. Eliminations can >> occur either horizontally or vertically but not diagonally. Each tile >> has a value now, that value is used when evaluating the rules. Currently >> there are only 5 allowed values of 0-4 although more could be added >> later, so any solution needs to be expandable. >> These are the basic rules that allow for an elimination to occur(values >> are put in quotes to distinguish values): >> 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. >> 2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes. >> 2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes. >> 2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes. >> 2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes. >> 2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes. >> 2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes. >> 2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes. >> 2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes. >> 2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes. >> >> The main focus of the code is the find_eliminations method. I think its >> implementation is smart since it uses a math trick, but then again I >> wrote it. >> My math trick works by first finding 2 matching nodes next to each other >> out of every 3 nodes, then adding the values of all 3 nodes together and >> checking for specific totals. None of the possible totals overlap. >> >> Here is the code: >> >> import random >> >> >> class GameTile(): >> def __init__(self, value, col, row, **kwargs): >> # id is grid (X,Y) which is equal to grid (col,row) >> self.id = str(col) + ',' + str(row) >> self.col = col >> self.row = row >> self.value = value >> self.eliminated = False >> >> def __str__(self): >> #return '%d, %d' % (self.col, self.row) >> if len(str(self.value)) == 1: >> return ' ' + str(self.value) >> return str(self.value) >> >> >> class GameGrid(): >> def __init__(self, cols=8, rows=7, **kwargs): >> self.cols = cols >> self.rows = rows >> self.make_grid() >> >> def make_grid(self): >> # grid is 2d array as x, y ie [x][y]. >> self.grid = [] >> for row_num in range(self.rows): >> self.grid.append([GameTile(value=random.choice([5, 6, 11, >> 19, 20]), col=col_num, >> row=row_num) for col_num in range(self.cols)]) >> >> def print_by_col(self): >> # As in going down the column assuming we started at the top. >> for col_num in range(self.cols): >> for row_list in self.grid: >> print(row_list[col_num]) >> >> def print_by_row(self): >> # As in going right across the row assuming we started at the >> left. >> for row in self.grid: >> for node in row: >> print(node) >> >> def check_bounds(self, x, y): >> return (0 <= x < self.rows) and (0 <= y < self.cols) >> >> def lookup_node(self, x, y): >> if not self.check_bounds(x, y): >> return False >> return self.grid[x][y] >> >> def draw(self): >> for col in self.grid: >> print(end='| ') >> for node in col: >> print(node, end=' | ') >> print() >> >> def find_eliminations(self): >> # I define 3 variables for holding the 3 nodes/tiles that I am >> # currently checking to see if an elimination possibility >> exists. >> # It uses a math trick to check for elimination by adding the >> values >> # and checking for specific totals. None of the possible totals >> overlap. >> #First Down the columns. >> for col_num in range(self.cols): >> first = None >> second = None >> third = None >> for row_list in self.grid: >> if row_list[col_num].row == 0: >> first = row_list[col_num] >> elif row_list[col_num].row == 1: >> second = row_list[col_num] >> elif row_list[col_num].row == 2: >> third = row_list[col_num] >> else: >> first = second >> second = third >> third = row_list[col_num] > > This code is way too complex for what it accomplishes. See below. > >> if third is not None: >> self.check_total_and_eliminate(first, second, third) >> # Now across the rows. >> for row in self.grid: >> first = None >> second = None >> third = None >> for node in row: >> if node.col == 0: >> first = node >> elif node.col == 1: >> second = node >> elif node.col == 2: >> third = node >> else: >> first = second >> second = third >> third = node > > If the self.rows is 3, this is equivalent to just: > first, second, third = row > If the self.rows is larger, it's equivalent to: > first, second, third = row[p: p+3] for some value of p > >> if third is not None: >> self.check_total_and_eliminate(first, second, third) > > But even better, let the method check_total_and_eliminate take a slice > as its argument. > self.check-total_and_eliminate(row[p: p+3]) > >> # Set all eliminated nodes to a value of 0. >> for col in self.grid: >> for node in col: >> if node.eliminated is True: >> node.eliminated = False >> node.value = 0 >> >> def check_total_and_eliminate(self, first, second, third): >> total = None >> if first.value == second.value: >> total = first.value + second.value + third.value >> elif second.value == third.value: >> total = first.value + second.value + third.value >> if total == 17 or total == 21 or total == 28 or total == 29 or \ >> total == 31 or total == 42 or total == 45 or total == 46 \ >> or total == 49 or total == 58: >> first.eliminated = True >> second.eliminated = True >> third.eliminated = True >> > > This doesn't come close to implementing the test you describe above. For > example, a total of 29 could be your first case, 5,5,19. But it could > also be 4,4,21. Or 6,6,17. Etc. > > I suggest instead that you compare the values against a table of > interesting values. If you make your table a list of 3-tuples, it can > be searched simply by: > if tuple(nodes) in table: > do-something My error. Since nodes are GameTile objects, not values, converting to a tuple is a little trickier: values = tuple( [node.value for node in nodes] ) if values in table: do-something > > So you don't need the separate variables first, second, and third at all. > >> >> >> grid = GameGrid(4, 8) >> grid.draw() >> grid.find_eliminations() >> print('After Eliminations') >> grid.draw() >> >> >> # END CODE >> >> After this part has been improved, I then need to search the columns >> backwards to be able to drop any floating values. Any none zero values >> should not have a zero value below it. That is what I mean by drop >> floating values. I think this will be simple by just using range method >> to count backwards. I will be working on coding that in the meantime. >> > > for what you've described so far, it might be convenient to store the > board and its transposed equivalent. Then search the one for columns, > and the other for rows. That's a later optimization, but it might save > time getting the more complicated parts figured out. > For example, print_by_col would look just like print_by_row, except that it would start with self.transposed_grid The only real assumption needed for this simplification is that once the grid is set up, you never create any more GameTile objects, just manipulate the existing rectangle of objects. To transpose a grid, you want to use the zip() function. self.transposed_grid = zip(*self.grid) -- DaveA From pramod.sp78 at gmail.com Sat Jan 3 12:48:02 2015 From: pramod.sp78 at gmail.com (pramod gowda) Date: Sat, 3 Jan 2015 17:18:02 +0530 Subject: [Tutor] Socket programming Message-ID: Hi, i am learning socket programming, client code: import socket client_socket=socket.socket() server_address='192.168.2.2' server_port= 80 print("hello") client_socket.connect((server_address,server_port)) print("hello") data=client_socket.recv(1024) print(data) client_socket.close() server code: import socket server_socket=socket.socket() server_name='192.168.2.2' server_port= 80 server_socket.bind((server_name,server_port)) server_socket.listen(1) 3.4.2 while True: print("hello") c,address=server_socket.accept() print("we got connection from:",address) c.send("hello,hw ru") c.close() I am not getting the output, i am using windows 7 OS,pyhton ver:.. please check and give me the solution. Regards, Pramod SP From alan.gauld at btinternet.com Sat Jan 3 14:20:01 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 13:20:01 +0000 Subject: [Tutor] Socket programming In-Reply-To: References: Message-ID: On 03/01/15 11:48, pramod gowda wrote: > client code: > > import socket > > client_socket=socket.socket() > server_address='192.168.2.2' > server_port= 80 see below regarding port numbers > print("hello") > client_socket.connect((server_address,server_port)) > print("hello") > data=client_socket.recv(1024) > print(data) > client_socket.close() I assume it is this code that is not doing what you expect? Try using more descriptive print statements. Also, when debugging, never use a print that could be blank, always have a fixed string so you can see it. So instead of print(data) use print('Received: ', data) That way you can see that data was empty rather than that the print didn't execute. I'd also put a print(finished') or similar after closing the socket. > server code: > import socket > > server_socket=socket.socket() > server_name='192.168.2.2' > server_port= 80 port 80 is usually reserved for http traffic, better to choose a port number greater than 1024 for user programs. > server_socket.bind((server_name,server_port)) > server_socket.listen(1) I'd up the queue size to at least 3 or 5. You are not leaving much room for errors. > while True: > print("hello") > c,address=server_socket.accept() > print("we got connection from:",address) Is this print appearing OK? > c.send("hello,hw ru") I'd add a print here too, to verify that the send worked. > c.close() > I am not getting the output, i am using windows 7 OS,pyhton ver:.. > please check and give me the solution. It's not clear what you mean by "the output". Are you getting anything printed? At the client and the server? It might help to show us a cut n paste from both client and server. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sat Jan 3 16:09:19 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 4 Jan 2015 02:09:19 +1100 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A74D36.5090308@gmail.com> References: <54A74D36.5090308@gmail.com> Message-ID: <20150103150916.GF27426@ando.pearwood.info> On Fri, Jan 02, 2015 at 09:00:22PM -0500, WolfRage wrote: > Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, > Windows, Linux, OSX). > > First an explanation of how the game works: The game is a simple > matching game but with a twist. Instead of matching a straight 3 in a > row, we have some rules that only certain combinations will result in an > elimination. In general 2 of the same value in a row with with 1 of 2 > other possible values will eliminate all three nodes. Do you mean "1 of 2" or "1 or 2"? > Eliminations can > occur either horizontally or vertically but not diagonally. Each tile > has a value now, that value is used when evaluating the rules. Currently > there are only 5 allowed values of 0-4 although more could be added > later, so any solution needs to be expandable. Okay, so the values are 0, 1, 2, 3, and 4. This doesn't match your code belong. Is the code wrong or your description? > These are the basic rules that allow for an elimination to occur(values > are put in quotes to distinguish values): > 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. [...] Since neither 5 nor 19 is a possible value, this can never apply. All the other rules you give include values greater than 4, and likewise can never apply. That means that no eliminations are ever possible. I think your description needs some work :-) > class GameTile(): [...] > def __str__(self): > #return '%d, %d' % (self.col, self.row) > if len(str(self.value)) == 1: > return ' ' + str(self.value) > return str(self.value) Eliminate comments which no longer apply. Don't use them for keeping old, obsolete or wrong code. This method can be better written like this: def __str__(self): return "%2d" % self.value > class GameGrid(): > def __init__(self, cols=8, rows=7, **kwargs): > self.cols = cols > self.rows = rows > self.make_grid() > > def make_grid(self): > # grid is 2d array as x, y ie [x][y]. > self.grid = [] > for row_num in range(self.rows): > self.grid.append([GameTile(value=random.choice([5, 6, 11, > 19, 20]), col=col_num, > row=row_num) for col_num in range(self.cols)]) That's rather gnarly code. If you're going to do that, it's probably nice to use a temporary variable to clarify your intention: for row_num in range(self.rows): row = [GameTile( value=random.choice([5, 6, 11,19, 20]), col=col_num, row=row_num) for col_num in range(self.cols) ] self.grid.append(row) Which is still pretty gnarly. You only have three arguments to GameTile, why do you need to use keyword arguments? This is neater and less noisy, although it does require you get the order right: # untested for row_num in range(self.rows): row = [GameTile(row_num, col_num, random.choice([5, 6, 11,19, 20]) for col_num in range(self.cols) ] self.grid.append(row) Even better: for row_num in range(self.rows): self.make_row(row_num) def make_row(self, row_num): values = self.allowed_values # [5, 6, 11,19, 20] row = [GameTile(row_num, col_num, random.choice(values) for col_num in range(self.cols)] self.grid.append(row) Notice that the values are stored in an attribute, for ease of maintanence in the future when you extend them. > def find_eliminations(self): > # I define 3 variables for holding the 3 nodes/tiles that I am > # currently checking to see if an elimination possibility exists. > # It uses a math trick to check for elimination by adding the values > # and checking for specific totals. None of the possible totals overlap. Sorry, I'm too tired to make sense of this function right now :-( > def check_total_and_eliminate(self, first, second, third): > total = None > if first.value == second.value: > total = first.value + second.value + third.value > elif second.value == third.value: > total = first.value + second.value + third.value > if total == 17 or total == 21 or total == 28 or total == 29 or \ > total == 31 or total == 42 or total == 45 or total == 46 \ > or total == 49 or total == 58: > first.eliminated = True > second.eliminated = True > third.eliminated = True I think this method does too much. I would prefer to see it split into two methods, one to check the total, and the other to eliminate the cells if needed: def eliminate(self, first, second, third): first.eliminated = True second.eliminated = True third.eliminated = True def check_total(self, first, second, third): if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) which you then use: if self.check_total(first, second, third): self.eliminate(first, second, third) -- Steven From wolfrage8765 at gmail.com Sat Jan 3 16:36:26 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 10:36:26 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A76027.3090801@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> Message-ID: <54A80C7A.4040108@gmail.com> On 01/02/2015 10:21 PM, Dave Angel wrote: > > This code is way too complex for what it accomplishes. See below. > Yes, that it why it needs to be optimized. It is unfortunate that my first goes at many tasks are not the most efficient. But hopefully that will get better as I learn from all of you. > > If the self.rows is 3, this is equivalent to just: > first, second, third = row > If the self.rows is larger, it's equivalent to: > first, second, third = row[p: p+3] for some value of p > >> if third is not None: >> self.check_total_and_eliminate(first, second, third) > > But even better, let the method check_total_and_eliminate take a slice > as its argument. > self.check-total_and_eliminate(row[p: p+3]) > I was able to implement this for the rows, but I was not able yet to get it to work with the column code, at least not before I went to sleep last night. Here is what I did for the method find_eliminations, now called find_eliminations2. def find_eliminations2(self): #First Down the columns. i = 0 for col_num in range(self.cols): for row_list in self.grid: try: # row_list[col_num] first, second, third = row_list[i: i + 3] print(first, second, third, sep=' | ') # The print above is not giving me the nodes down # each column as I would expect. # The above print is one of many tries. Will have # to keep trying. #self.check_total_and_eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. i = 0 for row in self.grid: for node in row: try: self.check_total_and_eliminate(row[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total_and_eliminate(self, slices): first, second, third = slices total = None if first.value == second.value: total = first.value + second.value + third.value elif second.value == third.value: total = first.value + second.value + third.value if total == 17 or total == 21 or total == 28 or total == 29 or \ total == 31 or total == 42 or total == 45 or total == 46 \ or total == 49 or total == 58: first.eliminated = True second.eliminated = True third.eliminated = True > > This doesn't come close to implementing the test you describe above. For > example, a total of 29 could be your first case, 5,5,19. But it could > also be 4,4,21. Or 6,6,17. Etc. Sorry I did not fully explain myself. The test case could not be 4,4,21 because I made a list of acceptable numbers and only acceptable numbers are allowed. Actually it is a table of letters on the top and side, the letters on the top occur once in the sequence, the letters on the side occur twice in the sequence. Each letter is representative of my earlier values. The table resolves all of the possible outcomes or totals from each sequence, allowing me to detect every possibility. |B |N |F |H |W |E |Z |X |Y *1 B|0 |5 |6 |11 |19 |20 |52 |61 |67 N|10 |15 |16 |21 |29 |30 |62 |71 |77 F|12 |17 |18 |23 |31 |32 |64 |73 |79 H|22 |27 |28 |33 |41 |42 |74 |83 |89 W|38 |43 |44 |49 |57 |58 |90 |99 |105 E|40 |45 |46 |51 |59 |60 |92 |101|107 Z|104|109|110|115|123|124|156|165|171 X|122|127|128|133|141|142|174|183|189 Y|134|139|140|145|153|154|186|195|201 *2 B=0 N=5 F=6 H=11 W=19 E=20 Z=52 X=61 Y=67 NNH=21 | NNW=29 FFN=17 | FFW=31 HHF=28 | HHE=42 WWE=58 | WWH=49 EEF=46 | EEN=45 > > I suggest instead that you compare the values against a table of > interesting values. If you make your table a list of 3-tuples, it can > be searched simply by: > if tuple(nodes) in table: > do-something I definitely want to improve the code so if there is a better way that is expandable then I would definitely like to implement it. > > So you don't need the separate variables first, second, and third at all. SNIP > > for what you've described so far, it might be convenient to store the > board and its transposed equivalent. Then search the one for columns, > and the other for rows. That's a later optimization, but it might save > time getting the more complicated parts figured out. > OK can you give me an example of how this would go. On to reading and answering the next emails. From wolfrage8765 at gmail.com Sat Jan 3 16:54:33 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 10:54:33 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A7D96A.6040606@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> Message-ID: <54A810B9.4000601@gmail.com> On 01/03/2015 06:58 AM, Dave Angel wrote: > > My error. Since nodes are GameTile objects, not values, converting to a > tuple is a little trickier: > > values = tuple( [node.value for node in nodes] ) > if values in table: > do-something > I will try an implement this after I see what values winds up yielding. > > For example, print_by_col would look just like print_by_row, except that > it would start with self.transposed_grid > > The only real assumption needed for this simplification is that once the > grid is set up, you never create any more GameTile objects, just > manipulate the existing rectangle of objects. > > To transpose a grid, you want to use the zip() function. > self.transposed_grid = zip(*self.grid) > > Thanks for the example of making the transposed_grid. I will implement this. Also your assumption is correct, once the grid is created it never gets changed as far as it's structure, only the game tiles with in are manipulated, and at that we just change there appearance and value. From wolfrage8765 at gmail.com Sat Jan 3 17:14:54 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 11:14:54 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <20150103150916.GF27426@ando.pearwood.info> References: <54A74D36.5090308@gmail.com> <20150103150916.GF27426@ando.pearwood.info> Message-ID: <54A8157E.8050001@gmail.com> On 01/03/2015 10:09 AM, Steven D'Aprano wrote: > On Fri, Jan 02, 2015 at 09:00:22PM -0500, WolfRage wrote: >> Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, >> Windows, Linux, OSX). >> >> First an explanation of how the game works: The game is a simple >> matching game but with a twist. Instead of matching a straight 3 in a >> row, we have some rules that only certain combinations will result in an >> elimination. In general 2 of the same value in a row with with 1 of 2 >> other possible values will eliminate all three nodes. > > Do you mean "1 of 2" or "1 or 2"? 1 of 2. > > >> Eliminations can >> occur either horizontally or vertically but not diagonally. Each tile >> has a value now, that value is used when evaluating the rules. Currently >> there are only 5 allowed values of 0-4 although more could be added >> later, so any solution needs to be expandable. > > Okay, so the values are 0, 1, 2, 3, and 4. This doesn't match your code > belong. Is the code wrong or your description? > My description was wrong, I am sorry I had started to simplify my code when I was first writing this, but realized that ruined my algorithm for finding matches.That is probably where I confused Dave. > >> These are the basic rules that allow for an elimination to occur(values >> are put in quotes to distinguish values): >> 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. > [...] > > Since neither 5 nor 19 is a possible value, this can never apply. Sorry again, these are actually the correct values. But my earlier mistake misleads on this section that is actually correct. > > All the other rules you give include values greater than 4, and likewise > can never apply. That means that no eliminations are ever possible. I > think your description needs some work :-) > Yes. Sorry. Let me re-do that. First an explanation of how the game works: The game is a simple matching game but with a twist. Instead of matching a straight 3 in a row, we have some rules that only certain combinations will result in an elimination. In general 2 of the same value in a row with with 1 of 2 other possible values will eliminate all three nodes. Eliminations can occur either horizontally or vertically but not diagonally. Each tile has a value now, that value is used when evaluating the rules. Currently there are only 5 allowed values of [5, 6, 11, 19, 20] although more could be added [52, 61, 67, etc] later, so any solution needs to be expandable. The remainder of the explanation was correct. Sorry about that. > >> class GameTile(): > [...] >> def __str__(self): >> #return '%d, %d' % (self.col, self.row) >> if len(str(self.value)) == 1: >> return ' ' + str(self.value) >> return str(self.value) > > Eliminate comments which no longer apply. Don't use them for keeping > old, obsolete or wrong code. > OK, good point, I should be using my bzr revision control. > This method can be better written like this: > > def __str__(self): > return "%2d" % self.value > I was switching between the 2 implementations of __str__ when I was testing some new code, but now need. I will just make it concrete and then directly request any other values. > >> class GameGrid(): >> def __init__(self, cols=8, rows=7, **kwargs): >> self.cols = cols >> self.rows = rows >> self.make_grid() >> >> def make_grid(self): >> # grid is 2d array as x, y ie [x][y]. >> self.grid = [] >> for row_num in range(self.rows): >> self.grid.append([GameTile(value=random.choice([5, 6, 11, >> 19, 20]), col=col_num, >> row=row_num) for col_num in range(self.cols)]) > > That's rather gnarly code. If you're going to do that, it's probably > nice to use a temporary variable to clarify your intention: > > for row_num in range(self.rows): > row = [GameTile( > value=random.choice([5, 6, 11,19, 20]), col=col_num, > row=row_num) for col_num in range(self.cols) > ] > self.grid.append(row) > > > Which is still pretty gnarly. You only have three arguments to GameTile, > why do you need to use keyword arguments? This is neater and less > noisy, although it does require you get the order right: > I don't need them. Just hadn't settled on the order of them. But I will eliminate the requirement for the keyword arguments. > # untested > for row_num in range(self.rows): > row = [GameTile(row_num, col_num, random.choice([5, 6, 11,19, 20]) > for col_num in range(self.cols) > ] > self.grid.append(row) > > Even better: > > for row_num in range(self.rows): > self.make_row(row_num) > > def make_row(self, row_num): > values = self.allowed_values # [5, 6, 11,19, 20] > row = [GameTile(row_num, col_num, random.choice(values) > for col_num in range(self.cols)] > self.grid.append(row) > > > Notice that the values are stored in an attribute, for ease of > maintanence in the future when you extend them. > Much better. I think I need to do better at breaking down the given tasks to their smallest chunks to best take advantage of functions. > >> def find_eliminations(self): >> # I define 3 variables for holding the 3 nodes/tiles that I am >> # currently checking to see if an elimination possibility exists. >> # It uses a math trick to check for elimination by adding the values >> # and checking for specific totals. None of the possible totals overlap. > > Sorry, I'm too tired to make sense of this function right now :-( > > >> def check_total_and_eliminate(self, first, second, third): >> total = None >> if first.value == second.value: >> total = first.value + second.value + third.value >> elif second.value == third.value: >> total = first.value + second.value + third.value >> if total == 17 or total == 21 or total == 28 or total == 29 or \ >> total == 31 or total == 42 or total == 45 or total == 46 \ >> or total == 49 or total == 58: >> first.eliminated = True >> second.eliminated = True >> third.eliminated = True > > I think this method does too much. I would prefer to see it split into > two methods, one to check the total, and the other to eliminate the > cells if needed: > > def eliminate(self, first, second, third): > first.eliminated = True > second.eliminated = True > third.eliminated = True > > def check_total(self, first, second, third): > if first.value == second.value or second.value == third.value: > total = first.value + second.value + third.value > return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) > > > which you then use: > > if self.check_total(first, second, third): > self.eliminate(first, second, third) > Yes, another example of me trying to have my functions do too much. Thanks I will break it up. Thanks again for the help, it should teach me to write better code in the future. From alan.gauld at btinternet.com Sat Jan 3 19:07:55 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 18:07:55 +0000 Subject: [Tutor] Fwd: Tutor Digest, Vol 131, Issue 14 In-Reply-To: References: Message-ID: <54A82FFB.5060709@btinternet.com> Forwarded to list for info. Please use ReplyAll in responses to the tutor list. And please do not quote the entire digest, delete any irrelevant parts. On 03/01/15 16:00, pramod gowda wrote: > Hello , > > I have chaged the code as per your input, except port number. > If i change the port number it give me error as > > Traceback (most recent call last): > File "C:\Users\Pramod\Desktop\client.py", line 7, in > client_socket.connect((server_address,server_port)) > ConnectionRefusedError: [WinError 10061] No connection could be made > because the target machine actively refused it > Interesting. I assumed you changed it at both ends? Does the server have a firewall running on it? If so you may need to open the port. > Server code: > > import socket > > server_socket=socket.socket() > server_name='192.168.2.2' > server_port= 80 > server_socket.bind((server_name,server_port)) > server_socket.listen(5) > > while True: > print("hello") > c,address=server_socket.accept() > print("acception the connection") > print("we got connection from:",address) > c.send("hello,hw ru") > c.close() > > Client Code: > > import socket > > client_socket=socket.socket() > server_address='192.168.2.2' > server_port= 80 > print("port number entered") > client_socket.connect((server_address,server_port)) > print("it is connected") > data=client_socket.recv(1024) > print("received:",data) > client_socket.close() > print('finished') > > port number entered > it is connected > received: *b''* > finished > Looks like you are receiving a bytestring in Python 3 (which is what I'd expect) so you may need to decode() it to get a text string > In the above output expected data is 'hello,hw ru' from the server and > print("acception the connection") > print("we got connection from:",address) > > the above print statements are not executed. > Really? You don't see the server output? That suggests your client is not connecting. Can you connect via telnet? I just tried your server code and get a typeError exception. You need to send a bytestring like so: c.send(b"Hello, hw ru") You can then test your server using telnet with telnet -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From wolfrage8765 at gmail.com Sat Jan 3 19:15:01 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 13:15:01 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A7D96A.6040606@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> Message-ID: <54A831A5.1030002@gmail.com> On 01/03/2015 06:58 AM, Dave Angel wrote: > self.transposed_grid = zip(*self.grid) zip() sounds confusing. But I am going to try this and see what it gives me. But Somehow I think it will require me to understand yield, which I still do not totally get how to use. Also from the documentation, will this work on my 2d List given that the lengths of the lists may not be the same? IE: 4 columns and 8 Rows. From alan.gauld at btinternet.com Sat Jan 3 19:20:26 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 18:20:26 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A8157E.8050001@gmail.com> References: <54A74D36.5090308@gmail.com> <20150103150916.GF27426@ando.pearwood.info> <54A8157E.8050001@gmail.com> Message-ID: On 03/01/15 16:14, WolfRage wrote: >>> def check_total_and_eliminate(self, first, second, third): Steven said: >> I think this method does too much. I would prefer to see it split into >> two methods, one to check the total, and the other to eliminate the >> cells if needed: > Yes, another example of me trying to have my functions do too much. > Thanks I will break it up. There is a strong hint in the function name. Any time you call a function xxxxANDyyyy() it probably should be two functions xxxx() and yyyy() :-) It's similar with classes, any time you write a class called XXXManager you should check that you are not just writing methods that should be in XXX itself. Good name choices serve many purposes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From pramod.sp78 at gmail.com Sat Jan 3 16:58:50 2015 From: pramod.sp78 at gmail.com (pramod gowda) Date: Sat, 3 Jan 2015 21:28:50 +0530 Subject: [Tutor] Tutor Digest, Vol 131, Issue 14 In-Reply-To: References: Message-ID: Hello , I have chaged the code as per your input, except port number. If i change the port number it give me error as Traceback (most recent call last): File "C:\Users\Pramod\Desktop\client.py", line 7, in client_socket.connect((server_address,server_port)) ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it Server code: import socket server_socket=socket.socket() server_name='192.168.2.2' server_port= 80 server_socket.bind((server_name,server_port)) server_socket.listen(5) while True: print("hello") c,address=server_socket.accept() print("acception the connection") print("we got connection from:",address) c.send("hello,hw ru") c.close() Client Code: import socket client_socket=socket.socket() server_address='192.168.2.2' server_port= 80 print("port number entered") client_socket.connect((server_address,server_port)) print("it is connected") data=client_socket.recv(1024) print("received:",data) client_socket.close() print('finished') Output : port number entered it is connected received: *b''* finished In the above output expected data is 'hello,hw ru' from the server and print("acception the connection") print("we got connection from:",address) the above print statements are not executed. Thanks and Regards, Pramod SP Regards, Pramod SP On Sat, Jan 3, 2015 at 8:39 PM, wrote: > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Re: Improving My Simple Game Code for Speed, Memory and > Learning (Dave Angel) > 2. Socket programming (pramod gowda) > 3. Re: Socket programming (Alan Gauld) > 4. Re: Improving My Simple Game Code for Speed, Memory and > Learning (Steven D'Aprano) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 03 Jan 2015 06:58:34 -0500 > From: Dave Angel > To: tutor at python.org > Subject: Re: [Tutor] Improving My Simple Game Code for Speed, Memory > and Learning > Message-ID: <54A7D96A.6040606 at davea.name> > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 01/02/2015 10:21 PM, Dave Angel wrote: > > On 01/02/2015 09:00 PM, WolfRage wrote: > >> Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, > >> Windows, Linux, OSX). > >> > >> First an explanation of how the game works: The game is a simple > >> matching game but with a twist. Instead of matching a straight 3 in a > >> row, we have some rules that only certain combinations will result in an > >> elimination. In general 2 of the same value in a row with with 1 of 2 > >> other possible values will eliminate all three nodes. Eliminations can > >> occur either horizontally or vertically but not diagonally. Each tile > >> has a value now, that value is used when evaluating the rules. Currently > >> there are only 5 allowed values of 0-4 although more could be added > >> later, so any solution needs to be expandable. > >> These are the basic rules that allow for an elimination to occur(values > >> are put in quotes to distinguish values): > >> 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. > >> 2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes. > >> 2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes. > >> 2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes. > >> 2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes. > >> 2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes. > >> 2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes. > >> 2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes. > >> 2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes. > >> 2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes. > >> > >> The main focus of the code is the find_eliminations method. I think its > >> implementation is smart since it uses a math trick, but then again I > >> wrote it. > >> My math trick works by first finding 2 matching nodes next to each other > >> out of every 3 nodes, then adding the values of all 3 nodes together and > >> checking for specific totals. None of the possible totals overlap. > >> > >> Here is the code: > >> > >> import random > >> > >> > >> class GameTile(): > >> def __init__(self, value, col, row, **kwargs): > >> # id is grid (X,Y) which is equal to grid (col,row) > >> self.id = str(col) + ',' + str(row) > >> self.col = col > >> self.row = row > >> self.value = value > >> self.eliminated = False > >> > >> def __str__(self): > >> #return '%d, %d' % (self.col, self.row) > >> if len(str(self.value)) == 1: > >> return ' ' + str(self.value) > >> return str(self.value) > >> > >> > >> class GameGrid(): > >> def __init__(self, cols=8, rows=7, **kwargs): > >> self.cols = cols > >> self.rows = rows > >> self.make_grid() > >> > >> def make_grid(self): > >> # grid is 2d array as x, y ie [x][y]. > >> self.grid = [] > >> for row_num in range(self.rows): > >> self.grid.append([GameTile(value=random.choice([5, 6, 11, > >> 19, 20]), col=col_num, > >> row=row_num) for col_num in range(self.cols)]) > >> > >> def print_by_col(self): > >> # As in going down the column assuming we started at the top. > >> for col_num in range(self.cols): > >> for row_list in self.grid: > >> print(row_list[col_num]) > >> > >> def print_by_row(self): > >> # As in going right across the row assuming we started at the > >> left. > >> for row in self.grid: > >> for node in row: > >> print(node) > >> > >> def check_bounds(self, x, y): > >> return (0 <= x < self.rows) and (0 <= y < self.cols) > >> > >> def lookup_node(self, x, y): > >> if not self.check_bounds(x, y): > >> return False > >> return self.grid[x][y] > >> > >> def draw(self): > >> for col in self.grid: > >> print(end='| ') > >> for node in col: > >> print(node, end=' | ') > >> print() > >> > >> def find_eliminations(self): > >> # I define 3 variables for holding the 3 nodes/tiles that I am > >> # currently checking to see if an elimination possibility > >> exists. > >> # It uses a math trick to check for elimination by adding the > >> values > >> # and checking for specific totals. None of the possible totals > >> overlap. > >> #First Down the columns. > >> for col_num in range(self.cols): > >> first = None > >> second = None > >> third = None > >> for row_list in self.grid: > >> if row_list[col_num].row == 0: > >> first = row_list[col_num] > >> elif row_list[col_num].row == 1: > >> second = row_list[col_num] > >> elif row_list[col_num].row == 2: > >> third = row_list[col_num] > >> else: > >> first = second > >> second = third > >> third = row_list[col_num] > > > > This code is way too complex for what it accomplishes. See below. > > > >> if third is not None: > >> self.check_total_and_eliminate(first, second, > third) > >> # Now across the rows. > >> for row in self.grid: > >> first = None > >> second = None > >> third = None > >> for node in row: > >> if node.col == 0: > >> first = node > >> elif node.col == 1: > >> second = node > >> elif node.col == 2: > >> third = node > >> else: > >> first = second > >> second = third > >> third = node > > > > If the self.rows is 3, this is equivalent to just: > > first, second, third = row > > If the self.rows is larger, it's equivalent to: > > first, second, third = row[p: p+3] for some value of p > > > >> if third is not None: > >> self.check_total_and_eliminate(first, second, > third) > > > > But even better, let the method check_total_and_eliminate take a slice > > as its argument. > > self.check-total_and_eliminate(row[p: p+3]) > > > >> # Set all eliminated nodes to a value of 0. > >> for col in self.grid: > >> for node in col: > >> if node.eliminated is True: > >> node.eliminated = False > >> node.value = 0 > >> > >> def check_total_and_eliminate(self, first, second, third): > >> total = None > >> if first.value == second.value: > >> total = first.value + second.value + third.value > >> elif second.value == third.value: > >> total = first.value + second.value + third.value > >> if total == 17 or total == 21 or total == 28 or total == 29 or > \ > >> total == 31 or total == 42 or total == 45 or total == 46 \ > >> or total == 49 or total == 58: > >> first.eliminated = True > >> second.eliminated = True > >> third.eliminated = True > >> > > > > This doesn't come close to implementing the test you describe above. For > > example, a total of 29 could be your first case, 5,5,19. But it could > > also be 4,4,21. Or 6,6,17. Etc. > > > > I suggest instead that you compare the values against a table of > > interesting values. If you make your table a list of 3-tuples, it can > > be searched simply by: > > if tuple(nodes) in table: > > do-something > > My error. Since nodes are GameTile objects, not values, converting to a > tuple is a little trickier: > > values = tuple( [node.value for node in nodes] ) > if values in table: > do-something > > > > > So you don't need the separate variables first, second, and third at all. > > > >> > >> > >> grid = GameGrid(4, 8) > >> grid.draw() > >> grid.find_eliminations() > >> print('After Eliminations') > >> grid.draw() > >> > >> > >> # END CODE > >> > >> After this part has been improved, I then need to search the columns > >> backwards to be able to drop any floating values. Any none zero values > >> should not have a zero value below it. That is what I mean by drop > >> floating values. I think this will be simple by just using range method > >> to count backwards. I will be working on coding that in the meantime. > >> > > > > for what you've described so far, it might be convenient to store the > > board and its transposed equivalent. Then search the one for columns, > > and the other for rows. That's a later optimization, but it might save > > time getting the more complicated parts figured out. > > > > For example, print_by_col would look just like print_by_row, except that > it would start with self.transposed_grid > > The only real assumption needed for this simplification is that once the > grid is set up, you never create any more GameTile objects, just > manipulate the existing rectangle of objects. > > To transpose a grid, you want to use the zip() function. > self.transposed_grid = zip(*self.grid) > > > -- > DaveA > > > ------------------------------ > > Message: 2 > Date: Sat, 3 Jan 2015 17:18:02 +0530 > From: pramod gowda > To: tutor at python.org > Subject: [Tutor] Socket programming > Message-ID: > kGJG51V3ywjw at mail.gmail.com> > Content-Type: text/plain; charset=UTF-8 > > Hi, > > i am learning socket programming, > > client code: > > import socket > > client_socket=socket.socket() > server_address='192.168.2.2' > server_port= 80 > print("hello") > client_socket.connect((server_address,server_port)) > print("hello") > data=client_socket.recv(1024) > print(data) > client_socket.close() > > server code: > import socket > > server_socket=socket.socket() > server_name='192.168.2.2' > server_port= 80 > server_socket.bind((server_name,server_port)) > server_socket.listen(1) 3.4.2 > > while True: > print("hello") > c,address=server_socket.accept() > print("we got connection from:",address) > c.send("hello,hw ru") > c.close() > > > > > I am not getting the output, i am using windows 7 OS,pyhton ver:.. > please check and give me the solution. > Regards, > > Pramod SP > > > ------------------------------ > > Message: 3 > Date: Sat, 03 Jan 2015 13:20:01 +0000 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] Socket programming > Message-ID: > Content-Type: text/plain; charset=windows-1252; format=flowed > > On 03/01/15 11:48, pramod gowda wrote: > > > client code: > > > > import socket > > > > client_socket=socket.socket() > > server_address='192.168.2.2' > > server_port= 80 > > see below regarding port numbers > > > print("hello") > > client_socket.connect((server_address,server_port)) > > print("hello") > > data=client_socket.recv(1024) > > print(data) > > client_socket.close() > > > I assume it is this code that is not doing what you expect? > Try using more descriptive print statements. > Also, when debugging, never use a print that could be blank, > always have a fixed string so you can see it. So instead of > > print(data) > > use > > print('Received: ', data) > > That way you can see that data was empty rather than that > the print didn't execute. > > I'd also put a print(finished') or similar after closing > the socket. > > > server code: > > import socket > > > > server_socket=socket.socket() > > server_name='192.168.2.2' > > server_port= 80 > > port 80 is usually reserved for http traffic, better > to choose a port number greater than 1024 for user > programs. > > > server_socket.bind((server_name,server_port)) > > server_socket.listen(1) > > I'd up the queue size to at least 3 or 5. > You are not leaving much room for errors. > > > while True: > > print("hello") > > c,address=server_socket.accept() > > print("we got connection from:",address) > > Is this print appearing OK? > > > c.send("hello,hw ru") > > I'd add a print here too, to verify that the send worked. > > > c.close() > > > I am not getting the output, i am using windows 7 OS,pyhton ver:.. > > please check and give me the solution. > > It's not clear what you mean by "the output". > Are you getting anything printed? At the client and the server? > > It might help to show us a cut n paste from both client > and server. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > > ------------------------------ > > Message: 4 > Date: Sun, 4 Jan 2015 02:09:19 +1100 > From: Steven D'Aprano > To: tutor at python.org > Subject: Re: [Tutor] Improving My Simple Game Code for Speed, Memory > and Learning > Message-ID: <20150103150916.GF27426 at ando.pearwood.info> > Content-Type: text/plain; charset=us-ascii > > On Fri, Jan 02, 2015 at 09:00:22PM -0500, WolfRage wrote: > > Python3.4+ Linux Mint 17.1 but the code will be cross platform (Mobile, > > Windows, Linux, OSX). > > > > First an explanation of how the game works: The game is a simple > > matching game but with a twist. Instead of matching a straight 3 in a > > row, we have some rules that only certain combinations will result in an > > elimination. In general 2 of the same value in a row with with 1 of 2 > > other possible values will eliminate all three nodes. > > Do you mean "1 of 2" or "1 or 2"? > > > > Eliminations can > > occur either horizontally or vertically but not diagonally. Each tile > > has a value now, that value is used when evaluating the rules. Currently > > there are only 5 allowed values of 0-4 although more could be added > > later, so any solution needs to be expandable. > > Okay, so the values are 0, 1, 2, 3, and 4. This doesn't match your code > belong. Is the code wrong or your description? > > > > These are the basic rules that allow for an elimination to occur(values > > are put in quotes to distinguish values): > > 2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes. > [...] > > Since neither 5 nor 19 is a possible value, this can never apply. > > All the other rules you give include values greater than 4, and likewise > can never apply. That means that no eliminations are ever possible. I > think your description needs some work :-) > > > > class GameTile(): > [...] > > def __str__(self): > > #return '%d, %d' % (self.col, self.row) > > if len(str(self.value)) == 1: > > return ' ' + str(self.value) > > return str(self.value) > > Eliminate comments which no longer apply. Don't use them for keeping > old, obsolete or wrong code. > > This method can be better written like this: > > def __str__(self): > return "%2d" % self.value > > > > class GameGrid(): > > def __init__(self, cols=8, rows=7, **kwargs): > > self.cols = cols > > self.rows = rows > > self.make_grid() > > > > def make_grid(self): > > # grid is 2d array as x, y ie [x][y]. > > self.grid = [] > > for row_num in range(self.rows): > > self.grid.append([GameTile(value=random.choice([5, 6, 11, > > 19, 20]), col=col_num, > > row=row_num) for col_num in range(self.cols)]) > > That's rather gnarly code. If you're going to do that, it's probably > nice to use a temporary variable to clarify your intention: > > for row_num in range(self.rows): > row = [GameTile( > value=random.choice([5, 6, 11,19, 20]), col=col_num, > row=row_num) for col_num in range(self.cols) > ] > self.grid.append(row) > > > Which is still pretty gnarly. You only have three arguments to GameTile, > why do you need to use keyword arguments? This is neater and less > noisy, although it does require you get the order right: > > # untested > for row_num in range(self.rows): > row = [GameTile(row_num, col_num, random.choice([5, 6, 11,19, > 20]) > for col_num in range(self.cols) > ] > self.grid.append(row) > > Even better: > > for row_num in range(self.rows): > self.make_row(row_num) > > def make_row(self, row_num): > values = self.allowed_values # [5, 6, 11,19, 20] > row = [GameTile(row_num, col_num, random.choice(values) > for col_num in range(self.cols)] > self.grid.append(row) > > > Notice that the values are stored in an attribute, for ease of > maintanence in the future when you extend them. > > > > def find_eliminations(self): > > # I define 3 variables for holding the 3 nodes/tiles that I am > > # currently checking to see if an elimination possibility exists. > > # It uses a math trick to check for elimination by adding the > values > > # and checking for specific totals. None of the possible totals > overlap. > > Sorry, I'm too tired to make sense of this function right now :-( > > > > def check_total_and_eliminate(self, first, second, third): > > total = None > > if first.value == second.value: > > total = first.value + second.value + third.value > > elif second.value == third.value: > > total = first.value + second.value + third.value > > if total == 17 or total == 21 or total == 28 or total == 29 or \ > > total == 31 or total == 42 or total == 45 or total == 46 \ > > or total == 49 or total == 58: > > first.eliminated = True > > second.eliminated = True > > third.eliminated = True > > I think this method does too much. I would prefer to see it split into > two methods, one to check the total, and the other to eliminate the > cells if needed: > > def eliminate(self, first, second, third): > first.eliminated = True > second.eliminated = True > third.eliminated = True > > def check_total(self, first, second, third): > if first.value == second.value or second.value == third.value: > total = first.value + second.value + third.value > return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) > > > which you then use: > > if self.check_total(first, second, third): > self.eliminate(first, second, third) > > > > > -- > Steven > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 131, Issue 14 > ************************************** > From tchannel at cableone.net Sat Jan 3 18:06:10 2015 From: tchannel at cableone.net (Ted) Date: Sat, 3 Jan 2015 10:06:10 -0700 Subject: [Tutor] Seismometer alarm Python Message-ID: Hi Folks, I have a small python code to write. It has at least three parts, 1,2 and 3. I think I have 1 and 3 working. I do not know how this Tutor at python.org works, but if someone can email me I can explain my questions. I do not wish to get into too much detail, on this first email. Basically, I am receiving a list of numbers (int)? on a serial port in python. I want to add a trigger, which will play an alarm file on the computer when these numbers reach a certain condition. Actually two conditions, or two IF?s? First IF..........if the number/average, go up or down by (x percent)..........Second IF, if the number/average stays above or below this average for (x number of seconds) If both conditions are met a .wav file plays on that computer. Thanks, Ted From alan.gauld at btinternet.com Sat Jan 3 19:46:57 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 18:46:57 +0000 Subject: [Tutor] Seismometer alarm Python In-Reply-To: References: Message-ID: On 03/01/15 17:06, Ted wrote: > Hi Folks, I have a small python code to write. It has at least three parts, 1,2 and 3. > I think I have 1 and 3 working. > > I do not know how this Tutor at python.org works, You post questions, the rest of us try to answer them. Please supply Python version, OS and the full text of any errors. Also, if the code is short(<100lines?), include it in your post. If it's longer put it on a pastebin - but be aware you may get fewer responses to long listings. Better to create a shorter example and post that. Please post in plain text not HTML since Python relies on indentation and HTML strips the spacing out making it impossible to read. And please don't top-post since it annoys some members... and also because it makes it harder to follow discussions. We cover anything to do with the Python language and its standard library, and we can usually take a stab at SciPy/NumPy and the standard web frameworks (Flask, Django etc) although there are dedicated fora for discussing these. > Basically, I am receiving a list of numbers (int)? on a serial port in python. > I want to add a trigger, which will play an alarm file on the computer > when these numbers reach a certain condition. OK, that's a good overview. Now, which part of it are you struggling with? - Reading the data from the serial port or - Using the data to trigger the alarm? or - Playing the alarm file? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Jan 3 19:48:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 18:48:07 +0000 Subject: [Tutor] Fwd: Tutor Digest, Vol 131, Issue 14 In-Reply-To: <54A82FFB.5060709@btinternet.com> References: <54A82FFB.5060709@btinternet.com> Message-ID: On 03/01/15 18:07, Alan Gauld wrote: > Forwarded to list for info. > > Please use ReplyAll in responses to the tutor list. Apologies, you did. It was stuck in the moderation queue. I've now taken you off moderation. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Jan 3 22:07:16 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 21:07:16 +0000 Subject: [Tutor] Seismometer alarm Python In-Reply-To: <79DC10AD2AAB45D1B07153704731C515@TedHP> References: <79DC10AD2AAB45D1B07153704731C515@TedHP> Message-ID: <54A85A04.3050002@btinternet.com> On 03/01/15 19:19, Ted wrote: > Alan Thank you so much for the reply, attached is a screenshot of a > 4.9M earthquake in Challis Idaho, about 150 miles north. > this is what I need the alarm for. > > I am using Python 2.7? and Windows 7. > > 1. Should I reply-all, or ok to you? or either? ReplyAll please, that way you get responses from everyone not just me. And that's a very good thing, trust me! :-) 3. The data is coming from a serial port from an arduino........and I think this is a "string" Yes, in Python2 it will be, in Python 3 it will be a bytestring but you can ignore that for now! :-) > I think I need to see it as an (int)? But I don't know how. > As you can see here is where I placed that. > myData = int (arduinoSerialData.readline()) Thats exactly correct. int() converts the string to a number. > I want to add an IF as you can see below, and this seems to work, > but I am not sure I am seeing (int), because the numbers don't seem right. Tell us what you see and what you expect. > The good news, is I do see the data in python, either a string or int??? > The good news, is I can play the sound file as it is below. Great, we'll look at it in more detail. > import serial #Import Serial Library > import time # Slows the print > import winsound > arduinoSerialData = serial.Serial('com7', 9600) #Create Serial port > object called arduinoSerialData # Don't change this. > myData = (arduinoSerialData.readline()) > > What happens if you print myData here? > > while (1==1): use while True: instead of the equality test. > myData = int (arduinoSerialData.readline()) > if myData >33500: > print(arduinoSerialData.readline()) Note this is printing the next thing from Arduino but not storing it anywhere. You are throwing it away... > time.sleep(1) #Slows to 1000ms > soundfile = "c:\Windows\Media\Alarms\Alarm.wav"#Song/Track > to play(MUST be wav) Windows paths can be troublesome due to the \ characters which Python treats as special, you should prefix them with r to tell Python to ignore the \ soundfile = r"c:\Windows\Media\Alarms\Alarm.wav" Alternatively use Unix style / instead: soundfile = "c:/Windows/Media/Alarms/Alarm.wav" -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From wolfrage8765 at gmail.com Sat Jan 3 22:22:19 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 16:22:19 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A7D96A.6040606@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> Message-ID: <54A85D8B.5040307@gmail.com> On 01/03/2015 06:58 AM, Dave Angel wrote: > To transpose a grid, you want to use the zip() function. > self.transposed_grid = zip(*self.grid) I see this gives me a list that is the column. Thus it solves the column iteration problem, because now I can feed it to my checking and elimination functions that take a slice. Thanks! Implementing now. From davea at davea.name Sat Jan 3 22:42:46 2015 From: davea at davea.name (Dave Angel) Date: Sat, 03 Jan 2015 16:42:46 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A85D8B.5040307@gmail.com> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> Message-ID: <54A86256.1070604@davea.name> On 01/03/2015 04:22 PM, WolfRage wrote: > On 01/03/2015 06:58 AM, Dave Angel wrote: >> To transpose a grid, you want to use the zip() function. >> self.transposed_grid = zip(*self.grid) > I see this gives me a list that is the column. Thus it solves the column > iteration problem, because now I can feed it to my checking and > elimination functions that take a slice. > Thanks! > Implementing now. I suspect you want instead: self.transposed_grid = list( zip(*self.grid) ) in Python 3.4. zip gives an iterable for python 3.x, while it gave a list in python 2.x This is what I meant by "untested." -- DaveA From wolfrage8765 at gmail.com Sat Jan 3 23:24:07 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 17:24:07 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A86256.1070604@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> Message-ID: <54A86C07.5020509@gmail.com> On 01/03/2015 04:42 PM, Dave Angel wrote: > On 01/03/2015 04:22 PM, WolfRage wrote: >> On 01/03/2015 06:58 AM, Dave Angel wrote: >>> To transpose a grid, you want to use the zip() function. >>> self.transposed_grid = zip(*self.grid) >> I see this gives me a list that is the column. Thus it solves the column >> iteration problem, because now I can feed it to my checking and >> elimination functions that take a slice. >> Thanks! >> Implementing now. > > I suspect you want instead: > > self.transposed_grid = list( zip(*self.grid) ) > > in Python 3.4. zip gives an iterable for python 3.x, while it gave a > list in python 2.x > > This is what I meant by "untested." > OK, I will try that implementation next. But I think this currently works well. Here is the latest iteration of my code. import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(row_num, col_num, self.values) for col_num in range(self.cols)] self.grid.append(row) self.transposed_grid = zip(*self.grid) def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.transposed_grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes(self): pass # Now we can used the transposed_grid! grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() From wolfrage8765 at gmail.com Sun Jan 4 00:10:31 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 18:10:31 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A86256.1070604@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> Message-ID: <54A876E7.4030509@gmail.com> On 01/03/2015 04:42 PM, Dave Angel wrote: > self.transposed_grid = list( zip(*self.grid) ) This results in the same thing with or with out the list() wrapper. Using Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux From steve at pearwood.info Sun Jan 4 00:46:00 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 4 Jan 2015 10:46:00 +1100 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A876E7.4030509@gmail.com> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> <54A876E7.4030509@gmail.com> Message-ID: <20150103234559.GH27426@ando.pearwood.info> On Sat, Jan 03, 2015 at 06:10:31PM -0500, WolfRage wrote: > On 01/03/2015 04:42 PM, Dave Angel wrote: > >self.transposed_grid = list( zip(*self.grid) ) > This results in the same thing with or with out the list() wrapper. Using > Python 3.4.0 (default, Apr 11 2014, 13:05:11) > [GCC 4.8.2] on linux I don't think so. Perhaps you need to look a little more closely? py> grid = [(1,2), (3,4), (5,6)] py> zip(*grid) py> list(zip(*grid)) [(1, 3, 5), (2, 4, 6)] Zip objects are not lists, although they can often (but not always) be used where you are expecting a list. -- Steve From alan.gauld at btinternet.com Sun Jan 4 00:52:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 03 Jan 2015 23:52:29 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A876E7.4030509@gmail.com> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> <54A876E7.4030509@gmail.com> Message-ID: On 03/01/15 23:10, WolfRage wrote: > On 01/03/2015 04:42 PM, Dave Angel wrote: >> self.transposed_grid = list( zip(*self.grid) ) > This results in the same thing with or with out the list() wrapper. Are you sure? Try inserting print(self.transposed_grid) immediately after the assignment and see if you get the same output with and without list(). It may be that for practical purposes in your code it makes no difference, but there should be a difference in return value. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From wolfrage8765 at gmail.com Sun Jan 4 02:00:35 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sat, 03 Jan 2015 20:00:35 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <20150103234559.GH27426@ando.pearwood.info> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> <54A876E7.4030509@gmail.com> <20150103234559.GH27426@ando.pearwood.info> Message-ID: <54A890B3.4020908@gmail.com> On 01/03/2015 06:46 PM, Steven D'Aprano wrote: > On Sat, Jan 03, 2015 at 06:10:31PM -0500, WolfRage wrote: >> On 01/03/2015 04:42 PM, Dave Angel wrote: >>> self.transposed_grid = list( zip(*self.grid) ) > >> This results in the same thing with or with out the list() wrapper. Using >> Python 3.4.0 (default, Apr 11 2014, 13:05:11) >> [GCC 4.8.2] on linux > > I don't think so. Perhaps you need to look a little more closely? > > py> grid = [(1,2), (3,4), (5,6)] > py> zip(*grid) > > py> list(zip(*grid)) > [(1, 3, 5), (2, 4, 6)] > > Zip objects are not lists, although they can often (but not always) be > used where you are expecting a list. > > Yes, you are correct. I was to naive, the result of both work the same in my code. But they are of different types. From davea at davea.name Sun Jan 4 03:57:20 2015 From: davea at davea.name (Dave Angel) Date: Sat, 03 Jan 2015 21:57:20 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A876E7.4030509@gmail.com> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> <54A876E7.4030509@gmail.com> Message-ID: <54A8AC10.6000904@davea.name> On 01/03/2015 06:10 PM, WolfRage wrote: > On 01/03/2015 04:42 PM, Dave Angel wrote: >> self.transposed_grid = list( zip(*self.grid) ) > This results in the same thing with or with out the list() wrapper. Using > Python 3.4.0 (default, Apr 11 2014, 13:05:11) > [GCC 4.8.2] on linux In Python 3, zip() returns an iterator. So you can traverse it once. I don't believe the second time is guaranteed to be the same. A list is what you want. -- DaveA From steve at pearwood.info Sun Jan 4 11:07:35 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 4 Jan 2015 21:07:35 +1100 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A8AC10.6000904@davea.name> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A85D8B.5040307@gmail.com> <54A86256.1070604@davea.name> <54A876E7.4030509@gmail.com> <54A8AC10.6000904@davea.name> Message-ID: <20150104100735.GI27426@ando.pearwood.info> On Sat, Jan 03, 2015 at 09:57:20PM -0500, Dave Angel wrote: > On 01/03/2015 06:10 PM, WolfRage wrote: > >On 01/03/2015 04:42 PM, Dave Angel wrote: > >>self.transposed_grid = list( zip(*self.grid) ) > >This results in the same thing with or with out the list() wrapper. Using > >Python 3.4.0 (default, Apr 11 2014, 13:05:11) > >[GCC 4.8.2] on linux > > In Python 3, zip() returns an iterator. So you can traverse it once. I > don't believe the second time is guaranteed to be the same. A list is > what you want. You cannot traverse iterators twice. Once they are exhausted, they stay exhausted. Technically you can write an iterator that can be re-used, but according to the iterator specification that is officially called "broken". Specifically in the case of zip, if its arguments are sequences such as lists or tuples, then you can call zip(a, b) twice and the resulting iterator will always be in the same order. But if the arguments are sets or dicts, then Dave is correct, the language does not guarantee that the zip iterator will have the same order each time. But that's not because of zip(), that's because the order of sets and dicts is not guaranteed to be the same each time. That is, given a set some_set, if you make two lists from it: a = list(some_set) b = list(some_set) # The same set. the language doesn't guarantee that a == b, as the order *could* be different each time. But in practice, I don't know any Python implementation *yet* where they actually are different, although I expect that there will be in the future. The reason is that there are some Denial Of Service attacks against Python related to being able to predict the order of dictionaries. Python 3.3 changes the order from one interpreter session to the next, but that's not actually enough to prevent the DOS attack, so I expect that future versions may eventually fully randomize the output: Python 2.7 has an arbitrary, but predictable, output, which is the same from one run to the next: [steve at ando ~]$ python2.7 -c "print set(['ape', 'bat', 'cat', 'dog', 'fox'])" set(['bat', 'cat', 'fox', 'dog', 'ape']) [steve at ando ~]$ python2.7 -c "print set(['ape', 'bat', 'cat', 'dog', 'fox'])" set(['bat', 'cat', 'fox', 'dog', 'ape']) Python 3.3 changes the order from one run to the next: [steve at ando ~]$ python3.3 -c "print({'ape', 'bat', 'cat', 'dog', 'fox'})" {'cat', 'fox', 'dog', 'bat', 'ape'} [steve at ando ~]$ python3.3 -c "print({'ape', 'bat', 'cat', 'dog', 'fox'})" {'cat', 'ape', 'bat', 'fox', 'dog'} -- Steve From tchannel at cableone.net Sun Jan 4 14:17:43 2015 From: tchannel at cableone.net (Ted) Date: Sun, 4 Jan 2015 06:17:43 -0700 Subject: [Tutor] Seismometer alarm Message-ID: On 03/01/15 19:19, Ted wrote: > Alan Thank you so much for the reply, attached is a screenshot of a > 4.9M earthquake in Challis Idaho, about 150 miles north. > this is what I need the alarm for. > > I am using Python 2.7? and Windows 7. > > 1. Should I reply-all, or ok to you? or either? ReplyAll please, that way you get responses from everyone not just me. And that's a very good thing, trust me! :-) 3. The data is coming from a serial port from an arduino........and I think this is a "string" Yes, in Python2 it will be, in Python 3 it will be a bytestring but you can ignore that for now! :-) > I think I need to see it as an (int)? But I don't know how. > As you can see here is where I placed that. > myData = int (arduinoSerialData.readline()) Thats exactly correct. int() converts the string to a number. Just to confirm myData = int (arduinoSerialData.readline()) is this line written right. ()) > I want to add an IF as you can see below, and this seems to work, > but I am not sure I am seeing (int), because the numbers don't seem right. Tell us what you see and what you expect. I now think, this is is correct, so I will go to the next step. > The good news, is I do see the data in python, either a string or int??? > The good news, is I can play the sound file as it is below. Great, we'll look at it in more detail. > import serial #Import Serial Library > import time # Slows the print > import winsound > arduinoSerialData = serial.Serial('com7', 9600) #Create Serial port > object called arduinoSerialData # Don't change this. > myData = (arduinoSerialData.readline()) > > What happens if you print myData here? > > while (1==1): use while True: instead of the equality test. I understand. > myData = int (arduinoSerialData.readline()) > if myData >33500: > print(arduinoSerialData.readline()) Here I would like to see it printed, AS WELL AS, doing the following. Note this is printing the next thing from Arduino but not storing it anywhere. You are throwing it away... HERE IS MY MAIN GOAL, Here I do want to go to the next step..and not throw the numbers away. 1. These numbers come it very fast 18 per second? and I can?t change that. I want these number to trigger an alarm. 2. Perhaps I need to say, save these numbers for 30 seconds, and give me one average number every 30 seconds. If that average number, increases or decrease by 10% go to the next step. if not do nothing. 3. Now the average number has increased or decrease by, say 12%....next 4. If this average number stays above/below this 10% for 30 seconds, trigger the alarm. 5. Hopefully both the IF?S (10%), and (30) seconds, would be changeable, as I don?t know for sure these conditions. It may be 12%, and 40 seconds. > time.sleep(1) #Slows to 1000ms > soundfile = "c:\Windows\Media\Alarms\Alarm.wav"#Song/Track > to play(MUST be wav) Windows paths can be troublesome due to the \ characters which Python treats as special, you should prefix them with r to tell Python to ignore the \ soundfile = r"c:\Windows\Media\Alarms\Alarm.wav" Alternatively use Unix style / instead: Thank you I understand. soundfile = "c:/Windows/Media/Alarms/Alarm.wav" Please let me know if, I need to change my Q&A?s style. I really need help, I have no python knowledge, and I am very appreciative. Thanks, Ted -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From davea at davea.name Sun Jan 4 15:35:55 2015 From: davea at davea.name (Dave Angel) Date: Sun, 04 Jan 2015 09:35:55 -0500 Subject: [Tutor] Seismometer alarm In-Reply-To: References: Message-ID: <54A94FCB.7070307@davea.name> On 01/04/2015 08:17 AM, Ted wrote: > On 03/01/15 19:19, Ted wrote: >> Alan Thank you so much for the reply, attached is a screenshot of a >> 4.9M earthquake in Challis Idaho, about 150 miles north. >> this is what I need the alarm for. >> Ted, I don't know what mail program you're using, but you're not doing a reply, you're leaving a new message, which breaks the thread. Further (and probably related), you're not adding the ">" characters in front of the parts you quote, and in fact, many times you're just adding to the end of an existing line. You're also not trimming the quoted parts, to what's relevant in your reply. For example, your message ends with Alan's footer, making it look like he wrote it. As a result, it's practically impossible for most of us to follow what you're saying now, and what's already been said. A few comments. 18 strings per second is not very fast; I wouldn't worry about that, unless your device has some other strange requirements. Timing can be awkward for a beginning programmer. Can you just count to N messages, like 18*30 or so? putting a readline() function inside a print function call is one way to be sure you can't process that number in some other way. Save it in a variable, and then (conditionally) print that variable. I'd also suggest you always label your prints, so you can tell in what part of your code that particular print was called. -- DaveA From alan.gauld at btinternet.com Sun Jan 4 16:55:53 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 04 Jan 2015 15:55:53 +0000 Subject: [Tutor] Seismometer alarm In-Reply-To: References: Message-ID: On 04/01/15 13:17, Ted wrote: > On 03/01/15 19:19, Ted wrote: >> Alan Thank you so much for the reply, No probs, but a few comments further to Dave A's reply. Some folks pay by the byte so please don;t attach large files such as screenshots. Post a link to a web site if you really need to show us an image Also many/most folks on the list are using plain text so they can't see colours or bold etc. So you really need to 1) send your messages in plain text if at all possible 2) keep your comments on separate lines. 3) If possible turn on quoting so we can see what is new and what is the previous message. Most mail tools support these features if you look in the options. >> myData = int (arduinoSerialData.readline()) >> if myData >33500: >> print(arduinoSerialData.readline()) Here I would like to see it printed, AS WELL AS, doing the following. > > Note this is printing the next thing from Arduino but not storing it > anywhere. > You are throwing it away... HERE IS MY MAIN GOAL, Here I do want to go to the next step..and not throw the numbers away. So you need to store the value in a variable and then print the variable. > 1. These numbers come it very fast 18 per second? To a computer that's very slow. 1800 per second might be a problem. 18000 per second definitely would. > 2. Perhaps I need to say, save these numbers for 30 seconds, and give me one average number every 30 seconds. They are slow enough that you could update the average on every reading if you wish. You could also store them to a file for later analysis, in a spreadsheet, say... > If that average number, increases or decrease by 10% go to the next step. if not do nothing. OK, so you now need another variable to hold the previous average. Something like current_data = read arduino old_average = new_average new_average = calc_new_Ave(current_data) if (new_average > old_average * UPPER) or # upper = 1.12 for +12% (new_average < old_average * LOWER): # lower = 0.88 for -12% # do something How you calculate the averages depends on how you store the readings... > 4. If this average number stays above/below this 10% for 30 seconds, trigger the alarm. Now you have introduced a timer. You can create variables to hold the current time and the change time: current_time = time.now() if changed_time < current_time - TIMEDELTA # eg 30 seconds alarm() > 5. Hopefully both the IF?S (10%), and (30) seconds, would be changeable, > as I don?t know for sure these conditions. Make them variables, define them near the top of your code for easy access. Make the letters uppercase to indicate they are constants. eg TIMEDELTA = 30 # seconds VARIANCE = 0.1 # percent as a decimal UPPER = 1+VARIANCE LOWER = 1-VARIANCE >> time.sleep(1) #Slows to 1000ms You could create a delay constant too DELAY = 1 # second to produce time.sleep(DELAY) As a future enhancement you could put the constant values in a file and read that file at startup. That way even non-programmers can control the program without messing with the source code. > Please let me know if, I need to change my Q&A?s style. See comments above and from Dave -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sun Jan 4 16:55:27 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 5 Jan 2015 02:55:27 +1100 Subject: [Tutor] Seismometer alarm In-Reply-To: <54A94FCB.7070307@davea.name> References: <54A94FCB.7070307@davea.name> Message-ID: <20150104155526.GM27426@ando.pearwood.info> On Sun, Jan 04, 2015 at 09:35:55AM -0500, Dave Angel wrote: > On 01/04/2015 08:17 AM, Ted wrote: > >On 03/01/15 19:19, Ted wrote: > >>Alan Thank you so much for the reply, attached is a screenshot of a > >>4.9M earthquake in Challis Idaho, about 150 miles north. > >>this is what I need the alarm for. > >> > > Ted, I don't know what mail program you're using, but you're not doing a > reply, you're leaving a new message, which breaks the thread. Further > (and probably related), you're not adding the ">" characters in front of > the parts you quote, and in fact, many times you're just adding to the > end of an existing line. You're also not trimming the quoted parts, to > what's relevant in your reply. For example, your message ends with > Alan's footer, making it look like he wrote it. > > As a result, it's practically impossible for most of us to follow what > you're saying now, and what's already been said. Dave, if you look at the full headers, you'll see that Ted appears to be using "Windows Live Mail", whatever that is. Is that the new name for Hotmail? X-Mailer: Microsoft Windows Live Mail 16.4.3528.331 Ah, it's the new name for Outlook! Ted, I'm sorry, but I cannot work out for the life of me what parts are written by you and what parts are written by other people. There is a long, long tradition of quoting in email, where parts written by others are prefixed with one (or more) > symbols. If you click the Reply or Reply-All button, your email program should quote the text by inserting such > symbols automatically. If it doesn't do that, that's rather like a car with no windshield wipers, forcing the driver to lean out the window with a squeegee whenever it rains. Apparently Live Mail (formerly Outlook) decided to go against decades of tradition in email quoting and remove the > symbols in favour of not quoting text at all since 2011, making it *literally impossible* to work out who said what except by context. http://www.w7forums.com/threads/windows-live-mail-11-how-to-reply-with.10514/ https://social.technet.microsoft.com/Forums/windows/en-US/72137445-0f32-495a-879d-a8a5f76f1cfe/how-to-quote-inline-with-windows-live-email https://groups.google.com/forum/#!topic/microsoft.public.windows.live.mail.desktop/GDAn2f1w0Ws If this is correct, Ted, I'm afraid that you are going to have a lot of pain communicating with technical forums like this, unless you can upgrade to an older version. Given that inserting > characters by hand is too painful, I can make two suggestions: (1) Give up quoting altogether, and go back to the way people used to write correspondence before the invention of email, e.g.: In your last message, you asked me whether I had done such-and-such. I'm afraid I have not. Can you explain more about this? Although that too will become unbelievably tedious for technical discussions, especially when it comes to program code. (2) Email is a tool. You wouldn't try cutting down a tree with a one-inch pen knife, or building a house with a set of plastic children's tools. If Live Mail doesn't include such vital functionality as quoting, replace it with a tool that does the job. https://www.mozilla.org/en-US/thunderbird/ Good luck. -- Steven From steve at pearwood.info Sun Jan 4 17:41:09 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 5 Jan 2015 03:41:09 +1100 Subject: [Tutor] Seismometer alarm Python In-Reply-To: References: Message-ID: <20150104164108.GN27426@ando.pearwood.info> On Sat, Jan 03, 2015 at 10:06:10AM -0700, Ted wrote: > Hi Folks, I have a small python code to write. It has at least three > parts, 1,2 and 3. I think I have 1 and 3 working. > > I do not know how this Tutor at python.org works, but if someone can > email me I can explain my questions. You can read many years of archived emails to get a feel of how it works: https://mail.python.org/pipermail/tutor/ I don't expect anyone to read thousands of emails, but spending a couple of minutes reading a few random posts to get a bit of an understanding of how the process works is not terribly hard. Here is a good place to start: https://mail.python.org/pipermail/tutor/2014-August/102232.html After you've read the message, click "Next Message" and continue until you get bored :-) > I do not wish to get into too much detail, on this first email. Thank you, but without some detail we can't do a thing to help you. > Basically, I am receiving a list of numbers (int)? on a serial port in > python. I want to add a trigger, which will play an alarm file on the > computer when these numbers reach a certain condition. Sorry, I have no idea how to read from the serial port, but I'll assume that you have the numbers in a list called "data". > Actually two conditions, or two IF?s? First IF..........if the > number/average, go up or down by (x percent)..........Second IF, if > the number/average stays above or below this average for (x number of > seconds) This sounds like you need to calculate a running average. I'm going to guess a window-size of 5 for the running average. Let's start with a small function to calculate the average. If you are using Python 3.4, you can do this: from statistics import mean Otherwise, in older versions: from math import fsum def mean(alist): return fsum(alist)/len(alist) Now let's calculate the running averages of the data, using a window-size of five: def running_averages(data): for i in range(len(data)-4): yield mean(data[i:i+5]) Now we write a function that gets called by the trigger: def trigger(): # YOU HAVE TO WRITE THE CODE FOR THIS # PLAY THE WAV FILE Now let's inspect those running averages, and trigger if we see a jump greater than 10% that lasts for at least three samples: prev = None count = 0 for ra in running_averages(data): if prev is not None: if abs(ra - prev)/ra < 0.1: # no spike, just background activity, so reset the count count = 0 prev = ra else: # a spike of 10% is detected, increment the count but # don't update the previous average count += 1 # check if this is the third spike if count >= 3: trigger() Something like this might do the job for you. -- Steve From tchannel at cableone.net Sun Jan 4 17:10:03 2015 From: tchannel at cableone.net (Ted) Date: Sun, 4 Jan 2015 09:10:03 -0700 Subject: [Tutor] Seismometer alarm In-Reply-To: <54A94FCB.7070307@davea.name> References: <54A94FCB.7070307@davea.name> Message-ID: <18BB5AC9E7494104AC96A051A5E2021E@TedHP> Hi Dave, and All, I hope this reply is in the correct form. If not please advise. Here is what I have to date. 1. on line 7 below, myData = int (arduinoSerialData.readline()) Is this written correctly? I think the data coming from the arduino is strings, and I think I need int? Is this correct? I don't understand the .readline()) but if it is correct, that's okay. 2. on line 8 below, if myData >32500: This seem to work. The number is meaningless, I just want to try an IF statement, and if I change it the printout reflect that change, so I think it is working. 3. Here is my goal: These numbers range from a center point of about 32768, coming from the arduino, when all is quiet. If an earthquake occurs, they will go up or down. A range of about +500 and or -500. Normally they will do both, up 500, then down 500, then over a few minuets return to 32768. I don't know how, but I want this to trigger, the alarm sound file, below which seem to work okay. Maybe I need to create an average number of say 30 seconds, worth of data? If that average number, increases or decrease by 10% go to the next step. if not do nothing. Now say the average number has increased or decrease by, 12%.... Go to the next condition. If this average number stays above/below this 10% for more than 30 seconds, trigger the alarm. The reason for this second condition, is to eliminate false alarms, normal footsteps or electrical spike happen all the time, but only for a few seconds, then the numbers return to normal. An Earthquake's number will be similar, BUT the fluctuations will last longer than 30 seconds. Hopefully both the IF?S (10%), and (30) seconds, would be changeable, as I don?t know for sure these conditions. It may be 12%, and 40 seconds. This approach may not be the way to achieve this goal, so I am open to all suggestions. Thanks, Ted import serial #Import Serial Library import time # Slows the print import winsound arduinoSerialData = serial.Serial('com7', 9600) #Create Serial port object called arduinoSerialData # Don't change this. myData = (arduinoSerialData.readline()) while True: myData = int (arduinoSerialData.readline()) if myData >32500: print(arduinoSerialData.readline()) time.sleep(1) #Slows to 1000ms soundfile = "c:/Windows/Media/Alarms/Alarm.wav" #Song/Track to play(MUST be wav) winsound.PlaySound(soundfile, winsound.SND_FILENAME) -----Original Message----- From: Dave Angel Sent: Sunday, January 04, 2015 7:35 AM To: tutor at python.org Subject: Re: [Tutor] Seismometer alarm On 01/04/2015 08:17 AM, Ted wrote: > On 03/01/15 19:19, Ted wrote: >> Alan Thank you so much for the reply, attached is a screenshot of a >> 4.9M earthquake in Challis Idaho, about 150 miles north. >> this is what I need the alarm for. >> Ted, I don't know what mail program you're using, but you're not doing a reply, you're leaving a new message, which breaks the thread. Further (and probably related), you're not adding the ">" characters in front of the parts you quote, and in fact, many times you're just adding to the end of an existing line. You're also not trimming the quoted parts, to what's relevant in your reply. For example, your message ends with Alan's footer, making it look like he wrote it. As a result, it's practically impossible for most of us to follow what you're saying now, and what's already been said. A few comments. 18 strings per second is not very fast; I wouldn't worry about that, unless your device has some other strange requirements. Timing can be awkward for a beginning programmer. Can you just count to N messages, like 18*30 or so? putting a readline() function inside a print function call is one way to be sure you can't process that number in some other way. Save it in a variable, and then (conditionally) print that variable. I'd also suggest you always label your prints, so you can tell in what part of your code that particular print was called. -- DaveA _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From connor.perkis at hotmail.co.uk Sun Jan 4 17:13:50 2015 From: connor.perkis at hotmail.co.uk (Connor Perkis) Date: Sun, 4 Jan 2015 16:13:50 +0000 Subject: [Tutor] Could you look over my code? Message-ID: Hello, I am currently learning python and I have a book to assist me called ?Python Programming For The Absolute Beginner (3E)? and I?ve just read the first chapter. I typed the code. Would you be able to help me with: 1.How to execute .py files properly on Mac OSX Yosemite 2. Have a look at this code fro the book and tell me what to improve (This is a program where it says game over, and it waits for the user to press the enter key to quit: print(?Game Over?) input(?\n\nPress the enter key to exit?) From alan.gauld at btinternet.com Sun Jan 4 20:01:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 04 Jan 2015 19:01:47 +0000 Subject: [Tutor] Could you look over my code? In-Reply-To: References: Message-ID: On 04/01/15 16:13, Connor Perkis wrote: > 1.How to execute .py files properly on Mac OSX Yosemite The best way when learning is to start a Terminal session and type at the Unix shell prompt: yourprompt$ python3 myfile.py > 2. Have a look at this code fro the book and tell me what > to improve > print(?Game Over?) > input(?\n\nPress the enter key to exit?) Given how simple it is there is not much you can improve. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Mon Jan 5 03:39:57 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 5 Jan 2015 13:39:57 +1100 Subject: [Tutor] Could you look over my code? In-Reply-To: References: Message-ID: <20150105023957.GV27426@ando.pearwood.info> Hi Connor, and welcome. My response is below. On Sun, Jan 04, 2015 at 04:13:50PM +0000, Connor Perkis wrote: > Hello, I am currently learning python and I have a book to assist me > called ?Python Programming For The Absolute Beginner (3E)? and I?ve > just read the first chapter. I typed the code. Would you be able to > help me with: > > 1.How to execute .py files properly on Mac OSX Yosemite Good question! I don't have a Mac, so I'm going to have to guess. I *guess* that the simplest way is to use the command line. To do that, you need to run the Terminal application. Here is a video that claims to show you how to do that, although I have not watched it: http://www.youtube.com/watch?v=zw7Nd67_aFw Here are some more instructions: http://www.wikihow.com/Open-Applications-Using-Terminal-on-Mac Once you have the terminal open, you will be presented with a command line prompt. It may look something like: MyMacPro:~ connor$ Notice the dollar sign at the end? That tells you that you are in the system shell, not python. Now you can run Python: type the following command, and press the ENTER key at the end: python You might need to specify a version number, say: python3.4 but I don't know what version you have installed. This will get you into the Python interactive interpreter, sometimes called the REPL ("Read, Eval, Print, Loop"). You can tell you are in the Python interactive interpreter, because the prompt will change to >>> (three greater-than symbols) instead. The interactive interpreter is really useful for using Python as a calculator, or to test small pieces of code. To exit the Python interpreter when you are finished, enter: quit() and you will be returned to the system shell with its $ prompt. Do that now, because we're not going to use Python interactively. Instead, let's run your file. At the system prompt, type: python path/to/my/script.py then press ENTER. Again, you might need to include the version number: python2.7 path/to/my/script.py for example. Very important, don't write *literally* "path/to/my/script.py", that probably won't work. You need to specify the pathname to your file. How do you do that? If your file is called "game.py" (it should end with .py) and it is inside a folder called "projects", which is inside your home directory, then you would type: projects/game.py Adjust as needed depending on which folders (if any) you use and the name of the file. If you have trouble with this bit, tell us: - the version number of Python you are using - the name of the file - where it is (the name of each folder it is inside) and we ought to be able to work out what command line you need to use. I strongly recommend that you learn how to use the command line, because when it comes to programming it will be very useful. But there are other alternatives, such as IDLE, and the OS X Finder. You can read more instructions here, and a few videos (which I haven't watched): https://docs.python.org/3/using/mac.html http://www.youtube.com/watch?v=ZBo0DuK92Kc http://www.youtube.com/watch?v=BE1wDsLzOJA If you're still having trouble after reading and/or watching these, please feel free to ask for more help. > 2. Have a look at this code fro the book and tell me what to improve > (This is a program where it says game over, and it waits for the user > to press the enter key to quit: > > print(?Game Over?) > input(?\n\nPress the enter key to exit?) Are you using Python 3 or better? If so, that code is absolutely fine and will work perfectly. It is so short and sweet that there is nothing to improve. If you are using Python 2, you may find that it gives you an error, which will probably look like this: SyntaxError: unexpected EOF while parsing Don't be distressed! You've just stumbled across a small difference between Python version 2 and version 3. In Python 3, you should use "raw_input" instead of "input", so your code will look like this: print("Game Over") raw_input("\n\nPress the enter key to exit") -- Steven From robertvstepp at gmail.com Mon Jan 5 04:53:37 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 4 Jan 2015 21:53:37 -0600 Subject: [Tutor] Could you look over my code? In-Reply-To: <20150105023957.GV27426@ando.pearwood.info> References: <20150105023957.GV27426@ando.pearwood.info> Message-ID: On Sun, Jan 4, 2015 at 8:39 PM, Steven D'Aprano wrote: [...] > >> 2. Have a look at this code fro the book and tell me what to improve >> (This is a program where it says game over, and it waits for the user >> to press the enter key to quit: >> >> print(?Game Over?) >> input(?\n\nPress the enter key to exit?) > > > Are you using Python 3 or better? If so, that code is absolutely fine > and will work perfectly. It is so short and sweet that there is nothing > to improve. > > If you are using Python 2, you may find that it gives you an error, > which will probably look like this: > > SyntaxError: unexpected EOF while parsing > > > Don't be distressed! You've just stumbled across a small difference > between Python version 2 and version 3. In Python 3, you should use > "raw_input" instead of "input", so your code will look like this: In the paragraph above, I believe that Steven meant to say, "... version 3. In Python 2, you should use ...", which should be evident from his earlier comments. boB From ranceh at gmail.com Mon Jan 5 06:19:33 2015 From: ranceh at gmail.com (Rance Hall) Date: Sun, 4 Jan 2015 23:19:33 -0600 Subject: [Tutor] threading in python 2.7 - 2nd version Message-ID: Thanks to the advice from Joseph and Alan, I hacked a quick python script which demonstrates my problem more accurately. Its not board specific as was my last code. This sample works the same on my pcduino as it does on my desktop. #threading problem example import threading import sys import time threads = [] exitFlag = 0 def delay(ms): time.sleep(1.0*ms/1000) def threadloop(): while not exitFlag: print "exitFlag value: ", exitFlag delay(2000) def cleanup(): exitFlag = 1 print "Exit flag value: ", exitFlag for t in threads: t.join() sys.exit() def main(): try: my_thread = threading.Thread( target = threadloop, args = () ) my_thread.start() threads.append(my_thread) delay(20) keypress = raw_input("Press a key and hit Enter to exit\n") cleanup() except KeyboardInterrupt: cleanup() main() the thread driven loop doesn't ever see the fact that the exitFlag as changed, based on the output to screen. Be warned, this code gives you an infinite loop, so be sure to run it in a terminal you can kill without impacting other work you are doing. There are many ways to work with theads. Class definitions, etc. The thread and threading modules. I've tried several and get the same results. What do I need to do to get the thread to stop based on the value of exitFlag? From akleider at sonic.net Mon Jan 5 06:33:08 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 04 Jan 2015 21:33:08 -0800 Subject: [Tutor] =?utf-8?q?Could_you_look_over_my_code=3F?= In-Reply-To: <20150105023957.GV27426@ando.pearwood.info> References: <20150105023957.GV27426@ando.pearwood.info> Message-ID: <4a569d891d43d3a56b1f1576c964b0cf@sonic.net> On 2015-01-04 18:39, Steven D'Aprano wrote: > Hi Connor, and welcome. My response is below. It might be helpful to add to what Steven has told you: I use GNU/Linux but my wife uses Apple products and my limited experience with them is that typing python at the command line will get you python2.7. If you need python3, it won't be so simple. With Linux (at least Ubuntu 14.04) you need only type python3 instead of python. From cs at zip.com.au Mon Jan 5 07:22:39 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 5 Jan 2015 17:22:39 +1100 Subject: [Tutor] Could you look over my code? In-Reply-To: <4a569d891d43d3a56b1f1576c964b0cf@sonic.net> References: <4a569d891d43d3a56b1f1576c964b0cf@sonic.net> Message-ID: <20150105062239.GA67960@cskk.homeip.net> On 04Jan2015 21:33, Alex Kleider wrote: >On 2015-01-04 18:39, Steven D'Aprano wrote: >>Hi Connor, and welcome. My response is below. > >It might be helpful to add to what Steven has told you: >I use GNU/Linux but my wife uses Apple products and my limited >experience with them is that typing python at the command line will >get you python2.7. >If you need python3, it won't be so simple. It really isn't very hard though. >With Linux (at least Ubuntu 14.04) you need only type python3 instead >of python. With linux: provided you've installed python 3. Our ubuntu box also has python3 to hand; I forget whether I installed it specially. My Mac is the same; you will need to add python 3. There are third party systems for adding most UNIX software not already present (a Mac has a pretty decent UNIX setup anyway, being UNIX Inside:-). HomeBrew, Fink and MacPorts are popular. You can use any or all of them; they generally do not conflict. I use MacPorts. For MacPorts and probably the others you will need a C compiler, so you will need to go to the App Store and fetch XCode (it is free); that is the Mac compiler suite. You can fetch MacPorts itself here: https://www.macports.org/ Then install python 3 by issuing the command: sudo port install python34 what as I type gets you python 3.4.2. The command: port search python found the name "python34" for me towards the bottom of the listing. Cheers, Cameron Simpson Mac OS X. Because making Unix user-friendly is easier than debugging Windows. - Mike Dawson, Macintosh Systems Administrator and Consultation. mdawson at mac.com http://herowars.onestop.net From cs at zip.com.au Mon Jan 5 07:39:01 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 5 Jan 2015 17:39:01 +1100 Subject: [Tutor] threading in python 2.7 - 2nd version In-Reply-To: References: Message-ID: <20150105063901.GA89330@cskk.homeip.net> On 04Jan2015 23:19, Rance Hall wrote: >Thanks to the advice from Joseph and Alan, I hacked a quick python script >which demonstrates my problem more accurately. >Its not board specific as was my last code. This sample works the same on >my pcduino as it does on my desktop. [...] > >[...] >exitFlag = 0 Ok. >def threadloop(): > while not exitFlag: > print "exitFlag value: ", exitFlag > delay(2000) > >def cleanup(): > exitFlag = 1 > print "Exit flag value: ", exitFlag > for t in threads: > t.join() > sys.exit() These two hold your issue. threadloop() _does_ consult the global "exitFlag". But only because you never assign to it in this function. So when you consult the name "exitFlag", it looks for a local variable and does not find one, so it looks in the global scope and finds it there. cleanup() uses exitFlag as a _local_ variable (like most variables in python). This is because it assigns to it. Python will always use a local variable for something you assign to unless you tell it not to; that (by default) keeps the effects of a function within the function. Because of this, cleanup does not affect the global variable. Here, it would be best to add the line: global exitFlag at the top of _both_ functions, to be clear that you are accessing the global in both cases. So: def threadloop(): global exitFlag while not exitFlag: print "exitFlag value: ", exitFlag delay(2000) def cleanup(): global exitFlag exitFlag = 1 print "Exit flag value: ", exitFlag for t in threads: t.join() sys.exit() Cheers, Cameron Simpson Out of memory. We wish to hold the whole sky, But we never will. - Haiku Error Messages http://www.salonmagazine.com/21st/chal/1998/02/10chal2.html From joseph.lee22590 at gmail.com Mon Jan 5 06:54:34 2015 From: joseph.lee22590 at gmail.com (Joseph Lee) Date: Sun, 4 Jan 2015 21:54:34 -0800 Subject: [Tutor] threading in python 2.7 - 2nd version In-Reply-To: References: Message-ID: <009201d028ac$17a8aa80$46f9ff80$@gmail.com> Hi, My answers are below. -----Original Message----- From: Tutor [mailto:tutor-bounces+joseph.lee22590=gmail.com at python.org] On Behalf Of Rance Hall Sent: Sunday, January 4, 2015 9:20 PM To: tutor Subject: [Tutor] threading in python 2.7 - 2nd version Thanks to the advice from Joseph and Alan, I hacked a quick python script which demonstrates my problem more accurately. Its not board specific as was my last code. This sample works the same on my pcduino as it does on my desktop. #threading problem example import threading import sys import time threads = [] exitFlag = 0 def delay(ms): time.sleep(1.0*ms/1000) def threadloop(): while not exitFlag: print "exitFlag value: ", exitFlag delay(2000) def cleanup(): exitFlag = 1 print "Exit flag value: ", exitFlag for t in threads: t.join() sys.exit() JL: Hmmm, can you take a look at the above code for cleanup function? If you look at it carefully, you'll see why the program will enter infinite loop. Specifically, take a look at the following textual chart: Function : exitFlag : threads main : global.exitFlag : global.threads loop : global.exitFlag : global.threads cleanup : cleanup.exitFlag : cleanup.threads As you can see, something odd is going on in cleanup function: it has its own exit flag and threads pool. If you ever need to peek a look at a variable outside of a given function (local scope) nad mess with it, you need to add the following at the beginning of the function in question: Gglobal *globalVars # I used * in there to denote unknown number of variables. In other words, the bug had to do with scope resolution, which is very important when threads need to access or modify global variables. That is, just because you give the variable the same name as a global flag in a function doesn't mean you are reading the actual global flags, which is what the threads here were trying to do. Original: the thread driven loop doesn't ever see the fact that the exitFlag as changed, based on the output to screen. Be warned, this code gives you an infinite loop, so be sure to run it in a terminal you can kill without impacting other work you are doing. There are many ways to work with theads. Class definitions, etc. The thread and threading modules. I've tried several and get the same results. What do I need to do to get the thread to stop based on the value of exitFlag? jL: See my comment and flow chart above. _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From steve at pearwood.info Mon Jan 5 11:22:58 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 5 Jan 2015 21:22:58 +1100 Subject: [Tutor] Could you look over my code? In-Reply-To: References: <20150105023957.GV27426@ando.pearwood.info> Message-ID: <20150105102257.GY27426@ando.pearwood.info> On Sun, Jan 04, 2015 at 09:53:37PM -0600, boB Stepp wrote: > On Sun, Jan 4, 2015 at 8:39 PM, Steven D'Aprano wrote: [...] > > Don't be distressed! You've just stumbled across a small difference > > between Python version 2 and version 3. In Python 3, you should use > > "raw_input" instead of "input", so your code will look like this: > > In the paragraph above, I believe that Steven meant to say, "... > version 3. In Python 2, you should use ...", which should be evident > from his earlier comments. D'oh! I mean, well done Bob, you have passed my cunning test to see who was paying attention. :-) Yes, you are correct. Use raw_input in Python 2, and input in Python 3. -- Steven From ranceh at gmail.com Mon Jan 5 20:00:45 2015 From: ranceh at gmail.com (Rance Hall) Date: Mon, 5 Jan 2015 13:00:45 -0600 Subject: [Tutor] threading in python 2.7 - 2nd version In-Reply-To: <20150105063901.GA89330@cskk.homeip.net> References: <20150105063901.GA89330@cskk.homeip.net> Message-ID: Cameron: This was the exact issue, and I had initially suspected as much, but had no idea how to fix it. I had tried to use the global variable directive, but as it turned out I had misused it. Anyway, everything is working as it should. Thanks Rance On Mon, Jan 5, 2015 at 12:39 AM, Cameron Simpson wrote: > On 04Jan2015 23:19, Rance Hall wrote: > >> Thanks to the advice from Joseph and Alan, I hacked a quick python script >> which demonstrates my problem more accurately. >> Its not board specific as was my last code. This sample works the same on >> my pcduino as it does on my desktop. [...] >> >> [...] >> exitFlag = 0 >> > > Ok. > > def threadloop(): >> while not exitFlag: >> print "exitFlag value: ", exitFlag >> delay(2000) >> >> def cleanup(): >> exitFlag = 1 >> print "Exit flag value: ", exitFlag >> for t in threads: >> t.join() >> sys.exit() >> > > These two hold your issue. > > threadloop() _does_ consult the global "exitFlag". But only because you > never assign to it in this function. So when you consult the name > "exitFlag", it looks for a local variable and does not find one, so it > looks in the global scope and finds it there. > > cleanup() uses exitFlag as a _local_ variable (like most variables in > python). This is because it assigns to it. Python will always use a local > variable for something you assign to unless you tell it not to; that (by > default) keeps the effects of a function within the function. Because of > this, cleanup does not affect the global variable. > > Here, it would be best to add the line: > > global exitFlag > > at the top of _both_ functions, to be clear that you are accessing the > global in both cases. So: > > def threadloop(): > global exitFlag > while not exitFlag: > print "exitFlag value: ", exitFlag > delay(2000) > def cleanup(): > global exitFlag > exitFlag = 1 > print "Exit flag value: ", exitFlag > for t in threads: > t.join() > sys.exit() > > Cheers, > Cameron Simpson > > Out of memory. > We wish to hold the whole sky, > But we never will. > - Haiku Error Messages http://www.salonmagazine.com/ > 21st/chal/1998/02/10chal2.html > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From breamoreboy at yahoo.co.uk Mon Jan 5 21:08:35 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 05 Jan 2015 20:08:35 +0000 Subject: [Tutor] Fwd: Newbie In-Reply-To: References: Message-ID: On 02/01/2015 18:21, Rohan Ds wrote: > ---------- Forwarded message ---------- > From: "Rohan Ds" > Date: 2 Jan 2015 23:46 > Subject: Newbie > To: > Cc: > > Hello everybody :) > I am Rohan from India. I'm new to Python. I have a basic understanding as > to how Python works. I want to contribute to PSF. The information available > on the site didn't really answer my questions. > If anyone here could tell me, how I should get started with it, I'd be > really grateful to you. Also, with GSoC coming up, if i keep contributing > dedicatedly to PSF, will I have a shot at GSoC? Someone please reply asap. https://mail.python.org/mailman/listinfo/core-mentorship -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Mon Jan 5 22:47:03 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 05 Jan 2015 21:47:03 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A831A5.1030002@gmail.com> References: <54A74D36.5090308@gmail.com> <54A76027.3090801@davea.name> <54A7D96A.6040606@davea.name> <54A831A5.1030002@gmail.com> Message-ID: On 03/01/2015 18:15, WolfRage wrote: > On 01/03/2015 06:58 AM, Dave Angel wrote: >> self.transposed_grid = zip(*self.grid) > zip() sounds confusing. But I am going to try this and see what it gives > me. But Somehow I think it will require me to understand yield, which I > still do not totally get how to use. > Also from the documentation, will this work on my 2d List given that the > lengths of the lists may not be the same? IE: 4 columns and 8 Rows. > The best way to answer this type of question is to try it yourself at the interactive prompt, it's a must have tool for any budding Python programmer. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From dyoo at hashcollision.org Tue Jan 6 00:21:39 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 5 Jan 2015 15:21:39 -0800 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54A71D2B.8070406@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> Message-ID: Apologies; haven't had time to look at this thread carefully yet. Busy start of the new year. :P Minor comment: you can improve this snippet: if total == 17 or total == 21 or total == 28 or total == 29 or \ total == 31 or total == 42 or total == 45 or total == 46 \ or total == 49 or total == 58: by testing to see if total is an element in a sequence: if total in (17, 21, 28, ...): which you can read as: "If 'total' is a member of the tuple (17, 21, 28, ...)" This will let you avoid having to write so much to check that condition. The other comment I'd make is to start thinking about how you'd _test_ your program automatically. There's enough non-trivial logic that I'm not convinced that it actually does what you think it does. But then again, I haven't read it closely, so maybe it's trivial. Even so, tests help by acting as regression detectors: you have more freedom to start changing implementation, and the tests will catch mistakes for you. By "tests", I mean the kind of thing presented by: http://www.diveintopython3.net/unit-testing.html Good luck to you! From coolshwetu at gmail.com Mon Jan 5 18:38:16 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Mon, 5 Jan 2015 23:08:16 +0530 Subject: [Tutor] How to get value of sublist as return to verify in other file Message-ID: Hi All, I need help for list. I am having one list of list list = [[1, 2, 3, 4], [1, 5, 9, 11,5], [1, 6, 7, 2]] In this list i am getting sublist value as shown below: >>> list = [[1,2,3,4,5],[2,3,4,4,6],[3,4,5,4,6],[1,4,5,4,8]] >>> for sublist in list: ... if sublist[3] == 4: ... print sublist[3] ... 4 4 4 4 >>> I want sublist[3] value when matched first time and don't want the value for second match. And also i want to return same sublist value i.e. sublist[3] and want to get the value of sublist[3] in another file. Please provide any solution how to do this. thanks all in advance. Regards, Shweta From steve at pearwood.info Tue Jan 6 01:28:14 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 6 Jan 2015 11:28:14 +1100 Subject: [Tutor] How to get value of sublist as return to verify in other file In-Reply-To: References: Message-ID: <20150106002813.GD27426@ando.pearwood.info> On Mon, Jan 05, 2015 at 11:08:16PM +0530, shweta kaushik wrote: > Hi All, > > I need help for list. > > I am having one list of list > > list = [[1, 2, 3, 4], [1, 5, 9, 11,5], [1, 6, 7, 2]] > > In this list i am getting sublist value as shown below: > > >>> list = [[1,2,3,4,5],[2,3,4,4,6],[3,4,5,4,6],[1,4,5,4,8]] > >>> for sublist in list: > ... if sublist[3] == 4: > ... print sublist[3] > ... > 4 > 4 > 4 > 4 > >>> > > I want sublist[3] value when matched first time and don't want the value > for second match. I do not understand what you are asking. Do you mean that you only want to match once? py> list_of_lists = [[1, 2, 3, 4], [4, 5, 6, 7], [5, 2, 1, 4]] py> for sublist in list_of_lists: ... if sublist[3] == 4: ... print(sublist) ... break ... [1, 2, 3, 4] py> > And also i want to return same sublist value i.e. sublist[3] and want to > get the value of sublist[3] in another file. I am sorry, I have no idea what you are asking. Can you show some sample code and data that demonstrates what you are trying to do? -- Steve From alan.gauld at btinternet.com Tue Jan 6 01:37:21 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 06 Jan 2015 00:37:21 +0000 Subject: [Tutor] How to get value of sublist as return to verify in other file In-Reply-To: References: Message-ID: On 05/01/15 17:38, shweta kaushik wrote: >>>> list = [[1,2,3,4,5],[2,3,4,4,6],[3,4,5,4,6],[1,4,5,4,8]] >>>> for sublist in list: > ... if sublist[3] == 4: > ... print sublist[3] > ... > 4 > 4 > 4 > 4 > I want sublist[3] value when matched first time and don't want the value > for second match. You need to break out of the for loop. The command to do that is 'break' Just add a break on a line after the print statement > And also i want to return same sublist value i.e. sublist[3] and want to > get the value of sublist[3] in another file. I'm not sure I understand what you mean there. If you break out of the loop you can still access your loop variable. But I'm not sure what you mean by "get the value of sublist[3] in another file." Do you want to read another file and compare it to sublist[3]? Or do you want to put the value of sublist[3] into another file? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From coolshwetu at gmail.com Tue Jan 6 04:02:06 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Tue, 6 Jan 2015 08:32:06 +0530 Subject: [Tutor] How to get value of sublist as return to verify in other file In-Reply-To: References: Message-ID: Hii Alan, Thank you.. I want to put the value of sublist[3] into another file (test case) for verification purpose. Shweta On Jan 6, 2015 6:09 AM, "Alan Gauld" wrote: > On 05/01/15 17:38, shweta kaushik wrote: > > list = [[1,2,3,4,5],[2,3,4,4,6],[3,4,5,4,6],[1,4,5,4,8]] >>>>> for sublist in list: >>>>> >>>> ... if sublist[3] == 4: >> ... print sublist[3] >> ... >> 4 >> 4 >> 4 >> 4 >> I want sublist[3] value when matched first time and don't want the value >> for second match. >> > > You need to break out of the for loop. > The command to do that is 'break' > Just add a break on a line after the print > statement > > And also i want to return same sublist value i.e. sublist[3] and want to >> get the value of sublist[3] in another file. >> > > I'm not sure I understand what you mean there. > If you break out of the loop you can still access > your loop variable. But I'm not sure what you mean > by "get the value of sublist[3] in another file." > > Do you want to read another file and compare > it to sublist[3]? > Or do you want to put the value of sublist[3] > into another file? > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From coolshwetu at gmail.com Tue Jan 6 06:40:24 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Tue, 6 Jan 2015 11:10:24 +0530 Subject: [Tutor] How to get value of sublist as return to verify in other file In-Reply-To: References: Message-ID: Hi all, Thanks for the help. I am able to resolve the issue. I need to return all values in one file and in other file I need to reading the response as response[0] , response[1] and so on.. Shweta On Jan 6, 2015 8:32 AM, "shweta kaushik" wrote: > Hii Alan, > > Thank you.. > > I want to put the value of sublist[3] into another file (test case) for > verification purpose. > > Shweta > On Jan 6, 2015 6:09 AM, "Alan Gauld" wrote: > >> On 05/01/15 17:38, shweta kaushik wrote: >> >> list = [[1,2,3,4,5],[2,3,4,4,6],[3,4,5,4,6],[1,4,5,4,8]] >>>>>> for sublist in list: >>>>>> >>>>> ... if sublist[3] == 4: >>> ... print sublist[3] >>> ... >>> 4 >>> 4 >>> 4 >>> 4 >>> I want sublist[3] value when matched first time and don't want the value >>> for second match. >>> >> >> You need to break out of the for loop. >> The command to do that is 'break' >> Just add a break on a line after the print >> statement >> >> And also i want to return same sublist value i.e. sublist[3] and want to >>> get the value of sublist[3] in another file. >>> >> >> I'm not sure I understand what you mean there. >> If you break out of the loop you can still access >> your loop variable. But I'm not sure what you mean >> by "get the value of sublist[3] in another file." >> >> Do you want to read another file and compare >> it to sublist[3]? >> Or do you want to put the value of sublist[3] >> into another file? >> >> -- >> Alan G >> Author of the Learn to Program web site >> http://www.alan-g.me.uk/ >> http://www.amazon.com/author/alan_gauld >> Follow my photo-blog on Flickr at: >> http://www.flickr.com/photos/alangauldphotos >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > From norman at khine.net Tue Jan 6 12:43:01 2015 From: norman at khine.net (Norman Khine) Date: Tue, 6 Jan 2015 11:43:01 +0000 Subject: [Tutor] regex advice Message-ID: hello, i have the following code: import os import sys import re walk_dir = ["app", "email", "views"] #t(" ") gettext_re = re.compile(r"""[t]\((.*)\)""").findall for x in walk_dir: curr_dir = "../node-blade-boiler-template/" + x for root, dirs, files in os.walk(curr_dir, topdown=False): if ".git" in dirs: dirs.remove(".git") if "node-modules" in dirs: dirs.remove("node-modules") for filename in files: file_path = os.path.join(root, filename) print('\n- file %s (full path: %s)' % (filename, file_path)) with open(file_path, 'rb') as f: f_content = f.read() msgid = gettext_re(f_content) print msgid which traverses a directory and tries to extract all strings that are within t(" ") for example: i have a blade template file, as replace page .row .large-8.columns form( method="POST", action="/product/saveall/#{style._id}" ) input( type="hidden" name="_csrf" value=csrf_token ) h3 #{t("Generate Product for")} #{tt(style.name)} .row .large-6.columns h4=t("Available Attributes") - for(var i = 0; i < attributes.length; i++) - var attr = attributes[i] - console.log(attr) ul.attribute-block.no-bullet li b= tt(attr.name) - for(var j = 0; j < attr.values.length; j++) - var val = attr.values[j] li label input( type="checkbox" title="#{tt(attr.name)}: #{tt(val.name)}" name="#{attr.id}" value="#{val.id}") | =tt(val.name) = " [Code: " + (val.code || val._id) + "]" !=val.htmlSuffix() .large-6.columns h4 Generated Products ul#products button.button.small i.icon-save |=t("Save") =" " a.button.small.secondary( href="/product/list/#{style.id}" ) i.icon-cancel |t=("Cancel") when i run the above code, i get - file add.blade (full path: ../node-blade-boiler-template/views/product/add.blade) type="hidden" name="_csrf" value=csrf_token "Generate product for")} #{tt(style.name "Available Attributes" attr.name type="checkbox" title="#{tt(attr.name)}: #{tt(val.name)}" name="#{attr.id}" value="#{val.id}" val.name "Generated products" "Save" so, gettext_re = re.compile(r"""[t]\((.*)\)""").findall is not correct as it includes results such as input( type="hidden" name="_csrf" value=csrf_token ) what is the correct way to pull all values that are within t(" ") but exclude any tt( ) and input( ) any advice much appreciated norman -- %>>> "".join( [ {'*':'@','^':'.'}.get(c,None) or chr(97+(ord(c)-83)%26) for c in ",adym,*)&uzq^zqf" ] ) From steve at pearwood.info Tue Jan 6 13:31:04 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 6 Jan 2015 23:31:04 +1100 Subject: [Tutor] regex advice In-Reply-To: References: Message-ID: <20150106123104.GD19387@ando.pearwood.info> On Tue, Jan 06, 2015 at 11:43:01AM +0000, Norman Khine wrote: > hello, > i have the following code: > > import os > import sys > import re > > walk_dir = ["app", "email", "views"] > #t(" ") > gettext_re = re.compile(r"""[t]\((.*)\)""").findall > > for x in walk_dir: [...] The first step in effectively asking for help is to focus on the actual problem you are having. If you were going to the car mechanic to report some strange noises from the engine, you would tell him about the noises, not give him a long and tedious blow-by-blow account of where you were going when the noise started, why you were going there, who you were planning on seeing, and what clothes you were wearing that day. At least, for your mechanic's sake, I hope you are not the sort of person who does that. That reminds me, I need to give my Dad a call... And so it is with code. Your directory walker code appears to work correctly, so there is no need to dump it in our laps. It is just a distraction and an annoyance. To demonstrate the problem, you need the regex, a description of what result you want, a small sample of data where the regex fails, and a description of what you get instead. So, let's skip all the irrelevant directory-walking code and move on to the important part: > which traverses a directory and tries to extract all strings that are > within > > t(" ") > > for example: > > i have a blade template file, as > > replace page > .row > .large-8.columns > form( method="POST", action="/product/saveall/#{style._id}" ) > input( type="hidden" name="_csrf" value=csrf_token ) > h3 #{t("Generate Product for")} #{tt(style.name)} [...] I'm not certain that we need to see an entire Blade template file. Perhaps just an extract would do. Or perhaps not. For now, I will assume an extract will do, and skip ahead: > so, gettext_re = re.compile(r"""[t]\((.*)\)""").findall is not correct as > it includes > > results such as input( type="hidden" name="_csrf" value=csrf_token ) > > what is the correct way to pull all values that are within t(" ") but > exclude any tt( ) and input( ) > > any advice much appreciated My first instinct is to quote Jamie Zawinski: Some people, when confronted with a problem, think, "I know, I'll use regular expressions." Now they have two problems. If you have nested parentheses or quotes, you *cannot* in general solve this problem with regular expressions. If Blade templates allow nesting, then you are in trouble and you will need another solution, perhaps a proper parser. But for now, let's assume that no nesting is allowed. Let's look at the data format again: blah blah blah don't care input(type="hidden" ...) h3 #{t("blah blah blah")} #{tt(style.name)} So it looks like the part you care about looks like this: ...#{t("spam")}... where you want to extract the word "spam", nothing else. This suggests a regex: r'#{t\("(.*)"\)}' and then you want the group (.*) not the whole regex. Here it is in action: py> import re py> text = """blah blah blah don't care input(type="hidden" ...) ... h3 #{t("we want this")} #{tt(style.name)} ... more junk ... #{tt(abcd)} #{t("and this too")}blah blah blah...""" py> pat = re.compile(r'#{t\("(.*)"\)}') py> pat.findall(text) ['we want this', 'and this too'] So it appears to be working. Now you can try it on the full Blade file and see how it goes. If the regex still gives false matches, you can try: - using a non-greedy match instead: r'#{t\("(.*?)"\)}' - rather than matching all possible characters with .* can you limit it to only alphanumerics? r'#{t\("(\w*?)"\)}' - perhaps you need a two-part filter, first you use a regex to extract all the candidate matches, and then you eliminate some of them using some other test (not necessarily a regex). Good luck! -- Steve From __peter__ at web.de Tue Jan 6 15:17:53 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 06 Jan 2015 15:17:53 +0100 Subject: [Tutor] regex advice References: Message-ID: Norman Khine wrote: > i have a blade template file, as > > replace page > .row > .large-8.columns > form( method="POST", action="/product/saveall/#{style._id}" ) > input( type="hidden" name="_csrf" value=csrf_token ) > h3 #{t("Generate Product for")} #{tt(style.name)} > .row > .large-6.columns > h4=t("Available Attributes") > - for(var i = 0; i < attributes.length; i++) > - var attr = attributes[i] > - console.log(attr) > ul.attribute-block.no-bullet > li > b= tt(attr.name) > - for(var j = 0; j < attr.values.length; j++) > - var val = attr.values[j] > li > label > input( type="checkbox" title="#{tt(attr.name)}: > #{tt(val.name)}" name="#{attr.id}" value="#{val.id}") > | > =tt(val.name) > = " [Code: " + (val.code || val._id) + "]" > !=val.htmlSuffix() > .large-6.columns > h4 Generated Products > ul#products > button.button.small > i.icon-save > |=t("Save") > =" " > a.button.small.secondary( href="/product/list/#{style.id}" ) > i.icon-cancel > |t=("Cancel") > > when i run the above code, i get > > - file add.blade (full path: > ../node-blade-boiler-template/views/product/add.blade) > type="hidden" name="_csrf" value=csrf_token > "Generate product for")} #{tt(style.name > "Available Attributes" > attr.name > type="checkbox" title="#{tt(attr.name)}: #{tt(val.name)}" > name="#{attr.id}" > value="#{val.id}" > val.name > "Generated products" > "Save" > > > > so, gettext_re = re.compile(r"""[t]\((.*)\)""").findall is not correct as > it includes > > results such as input( type="hidden" name="_csrf" value=csrf_token ) > > what is the correct way to pull all values that are within t(" ") but > exclude any tt( ) and input( ) > > any advice much appreciated You can require a word boundary before the 't'. Quoting : """ \b Matches the empty string, but only at the beginning or end of a word. A word is defined as a sequence of Unicode alphanumeric or underscore characters, so the end of a word is indicated by whitespace or a non-alphanumeric, non- underscore Unicode character. Note that formally, \b is defined as the boundary between a \w and a \W character (or vice versa), or between \w and the beginning/end of the string. This means that r'\bfoo\b' matches 'foo', 'foo.', '(foo)', 'bar foo baz' but not 'foobar' or 'foo3'. By default Unicode alphanumerics are the ones used, but this can be changed by using the ASCII flag. Inside a character range, \b represents the backspace character, for compatibility with Python?s string literals. """ Also you are probably better off with a non-greedy match. So >>> sample = 'yadda t("foo") [t("bar")] input("baz")' >>> re.findall(r"t\((.*)\)", sample) ['"foo") [t("bar")] input("baz"'] >>> re.findall(r"t\((.*?)\)", sample) ['"foo"', '"bar"', '"baz"'] >>> re.findall(r"\bt\((.*?)\)", sample) ['"foo"', '"bar"'] From cs at zip.com.au Tue Jan 6 22:22:35 2015 From: cs at zip.com.au (Cameron Simpson) Date: Wed, 7 Jan 2015 08:22:35 +1100 Subject: [Tutor] regex advice In-Reply-To: References: Message-ID: <20150106212235.GA6327@cskk.homeip.net> On 06Jan2015 11:43, Norman Khine wrote: >i have the following code: [...] >#t(" ") >gettext_re = re.compile(r"""[t]\((.*)\)""").findall My first thought is: "[t]" can just be written "t" [...] >so, gettext_re = re.compile(r"""[t]\((.*)\)""").findall is not correct as >it includes >results such as input( type="hidden" name="_csrf" value=csrf_token ) > >what is the correct way to pull all values that are within t(" ") but >exclude any tt( ) and input( ) Others have suggested word boundaries and nongreedy matches. You don't need them. Use this: \([a-zA-Z]\w*\)(\([^)]*\)) which matches any "foo(blah)". Then look at the returned match object and check that .group(1) == "t". Cheers, Cameron Simpson I heard a funny one this weekend. I was belaying a friend on a very short problem and when she was pumped out she told me to "Let me down" and my other friend that was standing nearby said. "You were never UP!". - Bryan Laws From sanelson at gmail.com Tue Jan 6 22:46:33 2015 From: sanelson at gmail.com (Stephen Nelson-Smith) Date: Tue, 6 Jan 2015 21:46:33 +0000 Subject: [Tutor] Ideas for Child's Project Message-ID: Hello, My son is interested in programming, and has dabbled in Scratch and done a tiny bit of Python at school. He's 11 and is going for an entrance exam for a selective school in a couple of weeks. They've asked him to bring along something to demonstrate an interest, and present it to them. In talking about it, we hit upon the idea that he might like to embark upon a prorgamming challenge, or learning objective / project, spending say 30 mins a day for the next week or two, so he can show what he's done and talk about what he learned. Any suggestions for accessible yet challenging and stimulating projects? Any recommendations for books / websites / tutorials that are worth a look? S. From davidheiserca at gmail.com Tue Jan 6 23:05:04 2015 From: davidheiserca at gmail.com (David Heiser) Date: Tue, 06 Jan 2015 14:05:04 -0800 Subject: [Tutor] Ideas for Child's Project In-Reply-To: References: Message-ID: <54AC5C10.9000905@gmail.com> Twelve years ago, I started with "The Quick Python Book". Harms and McDonald. Manning Pub. I learned a lot in a hurry. I still use it for reference once in a while to refresh my memory. On 1/6/2015 1:46 PM, Stephen Nelson-Smith wrote: > Hello, > > My son is interested in programming, and has dabbled in Scratch and done a > tiny bit of Python at school. He's 11 and is going for an entrance exam > for a selective school in a couple of weeks. They've asked him to bring > along something to demonstrate an interest, and present it to them. > > In talking about it, we hit upon the idea that he might like to embark upon > a prorgamming challenge, or learning objective / project, spending say 30 > mins a day for the next week or two, so he can show what he's done and talk > about what he learned. > > Any suggestions for accessible yet challenging and stimulating projects? > > Any recommendations for books / websites / tutorials that are worth a look? > > S. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From dyoo at hashcollision.org Tue Jan 6 23:07:54 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 6 Jan 2015 14:07:54 -0800 Subject: [Tutor] Ideas for Child's Project In-Reply-To: References: Message-ID: On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith wrote: > Hello, > > My son is interested in programming, and has dabbled in Scratch and done a > tiny bit of Python at school. He's 11 and is going for an entrance exam > for a selective school in a couple of weeks. They've asked him to bring > along something to demonstrate an interest, and present it to them. > > In talking about it, we hit upon the idea that he might like to embark upon > a prorgamming challenge, or learning objective / project, spending say 30 > mins a day for the next week or two, so he can show what he's done and talk > about what he learned. > > Any suggestions for accessible yet challenging and stimulating projects? > > Any recommendations for books / websites / tutorials that are worth a look? You might want to look at Bootstrapworld, a curriculum for middle-school/high-school math using programming and games: http://www.bootstrapworld.org/ Students who go through the material learn how math can be used productively toward writing a video game. Along the way, they learn the idea of function, of considering inputs and outputs, and how to test what they've designed. As disclosure: I worked for this project for several years, and so I am not unbiased. :P Also, Bootstrapworld is not Python-specific, though you might look at the workbook materials and get some general inspiration from them. You may also consider http://code.org, which has further resources that you can explore. As I understand it, that uses a Scratch-like environment and also puts proper consideration to its middle-school/high-school audience. Good luck to you! From sanelson at gmail.com Wed Jan 7 14:33:46 2015 From: sanelson at gmail.com (Stephen Nelson-Smith) Date: Wed, 7 Jan 2015 13:33:46 +0000 Subject: [Tutor] Ideas for Child's Project In-Reply-To: References: Message-ID: Hi Danny, On Tue, Jan 6, 2015 at 10:07 PM, Danny Yoo wrote: > On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith > wrote: > > You might want to look at Bootstrapworld, a curriculum for > middle-school/high-school math using programming and games: > > http://www.bootstrapworld.org/ > > Students who go through the material learn how math can be used > productively toward writing a video game. Along the way, they learn > the idea of function, of considering inputs and outputs, and how to > test what they've designed. > Sounds ace. I had a look. It seems optimised for Racket, which is also cool.... so I installed Racket on my son's computer and let him have a play. He immediately got into it, and got the hang of functions and expressions etc. S. From ishay.yemini at gmail.com Thu Jan 8 02:14:46 2015 From: ishay.yemini at gmail.com (ishay.yemini at gmail.com) Date: Thu, 8 Jan 2015 01:14:46 +0000 Subject: [Tutor] =?utf-8?q?Error_22?= Message-ID: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> How I fix this error? when I open my python project (.py) it closes immediately. please help. /: Sent from Windows Mail From jcgallaher78 at gmail.com Wed Jan 7 14:49:44 2015 From: jcgallaher78 at gmail.com (Jim Gallaher) Date: Wed, 7 Jan 2015 07:49:44 -0600 Subject: [Tutor] Ideas for Child's Project In-Reply-To: References: Message-ID: <993CB17E-E54C-47F6-9007-2E951CBFD0B9@gmail.com> Good day Stephen, I have a few recommendations. Make Magazine has a lot of fun projects that use Python programs along with either a Raspberry Pi or an Arduino to create interactive projects. Arduino is more for electronic/programming based projects, but you can, say for example, attach an LED to a breadboard and program the LED to flash at certain intervals using a fairly simple Python script. The hands on and visual results of seeing what a program does might keep your son's interest better and longer, especially at his age. Make Magazine's website is makezine.com Raspberry Pi is very Python friendly and there's add on boards you can use along with Python. geek gurl diaries has video tutorials on programing with Python and raspberry that are focused towards the youngsters. Her website is www.geekgurldiaries.co.uk Hope that helps! Jim Gallaher >> On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith wrote: >> Hello, >> >> My son is interested in programming, and has dabbled in Scratch and done a >> tiny bit of Python at school. He's 11 and is going for an entrance exam >> for a selective school in a couple of weeks. They've asked him to bring >> along something to demonstrate an interest, and present it to them. >> >> In talking about it, we hit upon the idea that he might like to embark upon >> a prorgamming challenge, or learning objective / project, spending say 30 >> mins a day for the next week or two, so he can show what he's done and talk >> about what he learned. >> >> Any suggestions for accessible yet challenging and stimulating projects? >> >> Any recommendations for books / websites / tutorials that are worth a look? From breamoreboy at yahoo.co.uk Wed Jan 7 18:56:19 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 07 Jan 2015 17:56:19 +0000 Subject: [Tutor] Error 22 In-Reply-To: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: On 08/01/2015 01:14, ishay.yemini at gmail.com wrote: > How I fix this error? when I open my python project (.py) it closes immediately. > > please help. /: > Please provide us with your OS, Python version, the code that produced this error and the entire traceback. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Wed Jan 7 19:04:30 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 8 Jan 2015 05:04:30 +1100 Subject: [Tutor] Error 22 In-Reply-To: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: <20150107180429.GJ19387@ando.pearwood.info> On Thu, Jan 08, 2015 at 01:14:46AM +0000, ishay.yemini at gmail.com wrote: > How I fix this error? when I open my python project (.py) it closes immediately. > > please help. /: You have given us no information to work with. You might as well have said "my program doesn't work, please fix it". We don't know your program, we don't know your operating system, we don't know how you are opening your project, and we don't know where the mysterious "Error 22" in the subject line comes from. How can we possibly help you? -- Steven From alan.gauld at btinternet.com Wed Jan 7 19:06:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 07 Jan 2015 18:06:36 +0000 Subject: [Tutor] Error 22 In-Reply-To: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: On 08/01/15 01:14, ishay.yemini at gmail.com wrote: > How I fix this error? when I open my python project (.py) it closes immediately. > > please help. /: You need to tell us a lot more. What does your project code do? What does it look like? Can you send a small example that shows this error? What OS are you using? What version of Python? What development tool are you using to "open your project"? How are you running the code? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From joel.goldstick at gmail.com Wed Jan 7 19:27:15 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Wed, 7 Jan 2015 13:27:15 -0500 Subject: [Tutor] Error 22 In-Reply-To: References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: On Wed, Jan 7, 2015 at 1:06 PM, Alan Gauld wrote: > On 08/01/15 01:14, ishay.yemini at gmail.com wrote: > >> How I fix this error? when I open my python project (.py) it closes >> immediately. >> >> please help. /: >> > > > Since the op sent from Windows, I'm guessing he isn't opening up a cmd window then running his program. But I'm not a windows guy lately. Perhaps someone can tell him how to invoke the program? > You need to tell us a lot more. > > What does your project code do? What does it look like? Can you > send a small example that shows this error? > > What OS are you using? What version of Python? > What development tool are you using to "open your project"? > How are you running the code? > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com From dyoo at hashcollision.org Wed Jan 7 22:32:17 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 7 Jan 2015 13:32:17 -0800 Subject: [Tutor] Error 22 In-Reply-To: References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: >>> How I fix this error? when I open my python project (.py) it closes >>> immediately. >> >> Since the op sent from Windows, I'm guessing he isn't opening up a cmd >> window then running his program. But I'm not a windows guy lately. >> Perhaps someone can tell him how to invoke the program? I think we simply need more information. "Error 22" on Windows is, according to web searches, associated with some kind of device driver failure. (What?!) So I am very confused. Without knowing anything else about the program, I'm at a loss and my first instinct is to think that this has nothing to do with Python. I think we don't have enough information, so let's hear back from the original questioner. From tchannel at cableone.net Wed Jan 7 18:56:44 2015 From: tchannel at cableone.net (Ted) Date: Wed, 7 Jan 2015 10:56:44 -0700 Subject: [Tutor] Ideas for Child's Project In-Reply-To: <993CB17E-E54C-47F6-9007-2E951CBFD0B9@gmail.com> References: <993CB17E-E54C-47F6-9007-2E951CBFD0B9@gmail.com> Message-ID: <9A701FDAB09443B68AFBAA3F85FE1FD0@TedHP> Hello, All, I too have an idea for students. I build seismometers for schools. A simple toy slinky spring/magnets/coil/plumbing parts. For students 10 to 90. please visit if interested http://tc1seismometer.wordpress.com/tc1-a-simple-solution/ This uses an Arduino Uno and simple amplifier, and free software. Presently working with this group "tutor" to add an alarm to python code. Cheers, Ted -----Original Message----- From: Jim Gallaher Sent: Wednesday, January 07, 2015 6:49 AM To: tutor at python.org Subject: Re: [Tutor] Ideas for Child's Project Good day Stephen, I have a few recommendations. Make Magazine has a lot of fun projects that use Python programs along with either a Raspberry Pi or an Arduino to create interactive projects. Arduino is more for electronic/programming based projects, but you can, say for example, attach an LED to a breadboard and program the LED to flash at certain intervals using a fairly simple Python script. The hands on and visual results of seeing what a program does might keep your son's interest better and longer, especially at his age. Make Magazine's website is makezine.com Raspberry Pi is very Python friendly and there's add on boards you can use along with Python. geek gurl diaries has video tutorials on programing with Python and raspberry that are focused towards the youngsters. Her website is www.geekgurldiaries.co.uk Hope that helps! Jim Gallaher >> On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith >> wrote: >> Hello, >> >> My son is interested in programming, and has dabbled in Scratch and done >> a >> tiny bit of Python at school. He's 11 and is going for an entrance exam >> for a selective school in a couple of weeks. They've asked him to bring >> along something to demonstrate an interest, and present it to them. >> >> In talking about it, we hit upon the idea that he might like to embark >> upon >> a prorgamming challenge, or learning objective / project, spending say 30 >> mins a day for the next week or two, so he can show what he's done and >> talk >> about what he learned. >> >> Any suggestions for accessible yet challenging and stimulating projects? >> >> Any recommendations for books / websites / tutorials that are worth a >> look? _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From steve at pearwood.info Thu Jan 8 06:25:42 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 8 Jan 2015 16:25:42 +1100 Subject: [Tutor] Working with prime numbers Message-ID: <20150108052541.GA8077@ando.pearwood.info> Generating prime numbers is a programming problem that many beginners are interested in. For those who are, you may be interested in my PyPrimes project: At long last, I am pleased to announce the latest version of PyPrimes, a pure Python package for working with prime numbers. PyPrimes is compatible with Python 2 and 3, and includes multiple algorithms for the generating and testing of prime numbers, including the Sieve of Eratosthenes, Croft Spiral, Miller-Rabin and Fermat probabilistic tests. https://pypi.python.org/pypi/pyprimes/ Examples ======== Generate prime numbers on demand: py> it = pyprimes.primes() py> next(it) 2 py> next(it) 3 Test whether numbers are prime: py> pyprimes.is_prime(23) True Generate primes between an upper and lower limit: py> import pyprimes py> list(pyprimes.primes(11000000, 11000500)) [11000027, 11000053, 11000057, 11000081, 11000083, 11000089, 11000111, 11000113, 11000149, 11000159, 11000179, 11000189, 11000273, 11000281, 11000287, 11000291, 11000293, 11000299, 11000347, 11000351, 11000369, 11000383, 11000387, 11000393, 11000399, 11000401, 11000419, 11000441, 11000461, 11000467] Find the previous and next primes from a given value: py> pyprimes.prev_prime(10**9) 999999937 py> pyprimes.next_prime(999999937) 1000000007 Find the prime factorisation of small numbers: py> import pyprimes.factors py> pyprimes.factors.factorise(999999997) [71, 2251, 6257] Pyprimes also includes examples of naive and poor-quality, but popular, algorithms which should be avoided: py> from pyprimes.awful import turner py> it = turner() py> [next(it) for i in range(20)] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] Study the source code of the "awful" module to see what not to do! Performance =========== As PyPrimes is written entirely in Python, it is not suitable for demanding high-performance applications, but performance can be quite reasonable for less-demanding applications. On a laptop with a AMD Turion(tm) II P520 Dual-Core Processor, it takes 0.005 second to generate the first prime larger than 2**63, and about 10 seconds to generate the first one million primes. Testing whether 2**63+7 is prime takes under 0.1 millisecond. Installing PyPrimes =================== You can download PyPrimes from here: https://pypi.python.org/pypi/pyprimes/ For Windows users, run the installer. For Linux, Mac and Unix users, unpack the source tarball and follow the instructions. You can also install using pip: pip install pyprimes==0.2.1a (Note: pip may have problems downloading the right version if you don't specify a version number.) Or you can access the latest development version: hg clone https://code.google.com/p/pyprimes/ -- Steve From crusier at gmail.com Fri Jan 9 06:32:23 2015 From: crusier at gmail.com (Crusier) Date: Fri, 9 Jan 2015 13:32:23 +0800 Subject: [Tutor] File Compare Message-ID: Hi, I am comparing two files, and the program has problem comparing two files. I am currently using Python 3.3 and Window 7. Attached is my code: import difflib old_file = open('0105-up.txt','r') file_contentsA = old_file.read() A = file_contentsA.split(",") print(A) print() new_file = open('0106-up.txt','r') file_contentsB = new_file.read() B = file_contentsB.split(",") print(B) print() print('\n'.join(difflib.unified_diff(A, B))) old_file.close() new_file.close() When the result comes out, I have noticed that some of the numbers are in both files and the program fails to the difference. Please help. Thank you Henry -------------- next part -------------- 0002.HK 0004.HK 0006.HK 0008.HK 0011.HK 0012.HK 0016.HK 0038.HK 0054.HK 0066.HK 0069.HK 0107.HK 0151.HK 0177.HK 0218.HK 0220.HK 0232.HK 0291.HK 0295.HK 0303.HK 0315.HK 0316.HK 0323.HK 0327.HK 0342.HK 0347.HK 0358.HK 0371.HK 0390.HK 0402.HK 0425.HK 0439.HK 0511.HK 0525.HK 0530.HK 0535.HK 0548.HK 0566.HK 0588.HK 0590.HK 0607.HK 0631.HK 0656.HK 0669.HK 0683.HK 0686.HK 0691.HK 0697.HK 0708.HK 0709.HK 0721.HK 0753.HK 0754.HK 0777.HK 0806.HK 0817.HK 0829.HK 0845.HK 0857.HK 0861.HK 0868.HK 0884.HK 0902.HK 0911.HK 0914.HK 0915.HK 0934.HK 0939.HK 0960.HK 0966.HK 0967.HK 0991.HK 0998.HK 1041.HK 1055.HK 1072.HK 1088.HK 1108.HK 1109.HK 1133.HK 1138.HK 1157.HK 1171.HK 1186.HK 1190.HK 1199.HK 1212.HK 1238.HK 1253.HK 1288.HK 1313.HK 1323.HK 1336.HK 1339.HK 1363.HK 1375.HK 1398.HK 1421.HK 1613.HK 1618.HK 1628.HK 1699.HK 1766.HK 1778.HK 1800.HK 1819.HK 1829.HK 1880.HK 1893.HK 1919.HK 1929.HK 1963.HK 1988.HK 2005.HK 2007.HK 2009.HK 2202.HK 2208.HK 2233.HK 2318.HK 2319.HK 2328.HK 2333.HK 2338.HK 2379.HK 2380.HK 2600.HK 2601.HK 2626.HK 2628.HK 2638.HK 2689.HK 2800.HK 2811.HK 2822.HK 2823.HK 2827.HK 2828.HK 2866.HK 2868.HK 2883.HK 2888.HK 2899.HK 3049.HK 3188.HK 3323.HK 3328.HK 3333.HK 3339.HK 3360.HK 3366.HK 3377.HK 3383.HK 3618.HK 3698.HK 3777.HK 3808.HK 3823.HK 3836.HK 3898.HK 3968.HK 3983.HK 3988.HK 6030.HK 6199.HK 6818.HK 6823.HK 6881.HK 6883.HK 8007.HK 8039.HK 8088.HK 8089.HK 8201.HK 8250.HK 82822.HK 8292.HK 83188.HK 8321.HK -------------- next part -------------- 1288.HK 3383.HK 0753.HK 0347.HK 0914.HK 0995.HK 0232.HK 3988.HK 3328.HK 2009.HK 1963.HK 0588.HK 1880.HK 2868.HK 0371.HK 1190.HK 1253.HK 8321.HK 3777.HK 1848.HK 3188.HK 83188.HK 1375.HK 0939.HK 6818.HK 6881.HK 1117.HK 1041.HK 2600.HK 0606.HK 8255.HK 3983.HK 6199.HK 1800.HK 1919.HK 0257.HK 2628.HK 2883.HK 2380.HK 1186.HK 0390.HK 1109.HK 0291.HK 1088.HK 1138.HK 1055.HK 0966.HK 0728.HK 0308.HK 2202.HK 1333.HK 1313.HK 8089.HK 1929.HK 0998.HK 6030.HK 0439.HK 0002.HK 3968.HK 1829.HK 3323.HK 1778.HK 1199.HK 2007.HK 2601.HK 3618.HK 8088.HK 2866.HK 2822.HK 82822.HK 1766.HK 3898.HK 1363.HK 0991.HK 0861.HK 8007.HK 1072.HK 3333.HK 3360.HK 0038.HK 2662.HK 0778.HK 0656.HK 0817.HK 1819.HK 0468.HK 0535.HK 0530.HK 2208.HK 2333.HK 0525.HK 0566.HK 0011.HK 0911.HK 1133.HK 3836.HK 8292.HK 0012.HK 3118.HK 2638.HK 0388.HK 2626.HK 0054.HK 0754.HK 2828.HK 2811.HK 0902.HK 3698.HK 1188.HK 1398.HK 1366.HK 0177.HK 0358.HK 0683.HK 1421.HK 0582.HK 2314.HK 2331.HK 2005.HK 0915.HK 0960.HK 3339.HK 0577.HK 0590.HK 1108.HK 0323.HK 0231.HK 1618.HK 2319.HK 1988.HK 0066.HK 3918.HK 1336.HK 0777.HK 0708.HK 0342.HK 1323.HK 2689.HK 1011.HK 0316.HK 6880.HK 0327.HK 0008.HK 0402.HK 0857.HK 1339.HK 2318.HK 0006.HK 8201.HK 1699.HK 0631.HK 0363.HK 0691.HK 0218.HK 0548.HK 0016.HK 0107.HK 3377.HK 1893.HK 0386.HK 3808.HK 0315.HK 0967.HK 2840.HK 2888.HK 1613.HK 1070.HK 3823.HK 0669.HK 0511.HK 0700.HK 1065.HK 3886.HK 2800.HK 0220.HK 0686.HK 0806.HK 0303.HK 0151.HK 0607.HK 2338.HK 2233.HK 0004.HK 2236.HK 3049.HK 2823.HK 2827.HK 0868.HK 1171.HK 1057.HK 2379.HK 2899.HK 1157.HK From dyoo at hashcollision.org Fri Jan 9 06:48:11 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 8 Jan 2015 21:48:11 -0800 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: On Thu, Jan 8, 2015 at 9:32 PM, Crusier wrote: > Hi, > > I am comparing two files, and the program has problem comparing two > files. I am currently using Python 3.3 and Window 7. > > Attached is my code: > > import difflib > > old_file = open('0105-up.txt','r') > file_contentsA = old_file.read() > A = file_contentsA.split(",") > print(A) > print() > > > new_file = open('0106-up.txt','r') > file_contentsB = new_file.read() > B = file_contentsB.split(",") > print(B) > print() > > print('\n'.join(difflib.unified_diff(A, B))) > > old_file.close() > new_file.close() > > When the result comes out, I have noticed that some of the numbers are > in both files and the program fails to the difference. Please help. You need to say a few more things: what is the output that you expect to see? What is the output that you see? The reason to say this is because your problem statement is missing details in the specification. Concretely, you say that you're "comparing two files". That's way too hand-wavy to be technically useful. :P Ideally, the problem should be described well enough that if we just have the spec and the inputs, we should know what the output looks like, even without seeing your code. Your problem isn't described to that level. As a substitute, if you show what you expect to come out, we can probably triangulate. Also, if you can, reduce the size of the input files to something smaller that still shows up the problem. By reducing the problem to a small size, it makes it easier for both you and us to figure out what's going on. From dyoo at hashcollision.org Fri Jan 9 06:54:12 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 8 Jan 2015 21:54:12 -0800 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: > old_file = open('0105-up.txt','r') > file_contentsA = old_file.read() > A = file_contentsA.split(",") > print(A) > print() Ah. One other thing. Can you explain what you're intending to do with this statement? A = file_contentsA.split(',') The reason I ask is because neither of your input files that you've shown us has a single comma in it, so I do not understand what the intent is. From davea at davea.name Fri Jan 9 07:22:29 2015 From: davea at davea.name (Dave Angel) Date: Fri, 09 Jan 2015 01:22:29 -0500 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: <54AF73A5.4020607@davea.name> On 01/09/2015 12:32 AM, Crusier wrote: > Hi, > Please specify Python version for any new question. I'll assume Python 3.4 Thank you for using text message, rather than html. But realize that attachments are also a problem for many people, as this forum goes through many gateways, some of which don't support attachments. Just make the program and data self-contained in the message, by keeping the data small enough to just paste it in place. > I am comparing two files, and the program has problem comparing two > files. I am currently using Python 3.3 and Window 7. > > Attached is my code: > > import difflib > > old_file = open('0105-up.txt','r') > file_contentsA = old_file.read() > A = file_contentsA.split(",") > print(A) > print() > > > new_file = open('0106-up.txt','r') > file_contentsB = new_file.read() > B = file_contentsB.split(",") > print(B) > print() > > print('\n'.join(difflib.unified_diff(A, B))) > > old_file.close() > new_file.close() > > When the result comes out, I have noticed that some of the numbers are > in both files and the program fails to the difference. Please help. > The difflib is doing exactly what it's supposed to. You passed it two lists, each with a single element. The single element was different, so it showed you both old and new versions of that element. Your problem is that you're trying to split on commas, but there are no commas in your sample data. You probably should be splitting on whitespace, like Steven showed you on 10/13. Change split(",") to split() and you've solved one problem. Next problem is that the two files are not in the same order. difflib looks for differences in sequences of items by matching up identical ones, and reporting the breaks in the matches (roughly). If your data is scrambled between one file and the other, you'll need to sort it. Easiest way to do that is to use A.sort() B.sort() Next possible problem is that this difflib.unified_diff shows the context for each difference. You may or may not like that, and if you don't, there are various ways to fix it. But that you'll have to judge, and perhaps ask for that specifically. -- -- DaveA From crusier at gmail.com Fri Jan 9 07:24:56 2015 From: crusier at gmail.com (Crusier) Date: Fri, 9 Jan 2015 14:24:56 +0800 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: Hi Danny, Thanks for your suggestion. The ideal of output of this program is to show if there is any new number added to the new file. In other words, the file content of file1 [0001.hk, 0002.hk, 0003.hk, 0004.hk] is comparing with the file content of file2 [0001.hk, 0002.hk, 0003.hk, 0005.hk]. The result should be +0005.hk, -0004.hk Ah. One other thing. Can you explain what you're intending to do with this statement? A = file_contentsA.split(',') My thinking is I want to make both files as a list, so I can compare the two files. However, as you can see, it is only my wishful thinking. Best Henry On Fri, Jan 9, 2015 at 1:54 PM, Danny Yoo wrote: >> old_file = open('0105-up.txt','r') >> file_contentsA = old_file.read() >> A = file_contentsA.split(",") >> print(A) >> print() > > > Ah. One other thing. Can you explain what you're intending to do > with this statement? > > A = file_contentsA.split(',') > > The reason I ask is because neither of your input files that you've > shown us has a single comma in it, so I do not understand what the > intent is. From davea at davea.name Fri Jan 9 07:42:32 2015 From: davea at davea.name (Dave Angel) Date: Fri, 09 Jan 2015 01:42:32 -0500 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: <54AF7858.9000807@davea.name> On 01/09/2015 01:24 AM, Crusier wrote: > Hi Danny, > > Thanks for your suggestion. > > The ideal of output of this program is to show if there is any new > number added to the new file. > > In other words, the file content of file1 [0001.hk, 0002.hk, 0003.hk, > 0004.hk] is comparing with the file content of file2 [0001.hk, > 0002.hk, 0003.hk, 0005.hk]. > But your files don't have commas in them. Either make sure there's a comma after each item, or change the delimiter you use to split with. I suspect you'd be happier with the latter, since there are also newlines in the file, so it'd be more work to get what you want with comma delimiting. > The result should be +0005.hk, -0004.hk That's not what unified_diff is documented to do. It produces each diff item with context around it. The default number of lines of context is 3, so you might try changing that with the keyword argument n= to unified_diff. See also my earlier message showing you the first two problems with your code. -- DaveA From diliupg at gmail.com Fri Jan 9 08:40:16 2015 From: diliupg at gmail.com (diliup gabadamudalige) Date: Fri, 9 Jan 2015 13:10:16 +0530 Subject: [Tutor] Error 22 In-Reply-To: References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com> Message-ID: :) On Thu, Jan 8, 2015 at 3:02 AM, Danny Yoo wrote: > >>> How I fix this error? when I open my python project (.py) it closes > >>> immediately. > >> > >> Since the op sent from Windows, I'm guessing he isn't opening up a cmd > >> window then running his program. But I'm not a windows guy lately. > >> Perhaps someone can tell him how to invoke the program? > > I think we simply need more information. "Error 22" on Windows is, > according to web searches, associated with some kind of device driver > failure. (What?!) > > So I am very confused. Without knowing anything else about the > program, I'm at a loss and my first instinct is to think that this has > nothing to do with Python. I think we don't have enough information, > so let's hear back from the original questioner. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Diliup Gabadamudalige http://www.diliupg.com http://soft.diliupg.com/ ********************************************************************************************** This e-mail is confidential. It may also be legally privileged. If you are not the intended recipient or have received it in error, please delete it and all copies from your system and notify the sender immediately by return e-mail. Any unauthorized reading, reproducing, printing or further dissemination of this e-mail or its contents is strictly prohibited and may be unlawful. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions. ********************************************************************************************** From dyoo at hashcollision.org Fri Jan 9 11:54:45 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 9 Jan 2015 02:54:45 -0800 Subject: [Tutor] File Compare In-Reply-To: References: Message-ID: > The ideal of output of this program is to show if there is any new > number added to the new file. > > In other words, the file content of file1 [0001.hk, 0002.hk, 0003.hk, > 0004.hk] is comparing with the file content of file2 [0001.hk, > 0002.hk, 0003.hk, 0005.hk]. > > The result should be +0005.hk, -0004.hk Ok, this is helpful. Thanks. If the file content were to be scrambled a bit (say, like 0005.hk shows up first in the file), should that affect the answer you want? From __peter__ at web.de Fri Jan 9 13:55:25 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 09 Jan 2015 13:55:25 +0100 Subject: [Tutor] File Compare References: Message-ID: Crusier wrote: > Hi Danny, > > Thanks for your suggestion. > > The ideal of output of this program is to show if there is any new > number added to the new file. > > In other words, the file content of file1 [0001.hk, 0002.hk, 0003.hk, > 0004.hk] is comparing with the file content of file2 [0001.hk, > 0002.hk, 0003.hk, 0005.hk]. > > The result should be +0005.hk, -0004.hk > > Ah. One other thing. Can you explain what you're intending to do > with this statement? > > A = file_contentsA.split(',') > > My thinking is I want to make both files as a list, so I can compare > the two files. However, as you can see, it is only my wishful > thinking. As Dave already mentioned you need to split on whitespace: >>> file_contentsA = "0001.hk 0002.hk 0003.hk" >>> file_contentsA.split() ['0001.hk', '0002.hk', '0003.hk'] The easiest way to get the added/removed entries is set arithmetic: >>> file_contentsB = "0001.hk 0002.hk 0005.hk 0006.hk" >>> entriesA = set(file_contentsA.split()) >>> entriesB = set(file_contentsB.split()) >>> entriesA - entriesB # removed items: {'0003.hk'} >>> entriesB - entriesA # added items: {'0005.hk', '0006.hk'} Now let's work on the output format: >>> added = entriesB - entriesA >>> removed = entriesA - entriesB >>> added_or_removed = added | removed # union of both sets >>> for entry in sorted(added_or_removed): ... if entry in added: ... print("+" + entry) ... else: ... print("-" + entry) ... -0003.hk +0005.hk +0006.hk Limitations of this approach: - information about duplicate entries is lost - the original order of entries is lost From jenaceerowens at gmail.com Sat Jan 10 07:30:21 2015 From: jenaceerowens at gmail.com (Jenacee) Date: Sat, 10 Jan 2015 00:30:21 -0600 Subject: [Tutor] (no subject) Message-ID: I know next to nothing about programing and I would very much like to learn how. Anything on how to get started or understanding how to start would be really great. From alan.gauld at btinternet.com Sat Jan 10 08:51:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 10 Jan 2015 07:51:32 +0000 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: On 10/01/15 06:30, Jenacee wrote: > I know next to nothing about programing and I would very much like to learn how. > Anything on how to get started or understanding how to start would be really great. There are lots of beginners tutorials on the web. This page lists some. https://wiki.python.org/moin/BeginnersGuide/NonProgrammers Which one suits you best depends on your own style and background. The best thing is to try a couple and see what feels like the best fit for you. If you get stuck ask questions here. We like to know: The OS and Python version you use A full listing of any error messages A listing of the code resulting in the error. Have fun, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sat Jan 10 08:49:54 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 10 Jan 2015 18:49:54 +1100 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: <20150110074954.GS19387@ando.pearwood.info> On Sat, Jan 10, 2015 at 12:30:21AM -0600, Jenacee wrote: > I know next to nothing about programing and I would very much like to learn how. > Anything on how to get started or understanding how to start would be really great. Here you go, have fun: https://duckduckgo.com/?q=python%20tutorial Or if you prefer: https://duckduckgo.com/?q=getting%20started%20with%20python Have a look at those and come back if you need help. -- Steve From kliateni at gmail.com Sat Jan 10 14:36:21 2015 From: kliateni at gmail.com (Karim) Date: Sat, 10 Jan 2015 14:36:21 +0100 Subject: [Tutor] Working with prime numbers In-Reply-To: <20150108052541.GA8077@ando.pearwood.info> References: <20150108052541.GA8077@ando.pearwood.info> Message-ID: <54B12AD5.5090206@gmail.com> On 08/01/2015 06:25, Steven D'Aprano wrote: > Sieve of Eratosthenes Very cool I will use it. Karim From wolfrage8765 at gmail.com Mon Jan 12 01:23:58 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sun, 11 Jan 2015 19:23:58 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> Message-ID: <54B3141E.7040500@gmail.com> On 01/05/2015 06:21 PM, Danny Yoo wrote: SNIP > if total in (17, 21, 28, ...): Implemented, thanks. SNIP > > The other comment I'd make is to start thinking about how you'd _test_ > your program automatically. SNIP You are right, I should. But I am fighting with myself on this topic. I have been fighting myself for some time. As it seems the test slow me down. I am sure latter they may speed me up, but then again I am still a relatively new programmer and so my code is very fluid to the situation at hand, so tests for immature code seems like a bad idea. Still you are right. Now I am having problem implementing a way to drop the zero values to the bottom of the grid. I need to look at more of the column at once possibly all of it, or remember where I was dropping. This is my latest code any help would be appreciated. import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(row_num, col_num, self.values) for col_num in range(self.cols)] self.grid.append(row) self.transposed_grid = list(zip(*self.grid)) def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def draw_by_id(self): for col in self.grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.transposed_grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.transposed_grid: while True: low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0 and low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 high.value = 0 i -= 1 if i == 1: i = self.rows first_zero_row = None break def drop_floating_nodes1(self): i = 0 for col_list in self.transposed_grid: while True: try: low, high = col_list[i: i + 2] # Goes Down the Rows if high.value == 0 and low.value != 0: high.value = low.value low.value = 0 i += 1 except ValueError: i = 0 break grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() #print() grid.drop_floating_nodes0() print('After Drops') grid.draw() From wolfrage8765 at gmail.com Mon Jan 12 01:57:01 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sun, 11 Jan 2015 19:57:01 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> Message-ID: <54B31BDD.9020500@gmail.com> I had an issue in my logic and again my named variables provided for confusion, so I had to add some comments to clarify. I got much closer by editing my code like this: def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.transposed_grid: while True: # Low is on Top, High is on Bottom low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 high.value = 0 first_zero_row = low else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break But it still fails as you can see here from the output: | 20 | 19 | 11 | 20 | | 11 | 5 | 5 | 11 | | 19 | 5 | 11 | 11 | | 19 | 20 | 20 | 5 | | 11 | 19 | 19 | 11 | | 20 | 6 | 6 | 11 | | 19 | 11 | 5 | 20 | | 11 | 20 | 11 | 20 | After Eliminations | 20 | 0 | 11 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 11 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 20 | 6 | 6 | 0 | | 19 | 11 | 5 | 0 | | 11 | 20 | 11 | 20 | After Drops | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 11 | 0 | | 0 | 0 | 0 | 0 | | 20 | 0 | 11 | 0 | | 20 | 6 | 6 | 0 | | 19 | 11 | 5 | 0 | | 11 | 20 | 11 | 20 | From wolfrage8765 at gmail.com Mon Jan 12 02:17:34 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Sun, 11 Jan 2015 20:17:34 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> Message-ID: <54B320AE.2020105@gmail.com> Ok, now the code works as expected to drop the non zero values. But I think there exist an error in the naming and display of the col and row variables at least from with in the GameTile() class, looking into that now. All Suggestions Welcome! Thank You All. import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(row_num, col_num, self.values) for col_num in range(self.cols)] self.grid.append(row) self.transposed_grid = list(zip(*self.grid)) def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def draw_by_id(self): for col in self.grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.transposed_grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.transposed_grid: while True: # Low is on Top, High is on Bottom low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row col = first_zero_row.col -1 first_zero_row = self.grid[col][row] except: i = self.rows first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break def drop_floating_nodes1(self): i = 0 for col_list in self.transposed_grid: while True: try: low, high = col_list[i: i + 2] # Goes Down the Rows if high.value == 0 and low.value != 0: high.value = low.value low.value = 0 i += 1 except ValueError: i = 0 break grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() #print() grid.drop_floating_nodes0() print('After Drops') grid.draw() # Output Follows; End of Code | 20 | 5 | 6 | 5 | | 11 | 19 | 5 | 5 | | 5 | 6 | 20 | 11 | | 11 | 11 | 11 | 19 | | 19 | 20 | 5 | 5 | | 11 | 6 | 5 | 20 | | 19 | 19 | 5 | 6 | | 6 | 5 | 20 | 5 | After Eliminations | 20 | 5 | 6 | 0 | | 11 | 0 | 0 | 0 | | 5 | 6 | 20 | 0 | | 11 | 11 | 0 | 19 | | 19 | 20 | 0 | 5 | | 11 | 6 | 0 | 20 | | 19 | 19 | 5 | 6 | | 6 | 5 | 20 | 5 | After Drops | 20 | 0 | 0 | 0 | | 11 | 5 | 0 | 0 | | 5 | 6 | 0 | 0 | | 11 | 11 | 0 | 19 | | 19 | 20 | 6 | 5 | | 11 | 6 | 20 | 20 | | 19 | 19 | 5 | 6 | | 6 | 5 | 20 | 5 | From wolfrage8765 at gmail.com Mon Jan 12 20:35:27 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 14:35:27 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54B3141E.7040500@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> Message-ID: <54B421FF.5050902@gmail.com> So I was write as I suspected; the grid is not actually being built like I thought it was. Sure the ID's print fine but when the grid positions are procedurally accessed the program fails with IndexError. python3 test1.py | 19 | 5 | 5 | 5 | | 11 | 6 | 19 | 11 | | 6 | 6 | 11 | 19 | | 11 | 20 | 6 | 5 | | 11 | 5 | 20 | 5 | | 20 | 20 | 11 | 11 | | 19 | 19 | 5 | 5 | | 11 | 19 | 19 | 5 | After Eliminations | 0 | 0 | 0 | 5 | | 11 | 0 | 19 | 11 | | 0 | 0 | 11 | 0 | | 0 | 20 | 6 | 0 | | 0 | 5 | 20 | 0 | | 0 | 0 | 0 | 0 | | 19 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | broke 0 5 0 6 broke 1 6 1 7 broke 2 6 2 7 broke 3 6 3 7 After Drops | 0 | 0 | 0 | 5 | | 0 | 0 | 19 | 0 | | 0 | 0 | 11 | 0 | | 0 | 20 | 6 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 11 | 0 | 0 | 0 | | 19 | 5 | 20 | 11 | Normal | 0,0 | 1,0 | 2,0 | 3,0 | | 0,1 | 1,1 | 2,1 | 3,1 | | 0,2 | 1,2 | 2,2 | 3,2 | | 0,3 | 1,3 | 2,3 | 3,3 | | 0,4 | 1,4 | 2,4 | 3,4 | | 0,5 | 1,5 | 2,5 | 3,5 | | 0,6 | 1,6 | 2,6 | 3,6 | | 0,7 | 1,7 | 2,7 | 3,7 | Procedurally # The first printed pair is the id, the second pair in parentheses is # the procedurally accessed id, which should be all ordered as (column, # row) | 0,0 (0,0) | 1,0 (0,1) | 2,0 (0,2) | 3,0 (0,3) | Traceback (most recent call last): File "test1.py", line 186, in grid.draw_by_id_proc() File "test1.py", line 75, in draw_by_id_proc print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') IndexError: list index out of range I am attempting to fix it now. Any help is appreciated. #Code Below import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False # hide_anim = hidden for animation purposes self.hide_anim = False # drop_value = value to be dropped during animation self.drop_value = None # drop_to could have inversely been a drop_from # drop_to = the id of where the value should be dropped too. self.drop_to = None def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(col_num, row_num, self.values) for col_num in range(self.cols)] self.grid.append(row) self.transposed_grid = list(zip(*self.grid)) def draw(self): for col in self.grid: print(end='| ') for node in col: print(node, end=' | ') print() def draw_by_id(self): for col in self.grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def draw_by_id_trans(self): for col in self.transposed_grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def draw_by_id_proc(self): # Draw Procedurally for col_num in range(self.cols): print(end='| ') for row_num in range(self.rows): print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.transposed_grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.transposed_grid: while True: # Low is on Top, High is on Bottom low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row - 1 col = first_zero_row.col first_zero_row = self.grid[col][row] except: i = self.rows print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break def drop_floating_nodes1(self): i = 0 for col_list in self.transposed_grid: while True: try: low, high = col_list[i: i + 2] # Goes Down the Rows if high.value == 0 and low.value != 0: high.value = low.value low.value = 0 i += 1 except ValueError: i = 0 break grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() #print() grid.drop_floating_nodes0() print('After Drops') grid.draw() print('Normal') grid.draw_by_id() #print('Tansposed') #grid.draw_by_id_trans() print('Procedurally') grid.draw_by_id_proc() From wolfrage8765 at gmail.com Mon Jan 12 21:04:25 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 15:04:25 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54B421FF.5050902@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> Message-ID: <54B428C9.3050109@gmail.com> Now I have the output that I expect and procedurally they output matches the id of the Node/Tile. But I am thoroughly confused as to why my by_id functions use the opposite grid to get the correct output? # Output python3 test1.py | 6 | 20 | 19 | 11 | 11 | 20 | 5 | 11 | | 20 | 19 | 20 | 11 | 11 | 19 | 19 | 20 | | 6 | 19 | 19 | 6 | 5 | 20 | 5 | 11 | | 11 | 5 | 5 | 11 | 11 | 6 | 6 | 5 | By ID | 0,0 | 1,0 | 2,0 | 3,0 | | 0,1 | 1,1 | 2,1 | 3,1 | | 0,2 | 1,2 | 2,2 | 3,2 | | 0,3 | 1,3 | 2,3 | 3,3 | | 0,4 | 1,4 | 2,4 | 3,4 | | 0,5 | 1,5 | 2,5 | 3,5 | | 0,6 | 1,6 | 2,6 | 3,6 | | 0,7 | 1,7 | 2,7 | 3,7 | Procedurally | 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) | | 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) | | 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) | | 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) | | 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) | | 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) | | 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) | | 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) | Tansposed | 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 | | 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 | | 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 | | 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 | Transposed & Procedurally | 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) | 0,6 (0,6) | 0,7 (0,7) | | 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) | 1,6 (1,6) | 1,7 (1,7) | | 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) | 2,6 (2,6) | 2,7 (2,7) | | 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) | 3,6 (3,6) | 3,7 (3,7) | # Code Below import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False # hide_anim = hidden for animation purposes self.hide_anim = False # drop_value = value to be dropped during animation self.drop_value = None # drop_to could have inversely been a drop_from # drop_to = the id of where the value should be dropped too. self.drop_to = None def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.transposed_grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(col_num, row_num, self.values) for col_num in range(self.cols)] self.transposed_grid.append(row) self.grid = list(zip(*self.transposed_grid)) def draw(self): for row in self.grid: print(end='| ') for node in row: print(node, end=' | ') print() def draw_by_id(self): # Why does this one use self.transposed_grid instead of self.grid ? for row in self.transposed_grid: print(end='| ') for node in row: print(node.id, end=' | ') print() def draw_by_id_proc(self): # Draw Procedurally for row_num in range(self.rows): print(end='| ') for col_num in range(self.cols): print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') print() def draw_by_id_trans(self): # Why does this one use self.grid instead of self.transposed_grid ? for col in self.grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def draw_by_id_proc_trans(self): # Draw Procedurally & Transposed for col_num in range(self.cols): print(end='| ') for row_num in range(self.rows): print(self.transposed_grid[row_num][col_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.transposed_grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.transposed_grid: while True: # Low is on Top, High is on Bottom low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row - 1 col = first_zero_row.col first_zero_row = self.grid[col][row] except: i = self.rows print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break def drop_floating_nodes1(self): i = 0 for col_list in self.transposed_grid: while True: try: low, high = col_list[i: i + 2] # Goes Down the Rows if high.value == 0 and low.value != 0: high.value = low.value low.value = 0 i += 1 except ValueError: i = 0 break grid = GameGrid(4, 8) grid.draw() #grid.find_eliminations() #print('After Eliminations') #grid.draw() #print() #grid.drop_floating_nodes0() #print('After Drops') #grid.draw() print('By ID') grid.draw_by_id() print('Procedurally') grid.draw_by_id_proc() print('Tansposed') grid.draw_by_id_trans() print('Transposed & Procedurally') grid.draw_by_id_proc_trans() From wolfrage8765 at gmail.com Mon Jan 12 21:28:33 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 15:28:33 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54B428C9.3050109@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> <54B428C9.3050109@gmail.com> Message-ID: <54B42E71.4070202@gmail.com> I fixed the other functions to again work as expected. But the procedural access of the self.grid and self.transposed_grid also function correctly. That is good because now I can again do lookups if I need to. Although I do not have a need to at this time. Can anyone see anything wrong with the logic as it is at this time? If anyone has any improvements or things to think about, I would love to hear it. I am going to work on some tests that will specifically involve the procedural code to verify that the id's are arranged in the grid as I expect them to be. I would also appreciate an explanation of why my by_id functions use the opposite grid to get the correct output? #Output Below python3 test1.py | 19 | 11 | 5 | 19 | | 11 | 19 | 19 | 5 | | 20 | 19 | 20 | 6 | | 11 | 19 | 11 | 5 | | 11 | 6 | 5 | 20 | | 6 | 5 | 19 | 19 | | 20 | 19 | 20 | 20 | | 6 | 20 | 19 | 20 | After Eliminations | 19 | 0 | 5 | 19 | | 0 | 0 | 0 | 5 | | 0 | 0 | 20 | 6 | | 0 | 19 | 11 | 5 | | 0 | 6 | 5 | 20 | | 0 | 5 | 19 | 19 | | 20 | 19 | 20 | 20 | | 6 | 20 | 19 | 20 | After Drops | 0 | 0 | 0 | 19 | | 0 | 0 | 5 | 5 | | 0 | 0 | 20 | 6 | | 0 | 19 | 11 | 5 | | 0 | 6 | 5 | 20 | | 19 | 5 | 19 | 19 | | 20 | 19 | 20 | 20 | | 6 | 20 | 19 | 20 | By ID | 0,0 | 1,0 | 2,0 | 3,0 | | 0,1 | 1,1 | 2,1 | 3,1 | | 0,2 | 1,2 | 2,2 | 3,2 | | 0,3 | 1,3 | 2,3 | 3,3 | | 0,4 | 1,4 | 2,4 | 3,4 | | 0,5 | 1,5 | 2,5 | 3,5 | | 0,6 | 1,6 | 2,6 | 3,6 | | 0,7 | 1,7 | 2,7 | 3,7 | Procedurally | 0,0 (0,0) | 1,0 (1,0) | 2,0 (2,0) | 3,0 (3,0) | | 0,1 (0,1) | 1,1 (1,1) | 2,1 (2,1) | 3,1 (3,1) | | 0,2 (0,2) | 1,2 (1,2) | 2,2 (2,2) | 3,2 (3,2) | | 0,3 (0,3) | 1,3 (1,3) | 2,3 (2,3) | 3,3 (3,3) | | 0,4 (0,4) | 1,4 (1,4) | 2,4 (2,4) | 3,4 (3,4) | | 0,5 (0,5) | 1,5 (1,5) | 2,5 (2,5) | 3,5 (3,5) | | 0,6 (0,6) | 1,6 (1,6) | 2,6 (2,6) | 3,6 (3,6) | | 0,7 (0,7) | 1,7 (1,7) | 2,7 (2,7) | 3,7 (3,7) | Tansposed | 0,0 | 0,1 | 0,2 | 0,3 | 0,4 | 0,5 | 0,6 | 0,7 | | 1,0 | 1,1 | 1,2 | 1,3 | 1,4 | 1,5 | 1,6 | 1,7 | | 2,0 | 2,1 | 2,2 | 2,3 | 2,4 | 2,5 | 2,6 | 2,7 | | 3,0 | 3,1 | 3,2 | 3,3 | 3,4 | 3,5 | 3,6 | 3,7 | Transposed & Procedurally | 0,0 (0,0) | 0,1 (0,1) | 0,2 (0,2) | 0,3 (0,3) | 0,4 (0,4) | 0,5 (0,5) | 0,6 (0,6) | 0,7 (0,7) | | 1,0 (1,0) | 1,1 (1,1) | 1,2 (1,2) | 1,3 (1,3) | 1,4 (1,4) | 1,5 (1,5) | 1,6 (1,6) | 1,7 (1,7) | | 2,0 (2,0) | 2,1 (2,1) | 2,2 (2,2) | 2,3 (2,3) | 2,4 (2,4) | 2,5 (2,5) | 2,6 (2,6) | 2,7 (2,7) | | 3,0 (3,0) | 3,1 (3,1) | 3,2 (3,2) | 3,3 (3,3) | 3,4 (3,4) | 3,5 (3,5) | 3,6 (3,6) | 3,7 (3,7) | # Code Below import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid (X,Y) which is equal to grid (col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False # hide_anim = hidden for animation purposes self.hide_anim = False # drop_value = value to be dropped during animation self.drop_value = None # drop_to could have inversely been a drop_from # drop_to = the id of where the value should be dropped too. self.drop_to = None def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def make_grid(self): # grid is 2d array as x, y ie [x][y]. self.transposed_grid = [] for row_num in range(self.rows): # Do you still think this needs to be broken into a smaller method? row = [GameTile(col_num, row_num, self.values) for col_num in range(self.cols)] self.transposed_grid.append(row) self.grid = list(zip(*self.transposed_grid)) def draw(self): for row in self.transposed_grid: print(end='| ') for node in row: print(node, end=' | ') print() def draw_by_id(self): # Why does this one use self.transposed_grid instead of self.grid ? for row in self.transposed_grid: print(end='| ') for node in row: print(node.id, end=' | ') print() def draw_by_id_proc(self): # Draw Procedurally for row_num in range(self.rows): print(end='| ') for col_num in range(self.cols): print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') print() def draw_by_id_trans(self): # Why does this one use self.grid instead of self.transposed_grid ? for col in self.grid: print(end='| ') for node in col: print(node.id, end=' | ') print() def draw_by_id_proc_trans(self): # Draw Procedurally & Transposed for col_num in range(self.cols): print(end='| ') for row_num in range(self.rows): print(self.transposed_grid[row_num][col_num].id, '(' + str(col_num) + ',' + str(row_num) + ')', end=' | ') print() def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.transposed_grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.transposed_grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.grid: while True: # Low is on Top, High is on Bottom low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row - 1 col = first_zero_row.col first_zero_row = self.grid[col][row] except: i = self.rows print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break def drop_floating_nodes1(self): i = 0 for col_list in self.transposed_grid: while True: try: low, high = col_list[i: i + 2] # Goes Down the Rows if high.value == 0 and low.value != 0: high.value = low.value low.value = 0 i += 1 except ValueError: i = 0 break grid = GameGrid(4, 8) grid.draw() grid.find_eliminations() print('After Eliminations') grid.draw() print() grid.drop_floating_nodes0() print('After Drops') grid.draw() print('By ID') grid.draw_by_id() print('Procedurally') grid.draw_by_id_proc() print('Tansposed') grid.draw_by_id_trans() print('Transposed & Procedurally') grid.draw_by_id_proc_trans() From breamoreboy at yahoo.co.uk Mon Jan 12 22:47:11 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 12 Jan 2015 21:47:11 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54B421FF.5050902@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> Message-ID: On 12/01/2015 19:35, WolfRage wrote: > So I was write as I suspected; the grid is not actually being built like > I thought it was. Sure the ID's print fine but when the grid positions > are procedurally accessed the program fails with IndexError. > > python3 test1.py > | 19 | 5 | 5 | 5 | > | 11 | 6 | 19 | 11 | > | 6 | 6 | 11 | 19 | > | 11 | 20 | 6 | 5 | > | 11 | 5 | 20 | 5 | > | 20 | 20 | 11 | 11 | > | 19 | 19 | 5 | 5 | > | 11 | 19 | 19 | 5 | > After Eliminations > | 0 | 0 | 0 | 5 | > | 11 | 0 | 19 | 11 | > | 0 | 0 | 11 | 0 | > | 0 | 20 | 6 | 0 | > | 0 | 5 | 20 | 0 | > | 0 | 0 | 0 | 0 | > | 19 | 0 | 0 | 0 | > | 0 | 0 | 0 | 0 | > broke 0 5 > 0 6 > broke 1 6 > 1 7 > broke 2 6 > 2 7 > broke 3 6 > 3 7 > After Drops > | 0 | 0 | 0 | 5 | > | 0 | 0 | 19 | 0 | > | 0 | 0 | 11 | 0 | > | 0 | 20 | 6 | 0 | > | 0 | 0 | 0 | 0 | > | 0 | 0 | 0 | 0 | > | 11 | 0 | 0 | 0 | > | 19 | 5 | 20 | 11 | > Normal > | 0,0 | 1,0 | 2,0 | 3,0 | > | 0,1 | 1,1 | 2,1 | 3,1 | > | 0,2 | 1,2 | 2,2 | 3,2 | > | 0,3 | 1,3 | 2,3 | 3,3 | > | 0,4 | 1,4 | 2,4 | 3,4 | > | 0,5 | 1,5 | 2,5 | 3,5 | > | 0,6 | 1,6 | 2,6 | 3,6 | > | 0,7 | 1,7 | 2,7 | 3,7 | > Procedurally > # The first printed pair is the id, the second pair in parentheses is > # the procedurally accessed id, which should be all ordered as (column, > # row) > | 0,0 (0,0) | 1,0 (0,1) | 2,0 (0,2) | 3,0 (0,3) | Traceback (most recent > call last): > File "test1.py", line 186, in > grid.draw_by_id_proc() > File "test1.py", line 75, in draw_by_id_proc > print(self.grid[col_num][row_num].id, '(' + str(col_num) + ',' + > str(row_num) + ')', end=' | ') > IndexError: list index out of range > I haven't looked carefully at your code but there's always a smell in Python when you see structure[x][y]. Can you change the grid so you always write something like:- for row in grid: for cell in row: process(cell) I say this as I'm all for short term pain, long term gain, especially when it's guaranteed to eliminate "list index out of range" errors. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Mon Jan 12 23:00:00 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 12 Jan 2015 22:00:00 +0000 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: <54B42E71.4070202@gmail.com> References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com> Message-ID: On 12/01/15 20:28, WolfRage wrote: > anyone has any improvements or things to think about, I would love to > hear it. Sorry, no time to read the detail, but one thing I thought might be handy is to convert the draw method to return a string and make it the __str__methodf of the grid. Then the draw method becomes print(self) And you can also just use print(aGrid) etc. Something like (untested): def __str__(self): output = [] for row in self.transposed_grid: s='| ' for node in row: s += (str(node) + ' | ') output.append(s) return '\n'.join(output) def draw(self): print (self) Just a thought. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From wolfrage8765 at gmail.com Mon Jan 12 23:54:58 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 17:54:58 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> Message-ID: <54B450C2.5020400@gmail.com> > > I haven't looked carefully at your code but there's always a smell in > Python when you see structure[x][y]. Can you change the grid so you > always write something like:- > > for row in grid: > for cell in row: > process(cell) > > I say this as I'm all for short term pain, long term gain, especially > when it's guaranteed to eliminate "list index out of range" errors. > I think in this case I have to say no. I purposely wrote those "proc" or "procedurally" style functions to ensure that access to the grid in this way would result in the correct output from id, and to test that it worked as expected. However there are other places in my code where I think I can eliminate this smell such as the new function that drops the non-zero values. From wolfrage8765 at gmail.com Tue Jan 13 00:33:27 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 18:33:27 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com> Message-ID: <54B459C7.7090704@gmail.com> On 01/12/2015 05:00 PM, Alan Gauld wrote: > Sorry, no time to read the detail, but one thing I thought might be > handy is to convert the draw method to return a string and make it the > __str__methodf of the grid. > Then the draw method becomes print(self) > > And you can also just use print(aGrid) etc. > > Something like (untested): > > def __str__(self): > output = [] > for row in self.transposed_grid: > s='| ' > for node in row: > s += (str(node) + ' | ') > output.append(s) > return '\n'.join(output) > > def draw(self): print (self) > > > Just a thought. > OK. I will implement this, thanks. It goes well with the __str__ method of the tiles/nodes. From wolfrage8765 at gmail.com Tue Jan 13 01:07:03 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 19:07:03 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com> Message-ID: <54B461A7.7030808@gmail.com> On 01/12/2015 05:00 PM, Alan Gauld wrote: > __str__methodf of the grid. > Then the draw method becomes print(self) > > And you can also just use print(aGrid) etc. Implemented with some other improvements using the same idea but applied to several of the other functions, that provide output. Now I am going to try and add the ability to have the table generated but with a set number of rows empty or pre-set to zero. #CODE BELOW import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid(X,Y) which is equal to grid(col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False # hide_anim = hidden for animation purposes self.hide_anim = False # drop_value = value to be dropped during animation self.drop_value = None # drop_to could have inversely been a drop_from # drop_to = the id of where the value should be dropped too. self.drop_to = None def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, **kwargs): if cols < 3 or rows < 3: raise ValueError("Minimum board size is 3x3! %sx%s is too small." % (cols, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid() def __str__(self): output = [] for row in self.transposed_grid: s = '| ' for node in row: s += str(node) + ' | ' output.append(s) return '\n'.join(output) def make_grid(self): # grid is 2d array as x, y ie [x][y]. # transposed_grid is 2d array as y, x ie [y][x] self.transposed_grid = [] for row_num in range(self.rows): row = [GameTile(col_num, row_num, self.values) for col_num in range(self.cols)] self.transposed_grid.append(row) self.grid = list(zip(*self.transposed_grid)) def draw(self): print(self) def draw_by_id(self): # Why does this one use self.transposed_grid instead of self.grid ? output = [] for row in self.transposed_grid: s = '| ' for node in row: s += str(node.id) + ' | ' output.append(s) return '\n'.join(output) def draw_by_id_proc(self): # Draw Procedurally output = [] for row_num in range(self.rows): s = '| ' for col_num in range(self.cols): s += (str(self.grid[col_num][row_num].id) + '(' + str(col_num) + ',' + str(row_num) + ')' + ' | ') output.append(s) return '\n'.join(output) def draw_by_id_trans(self): # Why does this one use self.grid instead of self.transposed_grid ? output = [] for col in self.grid: s = '| ' for node in col: s += str(node.id) + ' | ' output.append(s) return '\n'.join(output) def draw_by_id_trans_proc (self): # Draw Transposed & Procedurally output = [] for col_num in range(self.cols): s = '| ' for row_num in range(self.rows): s += (str(self.transposed_grid[row_num][col_num].id) + '(' + str(col_num) + ',' + str(row_num) + ')' + ' | ') output.append(s) return '\n'.join(output) def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.transposed_grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.transposed_grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_floating_nodes0(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.grid: while True: # Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row - 1 col = first_zero_row.col first_zero_row = self.grid[col][row] except: i = self.rows print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break grid = GameGrid(4, 8) print(grid) grid.find_eliminations() print('After Eliminations') print(grid) grid.drop_floating_nodes0() print('After Drops') print(grid) print('By ID') print(grid.draw_by_id()) print('By ID & Procedurally') print(grid.draw_by_id_proc()) print('Transposed') print(grid.draw_by_id_trans()) print('Transposed & Procedurally') print(grid.draw_by_id_trans_proc()) From wolfrage8765 at gmail.com Tue Jan 13 04:29:46 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 12 Jan 2015 22:29:46 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com> Message-ID: <54B4912A.1090706@gmail.com> Updated the code to now allow for a fill_rows optional argument for Grid, that determines how many rows are filled with values. I have also added some experimental code to invert the dropping, as in all of the values can float to the top. Other code is even more experimental and not yet working right that pulls the nodes to the right or left, with hope of being able to apply gravity in all 4 directions. But I still need to work out the bugs. Any help is greatly appreciated. Thanks for all of the contributions so far. #CODE BELOW import random class GameTile(): def __init__(self, col, row, values=None, value=None, **kwargs): # values is not required because the value can be directly set. # This is to support a future feature that will allow me to build a # board off of a list. # id is grid(X,Y) which is equal to grid(col,row) self.id = str(col) + ',' + str(row) self.col = col self.row = row if value is None: value = random.choice(values) self.value = value self.eliminated = False # hide_anim = hidden for animation purposes self.hide_anim = False # drop_value = value to be dropped during animation self.drop_value = None # drop_to could have inversely been a drop_from # drop_to = the id of where the value should be dropped too. self.drop_to = None def __str__(self): return "%2d" % self.value class GameGrid(): def __init__(self, cols=8, rows=7, fill_rows=None, **kwargs): if cols < 3 or rows < 3: raise ValueError('Minimum board size is 3x3! %sx%s is too small.' % (cols, rows)) if fill_rows > rows: string = 'Can not fill more rows than actual rows ' + \ 'exist. fill_rows=%s rows=%s' raise ValueError(string % (fill_rows, rows)) self.cols = cols self.rows = rows self.values = [5, 6, 11, 19, 20] self.make_grid(fill_rows) def __str__(self): output = [] for row in self.transposed_grid: s = '| ' for node in row: s += str(node) + ' | ' output.append(s) return '\n'.join(output) def make_grid(self, fill_rows=None): # grid is 2d array as x, y ie [x][y]. # transposed_grid is 2d array as y, x ie [y][x] self.transposed_grid = [] for row_num in range(self.rows): if fill_rows is None: values = self.values elif row_num < self.rows - fill_rows: values = [0, ] else: values = self.values row = [GameTile(col_num, row_num, values) for col_num in range(self.cols)] self.transposed_grid.append(row) self.grid = list(zip(*self.transposed_grid)) def draw(self): print(self) def draw_by_id(self): # Why does this one use self.transposed_grid instead of self.grid ? output = [] for row in self.transposed_grid: s = '| ' for node in row: s += str(node.id) + ' | ' output.append(s) return '\n'.join(output) def draw_by_id_proc(self): # Draw Procedurally output = [] for row_num in range(self.rows): s = '| ' for col_num in range(self.cols): s += (str(self.grid[col_num][row_num].id) + '(' + str(col_num) + ',' + str(row_num) + ')' + ' | ') output.append(s) return '\n'.join(output) def draw_by_id_trans(self): # Why does this one use self.grid instead of self.transposed_grid ? output = [] for col in self.grid: s = '| ' for node in col: s += str(node.id) + ' | ' output.append(s) return '\n'.join(output) def draw_by_id_trans_proc (self): # Draw Transposed & Procedurally output = [] for col_num in range(self.cols): s = '| ' for row_num in range(self.rows): s += (str(self.transposed_grid[row_num][col_num].id) + '(' + str(col_num) + ',' + str(row_num) + ')' + ' | ') output.append(s) return '\n'.join(output) def find_eliminations(self): #First Down the columns. i = 0 for col_list in self.grid: while True: try: if self.check_total(col_list[i: i + 3]): self.eliminate(col_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Now across the rows. for row_list in self.transposed_grid: while True: try: if self.check_total(row_list[i: i + 3]): self.eliminate(row_list[i: i + 3]) i += 1 except ValueError: i = 0 break # Set all eliminated nodes to a value of 0. for col in self.transposed_grid: for node in col: if node.eliminated is True: node.eliminated = False node.value = 0 def check_total(self, slices): first, second, third = slices if first.value == second.value or second.value == third.value: total = first.value + second.value + third.value return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58) def eliminate(self, slices): first, second, third = slices first.eliminated = True second.eliminated = True third.eliminated = True def drop_nodes(self): i = self.rows # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.grid: while True: # Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered low, high = col_list[i - 2: i] # Goes Up the Rows if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 row = first_zero_row.row - 1 col = first_zero_row.col first_zero_row = self.grid[col][row] else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.rows first_zero_row = None break def invert_drop_nodes(self): i = 0 # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for col_list in self.grid: while True: # Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered low, high = col_list[i: i + 2] # Goes Down the Rows if low.value == 0: if high.value != 0: if first_zero_row is None: low.value = high.value high.value = 0 first_zero_row = high else: first_zero_row.value = high.value high.value = 0 row = first_zero_row.row + 1 col = first_zero_row.col first_zero_row = self.grid[col][row] else: if first_zero_row is None: first_zero_row = low i += 1 if i == self.rows - 1: i = 0 first_zero_row = None break def pull_nodes(self): i = self.cols # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for row_list in self.transposed_grid: while True: # Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered low, high = row_list[i - 2: i] # Goes Up the Columns if high.value == 0: if low.value != 0: if first_zero_row is None: high.value = low.value low.value = 0 first_zero_row = low else: first_zero_row.value = low.value low.value = 0 try: row = first_zero_row.row - 1 # Testing Here col = first_zero_row.col # Or Here? first_zero_row = self.transposed_grid[col][row] except: i = self.cols print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = high i -= 1 if i == 1: i = self.cols first_zero_row = None break def invert_pull_nodes(self): i = 0 # first_zero_row serves as memory for how far to drop non-zero values first_zero_row = None for row_list in self.transposed_grid: while True: # Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered low, high = row_list[i: i + 2] # Goes Down the Columns if low.value == 0: if high.value != 0: if first_zero_row is None: low.value = high.value high.value = 0 first_zero_row = high else: first_zero_row.value = high.value high.value = 0 try: row = first_zero_row.row # Testing Here col = first_zero_row.col + 1 # Or Here? first_zero_row = self.transposed_grid[col][row] except: i = 0 print('broke', col, row) print(first_zero_row.col, first_zero_row.row) first_zero_row = None break else: if first_zero_row is None: first_zero_row = low i += 1 if i == self.cols - 1: i = 0 first_zero_row = None break grid = GameGrid(4, 8, 6) print(grid) grid.find_eliminations() print('After Eliminations') print(grid) grid.drop_nodes() print('After Drops') print(grid) grid.invert_drop_nodes() print('Reverse Gravity aka Inverted') print(grid) #grid.pull_nodes() #print('Pull Nodes') #print(grid) #grid.invert_pull_nodes() #print('Invert Pull Nodes') #print(grid) print(grid.draw_by_id()) From arvind.ramachandran at sial.com Tue Jan 13 18:13:57 2015 From: arvind.ramachandran at sial.com (Arvind Ramachandran) Date: Tue, 13 Jan 2015 11:13:57 -0600 Subject: [Tutor] Error getting cx_oracle to work with python 2.7 Message-ID: Hi All I am trying to get import cx_oracle work on my windows laptop I installed cx_Oracle-5.1.2-10g.win32-py2.7 on my laptop which is 64 bit as the 64 bit msi seem to be specific for AMD desktops Anyways after installed I do find cx_oracle.pyd in the lib site packages folder But when I try to pip install cx_oracle it gives an error saying it is already established When I issue python -c 'import cx_oracle' the error I get is Import : EOL while scanning string literal When I issue python -c "import cx_oracle" the error I get is Import : No module named cx_oracle My oracle version is 11.2.0.1.0 Please advice how I can get my oracle package to work so I can connected If there is a better mailing list please let me know as well -- Regards Arvind Ramachandran (414-530-8366) ===================== Conference Dail In Numbers Participant code : 5751206 Leader code :7903519 USA 1-517-466-2380 866-803-2146 INDIA 000-800-852-1259 ===================== -- This message and any files transmitted with it are the property of Sigma-Aldrich Corporation, are confidential, and are intended solely for the use of the person or entity to whom this e-mail is addressed. If you are not one of the named recipient(s) or otherwise have reason to believe that you have received this message in error, please contact the sender and delete this message immediately from your computer. Any other use, retention, dissemination, forwarding, printing, or copying of this e-mail is strictly prohibited. From dyoo at hashcollision.org Tue Jan 13 20:25:41 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Jan 2015 11:25:41 -0800 Subject: [Tutor] Error getting cx_oracle to work with python 2.7 In-Reply-To: References: Message-ID: On Tue, Jan 13, 2015 at 9:13 AM, Arvind Ramachandran wrote: > Hi All > > > I am trying to get import cx_oracle work on my windows laptop > > I installed cx_Oracle-5.1.2-10g.win32-py2.7 on my laptop which is 64 bit as > the 64 bit msi seem to be specific for AMD desktops > > Anyways after installed I do find cx_oracle.pyd in the lib site packages > folder > > But when I try to pip install cx_oracle it gives an error saying it is > already established > > When I issue python -c 'import cx_oracle' the error I get is > Import : EOL while scanning string literal > When I issue python -c "import cx_oracle" the error I get is > Import : No module named cx_oracle > > My oracle version is 11.2.0.1.0 Tutor is probably not going to be the best place to ask this database question. You should probably ask on cx-oracle-users: https://lists.sourceforge.net/lists/listinfo/cx-oracle-users By the way, please use copy-and-paste when showing the inputs and outputs of what you're doing. You should try to show verbatim output for any bug report or request for technical help. If you don't, you can easily introduce mistakes that make it hard to diagnose what's going on. I think that you've paraphrased the output from some of the error messages, and it's making it really hard to tell what's going on. The message you're reporting looks really suspicious: Import : No module named cx_oracle because there are too many spaces between the colon and the message, and it should be using the term "ImportError", not just "Import". If that's truly what you're getting, then something very strange is going on. From dyoo at hashcollision.org Tue Jan 13 20:30:49 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Jan 2015 11:30:49 -0800 Subject: [Tutor] Error getting cx_oracle to work with python 2.7 In-Reply-To: References: Message-ID: > By the way, please use copy-and-paste when showing the inputs and > outputs of what you're doing. You should try to show verbatim output > for any bug report or request for technical help. If you don't, you > can easily introduce mistakes that make it hard to diagnose what's > going on. I can't tell, given that you might be paraphrasing, whether or not you've typed cx_oracle or: cx_Oracle According to documentation on the web, it might make a difference. From paul at labergedaylight.com Wed Jan 14 22:48:10 2015 From: paul at labergedaylight.com (Paul LaBerge) Date: Wed, 14 Jan 2015 13:48:10 -0800 Subject: [Tutor] PyDeadObjectError: MainFrame deleted Message-ID: Hello, I was using a python script created GUI. The GUI locked up and produced the following message when I closed it. Can someone tell me if the ?MainFrame? object is in the GUI or part of Python ? It looks like I need to reinstall something, but I?m not sure what that is from this message. Thanks, Paul ____________ Pauls:PaulSan ~$ cd '/Users/OpenDAQ/opendaq-gui-master/easy_daq/' && '/usr/local/bin/pythonw' '/Users/OpenDAQ/opendaq-gui-master/easy_daq/main.py' && echo Exit status: $? && exit 1 Error trying to stop. Retrying Exception in thread Thread-1: Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner self.run() File "/Users/OpenDAQ/opendaq-gui-master/easy_daq/main.py", line 232, in run frame.daq.flush() File "/usr/local/lib/wxPython-3.0.1.1/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 16709, in __getattr__ raise PyDeadObjectError(self.attrStr % self._name) PyDeadObjectError: The C++ part of the MainFrame object has been deleted, attribute access no longer allowed. Exit status: 0 logout [Process completed] ____________ From steve at pearwood.info Thu Jan 15 02:24:50 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 15 Jan 2015 12:24:50 +1100 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: References: Message-ID: <20150115012450.GR10173@ando.pearwood.info> On Wed, Jan 14, 2015 at 01:48:10PM -0800, Paul LaBerge wrote: > Hello, > > I was using a python script created GUI. The GUI locked up and > produced the following message when I closed it. Can someone tell me > if the ?MainFrame? object is in the GUI or part of Python ? It looks > like I need to reinstall something, but I?m not sure what that is from > this message. Your wxPython GUI crashed: > PyDeadObjectError: The C++ part of the MainFrame object has been > deleted, attribute access no longer allowed. That's a wxPython error, not the Python interpreter. The way you can tell is by looking at the pathname of the file that raised the exception: > File "/usr/local/lib/wxPython-3.0.1.1/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", > line 16709, in __getattr__ > > raise PyDeadObjectError(self.attrStr % self._name) > > PyDeadObjectError: The C++ part of the MainFrame object has been > deleted, attribute access no longer allowed. (Also, because I happen to know that the wxPython GUI is written in C++ so any C++ errors are from it, not the Python interpreter.) I don't know whether this indicates corruption in the library which will be fixed by reinstalling, a bug in the library, or just a bug in your own code. -- Steven From dyoo at hashcollision.org Thu Jan 15 02:29:46 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 14 Jan 2015 17:29:46 -0800 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: References: Message-ID: Hi Paul, On Wed, Jan 14, 2015 at 1:48 PM, Paul LaBerge wrote: > Hello, > > I was using a python script created GUI. The GUI locked up and produced the following message when I closed it. > Can someone tell me if the ?MainFrame? object is in the GUI or part of Python ? It looks like I need to reinstall something, but I?m not sure what that is from this message. It's likely part of the GUI, as web searches for the error message come up with pages like: http://stackoverflow.com/questions/18198413/wxpython-pydeadobjecterror This looks specific to the wxPython GUI part of the program you're running. As far as I can tell, you'd see this only if there were a bug in the Python script. Who wrote the GUI? From dyoo at hashcollision.org Thu Jan 15 02:38:56 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 14 Jan 2015 17:38:56 -0800 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: References: Message-ID: > This looks specific to the wxPython GUI part of the program you're > running. As far as I can tell, you'd see this only if there were a > bug in the Python script. Who wrote the GUI? Ah. Looks like you are running the main.py program from: https://github.com/openDAQ/opendaq-gui/tree/master/easy_daq As such, then my best evaluation is that you've found a bug in their product. I'd recommend filing a bug report with the developer. Provide them the information you presented here. Be as specific as possible. You can find contact information from: https://github.com/openDAQ/opendaq-gui. Otherwise, I don't think we can do much else on Python-tutor: this program isn't a beginner program; rather, it's tied to a professional hardware product. From ben+python at benfinney.id.au Thu Jan 15 05:20:06 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 15 Jan 2015 15:20:06 +1100 Subject: [Tutor] PyDeadObjectError: MainFrame deleted References: Message-ID: <85oaq0u13d.fsf@benfinney.id.au> Paul LaBerge writes: > I was using a python script created GUI. The GUI locked up and > produced the following message when I closed it. Is this Python script your own code? If not, it will be good for you to correspond with the author(s) of the code. > Can someone tell me if the ?MainFrame? object is in the GUI or part of > Python ? The traceback output shows where the exception was raised. The end of the chain of calls shows: > File "/usr/local/lib/wxPython-3.0.1.1/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 16709, in __getattr__ > raise PyDeadObjectError(self.attrStr % self._name) > PyDeadObjectError: The C++ part of the MainFrame object has been deleted, attribute access no longer allowed. So this is a ?PyDeadObjectError? exception raised from the file named above. Judging by the path, it seems to be code within wxPython. You should ask for further help on the wxPython forums. You should also contact the author of the top-level code you're running. Good hunting. -- \ ?The entertainment industry calls DRM "security" software, | `\ because it makes them secure from their customers.? ?Cory | _o__) Doctorow, 2014-02-05 | Ben Finney From bw_dw at fastmail.fm Thu Jan 15 15:07:28 2015 From: bw_dw at fastmail.fm (dw) Date: Thu, 15 Jan 2015 06:07:28 -0800 Subject: [Tutor] Learning python scripts for practical linux activities. Message-ID: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> Hello, I'm new the the group and new to programming in Python. I would like to find a source, book etc.... of Python learning projects. Projects that are useful for standard Linux activities like bulk renaming files, managing repository packages. Maybe python scripts that incorporate "LAME" for modifying audio files. Anything of that nature. As I learn Python, I would like to create Python utilities. I'm hoping there is some learning material that might lead me in that direction. Sincere thanks d -- Bw_dw at fastmail.net From ch.de2.2309 at gmail.com Thu Jan 15 12:41:12 2015 From: ch.de2.2309 at gmail.com (Whees Northbee) Date: Thu, 15 Jan 2015 18:41:12 +0700 Subject: [Tutor] How to edit value of second column row i-th array in numpy? Message-ID: If I have array a=[[60,70,1],[43,54,2],[87,67,3],[90,89,4],[12,4,5]] where [x,y,id] and I want to find if x=87 and y=67, and find which row is it,and I need to edit the id column with new value.. I can search in first column using: if (x in a[:,0]): print('yes') how I can know index row so I can match if y same value with second column? And I search in numpy array document there is no function about edit, so how I can edit the value the third column/id column if I know which row? From alan.gauld at btinternet.com Thu Jan 15 17:53:00 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 15 Jan 2015 16:53:00 +0000 Subject: [Tutor] Learning python scripts for practical linux activities. In-Reply-To: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> References: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> Message-ID: On 15/01/15 14:07, dw wrote: > I would like to find a source, book etc.... of Python learning projects. > Projects that are useful for standard Linux activities like bulk > renaming files, managing repository packages. > Maybe python scripts that incorporate "LAME" for modifying audio files. > Anything of that nature. That's kind of the point of my new book "Python Projects" If you go to Amazon the free preview covers the first chapter (intro to Python) plus a section of chapter 1 which includes interacting with the OS. Other topics included are reading different file formats, Database access(dbm,shelve,SQL) UI design(CLI, argparse,cmd and GUI with Tkinter) Web dev (with Flask) and testing/debugging. Its targeted at those who have done a basic intro to python and want to go further and start their own projects. Have a look at the preview it might suit you. Sorry for the shameless plug but it does look like a fit. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From emile at fenx.com Thu Jan 15 19:15:59 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 15 Jan 2015 10:15:59 -0800 Subject: [Tutor] Learning python scripts for practical linux activities. In-Reply-To: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> References: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> Message-ID: On 1/15/2015 6:07 AM, dw wrote: > Hello, > I'm new the the group and new to programming in Python. > I would like to find a source, book etc.... of Python learning projects. > Projects that are useful for standard Linux activities like bulk > renaming files, managing repository packages. > Maybe python scripts that incorporate "LAME" for modifying audio files. > Anything of that nature. > As I learn Python, I would like to create Python utilities. > I'm hoping there is some learning material that might lead me in that > direction. > Sincere thanks > d > Check out http://it-ebooks.info/book/172/ Emile From __peter__ at web.de Thu Jan 15 19:33:35 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 15 Jan 2015 19:33:35 +0100 Subject: [Tutor] How to edit value of second column row i-th array in numpy? References: Message-ID: Whees Northbee wrote: > If I have array a=[[60,70,1],[43,54,2],[87,67,3],[90,89,4],[12,4,5]] where > [x,y,id] and I want to find if x=87 and y=67, and find which row is it,and > I need to edit the id column with new value.. > > I can search in first column using: > if (x in a[:,0]): > print('yes') > > how I can know index row so I can match if y same value with second > column? I needed some google hand-holding for this, so no warranties: >>> import numpy as np >>> a = np.array([[60,70,1],[43,54,2],[87,67,3],[87,89,4],[12,4,5]]) >>> a[:,:2] == [87,67] array([[False, False], [False, False], [ True, True], [ True, False], [False, False]], dtype=bool) >>> (a[:,:2] == [87,67]).all(axis=1) array([False, False, True, False, False], dtype=bool) >>> np.where((a[:,:2] == [87,67]).all(axis=1)) (array([2]),) > And I search in numpy array document there is no function about > edit, so how I can edit the value the third column/id column if I know > which row? Easy: >>> a[2,2] = 123456 >>> a array([[ 60, 70, 1], [ 43, 54, 2], [ 87, 67, 123456], [ 87, 89, 4], [ 12, 4, 5]]) From davidheiserca at gmail.com Thu Jan 15 20:25:38 2015 From: davidheiserca at gmail.com (David Heiser) Date: Thu, 15 Jan 2015 11:25:38 -0800 Subject: [Tutor] Alan's book - was "Learning python scripts for practical linux activities." In-Reply-To: References: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com> Message-ID: <54B81432.7010408@gmail.com> Thanks for the Shameless Plug, Alan. I went to Amazon, scanned through your book, and learned some things about "sets" that will help me in my job. Bought the Kindle version. Great stuff. On 1/15/2015 8:53 AM, Alan Gauld wrote: > On 15/01/15 14:07, dw wrote: > >> I would like to find a source, book etc.... of Python learning projects. >> Projects that are useful for standard Linux activities like bulk >> renaming files, managing repository packages. >> Maybe python scripts that incorporate "LAME" for modifying audio files. >> Anything of that nature. > > That's kind of the point of my new book "Python Projects" > If you go to Amazon the free preview covers the first chapter > (intro to Python) plus a section of chapter 1 which includes > interacting with the OS. > > Other topics included are reading different file formats, Database > access(dbm,shelve,SQL) UI design(CLI, argparse,cmd and GUI with > Tkinter) Web dev (with Flask) and testing/debugging. > > Its targeted at those who have done a basic intro to python and > want to go further and start their own projects. > > Have a look at the preview it might suit you. > > Sorry for the shameless plug but it does look like a fit. From paul at labergedaylight.com Thu Jan 15 19:42:35 2015 From: paul at labergedaylight.com (Paul LaBerge) Date: Thu, 15 Jan 2015 10:42:35 -0800 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: References: Message-ID: Steven, Danny, and Ben, Thanks for the help identifying the source of the crash and how to read the traceback, exception, paths, and search for errors. Very helpful since I?m quite new to Python programming. I'll send details to opendaq, and ask on the wxpython forum to see if they know what causes this. The GUI is open source from the opendaq folks, available on PYPI, and as surmised is tied to their commercial data acquisition hardware. They?re good about responding, so expect they?ll fix it. > I don't know whether this indicates corruption in the library which > will be fixed by reinstalling, a bug in the library, or just a bug in > your own code. I tried reinstalling wxpython but the error persisted. Thanks for places to look. > (Also, because I happen to know that the wxPython GUI is written in C++ > so any C++ errors are from it, not the Python interpreter.) Have you worked on easy_daq or did you download the GUI ? Cheers, Paul From steve at pearwood.info Fri Jan 16 00:43:52 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 16 Jan 2015 10:43:52 +1100 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: References: Message-ID: <20150115234351.GC18556@ando.pearwood.info> On Thu, Jan 15, 2015 at 10:42:35AM -0800, Paul LaBerge wrote: > > (Also, because I happen to know that the wxPython GUI is written in C++ > > so any C++ errors are from it, not the Python interpreter.) > > Have you worked on easy_daq or did you download the GUI ? Neither. I just know that wxPython is a Python wrapper around a C++ GUI toolkit, wxWidgets. Never used it though. -- Steve From paul at labergedaylight.com Fri Jan 16 00:52:36 2015 From: paul at labergedaylight.com (Paul LaBerge) Date: Thu, 15 Jan 2015 15:52:36 -0800 Subject: [Tutor] PyDeadObjectError: MainFrame deleted In-Reply-To: <20150115234351.GC18556@ando.pearwood.info> References: <20150115234351.GC18556@ando.pearwood.info> Message-ID: <9FBBBF57-AD2A-4B60-87E6-CF9743F8F165@labergedaylight.com> Good to know. Thanks again for the help. Paul ____________________________________________________________________________________ > On Jan 15, 2015, at 3:43 PM, Steven D'Aprano wrote: > > On Thu, Jan 15, 2015 at 10:42:35AM -0800, Paul LaBerge wrote: > >>> (Also, because I happen to know that the wxPython GUI is written in C++ >>> so any C++ errors are from it, not the Python interpreter.) >> >> Have you worked on easy_daq or did you download the GUI ? > > Neither. I just know that wxPython is a Python wrapper around a C++ > GUI toolkit, wxWidgets. Never used it though. > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From cltalk at gmail.com Fri Jan 16 06:02:27 2015 From: cltalk at gmail.com (CL Talk) Date: Fri, 16 Jan 2015 00:02:27 -0500 Subject: [Tutor] Timing a python program Message-ID: Hello - I have a python program that reads data from data files and does manipulation on the data and writes back to output files. I am developing this program on a macbook with python 2.7.6. This program takes close to 10 minutes on my machine to run. But, the issue is that it is not take the same amount of time on almost similar data files. I am trying to see how I can time the whole program as well as various functions that are part of the program. Say, that I have 5 functions in this program how can i time the whole program and time each individual function for every run? Thanks in advance for your help and ideas. From ben+python at benfinney.id.au Fri Jan 16 09:51:39 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 16 Jan 2015 19:51:39 +1100 Subject: [Tutor] Timing a python program References: Message-ID: <85fvbbt8f8.fsf@benfinney.id.au> CL Talk writes: > I am trying to see how I can time the whole program as well as various > functions that are part of the program. The term for this dynamic timing introspection of parts of the system is ?program profiling?; you are seeking a ?profiler? . Python has profilers installed by default in the standard library . See that documentation for how to profile your program. -- \ ?It is ? incumbent upon us to recognize that it is | `\ inappropriate for religion to play any role in issues of state | _o__) [of] a modern democracy.? ?Lawrence M. Krauss, 2012-05-28 | Ben Finney From alan.gauld at btinternet.com Fri Jan 16 09:52:42 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 16 Jan 2015 08:52:42 +0000 Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: On 16/01/15 05:02, CL Talk wrote: > I am trying to see how I can time the whole program as well as various > functions that are part of the program. > That's called profiling and there is a Python profiler. Here's the official doc page https://docs.python.org/2/library/profile.html And here's the 'module of the week' description of using it: http://pymotw.com/2/profile/ You might also find the timeit module handy. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Fri Jan 16 10:20:59 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 16 Jan 2015 09:20:59 +0000 Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: On 16/01/2015 08:52, Alan Gauld wrote: > On 16/01/15 05:02, CL Talk wrote: > >> I am trying to see how I can time the whole program as well as various >> functions that are part of the program. >> > > That's called profiling and there is a Python profiler. > > Here's the official doc page > > https://docs.python.org/2/library/profile.html > > And here's the 'module of the week' description of using it: > > http://pymotw.com/2/profile/ > > > You might also find the timeit module handy. > > hth For non Luddites https://docs.python.org/3/library/profile.html :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From wolfrage8765 at gmail.com Fri Jan 16 17:58:44 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Fri, 16 Jan 2015 11:58:44 -0500 Subject: [Tutor] Improving My Simple Game Code for Speed, Memory and Learning In-Reply-To: References: <549B318A.8030909@gmail.com> <54A2F355.9050607@gmail.com> <20141231235736.GH24472@ando.pearwood.info> <54A62312.2090905@gmail.com> <20150102072156.GF15262@ando.pearwood.info> <54A6C938.1010709@gmail.com> <54A6D07D.4090405@davea.name> <54A71D2B.8070406@gmail.com> <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com> Message-ID: <54B94344.1070403@gmail.com> On 01/12/2015 04:47 PM, Mark Lawrence wrote: > > I haven't looked carefully at your code but there's always a smell in > Python when you see structure[x][y]. Can you change the grid so you > always write something like:- > > for row in grid: > for cell in row: > process(cell) > > I say this as I'm all for short term pain, long term gain, especially > when it's guaranteed to eliminate "list index out of range" errors. > Revisiting this, I think I will write a function specifically to perform look-ups, kind of like your process() function. My purpose is going to be to prevent out of bounds look-ups. Although none of my posted code has had potential for this so far, I am writing more code to help play the game and one of the things I am needing now is to look at the neighbours of a selected node. This look-up can provide me two errors, one is the index out of range the and the more subtle error is going backwards in the list and giving me the end of the list which is not a valid neighbour. I will also use this look-up throughout the rest of my code where possible. Thank you Mark. From alan.gauld at btinternet.com Fri Jan 16 19:34:16 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 16 Jan 2015 18:34:16 +0000 Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: On 16/01/15 09:20, Mark Lawrence wrote: >> https://docs.python.org/2/library/profile.html >> > For non Luddites https://docs.python.org/3/library/profile.html :) Yeah, but the OP said it was for 2.7.6 on a Mac... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From bw_dw at fastmail.net Fri Jan 16 17:18:52 2015 From: bw_dw at fastmail.net (bw_dw at fastmail.net) Date: Fri, 16 Jan 2015 08:18:52 -0800 Subject: [Tutor] Tutor Digest, Vol 131, Issue 38 In-Reply-To: References: Message-ID: <1421425132.1744466.214814273.13EE5AFF@webmail.messagingengine.com> > Hello, > I'm new the the group and new to programming in Python. > Snipped.......... > Sincere thanks > d > From: Emile van Sebille > Check out http://it-ebooks.info/book/172/ > Emile From bw_dw at fastmail.net Fri Jan 16 17:19:34 2015 From: bw_dw at fastmail.net (bw_dw at fastmail.net) Date: Fri, 16 Jan 2015 08:19:34 -0800 Subject: [Tutor] Tutor Digest, Vol 131, Issue 38 In-Reply-To: <1421425132.1744466.214814273.13EE5AFF@webmail.messagingengine.com> References: <1421425132.1744466.214814273.13EE5AFF@webmail.messagingengine.com> Message-ID: <1421425174.1744624.214815533.2CBEA54D@webmail.messagingengine.com> THANKS EMILE!!! I downloaded the e-book and am having fun with it!! Much appreciate :-] > > Hello, > > I'm new the the group and new to programming in Python. > > Snipped.......... > > Sincere thanks > > d > > > From: Emile van Sebille > > Check out http://it-ebooks.info/book/172/ > > Emile From fomcl at yahoo.com Fri Jan 16 21:00:53 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 16 Jan 2015 12:00:53 -0800 Subject: [Tutor] Timing a python program Message-ID: <1421438453.96584.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> ---------------------------- On Fri, Jan 16, 2015 7:34 PM CET Alan Gauld wrote: >On 16/01/15 09:20, Mark Lawrence wrote: > >> https://docs.python.org/2/library/profile.html >> >> For non Luddites https://docs.python.org/3/library/profile.html :) > > >Yeah, but the OP said it was for 2.7.6 on a Mac python -m cProfile myscript.py python -m timeit '' From dyoo at hashcollision.org Fri Jan 16 21:33:56 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 16 Jan 2015 12:33:56 -0800 Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: On Thu, Jan 15, 2015 at 9:02 PM, CL Talk wrote: > Hello - I have a python program that reads data from data files and > does manipulation on the data and writes back to output files. I am > developing this program on a macbook with python 2.7.6. > > This program takes close to 10 minutes on my machine to run. But, the > issue is that it is not take the same amount of time on almost similar > data files. > > I am trying to see how I can time the whole program as well as various > functions that are part of the program. > > Say, that I have 5 functions in this program how can i time the whole > program and time each individual function for every run? The use of the profiler, as the others have discussed, is the right approach here. It's hard to say what's really going on without good timing data, and the profiler should help. Once you get that data, please feel free to share it on the mailing list if you can; folks here can help analyze what you're seeing too. Also, please put your source code somewhere for folks to inspect. Finally, if you can say how large your input and output are, that would also be helpful. If we're talking about megabytes, then since you're seeing minutes of runtime, I'd expect that the algorithms used are prime culprits, and good targets for chasing for optimizations. But if we're talking about terabytes, maybe your program is fine, and you just have a lot of data that needs chugging through. :P Good luck! From siya360 at gmail.com Sat Jan 17 00:39:06 2015 From: siya360 at gmail.com (Siya 360) Date: Sat, 17 Jan 2015 01:39:06 +0200 Subject: [Tutor] menu based programs Message-ID: Hi, Am still learning Python, and i have been tasked with writing a used menu, where once session is initialised by user inputing a used code e.g. *123#, it displays menu to user with option i want to learn how to write code to interact with the user, in a sequence where if option 1, then display a, if 2 then display b, if 3 display c, if 4 display exit, if 1 selected, leads to option a, which in turn has it own options please assist? kind regards, Siya From alan.gauld at btinternet.com Sat Jan 17 03:00:28 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 17 Jan 2015 02:00:28 +0000 Subject: [Tutor] menu based programs In-Reply-To: References: Message-ID: On 16/01/15 23:39, Siya 360 wrote: > i want to learn how to write code to interact with the user, > in a sequence where > if option 1, then display a, > if 2 then display b, > if 3 display c, > if 4 display exit, > if 1 selected, leads to option a, which in turn has it own options You don't say how these menus are presented. One option is the cmd module which has a lot of built in features such as context sensitive help screens. But it is similar in style ton the Python help() command which may not be what you want. Simple text based menus are just built using print statements (triple quoted multi-line strings often help a lot) Here is a very simple example modelled on your description ##################### def readMenu(menu): while not (1<= choice <= len(menu) ): for index, item in enumerate(menu,start=1): print (index, item) choice = input("\nchoose an item: ") return choice-1 def display(choice): print( 'ABC'[choice] ) menu = ['display A','display B', display C', 'exit'] while True: choice = readMenu(menu) if choice == 3: break else: display(choice) ######################## You can use a table driven approach with a data structure to link menu choices to screens. But without knowing what you want the application to look like it's hard to give solid advise And if you want a GUI then it's a whole new ball game... hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cltalk at gmail.com Sat Jan 17 04:04:30 2015 From: cltalk at gmail.com (CL Talk) Date: Fri, 16 Jan 2015 22:04:30 -0500 Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: Thanks to all the responses. I have started looking at the documentation and will be implementing it. Thanks for the direction. I only have megabytes of data files. I think that the program can be optimized and am hoping that with the profiler I will be able to get some insight. Thanks again. On Fri, Jan 16, 2015 at 3:33 PM, Danny Yoo wrote: > On Thu, Jan 15, 2015 at 9:02 PM, CL Talk wrote: >> Hello - I have a python program that reads data from data files and >> does manipulation on the data and writes back to output files. I am >> developing this program on a macbook with python 2.7.6. >> >> This program takes close to 10 minutes on my machine to run. But, the >> issue is that it is not take the same amount of time on almost similar >> data files. >> >> I am trying to see how I can time the whole program as well as various >> functions that are part of the program. >> >> Say, that I have 5 functions in this program how can i time the whole >> program and time each individual function for every run? > > > The use of the profiler, as the others have discussed, is the right > approach here. It's hard to say what's really going on without good > timing data, and the profiler should help. > > Once you get that data, please feel free to share it on the mailing > list if you can; folks here can help analyze what you're seeing too. > Also, please put your source code somewhere for folks to inspect. > > Finally, if you can say how large your input and output are, that > would also be helpful. If we're talking about megabytes, then since > you're seeing minutes of runtime, I'd expect that the algorithms used > are prime culprits, and good targets for chasing for optimizations. > > But if we're talking about terabytes, maybe your program is fine, and > you just have a lot of data that needs chugging through. :P > > > Good luck! From alan.gauld at btinternet.com Sat Jan 17 10:06:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 17 Jan 2015 09:06:39 +0000 Subject: [Tutor] menu based programs In-Reply-To: References: Message-ID: On 17/01/15 02:00, Alan Gauld wrote: > Here is a very simple example modelled on your description > > ##################### > def readMenu(menu): > while not (1<= choice <= len(menu) ): > for index, item in enumerate(menu,start=1): > print (index, item) > choice = input("\nchoose an item: ") > return choice-1 Oops, a couple of bugs in there, here is a working version def readMenu(menu): choice = 0 while not (1<= choice <= len(menu) ): for index, item in enumerate(menu,start=1): print (index, item) choice = int(input("\nchoose an item: ")) return choice-1 -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From fomcl at yahoo.com Sat Jan 17 12:45:44 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Sat, 17 Jan 2015 11:45:44 +0000 (UTC) Subject: [Tutor] Timing a python program In-Reply-To: References: Message-ID: <738103132.586307.1421495144812.JavaMail.yahoo@jws10751.mail.gq1.yahoo.com> ----- Original Message ----- > From: CL Talk > To: Danny Yoo > Cc: Python Tutor Mailing List > Sent: Saturday, January 17, 2015 4:04 AM > Subject: Re: [Tutor] Timing a python program > >T hanks to all the responses. I have started looking at the > documentation and will be implementing it. Thanks for the direction. > > I only have megabytes of data files. I think that the program can be > optimized and am hoping that with the profiler I will be able to get > some insight. Btw, if you use Ipython, things get even easier: %run -t -N3 /path/to/script.py # run the program 3 times, show how much time it took %run -p /path/to/script.py # run cProfile %timeit for example: In [1]: %timeit [i ** 2 for i in range(10)] 1000000 loops, best of 3: 1.02 ?s per loop In [2]: %timeit (i ** 2 for i in range(10)) 1000000 loops, best of 3: 535 ns per loop while we are at it, using the PDB debugger is also very easy: %run -d -b10 /path/to/script.py # run pdb, with a breakpoint on line10 %run -d -b myotherfile.py:20 script.py # run program script.py that uses myotherfile.py, and put a breakpoint in line 20 of myotherfile.py From colin.ross.dal at gmail.com Sun Jan 18 01:49:30 2015 From: colin.ross.dal at gmail.com (Colin Ross) Date: Sat, 17 Jan 2015 20:49:30 -0400 Subject: [Tutor] selecting data from a list Message-ID: Hi all, I am attempting to isolate a certain subset of data from the list "a" and then turn it into any array. To do so, I have written the following code: import numpy as np a = [0,1,2,3,4,5,6,7,8,9,10] b = [10,20,30,40,50,60,70,80,90,100,110] for a in range(len(a)): if a > 5: print a a_1 = np.array(a) print a_1 The output is as follows: 6 7 8 9 10 10 As you can see, when I attempt to turn the list of numbers 6 through 10 into an array I am left with it only printing out 10... The desired result is: [6,7,8,9,10} Any guidance would be greatly appreciated. Thank you. Colin From steve at pearwood.info Sun Jan 18 02:25:19 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 18 Jan 2015 12:25:19 +1100 Subject: [Tutor] selecting data from a list In-Reply-To: References: Message-ID: <20150118012519.GM18556@ando.pearwood.info> Hi Colin, and welcome. My responses are interleaved with your comments below. On Sat, Jan 17, 2015 at 08:49:30PM -0400, Colin Ross wrote: > Hi all, > > I am attempting to isolate a certain subset of data from the list "a" and > then turn it into any array. To do so, I have written the following code: > > import numpy as np > > a = [0,1,2,3,4,5,6,7,8,9,10] > b = [10,20,30,40,50,60,70,80,90,100,110] Your code below doesn't use either the list a or b. You create these lists, then (almost) immediately throw away "a" and don't use "b" at all. This makes is hard to tell precisely what you are attempting to do, since your description of what you want to do and what your code actually does are so very different, I'm having to guess what I imagine you probably want. > for a in range(len(a)): > if a > 5: > print a That's a syntax error. Indentation is significant when programming in Python, so be careful to not lose it. That should be: for a in range(len(a)): if a > 5: print a except it shouldn't because that is useless. All you are doing is printing out the matching numbers one at a time, then forgetting all about them. In this case, we can write out what the Python interpreter will do, step by step: * get the length of list "a" (in this case, 11) * generate a new list range(11) --> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] * re-assign the name "a" to the first item of this new list, 0 * which then allows the original list to be deleted and memory reclaimed * check whether "a" is larger than 5 * since it isn't, continue with a = 1, a = 2, a = 3, a = 4, a = 5 * at last we get to a = 6 * which is larger than 5, so print 6 * continue with a = 7 (which is printed), a = 8, etc. * finally the loop ends * which leaves us with list "b" untouched and never used * and "a" is set to 10 I'm going to guess what you intend instead: * starting with list "a" = [0, 1, 2, 3, ... 9, 10] * check each value to see if it is larger than 5 * if so, you want to REMEMBER THAT VALUE for later * and collect all those values. Here is the long way of doing that: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] collector = [] # will hold the values we collect for later for value in a: if value > 5: collector.append(value) # remember it for later print "Found", value print collector # optional: convert from a Python list to a numpy array import numpy as np a_1 = np.array(collector) print a_1 Note that I make sure to avoid using the same name for the list "a" and the individual items inside "a". Here's a shorter way to do the same, using a "list comprehension": a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] collector = [value for value in a if value > 5] a_1 = np.array(collector) print a_1 And here's an even shorter way: a_1 = np.array(range(6, 11)) print a_1 Can you work out what each of those three things are doing? Feel free to ask for help. -- Steven From alan.gauld at btinternet.com Sun Jan 18 02:37:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Jan 2015 01:37:35 +0000 Subject: [Tutor] selecting data from a list In-Reply-To: References: Message-ID: On 18/01/15 00:49, Colin Ross wrote: > a = [0,1,2,3,4,5,6,7,8,9,10] > b = [10,20,30,40,50,60,70,80,90,100,110] > > for a in range(len(a)): > if a > 5: > print a You have named your iteration cvariable the same as the list you are iterating over. Don't ever do this! In effect you have made your list invisible. Python just sees: for a in range(11): and a becomes each integer in turn. At the end of the loop a is the number 10. > a_1 = np.array(a) > print a_1 So now you try to create an array using just the number 10. > The desired result is: [6,7,8,9,10} You could just rename the iteration variable: for x in range(len(a)): if x > 5: print x You would be better using a list comprehension: a_1 = [x for x in range(len(a)) if x > 5] print a_1 or to create the array directly: a_1 = array(x for x in range(len(a)) if x > 5) should work. BTW I assume you will eventually want the contents of the original list rather than the indexes? If so it woyuld look like: a_1 = array(a[x] for x in range(len(a)) if a[x] > 5) or, working on the list directly, and more generally: a_1 = array(item for item in a if test(item) ) where test() is any filter function you care you write. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sun Jan 18 04:38:43 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 18 Jan 2015 04:38:43 +0100 Subject: [Tutor] selecting data from a list References: Message-ID: Colin Ross wrote: > Hi all, > > I am attempting to isolate a certain subset of data from the list "a" and > then turn it into any array. To do so, I have written the following code: > > import numpy as np > > a = [0,1,2,3,4,5,6,7,8,9,10] > b = [10,20,30,40,50,60,70,80,90,100,110] > > for a in range(len(a)): > if a > 5: > print a > > a_1 = np.array(a) > > print a_1 > > The output is as follows: > > 6 > 7 > 8 > 9 > 10 > 10 > > > As you can see, when I attempt to turn the list of numbers 6 through 10 > into an array I am left with it only printing out 10... > > The desired result is: [6,7,8,9,10} > > Any guidance would be greatly appreciated. I have a hunch that you may be looking for slicing: >>> a = [0,1,2,3,4,5,6,7,8,9,10] >>> b = [10,20,30,40,50,60,70,80,90,100,110] >>> a[6:] [6, 7, 8, 9, 10] >>> b[3:] [40, 50, 60, 70, 80, 90, 100, 110] If I'm right you should really work through a tutorial. From suhailmahmood at ymail.com Sun Jan 18 13:29:23 2015 From: suhailmahmood at ymail.com (Suhail Mahmood) Date: Sun, 18 Jan 2015 12:29:23 +0000 (UTC) Subject: [Tutor] Is this the right place for my pyqt questions? Message-ID: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> Hi, everyone Can I get my questions on python, and maybe some frameworks of python like pyqt, answered here? Sorry but I am not sure of it if this is right place for questions on something like pyqt as that is what I need right now. If not can you please refer to somewhere where I can get my answers right away? Thanks. From alan.gauld at btinternet.com Sun Jan 18 13:59:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Jan 2015 12:59:56 +0000 Subject: [Tutor] Is this the right place for my pyqt questions? In-Reply-To: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> Message-ID: On 18/01/15 12:29, Suhail Mahmood wrote: > Hi, everyone > Can I get my questions on python, and maybe some frameworks > of python like pyqt, answered here? This group is primarily for beginners to Python, as such, questions about using the Python language, general programming principles and the Python standard library are positively encouraged. Questions about libraries other than the standard one will be pot luck whether anyone can answer and, for deeper issues, you are usually better going to the library support forum. For PyQt this page describes the options: http://www.riverbankcomputing.com/mailman/listinfo/pyqt The PySide (almost a clone of PyQt) also has a web page with lots of helpful information. Likewise questions about the internals of Python or suggested improvements are better addressed on the main Python mailing list. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From s.shall at virginmedia.com Sun Jan 18 14:20:38 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Sun, 18 Jan 2015 13:20:38 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> Message-ID: <54BBB326.5010203@virginmedia.com> I am a beginner and I have a question of syntax. I am just learning to use list comprehension, which oc course, I find very helpful indeed. However, I am stuck with a specific problem of how to incorporate an else in a list comp-rehension. I cannot do it. The following snippet of code does what I need. But, perhaps I am solving this math error problem incorrectly. The problem is I am occasionally getting exactly zeros when I need to obtain the logarithm of the number. for i in range(len(cap)): if cap[i] == 0.0: tmp = math.log(1.0) lncap.append(tmp) else: lncap.append(math.log(cap[i])) I have set mu options to plain text. -- Sydney From s.shall at virginmedia.com Sun Jan 18 14:37:47 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Sun, 18 Jan 2015 13:37:47 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: <54BBB326.5010203@virginmedia.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> Message-ID: <54BBB72B.7080100@virginmedia.com> On 18/01/2015 13:20, Sydney Shall wrote: > I am a beginner and I have a question of syntax. > > I am just learning to use list comprehension, which oc course, I find > very helpful indeed. > > However, I am stuck with a specific problem of how to incorporate an > else in a list comp-rehension. I cannot do it. > > The following snippet of code does what I need. But, perhaps I am > solving this math error problem incorrectly. > The problem is I am occasionally getting exactly zeros when I need to > obtain the logarithm of the number. > > for i in range(len(cap)): > if cap[i] == 0.0: > tmp = math.log(1.0) > lncap.append(tmp) > else: > lncap.append(math.log(cap[i])) > > I have set mu options to plain text. I apoligise. I should have added: MAC OS OSX 10.9.5 python 2.7.6 (Enthought) -- Sydney From pasokan at talentsprint.com Sun Jan 18 14:41:10 2015 From: pasokan at talentsprint.com (Asokan Pichai) Date: Sun, 18 Jan 2015 19:11:10 +0530 Subject: [Tutor] list comprehension with else In-Reply-To: <54BBB326.5010203@virginmedia.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> Message-ID: On Sun, Jan 18, 2015 at 6:50 PM, Sydney Shall wrote: > I am a beginner and I have a question of syntax. > Welcome! > > I am just learning to use list comprehension, which oc course, I find very > helpful indeed. > > However, I am stuck with a specific problem of how to incorporate an else > in a list comp-rehension. I cannot do it. > > The following snippet of code does what I need. But, perhaps I am solving > this math error problem incorrectly. > The problem is I am occasionally getting exactly zeros when I need to > obtain the logarithm of the number. > > for i in range(len(cap)): > Using a for loop like this is generally a poor idea. for aCap in cap: is the more pythonic way. And also will help you translate to a list comprehension easily > if cap[i] == 0.0: > tmp = math.log(1.0) > lncap.append(tmp) > Possibly lncap.append(math.log(1.0)) or even lncap.append(0) is simpler > else: > lncap.append(math.log(cap[i])) > Having said that above your present code, let me try to explain the thought process behind constructing the list comprehension for your purpose. It is possible that what you need is not an else in the list comprehension lncap = [ f(aCap) for aCap in cap] will be the starting point; where f() will need to provide either math.log(aCap) or 0 as we saw earlier. You can actually write an auxiliary function f that does just that; like say def f(p): if p == 0.0: return 0.0 return math.log(p) Or write the list comprehension as: lncap = [ (math.log(aCap) if aCap > 0 else 0.0) for aCap in cap] Hope this helps From alan.gauld at btinternet.com Sun Jan 18 16:49:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Jan 2015 15:49:49 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: <54BBB326.5010203@virginmedia.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> Message-ID: On 18/01/15 13:20, Sydney Shall wrote: > The problem is I am occasionally getting exactly zeros when I need to > obtain the logarithm of the number. > > for i in range(len(cap)): Its usually better to iterate over the collection rather than use indexing: for item in cap: > if cap[i] == 0.0: Its usually a bad idea to compare floats for equality. It's better to define a small limit value and check if they are within the range. like this e = 0.0000000001 # or whatever if val-e <= cap[[i] <= val+e: do something. In your case where you test against zero it simplifies to if -e < cap[i] < e: do something > tmp = math.log(1.0) log(1) is a constant (0) so you might as well just say > lncap.append(tmp) lncap.append(0.0) > else: > lncap.append(math.log(cap[i])) But won't this cause you to have really dodgy results? How do you distinguish genuine log(1) values from your pseudo log(0) values? Or does it not matter? > I have set mu options to plain text. Thanks, always appreciated. While you can make comprehensions do what you want its not always a good idea. Sometimes its better to revert to explicit loops if the complexity of the comprehension gets too great. But in your case its fairly simple to use a conditional expression: lncap = [ 0.0 if (-e < item < e) else math.log(item) for item in cap] HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sun Jan 18 16:56:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Jan 2015 15:56:07 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: <54BBB326.5010203@virginmedia.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> Message-ID: On 18/01/15 13:20, Sydney Shall wrote: > I am a beginner and I have a question of syntax. Please don't hijack an existing thread. Simply changing the subject line is not enough. Always send a new mail to tutor at python.org to start a new discussion. Otherwise the new discussion gets interleaved with the old in the archoives and makes it messy to find in searches and for those using threaded mail/news readers. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From s.shall at virginmedia.com Sun Jan 18 17:43:42 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Sun, 18 Jan 2015 16:43:42 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> Message-ID: <54BBE2BE.3020601@virginmedia.com> On 18/01/2015 13:41, Asokan Pichai wrote: > > On Sun, Jan 18, 2015 at 6:50 PM, Sydney Shall > wrote: > > I am a beginner and I have a question of syntax. > > Welcome! > > > I am just learning to use list comprehension, which oc course, I > find very helpful indeed. > > However, I am stuck with a specific problem of how to incorporate an > else in a list comp-rehension. I cannot do it. > > The following snippet of code does what I need. But, perhaps I am > solving this math error problem incorrectly. > The problem is I am occasionally getting exactly zeros when I need > to obtain the logarithm of the number. > > for i in range(len(cap)): > > Using a for loop like this is generally a poor idea. > > for aCap in cap: > > is the more pythonic way. And also will help you translate to a list > comprehension easily > > if cap[i] == 0.0: > tmp = math.log(1.0) > lncap.append(tmp) > > Possibly lncap.append(math.log(1.0)) or even lncap.append(0) is simpler > > else: > lncap.append(math.log(cap[i])) > > > Having said that above your present code, let me try to explain the > thought process behind constructing the list comprehension for your > purpose. It is possible that what you need is not an else in the list > comprehension > > lncap = [ f(aCap) for aCap in cap] > > will be the starting point; where f() will need to provide either > math.log(aCap) or 0 as we saw earlier. > > You can actually write an auxiliary function f that does just that; like say > def f(p): > if p == 0.0: > return 0.0 > return math.log(p) > > Or write the list comprehension as: > > lncap = [ (math.log(aCap) if aCap > 0 else 0.0) for aCap in cap] > > Hope this helps Thanks. perfect. Thanks especialy for the explanation. -- Sydney From breamoreboy at yahoo.co.uk Sun Jan 18 18:42:38 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 18 Jan 2015 17:42:38 +0000 Subject: [Tutor] selecting data from a list In-Reply-To: References: Message-ID: On 18/01/2015 00:49, Colin Ross wrote: > Hi all, > > I am attempting to isolate a certain subset of data from the list "a" and > then turn it into any array. To do so, I have written the following code: > > import numpy as np > > a = [0,1,2,3,4,5,6,7,8,9,10] > b = [10,20,30,40,50,60,70,80,90,100,110] > > for a in range(len(a)): As others have already offered the usual sound advice I'll just say that using the above type of construct is usually wrong in Python. A useful tip is to make your container names plural, then process the singular name so lets have:- cars = ['Ford, 'Vauxhall', 'Land Rover', 'Jaguar'] for car in cars: doSomething(car) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From fomcl at yahoo.com Sun Jan 18 20:30:01 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Sun, 18 Jan 2015 19:30:01 +0000 (UTC) Subject: [Tutor] selecting data from a list In-Reply-To: References: Message-ID: <176793510.678441.1421609401732.JavaMail.yahoo@jws10735.mail.gq1.yahoo.com> ----- Original Message ----- > From: Peter Otten <__peter__ at web.de> > To: tutor at python.org > Cc: > Sent: Sunday, January 18, 2015 4:38 AM > Subject: Re: [Tutor] selecting data from a list > > Colin Ross wrote: > >> Hi all, >> >> I am attempting to isolate a certain subset of data from the list > "a" and >> then turn it into any array. To do so, I have written the following code: >> >> import numpy as np >> >> a = [0,1,2,3,4,5,6,7,8,9,10] >> b = [10,20,30,40,50,60,70,80,90,100,110] >> >> for a in range(len(a)): >> if a > 5: >> print a >> >> a_1 = np.array(a) >> >> print a_1 >> >> The output is as follows: >> >> 6 >> 7 >> 8 >> 9 >> 10 >> 10 >> >> >> As you can see, when I attempt to turn the list of numbers 6 through 10 >> into an array I am left with it only printing out 10... >> >> The desired result is: [6,7,8,9,10} >> >> Any guidance would be greatly appreciated. > > I have a hunch that you may be looking for slicing: > >>>> a = [0,1,2,3,4,5,6,7,8,9,10] >>>> b = [10,20,30,40,50,60,70,80,90,100,110] >>>> a[6:] > [6, 7, 8, 9, 10] >>>> b[3:] > [40, 50, 60, 70, 80, 90, 100, 110] > > If I'm right you should really work through a tutorial. If Peter is right about his hunch, then ignore the following. If not, then you could use a Boolean array to do the selection: >>> import numpy as np >>> arr = np.arange(11) >>> arr array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) >>> arr > 5 array([False, False, False, False, False, False, True, True, True, True, True], dtype=bool) >>> arr[arr > 5] array([ 6, 7, 8, 9, 10]) Regards, Albert-Jan From dyoo at hashcollision.org Sun Jan 18 23:20:55 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 18 Jan 2015 14:20:55 -0800 Subject: [Tutor] list comprehension with else In-Reply-To: <54BBE2BE.3020601@virginmedia.com> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> <54BBE2BE.3020601@virginmedia.com> Message-ID: Just to add, log(0) is mathematically undefined. https://en.m.wikipedia.org/wiki/Logarithm. So depending on the problem's context, it might be worth asking why log is being applied on this input. Is such input expected? Make sure the code isn't trying to correct for input that shouldn't be there in the first place. From steve at pearwood.info Mon Jan 19 01:55:53 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 19 Jan 2015 11:55:53 +1100 Subject: [Tutor] list comprehension with else In-Reply-To: References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> <54BBE2BE.3020601@virginmedia.com> Message-ID: <20150119005552.GR18556@ando.pearwood.info> On Sun, Jan 18, 2015 at 02:20:55PM -0800, Danny Yoo wrote: > Just to add, log(0) is mathematically undefined. > https://en.m.wikipedia.org/wiki/Logarithm. For the record, IEEE-754 specifies that log(0.0) should return -INF. That's what Decimal does: py> from decimal import Decimal py> Decimal(0).log10() Decimal('-Infinity') Alas, Python's math module only has partial support for the IEEE-754 standard. > So depending on the problem's context, it might be worth asking why log is > being applied on this input. Is such input expected? Make sure the code > isn't trying to correct for input that shouldn't be there in the first > place. Correct. Replacing too small values with 0.0 is the wrong solution. Using -INF is better, or a very large negative number. Otherwise, sticking 0 in the result is equivalent to replacing the negative values with 1. data = [0.5, 1.0, 0.0] # Good value, good value, bad value. # This is the wrong way: [0.0 if x == 0.0 else math.log(x) for x in data] => returns [-0.6931471805599453, 0.0, 0.0] That is mathematically equivalent to x = 0.0 being replaced with x = 1.0 before taking the log, and that makes no sense. -- Steve From jarod_v6 at libero.it Mon Jan 19 15:32:00 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Mon, 19 Jan 2015 15:32:00 +0100 (CET) Subject: [Tutor] How to use a function Message-ID: <1966991872.67441421677920502.JavaMail.httpd@webmail-07.iol.local> Dear All, I would like to understand how work this funcion: def parse_illumina_readset_file(illumina_readset_file): readsets = [] samples = [] log.info("Parse readset " + illumina_readset_file + " ...") readset_csv = csv.DictReader(open(illumina_readset_file, 'rb'), delimiter='\t') for line in readset_csv: sample_name = line['Sample'] sample_names = [sample.name for sample in samples] if sample_name in sample_names: # Sample already exists sample = samples[sample_names.index(sample_name)] else: # Create new sample sample = Sample(sample_name) samples.append(sample) # Create readset and add it to sample readset = IlluminaReadset(line['Readset'], line['RunType']) # Readset file paths are either absolute or relative to the readset file # Convert them to absolute paths for format in ("BAM", "FASTQ1", "FASTQ2"): if line.get(format, None): line[format] = os.path.expandvars(line[format]) if not os.path.isabs(line[format]): line[format] = os.path.dirname(os.path.abspath(os.path.expandvars(illumina_readset_file))) + os.sep + line[format] line[format] = os.path.normpath(line[format]) readset._bam = line.get('BAM', None) readset.fastq1 = line.get('FASTQ1', None) readset.fastq2 = line.get('FASTQ2', None) readset._library = line.get('Library', None) readset._run = line.get('Run', None) readset._lane = line.get('Lane', None) readset._adaptor1 = line.get('Adaptor1', None) readset._adaptor2 = line.get('Adaptor2', None) readset._quality_offset = int(line['QualityOffset']) if line.get('QualityOffset', None) else None readset._beds = line['BED'].split(";") if line.get('BED', None) else [] readsets.append(readset) sample.add_readset(readset) log.info(str(len(readsets)) + " readset" + ("s" if len(readsets) > 1 else "") + " parsed") log.info(str(len(samples)) + " sample" + ("s" if len(samples) > 1 else "") + " parsed\n") return readsets parser_illumina_readset_file("~/Desktop/file.csv") dir() I can't found the readsets list. Someone could please help me? thanks so much! From nik at naturalnet.de Mon Jan 19 15:54:38 2015 From: nik at naturalnet.de (Dominik George) Date: Mon, 19 Jan 2015 15:54:38 +0100 Subject: [Tutor] How to use a function In-Reply-To: <1966991872.67441421677920502.JavaMail.httpd@webmail-07.iol.local> References: <1966991872.67441421677920502.JavaMail.httpd@webmail-07.iol.local> Message-ID: <54BD1AAE.5040000@naturalnet.de> Hi, > parser_illumina_readset_file("~/Desktop/file.csv") > > dir() > > I can't found the readsets list. Someone could please help me? > thanks so much! Maybe: readsets = parser_illumina_readset_file("~/Desktop/file.csv") In your call, you discard the result, which, obviously, discards it. -nik From __peter__ at web.de Mon Jan 19 16:08:20 2015 From: __peter__ at web.de (Peter Otten) Date: Mon, 19 Jan 2015 16:08:20 +0100 Subject: [Tutor] How to use a function References: <1966991872.67441421677920502.JavaMail.httpd@webmail-07.iol.local> Message-ID: jarod_v6 at libero.it wrote: > Dear All, > I would like to understand how work this funcion: > > def parse_illumina_readset_file(illumina_readset_file): [snip code by someone who has yet to learn how to use dicts;)] > return readsets > > > parser_illumina_readset_file("~/Desktop/file.csv") > I can't found the readsets list. Someone could please help me? > thanks so much! It looks like the function returns that list, but you discard it. Instead bind it to a name: my_readset = parser_illumina_readset_file("~/Desktop/file.csv") print(my_readset) # print the list or do anything you like with it. Note: this is generally the right way to communicate with functions: have them return a value instead of modifying a global. Wrong (I assume that this is what you expected): a = [] def get_data(): a.append(1) # placeholder for more complex operations a.append(2) print(a) Right (this is what you got): def get_data(): a = [] a.append(1) # placeholder for more complex operations a.append(2) return a a = get_data() print(a) From s.shall at virginmedia.com Mon Jan 19 16:33:39 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Mon, 19 Jan 2015 15:33:39 +0000 Subject: [Tutor] list comprehension with else In-Reply-To: <20150119005552.GR18556@ando.pearwood.info> References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com> <54BBB326.5010203@virginmedia.com> <54BBE2BE.3020601@virginmedia.com> <20150119005552.GR18556@ando.pearwood.info> Message-ID: <54BD23D3.3010804@virginmedia.com> On 19/01/2015 00:55, Steven D'Aprano wrote: > On Sun, Jan 18, 2015 at 02:20:55PM -0800, Danny Yoo wrote: >> Just to add, log(0) is mathematically undefined. >> https://en.m.wikipedia.org/wiki/Logarithm. > > For the record, IEEE-754 specifies that log(0.0) should return -INF. > That's what Decimal does: > > py> from decimal import Decimal > py> Decimal(0).log10() > Decimal('-Infinity') > > > Alas, Python's math module only has partial support for the IEEE-754 > standard. > > >> So depending on the problem's context, it might be worth asking why log is >> being applied on this input. Is such input expected? Make sure the code >> isn't trying to correct for input that shouldn't be there in the first >> place. > > Correct. Replacing too small values with 0.0 is the wrong solution. > Using -INF is better, or a very large negative number. Otherwise, > sticking 0 in the result is equivalent to replacing the negative values > with 1. > > data = [0.5, 1.0, 0.0] # Good value, good value, bad value. > # This is the wrong way: > [0.0 if x == 0.0 else math.log(x) for x in data] > => returns [-0.6931471805599453, 0.0, 0.0] > > That is mathematically equivalent to x = 0.0 being replaced with x = 1.0 > before taking the log, and that makes no sense. > Thanks to both Steven and Danny. I will have to examine my logic again. Superficially, just setting the very occasional 0.0 value to 0 served, but it is clearly inappropriate. I will try and find the correct answer to my problem. I may return for advice, although it is not strictly python. Many thanks to you both. -- Sydney From fomcl at yahoo.com Mon Jan 19 21:27:45 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 19 Jan 2015 12:27:45 -0800 Subject: [Tutor] How to use a function Message-ID: <1421699265.66767.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> ---------------------------- On Mon, Jan 19, 2015 3:32 PM CET jarod_v6 at libero.it wrote: >Dear All, >I would like to understand how work this funcion: > >def parse_illumina_readset_file(illumina_readset_file): > readsets = [] > samples = [] > > log.info("Parse readset " + illumina_readset_file + " ...") > readset_csv = csv.DictReader(open(illumina_readset_file, 'rb'), delimiter='\t') > for line in readset_csv: > sample_name = line['Sample'] > sample_names = [sample.name for sample in samples] > if sample_name in sample_names: > # Sample already exists > sample = samples[sample_names.index(sample_name)] > else: > # Create new sample > sample = Sample(sample_name) > samples.append(sample) > > # Create readset and add it to sample > readset = IlluminaReadset(line['Readset'], line['RunType']) > > # Readset file paths are either absolute or relative to the readset file > # Convert them to absolute paths > for format in ("BAM", "FASTQ1", "FASTQ2"): > if line.get(format, None): > line[format] = os.path.expandvars(line[format]) > if not os.path.isabs(line[format]): > line[format] = os.path.dirname(os.path.abspath(os.path.expandvars(illumina_readset_file))) + os.sep + line[format] > line[format] = os.path.normpath(line[format]) > > readset._bam = line.get('BAM', None) > readset.fastq1 = line.get('FASTQ1', None) > readset.fastq2 = line.get('FASTQ2', None) > readset._library = line.get('Library', None) > readset._run = line.get('Run', None) > readset._lane = line.get('Lane', None) > readset._adaptor1 = line.get('Adaptor1', None) > readset._adaptor2 = line.get('Adaptor2', None) > readset._quality_offset = int(line['QualityOffset']) if line.get('QualityOffset', None) else None > readset._beds = line['BED'].split(";") if line.get('BED', None) else [] > > readsets.append(readset) > sample.add_readset(readset) > > log.info(str(len(readsets)) + " readset" + ("s" if len(readsets) > 1 else ") + " parsed") > log.info(str(len(samples)) + " sample" + ("s" if len(samples) > 1 else ") + " parsed\n") > return readsets > > >parser_illumina_readset_file("~/Desktop/file.csv") Too much code to read ony tiny phone screen, but I think you also need to wrap the filename in os.pat.expanduser to get tilde expansion. >dir() > >I can't found the readsets list. Someone could please help me? >thanks so much! > > > > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From jarod_v6 at libero.it Tue Jan 20 13:04:44 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Tue, 20 Jan 2015 13:04:44 +0100 (CET) Subject: [Tutor] Learning class code and function Message-ID: <1481721598.436201421755484302.JavaMail.httpd@webmail-07.iol.local> Dear all, I continue to try to understand some code: class Tutto(): def __init__(self): print "Ok" #@property def readsets(self,nome): self.nome = nome self._readsets = parse_tutto_readset_file(self.nome) return self._readsets Why If uncomment the decorator the code not work: p = Tutto() p.readsets("/home/mauro/Desktop/readset.csv") TypeError: readsets() takes exactly 2 arguments (1 given) thanks so muc? Could you suggest me some readings for better understand class structure? From alan.gauld at btinternet.com Tue Jan 20 16:44:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 20 Jan 2015 15:44:20 +0000 Subject: [Tutor] Learning class code and function In-Reply-To: <1481721598.436201421755484302.JavaMail.httpd@webmail-07.iol.local> References: <1481721598.436201421755484302.JavaMail.httpd@webmail-07.iol.local> Message-ID: On 20/01/15 12:04, jarod_v6 at libero.it wrote: > Dear all, I continue to try to understand some code: > class Tutto(): > > def __init__(self): > print "Ok" > #@property > def readsets(self,nome): > self.nome = nome > self._readsets = parse_tutto_readset_file(self.nome) > return self._readsets > > Why If uncomment the decorator the code not work: My understanding of the @property decorator is that it is only for defining read-only properties. In other wordss it expects you to use it like: t = Tutto() myvar = t.readsets notice no parens and no parameters. If you want to read the data from a file I'd suggest making the file part of the constructor and then use readsets as shown above: class Tutto: def __init__(self, filename): self.filename = filename print 'ok' @property def readsets(self): self._readsets = parse_tutto_readset_file(self.nome) return self._readsets p = Tutto("/home/mauro/Desktop/readset.csv") var = p.readsets I'd also question why you seem to have a function that has the class name in its name? Should that function not be a method of the class? Or is it part of some third party library perhaps? hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From fomcl at yahoo.com Tue Jan 20 21:23:30 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 20 Jan 2015 12:23:30 -0800 Subject: [Tutor] Learning class code and function Message-ID: <1421785410.75325.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> ----------------------------- On Tue, Jan 20, 2015 4:44 PM CET Alan Gauld wrote: >On 20/01/15 12:04, jarod_v6 at libero.it wrote: >> Dear all, I continue to try to understand some code: >> class Tutto(): I think you need a new-style class wit property. "Return a property attribute for new-style classes (classes that derive from object)." https://docs.python.org/2/library/functions.html#property I recently discovered that properties are implemented with descriptors: https://docs.python.org/2/howto/descriptor.html >> def __init__(self): >> print "Ok" >> #@property >> def readsets(self,nome): >> self.nome = nome >> self._readsets = parse_tutto_readset_file(self.nome) >> return self._readsets >> >> Why If uncomment the decorator the code not work: > >My understanding of the @property decorator is that it is only for defining read-only properties. In other wordss it expects you to use it like: > >t = Tutto() >myvar = t.readsets > >notice no parens and no parameters. > >If you want to read the data from a file I'd suggest making the file part of the constructor and then use readsets as shown above: > >class Tutto: > def __init__(self, filename): > self.filename = filename > print 'ok' > @property > def readsets(self): Might be useful to insert the following here (?) if hasattr(self, "_readsets"): return self._readsets > self._readsets = parse_tutto_readset_file(self.nome) > return self._readsets > >p = Tutto("/home/mauro/Desktop/readset.csv") >var = p.readsets > > >I'd also question why you seem to have a function that has the class name in its name? Should that function not be a method of the class? >Or is it part of some third party library perhaps? "tutto" means "everything"? Maybe FortyTwo would be a cool name. :-) >hth >-- Alan G >Author of the Learn to Program web site >http://www.alan-g.me.uk/ >http://www.amazon.com/author/alan_gauld >Follow my photo-blog on Flickr at: >http://www.flickr.com/photos/alangauldphotos > > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From ronykpa at yahoo.com Tue Jan 20 19:57:28 2015 From: ronykpa at yahoo.com (Ron Brinton) Date: Tue, 20 Jan 2015 18:57:28 +0000 (UTC) Subject: [Tutor] legacy help Message-ID: <1720391629.3785962.1421780248841.JavaMail.yahoo@jws106114.mail.bf1.yahoo.com> Help. We are upgrading our Win XP to Win7 (64bit) (intel) machines. We have a legacy Python program we need to still run. We were using ver 2.4 and we had a shortcut to C:\fileditor\main.py.I installed ver 2.7.9 "Windows x86-64 MSI installer". Is that what I wanted??? When I pick the shortcut, a black cmd window flashes and is gone. I can start the program from the Start Menu, so it's installed OK.? From fomcl at yahoo.com Tue Jan 20 23:13:53 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 20 Jan 2015 14:13:53 -0800 Subject: [Tutor] legacy help Message-ID: <1421792033.41859.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> ----------------------------- On Tue, Jan 20, 2015 7:57 PM CET Ron Brinton wrote: >Help. We are upgrading our Win XP to Win7 (64bit) (intel) machines. We have a legacy Python program we need to still run. We were using ver 2.4 and we had a shortcut to C:\fileditor\main.py.I installed ver 2.7.9 "Windows x86-64 MSI installer". Is that what I wanted??? >When I pick the shortcut, a black cmd window flashes and is gone. > >I can start the program from the Start Menu, so it's installed OK.? What do you see when you start cmd.exe ("DOS"), then you type: Python C:\fileditor\main.py >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From dyoo at hashcollision.org Wed Jan 21 00:25:21 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 20 Jan 2015 15:25:21 -0800 Subject: [Tutor] legacy help In-Reply-To: <1720391629.3785962.1421780248841.JavaMail.yahoo@jws106114.mail.bf1.yahoo.com> References: <1720391629.3785962.1421780248841.JavaMail.yahoo@jws106114.mail.bf1.yahoo.com> Message-ID: On Tue, Jan 20, 2015 at 10:57 AM, Ron Brinton wrote: > Help. We are upgrading our Win XP to Win7 (64bit) (intel) machines. We have a legacy Python program we need to still run. We were using ver 2.4 and we had a shortcut to C:\fileditor\main.py.I installed ver 2.7.9 "Windows x86-64 MSI installer". Is that what I wanted??? > When I pick the shortcut, a black cmd window flashes and is gone. > > I can start the program from the Start Menu, so it's installed OK. Hi Ron, You might want to ask this on a more general forum. The Tutor mailing list is for teaching beginners how to design and write Python programs. Installation and system administration issues are a little out of our scope. You might try Python-list: https://mail.python.org/mailman/listinfo/python-list From jarod_v6 at libero.it Wed Jan 21 10:10:07 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Wed, 21 Jan 2015 10:10:07 +0100 (CET) Subject: [Tutor] Learning class code and function (Alan Gauld) Message-ID: <1817391181.59101421831407479.JavaMail.defaultUser@defaultHost> >I'd also question why you seem to have a function that has the class >name in its name? Should that function not be a method of the class? >Or is it part of some third party library perhaps? Thanks for the clarification!! Could you please make an example of this two condition I still try to devolepe my skill on python study some good code. What is the best practice? From rdmoores at gmail.com Wed Jan 21 17:00:32 2015 From: rdmoores at gmail.com (Richard D. Moores) Date: Wed, 21 Jan 2015 08:00:32 -0800 Subject: [Tutor] How to paste text from from clipboard to command line? Message-ID: Thanks, Dick Moores Python 3.4.1 Win 7 From steve at pearwood.info Wed Jan 21 17:04:34 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 22 Jan 2015 03:04:34 +1100 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: References: Message-ID: <20150121160434.GC18556@ando.pearwood.info> On Wed, Jan 21, 2015 at 08:00:32AM -0800, Richard D. Moores wrote: > Thanks, Huh? Thanks for what? -- Steve From rdmoores at gmail.com Wed Jan 21 17:08:57 2015 From: rdmoores at gmail.com (Richard D. Moores) Date: Wed, 21 Jan 2015 08:08:57 -0800 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: <20150121160434.GC18556@ando.pearwood.info> References: <20150121160434.GC18556@ando.pearwood.info> Message-ID: On Wed, Jan 21, 2015 at 8:04 AM, Steven D'Aprano wrote: > Huh? Thanks for what? Please note the subject line. From steve at pearwood.info Wed Jan 21 17:10:38 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 22 Jan 2015 03:10:38 +1100 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: References: Message-ID: <20150121161038.GD18556@ando.pearwood.info> On Wed, Jan 21, 2015 at 08:00:32AM -0800, Richard D. Moores wrote: > Thanks, Ah, got it! Your question was in the subject line. "How to paste text from from clipboard to command line?" That depends on what command line you are using, and doesn't really have anything to do with Python. I'm not a Windows user, and it's been a long time since I've used a Windows command prompt, but I do know how to google so hopefully this will get you started: https://duckduckgo.com/?q=windows+command+line+paste If this is not what you mean, you will need to be more specific in your question. -- Steven From rdmoores at gmail.com Wed Jan 21 17:42:56 2015 From: rdmoores at gmail.com (Richard D. Moores) Date: Wed, 21 Jan 2015 08:42:56 -0800 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: <20150121161038.GD18556@ando.pearwood.info> References: <20150121161038.GD18556@ando.pearwood.info> Message-ID: On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano wrote: > https://duckduckgo.com/?q=windows+command+line+paste Ah, check QuickEdit Mode in Properties. Thanks very much. From breamoreboy at yahoo.co.uk Wed Jan 21 18:22:24 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 21 Jan 2015 17:22:24 +0000 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: References: <20150121161038.GD18556@ando.pearwood.info> Message-ID: On 21/01/2015 16:42, Richard D. Moores wrote: > On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano wrote: >> https://duckduckgo.com/?q=windows+command+line+paste > > Ah, check QuickEdit Mode in Properties. Thanks very much. Better yet download ConEmu and use CTRL-V -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Wed Jan 21 19:52:31 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 21 Jan 2015 18:52:31 +0000 Subject: [Tutor] How to paste text from from clipboard to command line? In-Reply-To: References: <20150121161038.GD18556@ando.pearwood.info> Message-ID: On 21/01/15 16:42, Richard D. Moores wrote: > On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano wrote: >> https://duckduckgo.com/?q=windows+command+line+paste > > Ah, check QuickEdit Mode in Properties. Thanks very much. I don't think you specifically need Quick Edit turned on, you can just use the Edit submenus. But QuickEdit makes it more convenient so is worth using. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From bw_dw at fastmail.fm Wed Jan 21 19:14:42 2015 From: bw_dw at fastmail.fm (dw) Date: Wed, 21 Jan 2015 10:14:42 -0800 Subject: [Tutor] Testing a string to see if it contains a substring Message-ID: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> Hello Python Friends. I have a string array, called "line_array". There may be up to 50 or more elements in the array. So: - line_array[1] may contain "01/04/2013 10:43 AM 17,410,217 DEV-ALL-01-04-13.rlc\n" - line_array[2] may contain "01/25/2013 03:21 PM 17,431,230 DEV-ALL-01-25-2013.rlc\n" - line_array[3] may contain "\n" I want to retain all elements which are valid (i.e. contains a date value xx/xx/xxxx) So I'm using a regex search for the date value located at the start of each element...this way misc_int1 = re.search(r'[0-9]{2}/[0-9]{2}/[0-9]{4}',line_array[x]).start() This method works really well when the regex date characters are found. It returns the value 0 to misc_int1 because the date regex starts at 0 position. I was hoping the .start() method would return a -1 value for the instance in which the regex search string is not found. That way I could iterate through the elements and retain only the valid ones. However, the .start() method throws an error if the regex search string is not found. Your suggestions greatly appreciated! Thanks!! d :-] -- Bw_dw at fastmail.net From alan.gauld at btinternet.com Thu Jan 22 00:39:38 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 21 Jan 2015 23:39:38 +0000 Subject: [Tutor] Testing a string to see if it contains a substring In-Reply-To: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> References: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> Message-ID: On 21/01/15 18:14, dw wrote: > - line_array[1] may contain "01/04/2013 10:43 AM 17,410,217 > DEV-ALL-01-04-13.rlc\n" > - line_array[2] may contain "01/25/2013 03:21 PM 17,431,230 > DEV-ALL-01-25-2013.rlc\n" > - line_array[3] may contain "\n" > > I want to retain all elements which are valid (i.e. contains a date > value xx/xx/xxxx) You need a bit more detail. Can a row contain anything other than just \n if there is no date? Is the date always at the start and always the same length? > So I'm using a regex search for the date value located at the start of > each element...this way > > misc_int1 = > re.search(r'[0-9]{2}/[0-9]{2}/[0-9]{4}',line_array[x]).start() You might be better with re.match() if its always at the start of the line. > This method works really well when the regex date characters are found. > It returns the value 0 to misc_int1 because the date regex starts at 0 > position. > I was hoping the .start() method would return a -1 value for the > instance in which the regex search string is not found. You can simply split the code over two lines and check the result: result = re.search(r'[0-9]{2}/[0-9]{2}/[0-9]{4}',line_array[x]) if result is not None: misc_intl = result.start() There are no prizes for writing code on one line, so don't be afraid to separate it out. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Thu Jan 22 01:15:28 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 22 Jan 2015 11:15:28 +1100 Subject: [Tutor] Testing a string to see if it contains a substring In-Reply-To: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> References: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> Message-ID: <20150122001528.GE18556@ando.pearwood.info> On Wed, Jan 21, 2015 at 10:14:42AM -0800, dw wrote: > Hello Python Friends. > I have a string array, called "line_array". Do you mean a list of strings? "String array" is not a standard Python term, it could mean something from the array module, from numpy, or something completely different. It's often good to give simplified example code, rather than try to describe it in words, e.g.: line_array = ["line 1", "line 2"] > There may be up to 50 or more elements in the array. > So: > - line_array[1] may contain "01/04/2013 10:43 AM 17,410,217 > DEV-ALL-01-04-13.rlc\n" > - line_array[2] may contain "01/25/2013 03:21 PM 17,431,230 > DEV-ALL-01-25-2013.rlc\n" > - line_array[3] may contain "\n" What happened to line_array[0] ? > I want to retain all elements which are valid (i.e. contains a date > value xx/xx/xxxx) > So I'm using a regex search for the date value located at the start of > each element...this way Based on your description, I think the best way to do this is: # remove blank lines line_array = [line for line in line_array if line != '\n'] Possibly this is even nicer: # get rid of unnecessary leading and trailing whitespace on each line # and then remove blanks line_array = [line.strip() for line in line_array] line_array = [line for line in line_array if line] This is an alternative, but perhaps a little cryptic for those not familiar with functional programming styles: line_array = filter(None, map(str.strip, line_array)) No regexes required! However, it isn't clear from your example whether non-blank lines *always* include a date. Suppose you have to filter date lines from non-date lines? Start with a regex and a tiny helper function, which we can use lambda to embed directly in the call to filter: DATE = r'\d{2}/\d{2}/\d{4}' line_array = filter(lambda line: re.search(DATE, line), line_array) In Python version 3, you may need to wrap that in a call to list: line_array = list(filter(lambda line: re.search(DATE, line), line_array)) but that isn't needed in Python 2. If that's a bit cryptic, here it is again as a list comp: DATE = r'\d{2}/\d{2}/\d{4}' line_array = [line for line in line_array if re.search(DATE, line)] Let's get rid of the whitespace at the same time! line_array = [line.strip() for line in line_array if re.search(DATE, line)] And if that's still too cryptic ("what's a list comp?") here it is again expanded out in full: temp = [] for line in line_array: if re.search(DATE, line): temp.append(line.strip()) line_array = temp How does this work? It works because the two main re functions, re.match and re.search, return None when then regex isn't found, and a MatchObject when it is found. None has the property that it is considered "false" in a boolean context, while MatchObjects are always consider "true". We don't care *where* the date is found in the string, only whether or not it is found, so there is no need to check the starting position. -- Steven From dyoo at hashcollision.org Thu Jan 22 02:13:51 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 21 Jan 2015 17:13:51 -0800 Subject: [Tutor] Testing a string to see if it contains a substring In-Reply-To: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> References: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> Message-ID: How large will your array be in production? If it going to be very large, you may want to consider a database. You're simulating a collection of records as an in-memory sequence of flat strings. This design won't scale, so if you are working with a lot of data, you may want to look into a dedicated database. > This method works really well when the regex date characters are found. > It returns the value 0 to misc_int1 because the date regex starts at 0 > position. > I was hoping the .start() method would return a -1 value for the > instance in which the regex search string is not found. > That way I could iterate through the elements and retain only the valid > ones. With regards to your original question: the return type of a search() is either a match object, or a None. So your program's control-flow logic should be accounting for these two possibilities. At the moment, the code assumes that it always gets a match object, but that assumption doesn't hold and explains why you're seeing run-time error messages. From breamoreboy at yahoo.co.uk Thu Jan 22 08:09:50 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 22 Jan 2015 07:09:50 +0000 Subject: [Tutor] Testing a string to see if it contains a substring In-Reply-To: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> References: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> Message-ID: On 21/01/2015 18:14, dw wrote: > Hello Python Friends. > I have a string array, called "line_array". > > There may be up to 50 or more elements in the array. > So: > - line_array[1] may contain "01/04/2013 10:43 AM 17,410,217 > DEV-ALL-01-04-13.rlc\n" > - line_array[2] may contain "01/25/2013 03:21 PM 17,431,230 > DEV-ALL-01-25-2013.rlc\n" > - line_array[3] may contain "\n" > > I want to retain all elements which are valid (i.e. contains a date > value xx/xx/xxxx) > So I'm using a regex search for the date value located at the start of > each element...this way > > misc_int1 = > re.search(r'[0-9]{2}/[0-9]{2}/[0-9]{4}',line_array[x]).start() > > This method works really well when the regex date characters are found. > It returns the value 0 to misc_int1 because the date regex starts at 0 > position. > I was hoping the .start() method would return a -1 value for the > instance in which the regex search string is not found. > That way I could iterate through the elements and retain only the valid > ones. > > However, the .start() method throws an error if the regex search string > is not found. > > Your suggestions greatly appreciated! > Thanks!! > d :-] > I'd use https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime to test the first ten characters of the string. I'll leave that and handling IndexError or ValueError to you :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From s.shall at virginmedia.com Thu Jan 22 13:56:30 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Thu, 22 Jan 2015 12:56:30 +0000 Subject: [Tutor] Installing psutil 2.2.0-1 on Canopy Enthought Message-ID: <54C0F37E.5070209@virginmedia.com> I use MAC OSX 10.9.5 Canopy Enthought python 2.7.6 I also use the Enthought Package Manager to keep my installation up-todate. For about two weeks now, Canopy says that I need to install psutil 2.2.0-1 instead of the currently installed version 2.1.1. I appear to do that successfully, but the next day the Package manager says to install the updated psutil. When I import psutil I get no error message. And when I do: psutil.__version__ , I get back '2.1.1', which is the old version, and I have just apparently succesfully udated the package. What in fact is my problem? I simply want to update this package, and I cannot. I do not know if this is the best Forum to get advice on this, but any guidance, including where else I might ask would be appreciated. -- Sydney From jarod_v6 at libero.it Thu Jan 22 17:11:45 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Thu, 22 Jan 2015 17:11:45 +0100 (CET) Subject: [Tutor] Class errors Message-ID: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> Dear All, I created a class that invoke from another file another class I get an error that I do not understand: gobal name Job is not defined However If I see the class imported I found the class Job. Any suggestion or example on class invoke another class #job,py class Jobs: ..... #trial.py from core.job import * class Second: def __initi__: tp = open("/tmp/file.txt") def gus(self): tr = Job() thanks so much!1 From dyoo at hashcollision.org Thu Jan 22 19:42:39 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 22 Jan 2015 10:42:39 -0800 Subject: [Tutor] Class errors In-Reply-To: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> References: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> Message-ID: On Thu, Jan 22, 2015 at 8:11 AM, jarod_v6 at libero.it wrote: > Dear All, > > I created a class that invoke from another file another class > I get an error that I do not understand: gobal name Job is not defined Please use copy-and-paste. You just typed out the error message by hand: we can tell because the error message you're presenting is misspelled. Copy-and-paste it, as well as the surrounding text around it. > However If I see the class imported I found the class Job. Ok. But where? In the code you present: > #job,py > class Jobs: > ..... > > #trial.py > > from core.job import * > class Second: > def __initi__: > tp = open("/tmp/file.txt") > > def gus(self): > tr = Job() I don't see a class named 'Job'. I see a class named 'Jobs' defined in 'job.py', but that's a different class. From dyoo at hashcollision.org Thu Jan 22 19:45:05 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 22 Jan 2015 10:45:05 -0800 Subject: [Tutor] Fwd: Testing a string to see if it contains a substring In-Reply-To: <1421941762.257799.217438729.12510CA1@webmail.messagingengine.com> References: <1421864082.4080312.216961817.7654978C@webmail.messagingengine.com> <1421941762.257799.217438729.12510CA1@webmail.messagingengine.com> Message-ID: ---------- Forwarded message ---------- From: dw Date: Thu, Jan 22, 2015 at 7:49 AM Subject: Re: [Tutor] Testing a string to see if it contains a substring To: Danny Yoo Hi Danny. Thanks for your email. The number of elements could start out as up to 500. But since they are short string elements, even that amount won't be a problem for in-ram memory. The eventual module is designed to ensure that the max elements count will be kept at 53. I'm playing with a module that will remove files that are created as archives weekly. Right now we have about 3 years and they are starting to eat up hard-drive. So I'm playing with a module that will remove the oldest files based on their creation date. And keep the max count of them to 52....(1 years worth of archives) Thanks for the additional explanation of the search() returning a match or None. Many thanks my friend!! Duane On Wed, Jan 21, 2015, at 05:13 PM, Danny Yoo wrote: > How large will your array be in production? > > If it going to be very large, you may want to consider a database. > You're simulating a collection of records as an in-memory sequence of > flat strings. This design won't scale, so if you are working with a > lot of data, you may want to look into a dedicated database. > > > > > This method works really well when the regex date characters are found. > > It returns the value 0 to misc_int1 because the date regex starts at 0 > > position. > > I was hoping the .start() method would return a -1 value for the > > instance in which the regex search string is not found. > > That way I could iterate through the elements and retain only the valid > > ones. > > With regards to your original question: the return type of a search() > is either a match object, or a None. So your program's control-flow > logic should be accounting for these two possibilities. At the > moment, the code assumes that it always gets a match object, but that > assumption doesn't hold and explains why you're seeing run-time error > messages. -- Bw_dw at fastmail.net From robertvstepp at gmail.com Thu Jan 22 22:17:58 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 22 Jan 2015 15:17:58 -0600 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? Message-ID: And will this vary depending on whether a version control system is being used or not? Or is the use of a version control system considered to be highly recommended (if not mandatory)? -- boB From cs at zip.com.au Thu Jan 22 22:31:27 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 23 Jan 2015 08:31:27 +1100 Subject: [Tutor] Class errors In-Reply-To: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> References: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> Message-ID: <20150122213127.GA98424@cskk.homeip.net> On 22Jan2015 17:11, jarod_v6 at libero.it wrote: >I created a class that invoke from another file another class > I get an error that I do not understand: gobal name Job is not defined >However If I see the class imported I found the class Job. >Any suggestion or example on class invoke another class First, please cut/paste error messages, filenames and code. Do not hand type them, as that introduces errors. >#job,py For example, I suspect you mean "job.py", not "job,py". >class Jobs: > ..... > >#trial.py > >from core.job import * It is not recommended to import "*". Just impor the names you need. It avoids _unexpected_ names leaking into your program: you might be using such a name for something else! >class Second: > def __initi__: > tp = open("/tmp/file.txt") > > def gus(self): > tr = Job() Because you have hand typed things I cannot be sure - it may just be a mistake - but "job.py" defines a class "Jobs". In "trial.py" you use the name "Job". Not the same! Cheers, Cameron Simpson Beware of bugs in the above code; I have only proved it correct, not tried it. - Donald E. Knuth From alan.gauld at btinternet.com Thu Jan 22 23:51:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 22 Jan 2015 22:51:44 +0000 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: References: Message-ID: On 22/01/15 21:17, boB Stepp wrote: > And will this vary depending on whether a version control system is > being used or not? Or is the use of a version control system > considered to be highly recommended (if not mandatory)? Virtually nothing in Python is mandatory - unless you plan on putting your code in the standard library. But the standard library is aq good template to follow... As to headers, I tend to put version control type stuff in real comments (author, version, date etc) and put comments about functionality in doc strings where the help() function can find them. There is a kind of standard presentation of doc strings; use help a few times and you'll see. But it's not mandatory in as much as everything will continue to work if you ignore the conventions. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Thu Jan 22 23:53:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 22 Jan 2015 22:53:58 +0000 Subject: [Tutor] Installing psutil 2.2.0-1 on Canopy Enthought In-Reply-To: <54C0F37E.5070209@virginmedia.com> References: <54C0F37E.5070209@virginmedia.com> Message-ID: On 22/01/15 12:56, Sydney Shall wrote: > I use MAC OSX 10.9.5 > Canopy Enthought python 2.7.6 > > I also use the Enthought Package Manager to keep my installation up-todate. > Canopy and Enthoughts paqckage management are well beyond the bounds of standard Python. > What in fact is my problem? I simply want to update this package, and I > cannot. > > I do not know if this is the best Forum to get advice on this, but any > guidance, including where else I might ask would be appreciated. I'd try the Enthought/Canopy forums. Or perhaps even the SciPy forums because Canopy has SciPy as standard (along with a bunch of other stuff) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From ben+python at benfinney.id.au Fri Jan 23 00:25:24 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 23 Jan 2015 10:25:24 +1100 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? References: Message-ID: <85iofyo0t7.fsf@benfinney.id.au> boB Stepp writes: > And [?] Could you write a message body that asks the question? (The Subject field isn't part of the message body.) As it is, I'm not sure what in particular you're asking about. -- \ ?Are you thinking what I'm thinking, Pinky?? ?Uh... yeah, | `\ Brain, but where are we going to find rubber pants our size?? | _o__) ?_Pinky and The Brain_ | Ben Finney From steve at pearwood.info Fri Jan 23 00:45:28 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 23 Jan 2015 10:45:28 +1100 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: References: Message-ID: <20150122234528.GG18556@ando.pearwood.info> On Thu, Jan 22, 2015 at 03:17:58PM -0600, boB Stepp hid the following question in the subject line: "Does the Python way of doing things have a definite preference for the structure and content of program file header comments?" and then wrote: > And will this vary depending on whether a version control system is > being used or not? Or is the use of a version control system > considered to be highly recommended (if not mandatory)? This is a language-agnostic question, it is not specific to Python. It may be a question about the community of users for a language, but in principle at least it applies to *every language*. I'm not entirely sure what you mean by "program file header comments", can you give an example? As far as version control, I consider it *absolutely essential* for anyone who is serious about programming professionalism. Clearly, however, I'm not serious, because I only use it about 50% of the time *wink* I consider the use of a DVCS (Distributed Version Control System) such as Mercurial or Git to be Best Practice for professional programmers and highly recommended for non-professionals. In this case, I'm referring to professionalism, not necessarily whether you are paid to program. DVCS is, in some ways, akin to having backups: if you're a home user who only uses the computer for playing games, you probably don't care about backups ("I lost my Minesweeper top scores!!! What shall I do???"), but for everyone else backups of some type or another are essential if you are treating your computer seriously. If you are collaborating with other programmers (or at least *hope* to collaborate with others), using a DVCS is all but mandatory, but if you're just working on your own, you can avoid using one. You probably shouldn't -- even for a single user programming alone, a DVCS makes it easier to experiment with your code without fear of irreversibly breaking things. Example: some years ago, before starting to use version control, I had a working script that I wanted to experiment on. So I made a copy of it, and edited the copy. Well, one thing lead to another, and at some point I broke the script so badly that I decided to throw it away and start again, which I did. Except that somehow I somehow managed to delete the original, so I was left with a non-working, heavily modified (to the point that it was almost unrecognisable) copy, and a .pyc (compiled byte-code) version of the original, but no source code to the original. Had I been working with version control, fixing this would have been easy. But I wasn't. Eventually, after many tears and much sweat, I was able to reconstruct most of the original from memory, the broken copy, and the byte-code in the .pyc file. I had no tests either, so to this day I cannot be sure that what I reconstructed does exactly what the original did, or whether I have introduced bugs. I surely have, but if I had tests for it, I would have quickly discovered where the bugs lie. So even for a lone programmer who doesn't share his work with others, using version control can be a good thing. As far as the Python community goes, that depends. The Python community is really many little subcommunities only linked by their use of Python. People working on Open Source projects these days pretty much always use a version control system. Business programmers may, or may not, it depends on whether or not they apply best practices. Does this help answer your question? -- Steve From jarod_v6 at libero.it Fri Jan 23 02:44:33 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Fri, 23 Jan 2015 02:44:33 +0100 (CET) Subject: [Tutor] Class learning Message-ID: <1373014271.806721421977473153.JavaMail.httpd@webmail-50.iol.local> Dear All How can gave the attributes __name__ to a function? class Foo(object): def __init__(self): steps = {} tmp = open("rnaseq.base.ini","rb") config.readfp(tmp) readsets = parse_illumina_readset_file("/home/mauro/Desktop/readset.csv") @property def steps(self): return [ self.one, self.two, self.fmit, ] def one(self): a = 5 return a def two(self): b = 5 return b def fmit(self): c = 7 return c #@property def show(self): ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) print ftp It is working In [5]: F = Foo() In [6]: F.show() 1- one 2- two 3- fmit Why if I define the data in the same way I have this error? in () ----> 1 rna.show() in show(self) 261 #@property 262 def show(self): --> 263 ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) 264 265 print ftp AttributeError: 'str' object has no attribute '__name__' Here you find all the other code the principal are the same:http://pastebin.com/nYGEiXY4 rna = Rnaseq() rna.show() thanks so much!! From robertvstepp at gmail.com Fri Jan 23 05:55:46 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 22 Jan 2015 22:55:46 -0600 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: <85iofyo0t7.fsf@benfinney.id.au> References: <85iofyo0t7.fsf@benfinney.id.au> Message-ID: On Thu, Jan 22, 2015 at 5:25 PM, Ben Finney wrote: > boB Stepp writes: > >> And [?] > > Could you write a message body that asks the question? (The Subject > field isn't part of the message body.) Does the Python way of doing things have a definite preference for the structure and content of program file header comments? > As it is, I'm not sure what in particular you're asking about. I am asking about what is considered "good practice" in what to include in the introductory comments to a program, just after the shebang line. I had done a web search, but had found a surprising variety of thoughts on this. Since the Python community culture seems to have strong opinions on making code and its explanation (where needed) as simple, direct and clear as possible, I was wondering if there existed similar opinions about this area of program comments. Some opinions (paraphrased from memory) I've found on this: 1) College courses usually have some blurb about including the course name, assignment name/number and an explanation of what the program proposes to do. 2) Some advise including information such as the file name, other files called by the program, global variables used, etc. Others advise that this type of information is superfluous and should not be included. 3) Most of what I found advised a brief statement of the program's purpose. 4) Most mentioned that the code's author should be stated and the date of creation. 5) Some advised to keep the change log/version info here. Others very strongly said no way, that is the function of version control systems, which make such records redundant and just something that might not be kept up to date. 6) Etc. -- boB From robertvstepp at gmail.com Fri Jan 23 07:10:38 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 23 Jan 2015 00:10:38 -0600 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: <20150122234528.GG18556@ando.pearwood.info> References: <20150122234528.GG18556@ando.pearwood.info> Message-ID: On Thu, Jan 22, 2015 at 5:45 PM, Steven D'Aprano wrote: > On Thu, Jan 22, 2015 at 03:17:58PM -0600, boB Stepp hid the following > question in the subject line: > > "Does the Python way of doing things have a definite preference for the > structure and content of program file header comments?" > > and then wrote: > >> And will this vary depending on whether a version control system is >> being used or not? Or is the use of a version control system >> considered to be highly recommended (if not mandatory)? > > This is a language-agnostic question, it is not specific to Python. It > may be a question about the community of users for a language, but in > principle at least it applies to *every language*. I was wondering if the Python culture had their own particular take on these types of comments. > I'm not entirely sure what you mean by "program file header comments", > can you give an example? I outlined what I meant in my response to Ben Finney. Briefly, just the introductory/explanatory comments made at the very beginning of a program, describing its purpose, the author, etc. > As far as version control, I consider it *absolutely essential* for > anyone who is serious about programming professionalism. Clearly, > however, I'm not serious, because I only use it about 50% of the time > *wink* > > I consider the use of a DVCS (Distributed Version Control System) such > as Mercurial or Git to be Best Practice for professional programmers and > highly recommended for non-professionals. In this case, I'm referring to > professionalism, not necessarily whether you are paid to program. I am striving hard to at least make myself aware of what constitutes "professionalism" in software creation. I fully intend to go in your stated direction, but finding time to become proficient in such a tool in the midst of all the other things I am trying to absorb is difficult. However, my mention of version control was in response to a web search where many said that including change logs/version history in a program's header comments is made unnecessary by modern version control systems and is even harmful in that it might lead to unmaintained comments. OTH, there seemed to be plenty of others who advocate that this information should indeed be included in the program's header comments. [...] > Example: some years ago, before starting to use version control, I had a > working script that I wanted to experiment on. So I made a copy of it, > and edited the copy. Well, one thing lead to another, and at some point > I broke the script so badly that I decided to throw it away and start > again, which I did. > > Except that somehow I somehow managed to delete the original, so I was > left with a non-working, heavily modified (to the point that it was > almost unrecognisable) copy, and a .pyc (compiled byte-code) version of > the original, but no source code to the original. Had I been working > with version control, fixing this would have been easy. But I wasn't. > Eventually, after many tears and much sweat, I was able to reconstruct > most of the original from memory, the broken copy, and the byte-code in > the .pyc file. I had no tests either, so to this day I cannot be sure > that what I reconstructed does exactly what the original did, or whether > I have introduced bugs. I surely have, but if I had tests for it, I > would have quickly discovered where the bugs lie. Ugh! Unfortunately I have mirrored your example recently, which has had me wondering whether I should "make" time to implement a DVCS. And I simply MUST learn how to do test driven development and how to automate such testing. Dave Angel was absolutely correct (Of course!) that manual testing is insufficient. The things I am starting to try to do are just getting too large and complex for manual testing and manual backups. > So even for a lone programmer who doesn't share his work with others, > using version control can be a good thing. "The Pragmatic Programmer" and some other books I have read in the past couple of years along with your and other's comments on this list make it sound better than the invention of sliced bread! > As far as the Python community goes, that depends. The Python community > is really many little subcommunities only linked by their use of Python. > People working on Open Source projects these days pretty much always use > a version control system. Business programmers may, or may not, it > depends on whether or not they apply best practices. "Best practices". "Software craftsmanship". Clarity of code. And more... As I continue to learn I am appreciating these things more and more, especially when I must suffer multi-day interruptions to the project I am working on and have to reconstruct what I had last been doing/thinking. I find myself almost constantly trying to rename things to make them more self-explanatory, break things down into more self-contained, single-purpose constructs, etc. Trying to make my code more "obvious" as to what it is doing to the casual reader is becoming much more important to me. So much to learn, and the more I learn the more I realize I do not know... > Does this help answer your question? Helps considerably on DVCS. Still puzzling over what comments to put at the very beginning of source code files, so as to enable myself to more quickly come back up to speed on a project I am taken away from for a period of time, or to assist someone who comes after me. Style issues aside, I am suspecting that well-crafted comments are more of an art than a science and is best learned via painful experience, which, for me, is coming back to my code after a break and cursing myself when what I have written is far from being as clear as I thought it was when I originally wrote it!!! -- boB From ben+python at benfinney.id.au Fri Jan 23 07:22:35 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 23 Jan 2015 17:22:35 +1100 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? References: <85iofyo0t7.fsf@benfinney.id.au> Message-ID: <85vbjym2xg.fsf@benfinney.id.au> boB Stepp writes: > Does the Python way of doing things have a definite preference for the > structure and content of program file header comments? To my knowledge, the term ?program file header comments? for Python would best describe a module docstring; not a comment, but documentation . It seems from what follows that this is what you're asking about; I'll assume so. > I am asking about what is considered "good practice" in what to > include in the introductory comments to a program, just after the > shebang line. I would consider it good practice to have a copyright statement and a grant of license at the top; a handful of lines should suffice. That way it's very easy for anyone diving into the code (as programmers tend to do when looking around a code base) to see what rights they have been granted to the code, without needing to engage in a lot of effort. But none of that belongs in the docstring. > I had done a web search, but had found a surprising variety of > thoughts on this. Since the Python community culture seems to have > strong opinions on making code and its explanation (where needed) as > simple, direct and clear as possible, I was wondering if there existed > similar opinions about this area of program comments. There is PEP 257 which defines the format a docstring should conform to. As for the content, I would advise the module docstring should contain a concise description of the module's purpose, and anything unusual about its API. Consider that the primary reader of that content will be a programmer using the Python interactive help (e.g. ?pydoc?). > Some opinions (paraphrased from memory) I've found on this: > 1) College courses usually have some blurb about including the > course name, assignment name/number and an explanation of what the > program proposes to do. That might be useful depending on the institution, I suppose. > 2) Some advise including information such as the file name, other > files called by the program, global variables used, etc. Others advise > that this type of information is superfluous and should not be > included. Right, a lot of that should either be in unit tests, or gathered automatically from introspection tools. Writing it in manually-maintained comments invites the comments and code getting out of sync without anyone realising the error. > 3) Most of what I found advised a brief statement of the program's purpose. That definitely belongs in the module docstring, IMO. Anyone reading ?pydoc? or other interactive help is likely to need a reminder of this module's intended purpose. > 4) Most mentioned that the code's author should be stated and the > date of creation. Not in the docstring, but I certainly want to see a concise copyright statement and grant of license (under free-software terms, please). > 5) Some advised to keep the change log/version info here. Others > very strongly said no way, that is the function of version control > systems, which make such records redundant and just something that > might not be kept up to date. Certainly, the VCS is the correct repository of that information. Duplicating it leads to disagreements between the VCS and the code comments as to the history of the file. > 6) Etc. Hope that helps. -- \ ?For fast acting relief, try slowing down.? ?Jane Wagner, via | `\ Lily Tomlin | _o__) | Ben Finney From ben+python at benfinney.id.au Fri Jan 23 08:02:23 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 23 Jan 2015 18:02:23 +1100 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? References: <85iofyo0t7.fsf@benfinney.id.au> <85vbjym2xg.fsf@benfinney.id.au> Message-ID: <85ppa6m134.fsf@benfinney.id.au> Ben Finney writes: > I would consider it good practice to have a copyright statement and a > grant of license at the top; a handful of lines should suffice. > [?] > But none of that belongs in the docstring. > > [?] > There is PEP 257 which > defines the format a docstring should conform to. > > As for the content, I would advise the module docstring should contain a > concise description of the module's purpose, and anything unusual about > its API. Consider that the primary reader of that content will be a > programmer using the Python interactive help (e.g. ?pydoc?). An example:: # -*- coding: utf-8 -*- # foo/frob.py # Part of FooBar, a garden gnome decoration library. # # Copyright ? 2011?2015 Ben Finney # # This is free software: you may copy, modify, and/or distribute this work # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3 of that license or any later version. # No warranty expressed or implied. See the file ?LICENSE.GPL-3? for details. """ Functionality to frobnicate spangules. Each frobnicator conforms to the Weebly-Ruckford standard for input and output vraxen. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque commodo elit eget odio hendrerit sollicitudin ac eget felis. Praesent cursus accumsan vehicula. Nullam ac euismod quam, tincidunt maximus augue. """ from __future__ import (absolute_import, unicode_literals) ? Much of the comment block is there to aid the reader who wants to know their rights. What is this file? What work is it part of? What rights are granted in this work? Who holds copyright and when? Which file in this code base contains the full license text? These are at the top of each file because frequently a code base will amalgamate files with different copyright holders, different copyright years, different license grants, etc. so it's necessary to answer the questions specifically for each file. Note that the docstring has a single-line synopsis of the module's purpose; the remaining paragraphs say only what is likely to be of interest to the reader of interactive help for the module. The copyright and other administrivia don't belong there. Note these absences: * No full license text. The *grant* of license is there so the reader knows a license is granted and what they can do, but the full terms can go into a separate named file included in the code base. * No history of changes. The VCS of the code base is the canonical place where that information should be, and a separate ?ChangeLog? document in the code base can be maintained for a higher-level, feature-based change history of interest to recipients. * Details of the contents of the file. Any objects created in the module are available via introspection tools, so duplicating them manually is again inviting discrepancies between comments and code. Hopefully that's some guidance in forming a convention on this matter. -- \ ?Religious faith is the one species of human ignorance that | `\ will not admit of even the *possibility* of correction.? ?Sam | _o__) Harris, _The End of Faith_, 2004 | Ben Finney From bw_dw at fastmail.fm Thu Jan 22 16:40:08 2015 From: bw_dw at fastmail.fm (dw) Date: Thu, 22 Jan 2015 07:40:08 -0800 Subject: [Tutor] Testing a string to see if it contains a substring (dw) Message-ID: <1421941208.254731.217420861.649777E8@webmail.messagingengine.com> Thanks for your good comments. I do think I found a work around body = "" for x in range(0,len(line_array)): test_line = len(re.findall(r'[0-9]{2}/[0-9]{2}/[0-9]{4}', line_array[x])) if test_line > 0: body = body + line_array[x]+"\n" For each iteration re.findall returns a list object based upon the regex search. If an element contains "01/04/2013".....the regex is found, and re.findall returns it as a list object ['01/04/2013'] I can then perform a len function on that which will = 1, since the list contains only one string object. For the row in which the regex is not found, re.findall will return [] Which is essentially a list with 0 objects, and the len function will then = 0. Thanks Alan G for your example!! It will be fun to try it!! :-] I look for the KISS model in coding, and I like your example. -- Bw_dw at fastmail.net From bw_dw at fastmail.fm Thu Jan 22 17:15:25 2015 From: bw_dw at fastmail.fm (dw) Date: Thu, 22 Jan 2015 08:15:25 -0800 Subject: [Tutor] Testing a string to see if it contains a substring (Steve and Mark) Message-ID: <1421943325.267294.217468261.19FF8823@webmail.messagingengine.com> Thanks so much Steve and Mark! You've given me a lot to chew on. :-D I'll pursue! More Python FUN!! ================================================================ Based on your description, I think the best way to do this is: # remove blank lines line_array = [line for line in line_array if line != '\n'] Possibly this is even nicer: # get rid of unnecessary leading and trailing whitespace on each line # and then remove blanks line_array = [line.strip() for line in line_array] line_array = [line for line in line_array if line] This is an alternative, but perhaps a little cryptic for those not familiar with functional programming styles: line_array = filter(None, map(str.strip, line_array)) No regexes required! However, it isn't clear from your example whether non-blank lines *always* include a date. Suppose you have to filter date lines from non-date lines? Start with a regex and a tiny helper function, which we can use lambda to embed directly in the call to filter: DATE = r'\d{2}/\d{2}/\d{4}' line_array = filter(lambda line: re.search(DATE, line), line_array) In Python version 3, you may need to wrap that in a call to list: line_array = list(filter(lambda line: re.search(DATE, line), line_array)) but that isn't needed in Python 2. If that's a bit cryptic, here it is again as a list comp: DATE = r'\d{2}/\d{2}/\d{4}' line_array = [line for line in line_array if re.search(DATE, line)] Let's get rid of the whitespace at the same time! line_array = [line.strip() for line in line_array if re.search(DATE, line)] And if that's still too cryptic ("what's a list comp?") here it is again expanded out in full: temp = [] for line in line_array: if re.search(DATE, line): temp.append(line.strip()) line_array = temp How does this work? It works because the two main re functions, re.match and re.search, return None when then regex isn't found, and a MatchObject when it is found. None has the property that it is considered "false" in a boolean context, while MatchObjects are always consider "true". We don't care *where* the date is found in the string, only whether or not it is found, so there is no need to check the starting position. -- Steven ============================= I'd use https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime to test the first ten characters of the string. I'll leave that and handling IndexError or ValueError to you :) -- Bw_dw at fastmail.net From pathunstrom at gmail.com Thu Jan 22 17:18:52 2015 From: pathunstrom at gmail.com (Patrick Thunstrom) Date: Thu, 22 Jan 2015 11:18:52 -0500 Subject: [Tutor] Class errors In-Reply-To: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> References: <1766731168.705211421943105429.JavaMail.httpd@webmail-07.iol.local> Message-ID: If the code I'm seeing is correct, the problem is the class is Jobs, and you instantiated a Job, which doesn't exit. Replace one with the other in either case should fix it. On Thu, Jan 22, 2015 at 11:11 AM, jarod_v6 at libero.it wrote: > Dear All, > > I created a class that invoke from another file another class > I get an error that I do not understand: gobal name Job is not defined > However If I see the class imported I found the class Job. > Any suggestion or example on class invoke another class > > #job,py > class Jobs: > ..... > > #trial.py > > from core.job import * > class Second: > def __initi__: > tp = open("/tmp/file.txt") > > def gus(self): > tr = Job() > > thanks so much!1 > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From danny.yoo at gmail.com Fri Jan 23 03:38:45 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Thu, 22 Jan 2015 18:38:45 -0800 Subject: [Tutor] Class learning In-Reply-To: <1373014271.806721421977473153.JavaMail.httpd@webmail-50.iol.local> References: <1373014271.806721421977473153.JavaMail.httpd@webmail-50.iol.local> Message-ID: > #@property > def show(self): > ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) > Questions you should be asking yourself: What is self.steps? What type is it? In the case where this breaks with an error, what is self.steps then? From bw_dw at fastmail.fm Fri Jan 23 04:09:24 2015 From: bw_dw at fastmail.fm (dw) Date: Thu, 22 Jan 2015 19:09:24 -0800 Subject: [Tutor] Initiating an external email transmission Message-ID: <1421982564.434144.217713981.727B20E7@webmail.messagingengine.com> I have a python script that I've created. It logs into an online email service and sends out an email. It works in my Linux box, and it works in my Windows 7 box. I've also converted it with Py2EXE and it works as an executable in my Win-7 box. The issue is, I made it for someone else to use in his PC. And its not working for him. His system is Windows 7. And I'm wondering if perhaps he has a firewall blocking it? Its his personal laptop. Any thoughts would be appreciated ============================================================== here is the code with account info x'd out #!/usr/bin/python #this is a funky way of clearing the screen for x in range(0, 20): print("\n") #Use checkip.dynds.org to get IP address import urllib2 u = urllib2.urlopen('http://checkip.dyndns.org') myIP = u.next() print("The data returned is: \n%s"%myIP) #Now we parse the returned string leaving only the IP address temp=myIP.split('>') getip=temp[6] temp=getip.split('<') getip=temp[0] temp=getip.split() myIP=temp[3] #include the python SMTP library file import smtplib print("Importing smtplib file") #Call SMTP library function to establish the email service #Here we need the server name and the port assignment print("Establishing server variables") server = smtplib.SMTP('xxx.xxxxxxx.xxx', 587) print("Establishing SMTP protocol ehlo") server.ehlo() server.starttls() #Next establish the user account of the online email service #we establish a connect using the user account credentials print("Establishing login") server.login("xxxxx at xxxxx.com", "xxxxxxxx") #Use the variable 'msg' for the text within the message print("creating message") msg = "\r\n".join([ "From: xxx at xxxxx.com", "To: xxx at xxxxx.com", "Subject: Automated Test Message from Python program", "", "The IP address of this PC is %s" % (myIP) ]) #Establish FROM and TO email addresses fromaddr="xxxx at xxxx.com" toaddr="xxxx at xxxxx.com" #Send the message print("Sending email") server.sendmail(fromaddr, toaddr, msg) print("Disconneting") server.quit() -- Bw_dw at fastmail.net From alan.gauld at btinternet.com Fri Jan 23 09:31:21 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 23 Jan 2015 08:31:21 +0000 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: <85ppa6m134.fsf@benfinney.id.au> References: <85iofyo0t7.fsf@benfinney.id.au> <85vbjym2xg.fsf@benfinney.id.au> <85ppa6m134.fsf@benfinney.id.au> Message-ID: On 23/01/15 07:02, Ben Finney wrote: > An example:: > > # -*- coding: utf-8 -*- > > # foo/frob.py > # Part of FooBar, a garden gnome decoration library. > # > # Copyright ? 2011?2015 Ben Finney > # > # This is free software: you may copy, modify, and/or distribute this work > # under the terms of the GNU General Public License as published by the > # Free Software Foundation; version 3 of that license or any later version. > # No warranty expressed or implied. See the file ?LICENSE.GPL-3? for details. Note that much of the information in the true comment block should come from the VCS system. Most VCS systems provide a markup type mechanism that allows you to insert meta-data from the VCS into the file when checked out. Things like filename, version, author, and version number. Often the change comments too - but that can get very wordy. For example in the (ancient) SCCS tool you could use: # File: %M% %R% # # Date: %E% And so on. This helps prevent the VCS and the file from getting out of step but also provides the key meta data if a user does not have access to the VCS - eg picking up files from a memory stick on a laptop say. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jarod_v6 at libero.it Fri Jan 23 09:37:12 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Fri, 23 Jan 2015 09:37:12 +0100 (CET) Subject: [Tutor] R: Re: Class learning Message-ID: <2051759524.113271422002232620.JavaMail.defaultUser@defaultHost> Thanks for the help and patience! It is a function on the class so I suppose for read that function list I need self.steps Where I'm wrong? @property def steps(self): return [ self.trimmomatic, self.merge_trimmomatic_stats, self.star, self.picard_sort_sam, self.rnaseqc, self.wiggle, self.cufflinks, self.gq_seq_utils_exploratory_analysis_rnaseq ] From alan.gauld at btinternet.com Fri Jan 23 09:39:42 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 23 Jan 2015 08:39:42 +0000 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: References: <20150122234528.GG18556@ando.pearwood.info> Message-ID: On 23/01/15 06:10, boB Stepp wrote: >> As far as version control, I consider it *absolutely essential* for >> anyone who is serious about programming professionalism. > > stated direction, but finding time to become proficient in such a tool > in the midst of all the other things I am trying to absorb is > difficult. If you are on Linux there are many freely available VCS. Many of these are quite powerful but for most users, most of the time you only ues two commands - check-in and check-out. Once you know those its very easy. eg In RCS those were just 'ci' and 'co' respectively. If you use a 'professional' grade editor such as Eclipse, emacs, vim etc they have version control built in and once configured with the actual tool you use its just a menu operation. Once happy with a simple VCS style of working you can expand into bigger release management tools. Here you will find a few 'big guns' in the open source world but also many commercial offerings, some costing 10,000 dollars or more! (eg Clearcase, Aide de Camp, Continuus etc) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From danny.yoo at gmail.com Fri Jan 23 11:08:50 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Fri, 23 Jan 2015 02:08:50 -0800 Subject: [Tutor] Class learning In-Reply-To: <2051759524.113271422002232620.JavaMail.defaultUser@defaultHost> References: <2051759524.113271422002232620.JavaMail.defaultUser@defaultHost> Message-ID: On Fri, Jan 23, 2015 at 12:37 AM, jarod_v6 at libero.it wrote: > Thanks for the help and patience! > It is a function on the class so I suppose for read that function list I > need self.steps Where I'm wrong? > @property > def steps(self): > return [ > > self.trimmomatic, > self.merge_trimmomatic_stats, > self.star, > self.picard_sort_sam, > self.rnaseqc, > self.wiggle, > self.cufflinks, > self.gq_seq_utils_exploratory_analysis_rnaseq > > ] > Do each of these elements in this list support the operations you're performing on any single step? That is, the code that you have here: def show(self): ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) seems to assume that every step must have a '__name__' property. But do all of the steps that you've put in there support '__name__'? From jarod_v6 at libero.it Fri Jan 23 11:26:07 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Fri, 23 Jan 2015 11:26:07 +0100 (CET) Subject: [Tutor] R: Re: Re: Class learning Message-ID: <1957294382.177691422008767401.JavaMail.httpd@webmail-07.iol.local> This is the all code: http://pastebin.com/nYGEiXY4 I don't know well which i meas . I suppose it is the name of the class (self. __name__). So the name it is present. it is correct? thanks for the patience! M. >----Messaggio originale---- >Da: danny.yoo at gmail.com >Data: 23/01/2015 11.08 >A: "jarod_v6 at libero.it" >Cc: "Python Tutor Mailing List" >Ogg: Re: Re: [Tutor] Class learning > >On Fri, Jan 23, 2015 at 12:37 AM, jarod_v6 at libero.it wrote: >> Thanks for the help and patience! >> It is a function on the class so I suppose for read that function list I >> need self.steps Where I'm wrong? >> @property >> def steps(self): >> return [ >> >> self.trimmomatic, >> self.merge_trimmomatic_stats, >> self.star, >> self.picard_sort_sam, >> self.rnaseqc, >> self.wiggle, >> self.cufflinks, >> self.gq_seq_utils_exploratory_analysis_rnaseq >> >> ] >> > > > >Do each of these elements in this list support the operations you're >performing on any single step? > >That is, the code that you have here: > > def show(self): > ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, >step in enumerate(self.steps)]) > >seems to assume that every step must have a '__name__' property. > >But do all of the steps that you've put in there support '__name__'? > From breamoreboy at yahoo.co.uk Fri Jan 23 11:26:52 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 23 Jan 2015 10:26:52 +0000 Subject: [Tutor] Testing a string to see if it contains a substring (Steve and Mark) In-Reply-To: <1421943325.267294.217468261.19FF8823@webmail.messagingengine.com> References: <1421943325.267294.217468261.19FF8823@webmail.messagingengine.com> Message-ID: On 22/01/2015 16:15, dw wrote: > Thanks so much Steve and Mark! > You've given me a lot to chew on. :-D > I'll pursue! > More Python FUN!! > ================================================================ > Thanks for the thanks, but please don't change the subject as it breaks threading, making it more difficult for people to find things in future in the mailing list archives. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Fri Jan 23 11:37:56 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 23 Jan 2015 10:37:56 +0000 Subject: [Tutor] Testing a string to see if it contains a substring (dw) In-Reply-To: <1421941208.254731.217420861.649777E8@webmail.messagingengine.com> References: <1421941208.254731.217420861.649777E8@webmail.messagingengine.com> Message-ID: On 22/01/2015 15:40, dw wrote: > Thanks for your good comments. > I do think I found a work around > > body = "" > for x in range(0,len(line_array)): > test_line = len(re.findall(r'[0-9]{2}/[0-9]{2}/[0-9]{4}', > line_array[x])) > if test_line > 0: > body = body + line_array[x]+"\n" Using range in a Python for loop is often a code smell. Your names are poor as well. The Pythonic way is:- body = "" for line in line_array: linelen = len(re.findall(r'[0-9]{2}/[0-9]{2}/[0-9]{4}', line)) if linelen > 0: body += line + "\n" Also note that although the above is adequate for small data sets, the performance dives terribly as the size of the data set goes up. Your homework for this weekend is to research how one normally joins strings in Python and report back. Have a good one :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From danny.yoo at gmail.com Fri Jan 23 11:49:21 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Fri, 23 Jan 2015 02:49:21 -0800 Subject: [Tutor] Class learning In-Reply-To: <1957294382.177691422008767401.JavaMail.httpd@webmail-07.iol.local> References: <1957294382.177691422008767401.JavaMail.httpd@webmail-07.iol.local> Message-ID: You are trying to use advanced features of Python, and they are not the right tool for what you're trying to do. Specifically, you're trying two things at the same time: 1. Properties, which allows method calls to look like simple variable access. 2. The __name__ special attribute on methods (reference: https://docs.python.org/2/reference/datamodel.html) to reflectively pick up a string that lets us get the name of a function. The problem is trying to use *both* of these features at the same time. It is self defeating. Here is a minimal example to demonstrate; ################## class Test(object): @property def x(self): return 42 ################## Consider the expression: Test2().x.__name__ This example is small enough that it should help to clarify what's going on. What did you want to happen? And what happens? Now look at: ##################### class Test(object): def x(self): return 42 Test().x().__name__ ##################### What do you expect to see when you run this, and why? The technical error in the first case is the same as the second. In short, I would strongly suggest you don't use @property, especially if you're learning the language. It's an advanced feature. In your particular case, you're getting into unnecessary trouble by using it. From jarod_v6 at libero.it Fri Jan 23 12:47:24 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Fri, 23 Jan 2015 12:47:24 +0100 (CET) Subject: [Tutor] R: Re: Re: Re: Class learning Message-ID: <485938766.222141422013644833.JavaMail.httpd@webmail-07.iol.local> Thanks so much for clear explanation!!! So in this way work . In [38]: Test().x.__name__ Out[38]: 'x' The decoratory proprerty dosen't help to create the class in fast way.. When it is advisable use @property? From s.shall at virginmedia.com Fri Jan 23 14:07:07 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Fri, 23 Jan 2015 13:07:07 +0000 Subject: [Tutor] Installing psutil 2.2.0-1 on Canopy Enthought In-Reply-To: References: <54C0F37E.5070209@virginmedia.com> Message-ID: <54C2477B.7020402@virginmedia.com> On 22/01/2015 22:53, Alan Gauld wrote: > On 22/01/15 12:56, Sydney Shall wrote: >> I use MAC OSX 10.9.5 >> Canopy Enthought python 2.7.6 >> >> I also use the Enthought Package Manager to keep my installation >> up-todate. >> > > Canopy and Enthoughts paqckage management are well beyond the bounds of > standard Python. > >> What in fact is my problem? I simply want to update this package, and I >> cannot. >> >> I do not know if this is the best Forum to get advice on this, but any >> guidance, including where else I might ask would be appreciated. > > I'd try the Enthought/Canopy forums. Or perhaps even the SciPy forums > because Canopy has SciPy as standard (along with a bunch of other stuff) > > Thanks Alan. You have solved my problem. I should have thought of Enthought/Canopy Forum. Enjoy your walking. -- Sydney From alan.gauld at btinternet.com Fri Jan 23 19:30:55 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 23 Jan 2015 18:30:55 +0000 Subject: [Tutor] Class learning In-Reply-To: <1373014271.806721421977473153.JavaMail.httpd@webmail-50.iol.local> References: <1373014271.806721421977473153.JavaMail.httpd@webmail-50.iol.local> Message-ID: On 23/01/15 01:44, jarod_v6 at libero.it wrote: > How can gave the attributes __name__ to a function? You don't Python does it for you. > class Foo(object): > > def __init__(self): > steps = {} > tmp = open("rnaseq.base.ini","rb") > config.readfp(tmp) > readsets = parse_illumina_readset_file("/home/mauro/Desktop/readset.csv") You realise that steps is a local variable that is not used and gets thrown away. So its a waste of space. Similarly you read the config file but throw away the results. Again a waste of space. And the same with readsets. Your init does a lot of work to no long term effect. > @property > def steps(self): > return [ > > self.one, > self.two, > self.fmit, > ] > def one(self): > a = 5 > return a ... > #@property > def show(self): > ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) > > print ftp > It is working > > In [5]: F = Foo() > > In [6]: F.show() > 1- one > 2- two > 3- fmit Yes, as expected. > Why if I define the data in the same way I have this error? > > in () > ----> 1 rna.show() > > in show(self) > 261 #@property > 262 def show(self): > --> 263 ftp="\n".join([str(idx + 1) + "- " + step.__name__ for idx, step in enumerate(self.steps)]) > 264 > 265 print ftp > > AttributeError: 'str' object has no attribute '__name__' Because you didn't define it in the same way. Consider this example from the pastebin: @property def star(self): print "Mitico Star" return "name" Here you make star a property so when in steps you store self.star you are not storing a reference to the method, as you did above, you are storing the return value of star - "name". Now in show() you try to take the __name__ of "name" but, as the error says, strings don't have __name__ attributes. The same applies to some, but not all, of the other method names in steps... You would make life much easier if you got rid of all the property stuff (some of it commented out and others not). Just use the methods and data attributes directly, it makes life so much easier. > Here you find all the other code the principal are the same:http://pastebin.com/nYGEiXY4 HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 23 21:33:40 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 23 Jan 2015 20:33:40 +0000 Subject: [Tutor] Initiating an external email transmission In-Reply-To: <1421982564.434144.217713981.727B20E7@webmail.messagingengine.com> References: <1421982564.434144.217713981.727B20E7@webmail.messagingengine.com> Message-ID: On 23/01/15 03:09, dw wrote: > I have a python script that I've created. > The issue is, I made it for someone else to use in his PC. > And its not working for him. The first thing to do when creating a program for use on another computer is to make everything that could be machine specific configurable. Either put it in a config file or use environment variables. That includes all IP addresses, port numbers and filenames. I don't know for sure that it's the problem here, but you have a lot of hard coded values in there. They may be the right values on your PC but there's no reason to think your client's will be the same. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 23 21:37:18 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 23 Jan 2015 20:37:18 +0000 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: <485938766.222141422013644833.JavaMail.httpd@webmail-07.iol.local> References: <485938766.222141422013644833.JavaMail.httpd@webmail-07.iol.local> Message-ID: On 23/01/15 11:47, jarod_v6 at libero.it wrote: > Thanks so much for clear explanation!!! So in this way work . > In [38]: Test().x.__name__ > Out[38]: 'x' > The decoratory proprerty dosen't help to create the class in fast way.. When > it is advisable use @property? Very rarely, and mainly when you need to access a number of attributes some of which are pure data and others are derived via a method. You can make the methods look like data by making them properties. In 18 years of using python I've used @property about 3 or 4 times in real projects. It is used a lot in Delphi (Object Pascal) and some similar languages but it's not often needed in Python. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at zip.com.au Sat Jan 24 01:37:10 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 24 Jan 2015 11:37:10 +1100 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: References: Message-ID: <20150124003710.GA7360@cskk.homeip.net> On 23Jan2015 20:37, Alan Gauld wrote: >On 23/01/15 11:47, jarod_v6 at libero.it wrote: >>Thanks so much for clear explanation!!! So in this way work . >>In [38]: Test().x.__name__ >>Out[38]: 'x' >>The decoratory proprerty dosen't help to create the class in fast way.. When >>it is advisable use @property? > >Very rarely, and mainly when you need to access a number of attributes >some of which are pure data and others are derived via a method. You >can make the methods look like data by making them properties. > >In 18 years of using python I've used @property about 3 or 4 times in >real projects. [...] By contrast, I use it a far bit (though still far less than non-property methods). Generally for derived properties which are: - cheap to compute i.e. O(1) - which I want to abstract from the things from which it is computed, so that the user need not know the object internals (which also leaves you freer to change those internals later should the need arise) - usually represent some property which is stable, such as a size - occasionally (much more rarely) a property which is not stable, eg: @property def active(self): return self._users > 0 Here's an example (from real code) where I keep (externally) a dict which maps from node keys to nodes, for fast access and to avoid making more than one node for the same key. class URI_Node(object): def __init__(self, method, uri): self.method = method self.uri = uri @property def key(self): return self.method, self.uri Here the .key property happens to be a (method, uri) tuple. Might change in the future if that is not enough to uniquely identify the node. Cheers, Cameron Simpson Surely it was of this place, now Cambridge but formerly known by the name of Babylon, that the prophet spoke when he said, 'the wild beasts of the desert shall dwell there, and their houses shall be full of doleful creatures, and owls shall build there, and satyrs shall dance there.' - Thomas Gray (1716-1771) From alan.gauld at btinternet.com Sat Jan 24 01:47:02 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 24 Jan 2015 00:47:02 +0000 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: <20150124003710.GA7360@cskk.homeip.net> References: <20150124003710.GA7360@cskk.homeip.net> Message-ID: On 24/01/15 00:37, Cameron Simpson wrote: > By contrast, I use it a far bit (though still far less than non-property > methods). Generally for derived properties which are: > > - cheap to compute i.e. O(1) > > - which I want to abstract > > - usually represent some property which is stable, such as a size > > - occasionally (much more rarely) a property which is not stable, But why a property rather than a simple method? Why is k = url.key better than k = url.key() for meeting those criteria? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Sat Jan 24 02:16:50 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 23 Jan 2015 17:16:50 -0800 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: References: <20150124003710.GA7360@cskk.homeip.net> Message-ID: > > But why a property rather than a simple method? > Why is > > k = url.key > > better than > > k = url.key() > > for meeting those criteria? My understanding is this is very much a Python-specific problem. Python style encourages raw access to the attributes of an object via direct lookup and assignment. We use underscores conventionally to hide private details. The language itself says very little about privacy enforcement. Given that state of the world, people wrote code. And once something's written, it has a legacy. Once we have legacy code full of attribute setting and getting, we might revise our view and desire to manage those attributes more carefully. Maybe we want to compute those values lazily and cache aggressively. Maybe we want to make sure an attribute's value is always a positive integer. In other languages like Java, we can do this management with explicit setters and getters: we can have code that does runtime checks before permitting an attribute to be assigned. That's one reason for the getter/setter boilerplate we see out there: it's all in preparation for the inevitable code revision. But maybe we don't want to rewrite all that legacy code. Python properties let us retrofit setter/getter-like attribute management, but without having to rewrite clients to use method calls. It's syntactic sugar. --- In the context of beginner programming, there's no "legacy code" to talk about, so that's why I don't think it's appropriate to teach properties to beginners: it's not the right audience. From cs at zip.com.au Sat Jan 24 02:50:40 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 24 Jan 2015 12:50:40 +1100 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: References: Message-ID: <20150124015040.GA69318@cskk.homeip.net> On 24Jan2015 00:47, Alan Gauld wrote: >On 24/01/15 00:37, Cameron Simpson wrote: >>By contrast, I use it a far bit (though still far less than non-property >>methods). Generally for derived properties which are: >> - cheap to compute i.e. O(1) >> - which I want to abstract >> - usually represent some property which is stable, such as a size >> - occasionally (much more rarely) a property which is not stable, > >But why a property rather than a simple method? >Why is > >k = url.key > >better than > >k = url.key() > >for meeting those criteria? Because it is a value that feels like an attribute. A method that always returns the same value for a given object (and is very cheap) is, to my mind, not worth burdening the caller with the detail that is it a function. If the caller can ask for o.key() and be given a value that is stable, and will not change (and therefore will never require another call if the caller bothers keeping the value around) then why should the caller care that it is a function? So why should it even look like a function? It should look and feel like any other object attribute - a simple value that can just be examined. My intuition is that a function is costly (potentially) and that consulting an attribute is very cheap. I don't want to break such intuition. Consider .keys() for a dynamic mapping. Changeable, and expensive. It should look like a function. Cheers, Cameron Simpson A pessimist is an optimist in full possession of the facts. From alan.gauld at btinternet.com Sat Jan 24 10:16:48 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 24 Jan 2015 09:16:48 +0000 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: <20150124015040.GA69318@cskk.homeip.net> References: <20150124015040.GA69318@cskk.homeip.net> Message-ID: On 24/01/15 01:50, Cameron Simpson wrote: > On 24Jan2015 00:47, Alan Gauld wrote: >> But why a property rather than a simple method? > Because it is a value that feels like an attribute. OK, Having seen Dannys reply as well as yours I guess I see the logic. I think Python's openness has lead ton this problem of breaking the basic OOP model. The whole concept of OOP is that objects communicate via messages. Direct access to the internals should be discouraged. So the default mechanism should be a message which in Python is represented by a method call. But Python has traditionally allowed direct access to data which has encouraged a style of programming that forgets that objects are not *supposed* to be directly accessed. That leads to a kind of mentality that treats objects as mere containers rather than as active subprograms, In that frame of reference properties sound like a good thing even though they break the fundamental theoretical OOP model. The problem I have with properties is that they are fundamentally a way of "fixing" a broken model. We have allowed people to mix direct access and message calling then bolted on a way to convert the direct access into a method call. Its pragmatic but not conducive to fixing the underlying issue. Future incarnations of the classes involved are likely to promulgate the direct access approach. > A method that always returns the same value for a given object (and is > very cheap) is, to my mind, not worth burdening the caller with the > detail that is it a function. There is the problem. When using objects we shouldn't be thinking that we are calling a function we should be thinking we are sending a message. The message may look like a kind of function call but conceptually its very different. We are instructing an independent computing entity (the object) to perform some task on our behalf. The object may be a part of our programs computing environment or it could be on another processor or even on another network node, we shouldn't care. > the caller bothers keeping the value around) then why should the caller > care that it is a function? So why should it even look like a function? Because they should remember that they are dealing with an object not just a data container. It encourages the client (and designer) to treat the object as a separate "living" entity within the program. > It should look and feel like any other object attribute - a simple value > that can just be examined. But that's a broken object model. It's a concession Python makes for pragmatic reasons. Unfortunately we, as Python programmers, are starting to abuse that freedom and forget the fundamentals of OOP. Our programs become more brittle because of it and we need to introduce "fixes" like properties to tidy up the mess. > My intuition is that a function is costly (potentially) and that > consulting an attribute is very cheap. I don't want to break such > intuition. That's true, there is a small overhead in calling a function but considering that aspect in the OOP design stage is always a premature optimisation. Bad OOP design that encourages direct access to data for processing outside the object is far more likely to lead to performance issues. Of course pure OOP design is often not practical (or even possible) and very occasionally we do need to consider the performance impact of a function call, but those occasions are as rare as hens teeth in most real world programs, there are usually far bigger factors to consider. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at zip.com.au Sat Jan 24 12:32:31 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 24 Jan 2015 22:32:31 +1100 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: References: Message-ID: <20150124113231.GA61910@cskk.homeip.net> On 24Jan2015 09:16, Alan Gauld wrote: >On 24/01/15 01:50, Cameron Simpson wrote: >>On 24Jan2015 00:47, Alan Gauld wrote: > >>>But why a property rather than a simple method? > >>Because it is a value that feels like an attribute. > >OK, Having seen Dannys reply as well as yours I guess I see the logic. >I think Python's openness has lead ton this problem of breaking the >basic OOP model. The whole concept of OOP is that objects communicate >via messages. Direct access to the internals should be discouraged. >So the default mechanism should be a message which in Python is >represented by a method call. However, Python is an "open Kimono" language; direct access to object attributes is permitted and, with restraint, encouraged what appropriate. EVen the leading underscore convention for "private" attributes is just a naming convention. The point here is that while you _can_ program in a pure OOP fashion, using only method calls, the language does not enforce this. Since OOP is just a particular paradigm, this is a good thing: one can choose to work that way or you can choose not to, or you can mix at your discretion. >But Python has traditionally allowed direct access to data which >has encouraged a style of programming that forgets that objects >are not *supposed* to be directly accessed. In a "pure" OOP environment yes. But this needn't be. >That leads to a kind of mentality that treats objects as mere >containers rather than as active subprograms, In that frame of >reference properties sound like a good thing even though they break >the fundamental theoretical OOP model. > >The problem I have with properties is that they are fundamentally >a way of "fixing" a broken model. We have allowed people to mix >direct access and message calling then bolted on a way to convert the >direct access into a method call. Its pragmatic but not conducive to >fixing the underlying issue. Future incarnations of the classes >involved are likely to promulgate the direct access approach. There is a flip side to that. In a language like Python or Java, every entity is an object. Including mere containers. If the only medium for interacting with a contained is a message in the form of a method call, things get very painful very fast. So there is a line to be drawn, several in fact. For notational convenience, a property is worthwhile all on its own: it presents succinct access to object messages that retrieve or set an aspect of a message. And for containers, again you have a choice. You can permit direct access to container members as ordinary attributes, or you can require cumbersome method access and some kind of (perhaps implicit) mapping from method names to the private container member attributes. While you see a property as a hack, I view it as a succinct way to provide method mediated access to an attribute with the benefits that can accompany it: programmed behaviour around the access or setting, or simple abstraction, separating the published name of the property from whatever object internals are used in its implementation. >>A method that always returns the same value for a given object (and is >>very cheap) is, to my mind, not worth burdening the caller with the >>detail that is it a function. > >There is the problem. When using objects we shouldn't be thinking that >we are calling a function we should be thinking we are sending a >message. The message may look like a kind of function call but >conceptually its very different. We are instructing an independent >computing entity (the object) to perform some task on our behalf. The >object may be a part of our programs computing environment or it could >be on another processor or even on another network node, we shouldn't >care. > >>the caller bothers keeping the value around) then why should the caller >>care that it is a function? So why should it even look like a function? > >Because they should remember that they are dealing with an object not >just a data container. It encourages the client (and designer) to >treat the object as a separate "living" entity within the program. > >>It should look and feel like any other object attribute - a simple value >>that can just be examined. > >But that's a broken object model. It's a concession Python makes >for pragmatic reasons. Unfortunately we, as Python programmers, are >starting to abuse that freedom and forget the fundamentals of OOP. >Our programs become more brittle because of it and we need >to introduce "fixes" like properties to tidy up the mess. OOP is a tool to an end. It is a very expressive and powerful discipline giving you good data separation. But it isn't the only tool, and it isn't always the preferred choice. >>My intuition is that a function is costly (potentially) and that >>consulting an attribute is very cheap. I don't want to break such >>intuition. > >That's true, there is a small overhead in calling a function >but considering that aspect in the OOP design stage is always >a premature optimisation. Bad OOP design that encourages direct >access to data for processing outside the object is far more >likely to lead to performance issues. [...] Here you have missed my point. I am not referring to the overhead of making a function call, but the intuitive cost that distinguishes something one thinks of as an attribute from something one thinks of as a function: a function may entain an arbitrary amount of work whereas an attibute is almost free, and constant in cost. I'm not talking about optimisation here, I'm talking about the notion of a value that is derived from (unspecified and perhaps costly) computation versus a value that is merely stored, and trivially retrieved. The an attribute/method/function very closely resembles the latter, I am prone to make it into a property. Cheers, Cameron Simpson ... you could spend *all day* customizing the title bar. Believe me. I speak from experience. - Matt Welsh From steve at pearwood.info Sat Jan 24 15:58:09 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 25 Jan 2015 01:58:09 +1100 Subject: [Tutor] Does the Python way of doing things have a definite preference for the structure and content of program file header comments? In-Reply-To: References: <20150122234528.GG18556@ando.pearwood.info> Message-ID: <20150124145806.GC20517@ando.pearwood.info> On Fri, Jan 23, 2015 at 12:10:38AM -0600, boB Stepp wrote: > On Thu, Jan 22, 2015 at 5:45 PM, Steven D'Aprano wrote: > > On Thu, Jan 22, 2015 at 03:17:58PM -0600, boB Stepp hid the following > > question in the subject line: > > > > "Does the Python way of doing things have a definite preference for the > > structure and content of program file header comments?" > > > > and then wrote: > > > >> And will this vary depending on whether a version control system is > >> being used or not? Or is the use of a version control system > >> considered to be highly recommended (if not mandatory)? > > > > This is a language-agnostic question, it is not specific to Python. It > > may be a question about the community of users for a language, but in > > principle at least it applies to *every language*. > > I was wondering if the Python culture had their own particular take on > these types of comments. A good place to learn about Python culture is to look at the standard library. Assuming you are using Python 2.7, you can look at the .py files in some place like /usr/lib/python2.7/ or /usr/local/lib/python2.7/ on Linux. If you have trouble locating the standard library, run this: import warnings print warnings.__file__ and it will print the location of the warnings module from the standard library. (Standard disclaimer applies: if you have created a file called "warnings.py", it will shadow the standard module.) Have a look at the sort of thing that the standard library does. (Remember not to edit the files, lest you break them.) If you don't like the idea of poking around in the standard library with an editor, you can also see the files on the web. Go to the Python docs, choose a module, and many of them will include a read-only link to the source code, e.g.: https://docs.python.org/2/library/pprint.html has a link to: https://hg.python.org/cpython/file/2.7/Lib/pprint.py You might also like to see the sort of thing I put in my modules: http://code.google.com/p/pyprimes/source/browse/ [...] > I am striving hard to at least make myself aware of what constitutes > "professionalism" in software creation. I fully intend to go in your > stated direction, but finding time to become proficient in such a tool > in the midst of all the other things I am trying to absorb is > difficult. I know. So many things to learn, so many distractions, so little time... > However, my mention of version control was in response to a > web search where many said that including change logs/version history > in a program's header comments is made unnecessary by modern version > control systems and is even harmful in that it might lead to > unmaintained comments. OTH, there seemed to be plenty of others who > advocate that this information should indeed be included in the > program's header comments. My take on this is: - your version control system will track the minutiae of your changes; - you should have a separate CHANGELOG file as part of your project, where you put the "important" changes that will be of interest to your users; - keep the change log out of the source code. So, from my "pyprimes" project linked to above, you can see my change log file here: http://code.google.com/p/pyprimes/source/browse/CHANGES.txt That's the things I think are important enough to mention. Because the change log itself is under version control, you can look back at each revision and see how the change log itself changes. And here are all the individual changes, as recorded by the version control system: http://code.google.com/p/pyprimes/source/list > Ugh! Unfortunately I have mirrored your example recently, which has > had me wondering whether I should "make" time to implement a DVCS. By "implement", I trust you don't mean "write your own" :-) There's a good tutorial for Mercurial, or hg, writen by Joel Spolsky: http://hginit.com/ [...] > "Best practices". "Software craftsmanship". Clarity of code. And > more... As I continue to learn I am appreciating these things more and > more, especially when I must suffer multi-day interruptions to the > project I am working on and have to reconstruct what I had last been > doing/thinking. I find myself almost constantly trying to rename > things to make them more self-explanatory, break things down into more > self-contained, single-purpose constructs, etc. Trying to make my code > more "obvious" as to what it is doing to the casual reader is becoming > much more important to me. So much to learn, and the more I learn the > more I realize I do not know... That is excellent! If you are busy or suffer a lot of distractions, *you* are your own Number 1 casual reader. Actually, even if you are not distracted, comments and good naming conventions are essential. A few days ago, one of the programmers I work with was bitterly complaining about some code. Let's call him Trevor (not his real name). After a while, he went quiet, then called out "Stupid yesterday Trevor!" -- it was his own code, written just one day ago, and he couldn't work out what it did. -- Steve From breamoreboy at yahoo.co.uk Sat Jan 24 16:03:10 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 24 Jan 2015 15:03:10 +0000 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: <20150124015040.GA69318@cskk.homeip.net> References: <20150124015040.GA69318@cskk.homeip.net> Message-ID: On 24/01/2015 01:50, Cameron Simpson wrote: > > My intuition is that a function is costly (potentially) and that > consulting an attribute is very cheap. I don't want to break such > intuition. > It's not just your intuition, it's a fact. Function calls are costly, relative to attribute lookup that is, at least in cPython. I've no idea what the impact is in other implementations. I'd guess that 99% of the time 99% of Python programmers needn't worry about it. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Sat Jan 24 17:17:41 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 25 Jan 2015 03:17:41 +1100 Subject: [Tutor] Initiating an external email transmission In-Reply-To: <1421982564.434144.217713981.727B20E7@webmail.messagingengine.com> References: <1421982564.434144.217713981.727B20E7@webmail.messagingengine.com> Message-ID: <20150124161741.GD20517@ando.pearwood.info> On Thu, Jan 22, 2015 at 07:09:24PM -0800, dw wrote: > I have a python script that I've created. > It logs into an online email service and sends out an email. > It works in my Linux box, and it works in my Windows 7 box. > I've also converted it with Py2EXE and it works as an executable in my > Win-7 box. > > The issue is, I made it for someone else to use in his PC. > And its not working for him. Well, what does it do? The most useless problem report is "it isn't working". That tells us nothing. Does it raise an exception? Crash? Set the laptop on fire? Something else? > His system is Windows 7. > And I'm wondering if perhaps he has a firewall blocking it? Quite possibly. Can he send email from his laptop? If so, how? Does he use Gmail via their website, Outlook, something else? Does his ISP block outgoing email on port 25? Many ISPs do, to try to prevent viruses from sending out spam. Does your friend actually have a mail server running? I recommend that you run through the example here: https://docs.python.org/2/library/email-examples.html and see what happens. -- Steven From cs at zip.com.au Sat Jan 24 21:20:18 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 25 Jan 2015 07:20:18 +1100 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: References: Message-ID: <20150124202018.GA50479@cskk.homeip.net> On 24Jan2015 15:03, Mark Lawrence wrote: >On 24/01/2015 01:50, Cameron Simpson wrote: >>My intuition is that a function is costly (potentially) and that >>consulting an attribute is very cheap. I don't want to break such >>intuition. > >It's not just your intuition, it's a fact. Function calls are costly, >relative to attribute lookup that is, at least in cPython. I've no >idea what the impact is in other implementations. I'd guess that 99% >of the time 99% of Python programmers needn't worry about it. Like Alan, you've missed my intent here. To quote from my reply to Alan: I am not referring to the overhead of making a function call, but the intuitive cost that distinguishes something one thinks of as an attribute from something one thinks of as a function: a function may entain an arbitrary amount of work whereas an attibute is almost free, and constant in cost. I'm not talking about optimisation here, I'm talking about the notion of a value that is derived from (unspecified and perhaps costly) computation versus a value that is merely stored, and trivially retrieved. The an attribute/method/function very closely resembles the latter, I am prone to make it into a property. Cheers, Cameron Simpson On two occasions I have been asked [by members of Parliament], 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. - Babbage From bw_dw at fastmail.net Sat Jan 24 23:49:41 2015 From: bw_dw at fastmail.net (bw_dw at fastmail.net) Date: Sat, 24 Jan 2015 14:49:41 -0800 Subject: [Tutor] Initiating an external email transmission In-Reply-To: References: Message-ID: <1422139781.1199476.218372441.2A71EE99@webmail.messagingengine.com> I apologize .... I should have known better than to have posted without getting more info from the user. Since then, I've discovered that simply sending someone a Py2ExE executable is not sufficient. A little more investigation about Py2EXE and I'm beginning to see it requires both the executable file along with supportive files. I loaded the executable with all of the supportive files in a win-7 laptop last night. The error message was urllib2.URLError: I googled a little bit and got indicators...something having to do with a proxy. But that doesn't make any sense to me. Getting something to work in Python is fairly easy. Getting it to work as an executable in a different PC is something else altogether. Sorry for causing people frustration!! :-/ From steve at pearwood.info Sun Jan 25 09:00:22 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 25 Jan 2015 19:00:22 +1100 Subject: [Tutor] R: Re: Re: Re: Class learning In-Reply-To: <20150124202018.GA50479@cskk.homeip.net> References: <20150124202018.GA50479@cskk.homeip.net> Message-ID: <20150125080022.GF20517@ando.pearwood.info> Sorry folks, I haven't been keeping up with this specific thread, so I'm going to just jump in with an opinion no matter how ignorant... :-) On Sun, Jan 25, 2015 at 07:20:18AM +1100, Cameron Simpson wrote: > Like Alan, you've missed my intent here. > > To quote from my reply to Alan: > > I am not referring to the overhead of making a function call, but the > intuitive cost that distinguishes something one thinks of as an attribute > from > something one thinks of as a function: a function may entain an arbitrary > amount of work whereas an attibute is almost free, and constant in cost. > > I'm not talking about optimisation here, I'm talking about the notion of a > value that is derived from (unspecified and perhaps costly) computation > versus > a value that is merely stored, and trivially retrieved. If I understand you correctly, I think what you are trying to get across is that if you have a computed value which is *conceptually* just a attribute look-up, use a property, but if it is conceptually a matter of detailed calculation (or if, in fact, it actually is an expensive calculation) then make it a method call. Something like this: class Dog: @property def number_of_legs(self): # not necessarily four, some dogs have lost limbs and # there are mutant dogs with more than four legs legs = [part for part in self.body_parts if isinstance(part, Leg)] return len(legs) def number_of_fleas(self): """Count the number of fleas on the dog.""" count = 0 area = get_surface(self) grid = divide_into_grid(area) for section in grid: n = Inspect(section).count(Flea) count += n return count The number of legs feels like a simple attribute of the dog, which we should be able to take in at a glance. Counting the number of fleas on a dog feels like something hard and time consuming. In this case, our intuition about what is hard and what is easy is probably correct, but it may not be for all classes. TL;DR: If you have a computed attribute, and it feels like it should be cheap to calculate, and it actually is cheap to calculate, then make it a property. If it is expensive, then make it a method. -- Steve From jarod_v6 at libero.it Mon Jan 26 11:48:52 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Mon, 26 Jan 2015 11:48:52 +0100 (CET) Subject: [Tutor] order loop from methos on class Message-ID: <2044122047.125321422269332108.JavaMail.defaultUser@defaultHost> Dear All, What is the best way to loop on methos on a class? class Rna(): def trim(): ... def align(): ... ena = Rna() ena.trim() ena.aling() Thanks for any suggestion!!! From steve at pearwood.info Mon Jan 26 12:04:40 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 26 Jan 2015 22:04:40 +1100 Subject: [Tutor] order loop from methos on class In-Reply-To: <2044122047.125321422269332108.JavaMail.defaultUser@defaultHost> References: <2044122047.125321422269332108.JavaMail.defaultUser@defaultHost> Message-ID: <20150126110440.GK20517@ando.pearwood.info> On Mon, Jan 26, 2015 at 11:48:52AM +0100, jarod_v6 at libero.it wrote: > > > Dear All, > What is the best way to loop on methos on a class? I do not understand the question. Can you explain in more detail? > class Rna(): > def trim(): > ... > def align(): > ... Both methods need a "self" parameter: def trim(self): ... def align(self): ... > ena = Rna() > ena.trim() > ena.aling() ena.align() -- Steve From ljetibo at gmail.com Mon Jan 26 12:41:19 2015 From: ljetibo at gmail.com (=?ISO-8859-2?Q?Dino_Bekte=B9evi=E6?=) Date: Mon, 26 Jan 2015 12:41:19 +0100 Subject: [Tutor] Tutor Digest, Vol 131, Issue 59 Order loop from methos on class (jarod_v6@libero.it) Message-ID: > Message: 1 > Date: Mon, 26 Jan 2015 11:48:52 +0100 (CET) > From: "jarod_v6 at libero.it" > To: tutor at python.org > Subject: [Tutor] order loop from methos on class > Message-ID: > <2044122047.125321422269332108.JavaMail.defaultUser at defaultHost> > Content-Type: text/plain; charset=UTF-8 > > > > Dear All, > What is the best way to loop on methos on a class? > > class Rna(): > def trim(): > ... > def align(): > ... > > ena = Rna() > > ena.trim() > ena.aling() > > > > Thanks for any suggestion!!! Not quite sure where you're going with this, but to loop through the methods of a class can be done and is dependent on the python version... For py3: class Rna(): def trim(): print(1) def align(): print(2) ena = Rna() for method in dir(Rna): if method[:2] != "__": ena.__getattribute__(method)() the other way to do it is to: for method in dir(Rna): if method[:2] != "__": getattr(ena, method)() DO NOTICE HOW "WONKY" THIS IS. If you have a method that expects input, or if you defined private methods (with __) this will either skip them, or in worse case, if you cut out the if question, try to call all the builtin methods (such as getattribute) and it will fail because no proper input has been sent. This will only work for C style "void" kind of methods. Probably the best way to get them, though, do it is to: import inspect inspect.getmembers(Rna(), predicate=inspect.ismethod) [('__init__', >), ('align', >), ('trim', >)] This gets you tuples of (name, reference) kind of deal you can run through. This does help to weed out some of the builtin methods, but __init__ (or possibly __new__ ?) will still show up. If you need the builtins as well you can ask for inspect.isbuiltin. In python2 the first way is not going to work for sure, I don't think there exist a __getattribute__, but the 2nd way (getattr) and the inpect module will. I do wonder why do you need this though. I've only once run into a situation where I did something similar and that was _ONLY_ because I was too lazy to write up proper classes and decompose the problem, for what at the time seemed like a simple test run, so I ended up reading a lot of properties from a file and did not want to name all of them myself in the code. I ended up paying the price and wrote all the necessary classes because it was hard to debug.... Hopefully you'll think it through, don't be lazy it never pays off! Best of luck, Dino From jarod_v6 at libero.it Mon Jan 26 14:54:03 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Mon, 26 Jan 2015 14:54:03 +0100 (CET) Subject: [Tutor] R: Re: Tutor Digest, Vol 131, Issue 59 Order loop from methos on class (jarod_v6@libero.it) Message-ID: <22530215.206571422280443148.JavaMail.defaultUser@defaultHost> Thanks so much!! Now I understood it is a stupid thing! So, could you elpme to decompose the problem? I initiazlizate the class with the file to use so all the function have all the parameters that I need. At the moment I have in mind only to do this: ena = Rna() job1 = ena.trim() job2 = ena.align() It is no so elegant.. Any suggestion? From ljetibo at gmail.com Mon Jan 26 15:41:12 2015 From: ljetibo at gmail.com (=?ISO-8859-2?Q?Dino_Bekte=B9evi=E6?=) Date: Mon, 26 Jan 2015 15:41:12 +0100 Subject: [Tutor] Tutor Digest, Vol 131, Issue 59 Order loop from methos on class (jarod_v6@libero.it) Message-ID: 2015-01-26 14:54 GMT+01:00 jarod_v6 at libero.it : > Thanks so much!! Now I understood it is a stupid thing! > So, could you elpme to decompose the problem? > I initiazlizate the class with the file to use so all the function have all > the parameters that I need. > > At the moment I have in mind only to do this: > ena = Rna() > job1 = ena.trim() > job2 = ena.align() > It is no so elegant.. > > > > Any suggestion? > Without seeing what exactly are you trying to do (I'm not a chemist/biologist) I'm not sure. Any detail about what you're trying to do would be helpful. If you're bothered by having to call 2 methods except of 1 you could always make another method that uses the two. It really depends on the decision if you want to do the operations in place or not, that is transform the original object through it's methods, or do you want to return a new object of the same class. In your example you write "job" as if you're dealing with threads. I can't tell if you want job1 and job2 to be another different objects (maybe of Rna class maybe not) or is it just that you don't understand that you can also call a method on an object without having a variable to hold a return value. If you want to return another Rna object that is the same as the original one, maybe something like this is what you need? i.e. import copy class Rna(): def __init__(self): self.trimmed = False self.aligned = False #NOT a part of the class def trim(rna): temp = copy.copy(rna) temp.trimmed = True return temp #in interpreter >>>> ena = Rna() >>>> ena.trimmed False >>>> tena = trim(ena) >>>> ena.trimmed False >>>> tena.trimmed True and both of ena and tena will be of class Rna. So you now have 2 different Rna objects. You could also have it done in place, which saves memory and is more natural and I'd recommend it: class Rna(): def __init__(self): self.trimmed=False self.aligned=False def trim(self): self.trimmed=True def align(self): self.aligned=True def DoBoth(self): self.trim() self.align() print("Done!") #in the interpreter >>>> ena = Rna() >>>> ena.trimmed False >>>> ena.aligned False >>>> ena.DoBoth() Done! >>>> ena.trimmed True >>>> ena.aligned True This way you can do both without having to constantly write them yourself... you issue 1 call which then calls various other methods you have on the instance itself.... Even that print isn't necessary, that's just there to show it finished. You don't always have to have a variable to catch potential output of a method. But maybe if you need/want to catch the output maybe that output is an object of a different class(?) maybe it's a tuple, or an array? class Rna(): def __init__(self): self.trimmed=False self.aligned=False def trim(self): self.trimmed=True def align(self): self.aligned=True def DoBoth(self): self.trim() self.align() print("Done! We return an list of solutions:") return [1,2,3,4,5,6,7,8,9] #in the interpreter >>>> ena = Rna() >>>> solutions = ena.DoBoth() Done! We return an list of solutions: >>>> solutions [1,2,3,4,5,6,7,8,9] You could also add the solutions as an attribute to the object you just did the calculation on: def DoBoth(self): self.trim() self.align() print("Done! We return an list of solutions:") self.solutions = [1,2,3,4,5,6,7,8,9] #in the interpreter >>>> ena = Rna() >>>> ena.DoBoth() Done! We return an list of solutions: >>>> ena.solutions [1,2,3,4,5,6,7,8,9] The better you describe WHAT you want and HOW you want it the better people here will be able to help you.... Best of luck, Dino From alan.gauld at btinternet.com Mon Jan 26 16:26:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 26 Jan 2015 15:26:27 +0000 Subject: [Tutor] R: Re: Tutor Digest, Vol 131, Issue 59 Order loop from methos on class (jarod_v6@libero.it) In-Reply-To: <22530215.206571422280443148.JavaMail.defaultUser@defaultHost> References: <22530215.206571422280443148.JavaMail.defaultUser@defaultHost> Message-ID: On 26/01/15 13:54, jarod_v6 at libero.it wrote: > I initiazlizate the class with the file to use so all the function have all > the parameters that I need. > > At the moment I have in mind only to do this: > ena = Rna() > job1 = ena.trim() > job2 = ena.align() > It is no so elegant.. You originally posted a solution where you had a list of methods in an attribute called steps. That's a better solution than trying to iterate over all the methods in the class. for method in self.steps: method() But you don't really tell us what you are trying to do. So its hard to determine what an elegant solution is when we don't know the problem we are trying to solve. It looks as if you are trying to create a workflow of some sort? Does the flow always follow the same sequence - use a list of methods Does the workflow vary depending on results - use a table where the return value of each method indicates which column to call next. Is each method called only once or can it repeat steps? How are errors to be handled? Is timing critical? Do you need to fully process one record at a time or can it be batch oriented? There are lots of questions to consider, all of which affect the "best" solution. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From agarwal7781 at gmail.com Mon Jan 26 16:56:40 2015 From: agarwal7781 at gmail.com (Arpit Agarwal) Date: Mon, 26 Jan 2015 21:26:40 +0530 Subject: [Tutor] Inquiry regarding GSoC 2015 Message-ID: Hello, I want to take part in GSoC 2015 under PSF. I am a beginner in python and have started contributing and i am also registerd at github. Please suggest as from which projects i should start for contributing as i am beginner in python. thanks. From mnickey at gmail.com Mon Jan 26 18:15:05 2015 From: mnickey at gmail.com (Mike Nickey) Date: Mon, 26 Jan 2015 09:15:05 -0800 Subject: [Tutor] SQLAlchemy Message-ID: Hey folks, I'm working my way through Thinkful with python and I'm trying to get a setup working. Part of this setup is using SQLAlchemy. While I understand this is a python tutor list, would it be OK to ask questions like 'how do I change my SQLAlchemy URL to include a user name' here? -- ~MEN From martin at linux-ip.net Mon Jan 26 19:23:35 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Mon, 26 Jan 2015 10:23:35 -0800 Subject: [Tutor] SQLAlchemy In-Reply-To: References: Message-ID: Greetings Mike, : I'm working my way through Thinkful with python and I'm trying to : get a setup working. Part of this setup is using SQLAlchemy. : While I understand this is a python tutor list, would it be OK to : ask questions like 'how do I change my SQLAlchemy URL to include : a user name' here? You could ask here about this (excellent) third-party library, but you will doubtless find a much richer pool of knowledge to draw from if you were to ask this question directly of the SQLAlchemy crowd [0]. There's a mailing list [1] or IRC [2]. I expect that you are calling sqlalchemy.engine.create_engine() at some point. When you are doing that, you can/should pass your desired user credentials into this function. http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html Good luck, -Martin [0] http://www.sqlalchemy.org/support.html [1] https://groups.google.com/forum/#!forum/sqlalchemy [2] 'The IRC channel is on the Freenode network as #sqlalchemy.' -- Martin A. Brown http://linux-ip.net/ From dyoo at hashcollision.org Mon Jan 26 19:35:15 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 26 Jan 2015 10:35:15 -0800 Subject: [Tutor] Inquiry regarding GSoC 2015 In-Reply-To: References: Message-ID: We (the Tutor list) are not a mentor for GSoC. You'll want to talk to the right organization for this, because I don't think any of us here have any direct experience with that program. GSoC has a Frequently Asked Questions that you should read: http://www.google-melange.com/gsoc/document/show/gsoc_program/google/gsoc2015/help_page#whatis There are mailing lists specific to GSoC. See: https://www.google-melange.com/gsoc/document/show/gsoc_program/google/gsoc2015/about_page for details. On Mon, Jan 26, 2015 at 7:56 AM, Arpit Agarwal wrote: > Hello, > > I want to take part in GSoC 2015 under PSF. I am a beginner in python > and have started contributing and i am also registerd at github. > Please suggest as from which projects i should start for contributing > as i am beginner in python. > > thanks. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From s.shall at virginmedia.com Mon Jan 26 19:44:56 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Mon, 26 Jan 2015 18:44:56 +0000 Subject: [Tutor] Tutor Digest, Vol 131, Issue 59 Order loop from methos on class (jarod_v6@libero.it) In-Reply-To: References: Message-ID: <54C68B28.4070908@virginmedia.com> On 26/01/2015 14:41, Dino Bekte?evi? wrote: > 2015-01-26 14:54 GMT+01:00 jarod_v6 at libero.it : >> Thanks so much!! Now I understood it is a stupid thing! >> So, could you elpme to decompose the problem? >> I initiazlizate the class with the file to use so all the function have all >> the parameters that I need. >> >> At the moment I have in mind only to do this: >> ena = Rna() >> job1 = ena.trim() >> job2 = ena.align() >> It is no so elegant.. >> >> >> >> Any suggestion? >> > > Without seeing what exactly are you trying to do (I'm not a > chemist/biologist) I'm not sure. Any detail about what you're trying > to do would be helpful. > If you're bothered by having to call 2 methods except of 1 you could > always make another method that uses the two. It really depends on the > decision if you want to do the operations in place or not, that is > transform the original object through it's methods, or do you want to > return a new object of the same class. > In your example you write "job" as if you're dealing with threads. I > can't tell if you want job1 and job2 to be another different objects > (maybe of Rna class maybe not) or is it just that you don't understand > that you can also call a method on an object without having a variable > to hold a return value. > > If you want to return another Rna object that is the same as the > original one, maybe something like this is what you need? > > i.e. > import copy > > class Rna(): > def __init__(self): > self.trimmed = False > self.aligned = False > > #NOT a part of the class > def trim(rna): > temp = copy.copy(rna) > temp.trimmed = True > return temp > > #in interpreter >>>>> ena = Rna() >>>>> ena.trimmed > False >>>>> tena = trim(ena) >>>>> ena.trimmed > False >>>>> tena.trimmed > True > > and both of ena and tena will be of class Rna. So you now have 2 > different Rna objects. > You could also have it done in place, which saves memory and is more > natural and I'd recommend it: > > class Rna(): > def __init__(self): > self.trimmed=False > self.aligned=False > def trim(self): > self.trimmed=True > def align(self): > self.aligned=True > def DoBoth(self): > self.trim() > self.align() > print("Done!") > > #in the interpreter >>>>> ena = Rna() >>>>> ena.trimmed > False >>>>> ena.aligned > False >>>>> ena.DoBoth() > Done! >>>>> ena.trimmed > True >>>>> ena.aligned > True > > This way you can do both without having to constantly write them > yourself... you issue 1 call which then calls various other methods > you have on the instance itself.... > > Even that print isn't necessary, that's just there to show it > finished. You don't always have to have a variable to catch potential > output of a method. But maybe if you need/want to catch the output > maybe that output is an object of a different class(?) maybe it's a > tuple, or an array? > > class Rna(): > def __init__(self): > self.trimmed=False > self.aligned=False > def trim(self): > self.trimmed=True > def align(self): > self.aligned=True > def DoBoth(self): > self.trim() > self.align() > print("Done! We return an list of solutions:") > return [1,2,3,4,5,6,7,8,9] > > #in the interpreter >>>>> ena = Rna() >>>>> solutions = ena.DoBoth() > Done! We return an list of solutions: >>>>> solutions > [1,2,3,4,5,6,7,8,9] > > You could also add the solutions as an attribute to the object you > just did the calculation on: > def DoBoth(self): > self.trim() > self.align() > print("Done! We return an list of solutions:") > self.solutions = [1,2,3,4,5,6,7,8,9] > > #in the interpreter >>>>> ena = Rna() >>>>> ena.DoBoth() > Done! We return an list of solutions: >>>>> ena.solutions > [1,2,3,4,5,6,7,8,9] > > The better you describe WHAT you want and HOW you want it the better > people here will be able to help you.... > > > Best of luck, > Dino > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > I do not know exactly what the OP wants to do, but it sounds like he is aligning RNA sequences. At this stage I would suggest that he studies the possibilities of the BioPython package and the programs available at the NLM, USA or the Sanger Lab in Cambridge, England. But I am only a beginner myself, so I might be way off track. -- Sydney From jarod_v6 at libero.it Mon Jan 26 20:48:08 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Mon, 26 Jan 2015 20:48:08 +0100 (CET) Subject: [Tutor] R: Tutor Digest, Vol 131, Issue 60 order loop from methos on class Message-ID: <680581080.376931422301688280.JavaMail.httpd@webmail-33.iol.local> dear all, thanks so much!! I explain better my problem :http://pastebin.com/iiPZMi2U this is my workflow. Take my data from readset an create a command list ena = Rnaseq() The order of the self.step are the order I wan to to execute my analisys. So this is the order: In [160]: ena.show() 1- trimmomatic 2- merge_trimmomatic_stats 3- star 4- picard_sort_sam 5- rnaseqc 6- wiggle 7- cufflinks 8- cuffquant 9- gq_seq_utils_exploratory_analysis_rnaseq First aim is to write a code to write all the pipeline . up to now I use this: job1 = ena.trimming() ena.prepare_run(job1) ena.prepare_run(job2) .. the other aim is to selcet a range number to execute i.e. 2-9 or 1-4... From dyoo at hashcollision.org Mon Jan 26 21:56:26 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 26 Jan 2015 12:56:26 -0800 Subject: [Tutor] R: Tutor Digest, Vol 131, Issue 60 order loop from methos on class In-Reply-To: <680581080.376931422301688280.JavaMail.httpd@webmail-33.iol.local> References: <680581080.376931422301688280.JavaMail.httpd@webmail-33.iol.local> Message-ID: Hello, > The order of the self.step are the order I wan to to execute my analisys. > So this is the order: > In [160]: ena.show() > 1- trimmomatic > 2- merge_trimmomatic_stats > 3- star > 4- picard_sort_sam > 5- rnaseqc > 6- wiggle > 7- cufflinks > 8- cuffquant > 9- gq_seq_utils_exploratory_analysis_rnaseq > > First aim is to write a code to write all the pipeline . > up to now I use this: > job1 = ena.trimming() > ena.prepare_run(job1) > ena.prepare_run(job2) > .. > the other aim is to selcet a range number to execute i.e. 2-9 or 1-4... In this case, yes, you probably want to explicitly represent the sequence of steps as an explicit list of operators. I think you may have wanted somehow to get this ordered sequence "for free" by iterating over the class's methods, perhaps through a dir(). However, trying to get this ordering from the class via method iteration is unreliable because, underneath the service, the iteration is walking through a dictionary, and dictionaries do not give us a deterministic ordering: the ordering is allowed to change on us between program runs. And in fact, in certain environments, dictionary iteration is _guaranteed_ to give us a different ordering on every program run. See: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED Ultimately, this means that if we want an ordered sequence, we can't depend on dictionary iteration. Lists are what we want. From felisha.lawrence at gmail.com Tue Jan 27 00:24:41 2015 From: felisha.lawrence at gmail.com (Felisha Lawrence) Date: Mon, 26 Jan 2015 18:24:41 -0500 Subject: [Tutor] Overlay Quiver Plot on Contours Message-ID: Hello, I have the following script: import netCDF4 import numpy as np import matplotlib.pyplot as plt import pylab ncfile = netCDF4.Dataset('30JUNE2012_0300UTC.cdf', 'r') dbZ = ncfile.variables['MAXDBZF'] data = dbZ[0,0] data.shape x = np.array([0,10,11]) y = np.array([0,15,16]) X,Y = np.meshgrid(x,y) u = 5*X v = 5*Y plt.figure() plt.rcParams['figure.figsize'] = (12.0,8.0) c = plt.contourf(data, 20, cmap='jet') plt.hold(True) q = plt.quiver(X,Y,u,v,angles='xy',scale=1000,color='r') p = plt.quiverkey(q,1,16.5,50,"50 m/s",coordinates='data',color='r') plt.colorbar() plt.show() and I am getting this error: TypeError: You must first set_array for mappable Can anyone provide guidance on how you overlay quiver plots on top of contours? Please and thanks Felisha Lawrence -- Felisha Lawrence Howard University Program for Atmospheric Sciences(HUPAS), Graduate Student NASA URC/BCCSO Graduate Fellow NOAA NCAS Graduate Fellow Graduate Student Association for Atmospheric Sciences(GSAAS), Treasurer (240)-535-6665 (cell) felisha.lawrence at gmail.com (email) From alan.gauld at btinternet.com Tue Jan 27 02:29:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 01:29:44 +0000 Subject: [Tutor] Overlay Quiver Plot on Contours In-Reply-To: References: Message-ID: On 26/01/15 23:24, Felisha Lawrence wrote: > Hello, > I have the following script: > > import netCDF4 > import numpy as np > import matplotlib.pyplot as plt > import pylab ... > and I am getting this error: > > TypeError: You must first set_array for mappable > > Can anyone provide guidance on how you overlay quiver plots on top of > contours? This list is for newcomers to Python and its standard library. This looks like a fairly specific SciPy/Numpy, and especially matplotlib type question. You would probably be better off asking on the SciPy forums/lists. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Tue Jan 27 02:45:30 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 26 Jan 2015 17:45:30 -0800 Subject: [Tutor] Overlay Quiver Plot on Contours In-Reply-To: References: Message-ID: >> and I am getting this error: >> >> TypeError: You must first set_array for mappable >> >> Can anyone provide guidance on how you overlay quiver plots on top of >> contours? > > > This list is for newcomers to Python and its standard > library. This looks like a fairly specific SciPy/Numpy, > and especially matplotlib type question. > > You would probably be better off asking on the SciPy > forums/lists. Agree with Alan. You'll get better help from people who know the library. Very few of us here do things with SciPy. Just to add: please add more context to your error message reports, regardless of who you're asking help from. To include the single line: ####### TypeError: You must first set_array for mappable ####### is somewhat helpful: it does have some information. But unless you've suppressed error reporting, you should be getting significantly more information from the error message. I did a quick web search for your error message, and came up with: http://stackoverflow.com/questions/6600579/colorbar-for-matplotlib-plot-surface-command which might look reasonably close to what you're seeing. And note how, in that message, they include a full stack trace of the problem, which looks like: ######################################################################### Traceback (most recent call last): File "", line 1, in File "C:\Python26\lib\site-packages\spyderlib\widgets\externalshell\startup.py", line 122, in runfile execfile(filename, glbs) File "C:\Documents and Settings\mramacha\My Documents\Python\Candela\test.py", line 22, in fig.colorbar(surf, shrink=0.5, aspect=5) File "C:\Python26\lib\site-packages\matplotlib\figure.py", line 1104, in colorbar cb = cbar.Colorbar(cax, mappable, **kw) File "C:\Python26\lib\site-packages\matplotlib\colorbar.py", line 706, in __init__ mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax File "C:\Python26\lib\site-packages\matplotlib\cm.py", line 261, in autoscale_None raise TypeError('You must first set_array for mappable') TypeError: You must first set_array for mappable ######################################################################### This is the sort of thing that is a *joy* to see when debugging. If I don't have a good stack trace when trying to diagnose a problem, I am not as happy, because I don't have my hand on any useful context to work with. It's like working in the dark. In your case, I can't tell for sure if your scenario matches the above, because the error message information content is low enough to raise doubts. From akleider at sonic.net Tue Jan 27 03:04:10 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 26 Jan 2015 18:04:10 -0800 Subject: [Tutor] =?utf-8?q?functions_first=3F?= Message-ID: Please correct me if I am wrong, but I've assumed that it is proper to define all functions before embarking on the main body of a program. I find myself breaking this rule because I want to set the default values of some named function parameters based on a configuration file which I have to first read, hence the need to break the rule. ..so my question is "is this acceptable" or "is there a better way?" thks Alex From ben+python at benfinney.id.au Tue Jan 27 07:30:41 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 27 Jan 2015 17:30:41 +1100 Subject: [Tutor] functions first? References: Message-ID: <85wq48loq6.fsf@benfinney.id.au> Alex Kleider writes: > Please correct me if I am wrong, but I've assumed that it is proper to > define all functions before embarking on the main body of a program. I would say rather that as much code as possible should be in small well-defined functions, with the ?main body? a tiny and trivial call to a function. That way, all the code is easily tested by unit testing tools. > I find myself breaking this rule because I want to set the default > values of some named function parameters based on a configuration file > which I have to first read, hence the need to break the rule. Module-level constants are fine, and they obviously need to be bound before the definition of the function which uses them for parameter defaults. But if they're not constants ? as implied by your statement you read them from a configuration file ? then they should not be in the function definition, because reading the configuration file should itself be encapsulated in a well-tested function. -- \ ?It is the integrity of each individual human that is in final | `\ examination. On personal integrity hangs humanity's fate.? | _o__) ?Richard Buckminster Fuller, _Critical Path_, 1981 | Ben Finney From alan.gauld at btinternet.com Tue Jan 27 09:15:38 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 08:15:38 +0000 Subject: [Tutor] functions first? In-Reply-To: References: Message-ID: On 27/01/15 02:04, Alex Kleider wrote: > Please correct me if I am wrong, but I've assumed that it is proper to > define all functions before embarking on the main body of a program. No, you can do it either way round. Top-Down or Bottom-Up as they are known. Usually its a muxture of both. But most folks like to have a running program at all times. So you might write the function headers with dummy bodies then write the main code that calls the functions. Then go back and fill in the functions one at a time, for example. eg. A trivial example: ### pass 1 ################################ def sayHello(msg): pass def getGreeting(prompt): return "hello world" def main(): greeting = getGreeting("What to say: ") sayHello(greeting) if __name__ == "__main__": main() ### pass 2 ############################## def sayHello(msg): print(msg) def getGreeting(prompt): return "hello world" def main(): greeting = getGreeting("What to say: ") sayHello(greeting) if __name__ == "__main__": main() ### pass 3 ############################## def sayHello(msg): print(msg) def getGreeting(prompt): return input(prompt) def main(): greeting = getGreeting("What to say: ") sayHello(greeting) if __name__ == "__main__": main() HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Tue Jan 27 12:18:35 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 27 Jan 2015 22:18:35 +1100 Subject: [Tutor] functions first? In-Reply-To: References: Message-ID: <20150127111835.GR20517@ando.pearwood.info> On Mon, Jan 26, 2015 at 06:04:10PM -0800, Alex Kleider wrote: > Please correct me if I am wrong, but I've assumed that it is proper to > define all functions before embarking on the main body of a program. > I find myself breaking this rule because I want to set the default > values of some named function parameters based on a configuration file > which I have to first read, hence the need to break the rule. > ..so my question is "is this acceptable" or "is there a better way?" I'm not really sure I understand the question correctly. As far as *design* go, there are two competing paradigms, "top-down" versus "bottom-up". Perhaps you are thinking about that? In top-down, you start with the part of the application closest to the user, say, a web browser: def run_browser(): win = make_window() page = get_url(whatever) show_page(page, win) Then you write the next level down: def make_window() ... def get_url(address): ... def show_page(page, win): ... and so on, all the way down to the most primitive and simple parts of the application: def add_one(n): return n+1 In bottom-up programming, you do the same, only in reverse. You build the most primitive functions first, then add them together like Lego blocks, getting more and more complicated and powerful until you end up with a fully-functioning web browser. Personally, I think that in any real application, you need a combination of both top-down and bottom-up, but mostly top-down. (How do you know what primitive operations you will need right at the start of the design process?) Also, many of the primitive "Lego blocks" already exist for you, in the Python standard library. If you are talking about the order in which functions appear in the source file, I tend to write them like this: === start of file === hash-bang line encoding cookie licence doc string explaining what the module does from __future__ imports import standard library modules import custom modules metadata such as version number other constants global variables custom exception types private functions and classes public functions and classes main function if __name__ == '__main__' code block to run the application === end of file === All of those are optional (especially global variables, which I try hard to avoid). Sometimes I swap the order of private and public sections, but the main function (if any) is always at the end just before the "if __name__" section. As far as the default values go, I *think* what you are doing is something like this: f = open("config") value = int(f.readline()) f.close() def function(x, y=value): return x + y Am I right? If so, that's not too bad, especially for small scripts, but I think a better approach (especially for long-lasting applications like a server) might be something like this: def read_config(fname, config): f = open(fname) config['value'] = int(f.readline()) f.close() PARAMS = { # set some default-defaults that apply if the config file # isn't available value: 0, } read_config('config', PARAMS) def func(x, y=None): if y is None: y = PARAMS['value'] return x + y This gives lots of flexibility: - you can easily save and restore the PARAMS global variable with just a dict copy operation; - you can apply multiple config files; - you can keep multiple PARAMS dicts (although as written, func only uses the one named specifically PARAMS); - read_config can be isolated for testing; - you can re-read the config file without exiting the application; etc. Does this help? -- Steve From akleider at sonic.net Tue Jan 27 17:39:17 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 27 Jan 2015 08:39:17 -0800 Subject: [Tutor] =?utf-8?q?functions_first=3F?= In-Reply-To: <20150127111835.GR20517@ando.pearwood.info> References: <20150127111835.GR20517@ando.pearwood.info> Message-ID: <6ee3221cdce0a0bd9a63bfde9582d4ba@sonic.net> On 2015-01-27 03:18, Steven D'Aprano wrote: > On Mon, Jan 26, 2015 at 06:04:10PM -0800, Alex Kleider wrote: >> Please correct me if I am wrong, but I've assumed that it is proper to >> define all functions before embarking on the main body of a program. >> I find myself breaking this rule because I want to set the default >> values of some named function parameters based on a configuration file >> which I have to first read, hence the need to break the rule. >> ..so my question is "is this acceptable" or "is there a better way?" > > I'm not really sure I understand the question correctly. > > As far as *design* go, there are two competing paradigms, "top-down" > versus "bottom-up". Perhaps you are thinking about that? > > In top-down, you start with the part of the application closest to the > user, say, a web browser: > > def run_browser(): > win = make_window() > page = get_url(whatever) > show_page(page, win) > > Then you write the next level down: > > def make_window() > ... > > def get_url(address): > ... > > def show_page(page, win): > ... > > and so on, all the way down to the most primitive and simple parts of > the application: > > def add_one(n): > return n+1 > > > In bottom-up programming, you do the same, only in reverse. You build > the most primitive functions first, then add them together like Lego > blocks, getting more and more complicated and powerful until you end up > with a fully-functioning web browser. > > Personally, I think that in any real application, you need a > combination > of both top-down and bottom-up, but mostly top-down. (How do you know > what primitive operations you will need right at the start of the > design > process?) Also, many of the primitive "Lego blocks" already exist for > you, in the Python standard library. > > If you are talking about the order in which functions appear in the > source file, I tend to write them like this: > > === start of file === > hash-bang line > encoding cookie > licence > doc string explaining what the module does > from __future__ imports > import standard library modules > import custom modules > metadata such as version number > other constants > global variables > custom exception types > private functions and classes > public functions and classes > main function > if __name__ == '__main__' code block to run the application > === end of file === > > > All of those are optional (especially global variables, which I try > hard > to avoid). Sometimes I swap the order of private and public sections, > but the main function (if any) is always at the end just before the "if > __name__" section. > > > As far as the default values go, I *think* what you are doing is > something like this: > > f = open("config") > value = int(f.readline()) > f.close() > > def function(x, y=value): > return x + y > > > > Am I right? Yes, this is indeed what I was doing (but then on reflection, became uncertain about the wisdom of doing it this way- hence the question.) > > If so, that's not too bad, especially for small scripts, but I think a > better approach (especially for long-lasting applications like a > server) > might be something like this: > > def read_config(fname, config): > f = open(fname) > config['value'] = int(f.readline()) > f.close() > > PARAMS = { > # set some default-defaults that apply if the config file > # isn't available > value: 0, > } > > read_config('config', PARAMS) > > > def func(x, y=None): > if y is None: > y = PARAMS['value'] > return x + y > > > > This gives lots of flexibility: > > - you can easily save and restore the PARAMS global variable with > just a dict copy operation; > > - you can apply multiple config files; > > - you can keep multiple PARAMS dicts (although as written, func only > uses the one named specifically PARAMS); > > - read_config can be isolated for testing; > > - you can re-read the config file without exiting the application; > > etc. > > > Does this help? Yes, very much so. Thank you again! I use the docopt module to collect command line options and then configparser to read a file. Some of the values (such as a port number, for example) must then be adjusted. An example is a port number which I want to convert from "5022" to ":5022" if it's a non standard port or to "" if it is the standard "22" so it can then be used as a string format parameter. Perhaps I should be doing this in the same place as I set up the string rather than where I populate the 'config' and 'PARAMS' dictionaries? Sincerely, Alex From reuben.dlink at gmail.com Tue Jan 27 17:50:04 2015 From: reuben.dlink at gmail.com (Reuben) Date: Tue, 27 Jan 2015 22:20:04 +0530 Subject: [Tutor] Python for linux In-Reply-To: References: Message-ID: Hello, I wish to know which python module works well with Linux commands - for e.g. Searching a string in file, number of occurrences of a string in a file, what is the permission of a file. To test this operation I need my python script to login into the Linux machine and then perform the above mentioned operations Any specific pointers to help me with this task? Thanks Regards, Reuben From pathunstrom at gmail.com Tue Jan 27 18:04:01 2015 From: pathunstrom at gmail.com (Patrick Thunstrom) Date: Tue, 27 Jan 2015 12:04:01 -0500 Subject: [Tutor] Python for linux In-Reply-To: References: Message-ID: You're actually asking multiple subquestions here, let me start by asking a clarifying question: When you say "log in to the Linux machine" I assume you mean you need to access a remote host? Your script will be running locally? Next your other questions: Checking permissions of a file: Look into the os module. Checking for substrings: This is has many answers. Have you tried to do this yet? Patrick On Tue, Jan 27, 2015 at 11:50 AM, Reuben wrote: > Hello, > > I wish to know which python module works well with Linux commands - for > e.g. Searching a string in file, number of occurrences of a string in a > file, what is the permission of a file. > > To test this operation I need my python script to login into the Linux > machine and then perform the above mentioned operations > > Any specific pointers to help me with this task? > > Thanks > > Regards, > Reuben > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From tgmiller5 at hotmail.com Tue Jan 27 14:04:37 2015 From: tgmiller5 at hotmail.com (Tammy Miller) Date: Tue, 27 Jan 2015 08:04:37 -0500 Subject: [Tutor] Using if statement with csv file Message-ID: I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do.Thank you, Tammy From alan.gauld at btinternet.com Tue Jan 27 19:18:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 18:18:46 +0000 Subject: [Tutor] Python for linux In-Reply-To: References: Message-ID: On 27/01/15 16:50, Reuben wrote: > I wish to know which python module works well with Linux commands Most Python modules work on Linux if you are running your Python program on a Linux machine. > e.g. Searching a string in file, number of occurrences of a string in a > file, Thee isn't a specific module for that but you can write a Pyhon function to do that quite easily. Or you can call the OS tools (such as grep) > what is the permission of a file. The OS module does include functions for that kind of work though. > To test this operation I need my python script to login into the Linux > machine and then perform the above mentioned operations So what kind of machine is your program running on? If it is a Windows box then that's a very different thing to running commands on a local Linux PC. Normally your put the Python script on the target Linux machine if possible then remotely login and run that script. You appear to want to run the script locally and run commands remotely on a Linux box. very different. For that you probably want to run OS commands using the ssh (or telnet? or pyexpect?) modules. But that brings another bunch of issues. But if you are just reading files can you mount those files on the network so that your local script can see the drive/folder? Then you can do it all from python. > Any specific pointers to help me with this task? We need a clearer explanation of what you are tying to do. ie the actual problem you are trying to solve rather than the coding approach you are trying to use. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Tue Jan 27 19:20:00 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 18:20:00 +0000 Subject: [Tutor] Using if statement with csv file In-Reply-To: References: Message-ID: On 27/01/15 13:04, Tammy Miller wrote: > I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do.Thank you, Tammy Can you repost in plain text please? As you can see the html version has come through as a single long line with no clue to indentation etc. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Tue Jan 27 19:20:59 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Jan 2015 10:20:59 -0800 Subject: [Tutor] Using if statement with csv file In-Reply-To: References: Message-ID: On Tue, Jan 27, 2015 at 5:04 AM, Tammy Miller wrote: > I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do. Hi Tammy, Ah. Take a look at the following: ######################## >>> 'foo' > 10 True ######################## Waaaaaa? What does it even mean to compare a string to a number? It turns out that Python's comparison operator decides that if we're comparing a string vs a number, the string is "bigger", regardless of its content. (Reference: https://docs.python.org/2/library/stdtypes.html#comparisons.) Now take a look at this: ######################## >>> '10' > 10 True ######################## Waaaaaaa? But yes, it's doing this for the same reasons as before: a string is just bigger than a number. In your code, you are comparing a string (an element of your CSV row) with a number. Hope this helps! From dyoo at hashcollision.org Tue Jan 27 19:28:11 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Jan 2015 10:28:11 -0800 Subject: [Tutor] Using if statement with csv file In-Reply-To: References: Message-ID: > > In your code, you are comparing a string (an element of your CSV row) > with a number. Whoops, forgot to include recommendations. You probably do not want to have comparisons of mixed type. As we have found, the result we get back is arbitrary and capricous. Rather, we probably want to compare two numbers. To interpret a string as a number, use the int() or float() functions. ############################ >>> '10' > 10 True >>> int('10') > 10 False ############################ References: https://docs.python.org/2/library/functions.html#int https://docs.python.org/2/library/functions.html#float From breamoreboy at yahoo.co.uk Tue Jan 27 19:59:37 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 27 Jan 2015 18:59:37 +0000 Subject: [Tutor] Using if statement with csv file In-Reply-To: References: Message-ID: On 27/01/2015 18:20, Danny Yoo wrote: > On Tue, Jan 27, 2015 at 5:04 AM, Tammy Miller wrote: >> I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do. > > Hi Tammy, > > Ah. Take a look at the following: > > ######################## >>>> 'foo' > 10 > True > ######################## > Meanwhile in the non-Luddite world of Python 3. >>> 10 > '10' Traceback (most recent call last): File "", line 1, in TypeError: unorderable types: int() > str() >>> '10' > 10 Traceback (most recent call last): File "", line 1, in TypeError: unorderable types: str() > int() -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From akleider at sonic.net Tue Jan 27 20:08:33 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 27 Jan 2015 11:08:33 -0800 Subject: [Tutor] =?utf-8?q?functions_first=3F?= In-Reply-To: <85wq48loq6.fsf@benfinney.id.au> References: <85wq48loq6.fsf@benfinney.id.au> Message-ID: <79f883c29c0f3ea356cc2130e6d15d46@sonic.net> On 2015-01-26 22:30, Ben Finney wrote: > Alex Kleider writes: > >> Please correct me if I am wrong, but I've assumed that it is proper to >> define all functions before embarking on the main body of a program. > > I would say rather that as much code as possible should be in small > well-defined functions, with the ?main body? a tiny and trivial call to > a function. > > That way, all the code is easily tested by unit testing tools. > >> I find myself breaking this rule because I want to set the default >> values of some named function parameters based on a configuration file >> which I have to first read, hence the need to break the rule. > > Module-level constants are fine, and they obviously need to be bound > before the definition of the function which uses them for parameter > defaults. > > But if they're not constants ? as implied by your statement you read > them from a configuration file ? then they should not be in the > function > definition, because reading the configuration file should itself be > encapsulated in a well-tested function. Thanks for your well reasoned advice. You are of course correct in that if they are read from a configuration file then they are not constants but in a sense they are, at least for the life of the current program run. I'm probably going to go with the way Steve recommended which is to use global dictionaries to contain the command line arguments (which docopt already does) and configuration values (which are also placed into a dictionary by configparser) and then use those dictionaries within functions that need them rather than setting default named parameters for the functions. From akleider at sonic.net Tue Jan 27 20:15:40 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 27 Jan 2015 11:15:40 -0800 Subject: [Tutor] =?utf-8?q?functions_first=3F?= In-Reply-To: References: Message-ID: <55d21744edd888e787e72bde7132523f@sonic.net> On 2015-01-27 00:15, Alan Gauld wrote: > On 27/01/15 02:04, Alex Kleider wrote: >> Please correct me if I am wrong, but I've assumed that it is proper to >> define all functions before embarking on the main body of a program. > > No, you can do it either way round. Top-Down or Bottom-Up as they are > known. > > Usually its a muxture of both. > > But most folks like to have a running program at all times. So you > might write the function headers with dummy bodies then write the main > code that calls the functions. Then go back and fill in the functions I've just realized where the confusion arises. As Steve guessed, I was talking about the order in which they appear in the file, not the order in which they were written. Only when this light went on did I realize why I had inadvertently precipitated a discussion of top down vs bottom up design. Sorry about the confusion. From dilloncortez at gmail.com Tue Jan 27 20:12:22 2015 From: dilloncortez at gmail.com (Dillon Cortez) Date: Tue, 27 Jan 2015 12:12:22 -0700 Subject: [Tutor] Risk Dice Program Message-ID: I?m trying to write a program for the dice in a game of risk. It runs but the problem is that if any of the offensive dice is bigger than only one of the defensive dice, the program shows the offense as the winner, even when the defense should win. Can you help me out with this? here?s the code: # To be used during risk in the abesense of dice import random o_die1 = random.randint(1, 6) o_die2 = random.randint(1, 6) o_die3 = random.randint(1, 6) d_die1 = random.randint(1, 6) d_die2 = random.randint(1, 6) print "the offense has rolled a %s, %s and a %s" % (o_die1, o_die2, o_die3) print "The defense has rolled a %s and a %s" % (d_die1, d_die2) def winner(): if o_die1 > d_die1 or d_die2: print "The offense has won" elif o_die2 > d_die1 or d_die2: print "The offense has won" elif o_die3 > d_die1 or d_die2: print "The offense has won" else: print "The defense has won" winner() From jfdorsten at gmail.com Tue Jan 27 23:07:58 2015 From: jfdorsten at gmail.com (joseph dorsten) Date: Tue, 27 Jan 2015 17:07:58 -0500 Subject: [Tutor] Problem with chap. 3. 'Craps Roller' Message-ID: When I run the program I get: NameError: name 'die1' is not defined However I defined die1 in the program as die1 = random,randint (1, 6) Thanks for any help, joe From mmr15 at case.edu Tue Jan 27 19:15:00 2015 From: mmr15 at case.edu (Matthew Ruffalo) Date: Tue, 27 Jan 2015 13:15:00 -0500 Subject: [Tutor] Using if statement with csv file In-Reply-To: References: Message-ID: <54C7D5A4.1020305@case.edu> On 01/27/2015 08:04 AM, Tammy Miller wrote: > I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do.Thank you, Tammy Hi Tammy- A few things: 1. Indentation is semantically significant in Python programs, so please send mail in a way that doesn't collapse all of your code to a single line. I assume this is an appropriate reconstruction (though note that you are missing a colon after "if row['Absent'] > 10" and I have added this in my version): import csv with open('test.csv') as csvfile: reader = csv.DictReader(csvfile) for row in reader: if row['Absent'] > 10: print row 2. Please state the operating system and version of Python you are using. In this case it's clear that you are using Python 2.x from the 'print' statement, and operating system is not relevant, but this is not always the case and it's best to not have to guess about how to help you. In this case, since it's clear that you're using Python 2, you're encountering some suboptimal behavior that was fixed in Python 3. Specifically, you're not converting row['Absent'] into an integer and strings always compare greater than integers: """ Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> '5' > 10 True >>> '' > 3 True """ In Python 3, this meaningless comparison raises a TypeError: """ Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> '5' > 10 Traceback (most recent call last): File "", line 1, in TypeError: unorderable types: str() > int() """ It will probably suffice to change your "if row['Absent'] > 10" to "if int(row['Absent']) > 10". MMR... From jarod_v6 at libero.it Tue Jan 27 23:47:08 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Tue, 27 Jan 2015 23:47:08 +0100 (CET) Subject: [Tutor] Execution of local data Message-ID: <2019039507.9481422398828743.JavaMail.defaultUser@defaultHost> I create a list of local object: but I can't execute as object only as string: ena = Rnaseq(options.configura, options.rst) job_1 = ena.trimmomatic() job_2 = ena.star() job_3 = ena.wiggle() job_4 = ena.rnaseqc() job_5 = ena.picard_sort_sam() job_6 = ena.cufflinks job_7 = ena.merge_trimmomatic_stats() #ena.write_out(job2) cmdset=[] for item in locals().keys(): if item.startswith('job_'): cmdset.append(item) cmdset.sort() for i in range(0,len(cmdset)): ena.prepare_run(cmdset[i]) for i in range(0,len(cmdset)): cmd=cmdset[i] print type(cmd) .....: ? How can use the object created? From alan.gauld at btinternet.com Wed Jan 28 00:09:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 23:09:34 +0000 Subject: [Tutor] Risk Dice Program In-Reply-To: References: Message-ID: On 27/01/15 19:12, Dillon Cortez wrote: > problem is that if any of the offensive dice is bigger > than only one of the defensive dice, > the program shows the offense as the winner, > def winner(): > if o_die1 > d_die1 or d_die2: > print "The offense has won" The problem is that the computer reads that differently to you. It sees it as if (o_die1 > d_die1) or d_die2: Now, due to how Python evaluates logical 'or' expressions, it knows that if the first part is True it doesn't need to evaluate the second part so, if d_die1 is less that o_die1 then it returns True and all is well. But if d_die1 is greater that o_die1 it then returns the value of the second expression in the 'or', namely d_die2. Which is not what you want in this case. To get round that you need to explicitly compare o_die1 to both values: if (o_die1 > d_die1) or (o_die1 > d_die2): You don't strictly need the parens but I prefer to keep them there to remind me of what's going on. You could tidy up the code slightly by using a loop: for die in [o_die1, o_die2,o_die3]: if die > d_die1 or d > d_die2: print 'offense won' else: print 'defense won' This is more extendible if you increase the number of die. A further change caters for more defensive die too: for od in [o_die1, o_die2, o_die3]: if any(od > dd for dd in [d_die1, d_die2]): print 'offense won' else: print 'defense won' -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Wed Jan 28 00:13:51 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Jan 2015 15:13:51 -0800 Subject: [Tutor] Execution of local data In-Reply-To: <2019039507.9481422398828743.JavaMail.defaultUser@defaultHost> References: <2019039507.9481422398828743.JavaMail.defaultUser@defaultHost> Message-ID: On Tue, Jan 27, 2015 at 2:47 PM, jarod_v6 at libero.it wrote: > I create a list of local object: but I can't execute as object only as string: > ena = Rnaseq(options.configura, options.rst) > job_1 = ena.trimmomatic() > job_2 = ena.star() > job_3 = ena.wiggle() > job_4 = ena.rnaseqc() > job_5 = ena.picard_sort_sam() > job_6 = ena.cufflinks > job_7 = ena.merge_trimmomatic_stats() > #ena.write_out(job2) > cmdset=[] > for item in locals().keys(): > if item.startswith('job_'): > cmdset.append(item) > cmdset.sort() > for i in range(0,len(cmdset)): > ena.prepare_run(cmdset[i]) Technically: the code is collecting a list of strings in cmdset. I don't think this is what you want. Stylistically: this code is trying to be too clever. You're typing out the jobs in sequence, so you might as well arrange them as a list. The use of locals() is dubious, and your use of sort() is trying to undo the damage that is being introduced by locals(). Why not just do the direct thing? The pseudocode would be something like: #################################################### cmdset = [ena.trimmomatic, end.star, ena.wiggle, ena.maseqc, ...] for cmd in cmdset: print cmd.__name__ cmd() #################################################### where you keep a list of commands, and you can execute them in turn. Because the representation of the command set is a list, it's ordered the way it's typed. From alan.gauld at btinternet.com Wed Jan 28 00:13:53 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 23:13:53 +0000 Subject: [Tutor] Problem with chap. 3. 'Craps Roller' In-Reply-To: References: Message-ID: On 27/01/15 22:07, joseph dorsten wrote: > When I run the program I get: NameError: name 'die1' is not > defined However I defined die1 in the program as die1 = > random,randint (1, 6) Thanks for any help, joe Which program? Your subject says chapter 3, but of which book? There are dozens of Python books out there... and most of us only have a few of them. Show us the program. Give us a clue. And while doing so, tell us which Python version, which OS and provide the whole error message not just the last line. There is a wealth of information in error messages once you get used to reading them. thanks -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Jan 28 00:31:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Jan 2015 23:31:29 +0000 Subject: [Tutor] Execution of local data In-Reply-To: <2019039507.9481422398828743.JavaMail.defaultUser@defaultHost> References: <2019039507.9481422398828743.JavaMail.defaultUser@defaultHost> Message-ID: On 27/01/15 22:47, jarod_v6 at libero.it wrote: > I create a list of local object: but I can't execute as object only as string: > ena = Rnaseq(options.configura, options.rst) > > > job_1 = ena.trimmomatic() > > job_2 = ena.star() > job_3 = ena.wiggle() > job_4 = ena.rnaseqc() > job_5 = ena.picard_sort_sam() > job_6 = ena.cufflinks > job_7 = ena.merge_trimmomatic_stats() Note that you are storing the results of the function calls here. I suspect you want to store the function objects themselves (ie no parens after the name) > cmdset=[] > for item in locals().keys(): > if item.startswith('job_'): > cmdset.append(item) But this looks like overkill, why not just create a list of commands directly? > cmdset.sort() > for i in range(0,len(cmdset)): > ena.prepare_run(cmdset[i]) Please get out of the habit of using indexes in Python for loopps. This is better written as for cmd in cmdset: ena.prepare_run(cmd) > for i in range(0,len(cmdset)): > cmd=cmdset[i] > print type(cmd) same here: for cmd in cmdset: print type(cmd) > How can use the object created? We must assume (since we can't see them) that the fuctions above (ena.star etc) all return strings. If you remove the parens you will get the function objects themselves. But it all looks more complex than it need be. Could something like this work: ena = Rnaseq(options.configura, options.rst) cmdset = [ ena.trimmomatic, ena.star, ena.wiggle, ena.rnaseqc, ena.picard_sort_sam, ena.cufflinks, ena.merge_trimmomatic_stats ] for cmd in cmdset: cmd() -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Wed Jan 28 00:50:56 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Jan 2015 15:50:56 -0800 Subject: [Tutor] Problem with chap. 3. 'Craps Roller' In-Reply-To: References: Message-ID: On Tue, Jan 27, 2015 at 2:07 PM, joseph dorsten wrote: > When I run the program I get: NameError: name 'die1' is not > defined However I defined die1 in the program as die1 = > random,randint (1, 6) Thanks for any help, joe Hi Joe, Unfortunately, this is insufficient information. Read your question again and keep in mind: 1. We're not in your class. We may not even be on the same country or continent as you. 2. We don't have your book, and we can't see your program. When you say "the program", you have to imagine a world where there are a lot of programs out there. 3. We can't read your mind. That is, imagine one of your fellow students just sent you your own question. What's the first thing you'd ask? Chances are, the first question you'd ask is: what does your program look like? From breamoreboy at yahoo.co.uk Wed Jan 28 01:09:31 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 28 Jan 2015 00:09:31 +0000 Subject: [Tutor] Risk Dice Program In-Reply-To: References: Message-ID: On 27/01/2015 23:09, Alan Gauld wrote: > On 27/01/15 19:12, Dillon Cortez wrote: >> problem is that if any of the offensive dice is bigger > > than only one of the defensive dice, >> the program shows the offense as the winner, > >> def winner(): >> if o_die1 > d_die1 or d_die2: >> print "The offense has won" > > The problem is that the computer reads that differently to you. > > It sees it as > > if (o_die1 > d_die1) or d_die2: > > Now, due to how Python evaluates logical 'or' expressions, > it knows that if the first part is True it doesn't need to evaluate > the second part so, if d_die1 is less that o_die1 then it returns True > and all is well. > > But if d_die1 is greater that o_die1 it then returns the value > of the second expression in the 'or', namely d_die2. Which is not > what you want in this case. > > To get round that you need to explicitly compare o_die1 > to both values: > > if (o_die1 > d_die1) or (o_die1 > d_die2): > > You don't strictly need the parens but I prefer to keep them there > to remind me of what's going on. > I consider the chained comparisons shown here https://docs.python.org/3/reference/expressions.html#not-in to be far more Pythonic. It also avoids the superfluous brackets which always drive me around the bend. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Wed Jan 28 01:10:10 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 28 Jan 2015 11:10:10 +1100 Subject: [Tutor] functions first? In-Reply-To: <6ee3221cdce0a0bd9a63bfde9582d4ba@sonic.net> References: <20150127111835.GR20517@ando.pearwood.info> <6ee3221cdce0a0bd9a63bfde9582d4ba@sonic.net> Message-ID: <20150128001010.GT20517@ando.pearwood.info> On Tue, Jan 27, 2015 at 08:39:17AM -0800, Alex Kleider wrote: > I use the docopt module to collect command line options and then > configparser to read a file. > Some of the values (such as a port number, for example) must then be > adjusted. An example is > a port number which I want to convert from "5022" to ":5022" if it's a > non standard port or > to "" if it is the standard "22" so it can then be used as a string > format parameter. > Perhaps I should be doing this in the same place as I set up the string > rather than where > I populate the 'config' and 'PARAMS' dictionaries? I see the basic problem as this: - you have config settings (command line options, config files) which by their nature are always strings - furthermore they are strings in a format designed for human use rather than machine use - by the time your function uses them, they need to be converted from human-format to machine-format. That last step might involve a type conversion like int(s), trimming whitespace, or more complex operations. The most obvious way to do them is to apply the operation after reading the config value but before storing it in the params dict. If that works, I wouldn't add complexity where it isn't needed. If it doesn't work for you, I think you need to explain what the problem is before we can suggest a better design. -- Steve From akleider at sonic.net Wed Jan 28 01:59:27 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 27 Jan 2015 16:59:27 -0800 Subject: [Tutor] =?utf-8?q?functions_first=3F?= In-Reply-To: <20150128001010.GT20517@ando.pearwood.info> References: <20150127111835.GR20517@ando.pearwood.info> <6ee3221cdce0a0bd9a63bfde9582d4ba@sonic.net> <20150128001010.GT20517@ando.pearwood.info> Message-ID: On 2015-01-27 16:10, Steven D'Aprano wrote: > On Tue, Jan 27, 2015 at 08:39:17AM -0800, Alex Kleider wrote: > >> I use the docopt module to collect command line options and then >> configparser to read a file. >> Some of the values (such as a port number, for example) must then be >> adjusted. An example is >> a port number which I want to convert from "5022" to ":5022" if it's a >> non standard port or >> to "" if it is the standard "22" so it can then be used as a string >> format parameter. >> Perhaps I should be doing this in the same place as I set up the >> string >> rather than where >> I populate the 'config' and 'PARAMS' dictionaries? > > > I see the basic problem as this: > > - you have config settings (command line options, config files) > which by their nature are always strings > - furthermore they are strings in a format designed for human use > rather than machine use > - by the time your function uses them, they need to be converted > from human-format to machine-format. > > That last step might involve a type conversion like int(s), trimming > whitespace, or more complex operations. > > The most obvious way to do them is to apply the operation after reading > the config value but before storing it in the params dict. If that > works, I wouldn't add complexity where it isn't needed. > > If it doesn't work for you, I think you need to explain what the > problem > is before we can suggest a better design. Again, thank you very much. I'll do as you suggest above and see if I can make it work. Alex From alan.gauld at btinternet.com Wed Jan 28 02:28:52 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Jan 2015 01:28:52 +0000 Subject: [Tutor] Risk Dice Program In-Reply-To: References: Message-ID: On 28/01/15 00:09, Mark Lawrence wrote: >> To get round that you need to explicitly compare o_die1 >> to both values: >> >> if (o_die1 > d_die1) or (o_die1 > d_die2): >> > > I consider the chained comparisons shown here > https://docs.python.org/3/reference/expressions.html#not-in to be far > more Pythonic. It also avoids the superfluous brackets which always > drive me around the bend. Sorry Mark, I'm missing something. How would chained comparisons work for this case? Especially a not-in? You can avoid the compound test using any() and a generator as per my earlier post but I can't think how a chained test would work here? But it is getting late... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Wed Jan 28 07:12:57 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 28 Jan 2015 06:12:57 +0000 Subject: [Tutor] Risk Dice Program In-Reply-To: References: Message-ID: On 28/01/2015 01:28, Alan Gauld wrote: > On 28/01/15 00:09, Mark Lawrence wrote: > >>> To get round that you need to explicitly compare o_die1 >>> to both values: >>> >>> if (o_die1 > d_die1) or (o_die1 > d_die2): >>> >> >> I consider the chained comparisons shown here >> https://docs.python.org/3/reference/expressions.html#not-in to be far >> more Pythonic. It also avoids the superfluous brackets which always >> drive me around the bend. > > Sorry Mark, I'm missing something. How would chained comparisons work > for this case? Especially a not-in? > You can avoid the compound test using any() and a generator as per my > earlier post but I can't think how a chained test would work here? > > But it is getting late... > Forget it, just me being a burke, I must remember not to post after midnight :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From sunil.techspk at gmail.com Wed Jan 28 10:35:58 2015 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 28 Jan 2015 15:05:58 +0530 Subject: [Tutor] Decode and Encode Message-ID: Hi All, When i copied a text from web and pasted in the python-terminal, it automatically coverted into unicode(i suppose) can anyone tell me how it does? Eg: >>> p = "??" >>> p '\xe4\xbd\xa0\xe5\xa5\xbd' >>> o = '??V' >>> o '\xc2\xaa\xc3\xaeV' >>> From bw_dw at fastmail.fm Tue Jan 27 23:40:50 2015 From: bw_dw at fastmail.fm (dw) Date: Tue, 27 Jan 2015 14:40:50 -0800 Subject: [Tutor] Using if statement with csv file Message-ID: <1422398450.1132831.219724005.5FC4DC69@webmail.messagingengine.com> Hi Tammy, I wonder how big your csv file is? I have ever read a small csv file into one variable. Even a csv file with 100 rows. And then split it into identified fields from there. I look at the csv file with Notepad++ to see if the data rows end with a \r or a \n. I then split that into a list and each row is an element in the list. I can then split each row by the comma delimiter, to resolve down to each field. Just an idea. I have a csv file. I would like to create a filter or if statement on a column but it is not producing the right results. It displays everythingHere is the example:import csvwith open('test.csv') as csvfile: reader = csv.DictReader(csvfile)for row in reader: if row['Absent'] > 10 print rowI just want the column Absent to show me all of the numbers that are greater than 10. It gives me all the results. I am not sure what to do.Thank you, Tammy -- Bw_dw at fastmail.net From kwpolska at gmail.com Wed Jan 28 11:26:43 2015 From: kwpolska at gmail.com (Chris Warrick) Date: Wed, 28 Jan 2015 11:26:43 +0100 Subject: [Tutor] Decode and Encode In-Reply-To: References: Message-ID: On Wed, Jan 28, 2015 at 10:35 AM, Sunil Tech wrote: > Hi All, > > When i copied a text from web and pasted in the python-terminal, it > automatically coverted into unicode(i suppose) > > can anyone tell me how it does? > Eg: >>>> p = "??" >>>> p > '\xe4\xbd\xa0\xe5\xa5\xbd' >>>> o = '??V' >>>> o > '\xc2\xaa\xc3\xaeV' >>>> No, it didn?t. You created a bytestring, that contains some bytes. Python does NOT think of `p` as a unicode string of 2 characters, it?s a bytestring of 6 bytes. You cannot use that byte string to reliably get only the first character, for example ? `p[0]` will get you garbage ('\xe4' which will render as a question mark on an UTF-8 terminal). In order to get a real unicode string, you must do one of the following: (a) prepend it with u''. This works only if your locale is set correctly and Python knows you use UTF-8. For example: >>> p = u"??" >>> p u'\u4f60\u597d' (b) Use decode on the bytestring, which is safer and does not depend on a properly configured system. >>> p = "??".decode('utf-8') >>> p u'\u4f60\u597d' However, this does not apply in Python 3. Python 3 defaults to Unicode strings, so you can do: >>> p = "??" and have proper Unicode handling, assuming your system locale is set correctly. If it isn?t, >>> p = b"??".decode('utf-8') would do it. -- Chris Warrick PGP: 5EAAEA16 From alan.gauld at btinternet.com Wed Jan 28 11:30:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Jan 2015 10:30:07 +0000 Subject: [Tutor] Using if statement with csv file In-Reply-To: <1422398450.1132831.219724005.5FC4DC69@webmail.messagingengine.com> References: <1422398450.1132831.219724005.5FC4DC69@webmail.messagingengine.com> Message-ID: On 27/01/15 22:40, dw wrote: > I have ever read a small csv file into one variable. > Even a csv file with 100 rows. > And then split it into identified fields from there. > I look at the csv file with Notepad++ to see if the data rows end with a > \r or a \n. > I then split that into a list and each row is an element in the list. > I can then split each row by the comma delimiter, to resolve down to > each field. > Just an idea. Probably not a good one though. The CSV module is a better approach since it can take account of all the complexities of CSV files which your approach would fail on. For example how do you handle an embedded text field with commas in it? Or newlines? Or a quoted field containing quotes? When a module exists in the standard library its nearly always worth using it. Somebody has taken the time to write it, test it and submit it precisely because the simple approach doesn't work reliably. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Wed Jan 28 12:26:50 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 28 Jan 2015 22:26:50 +1100 Subject: [Tutor] Decode and Encode In-Reply-To: References: Message-ID: <20150128112650.GV20517@ando.pearwood.info> On Wed, Jan 28, 2015 at 03:05:58PM +0530, Sunil Tech wrote: > Hi All, > > When i copied a text from web and pasted in the python-terminal, it > automatically coverted into unicode(i suppose) > > can anyone tell me how it does? > Eg: > >>> p = "??" > >>> p > '\xe4\xbd\xa0\xe5\xa5\xbd' It is hard to tell exactly, since we cannot see what p is supposed to be. I am predicting that you are using Python 2.7, which uses byte-strings by default, not Unicode text-strings. To really answer your question correctly, we need to know the operating system and which terminal you are using, and the terminal's encoding. I will guess a Linux system, with UTF-8 encoding in the terminal. So, when you paste some Unicode text into the terminal, the terminal receives the UTF-8 bytes, and displays the characters: ?? On my system, they display like boxes, but I expect that they are: CJK UNIFIED IDEOGRAPH-4F60 CJK UNIFIED IDEOGRAPH-597D But, because this is Python 2, and you used byte-strings "" instead of Unicode strings u"", Python sees the raw UTF-8 bytes. py> s = u'??' # Note this is a Unicode string u'...' py> import unicodedata py> for c in s: ... print unicodedata.name(c) ... CJK UNIFIED IDEOGRAPH-4F60 CJK UNIFIED IDEOGRAPH-597D py> s.encode('UTF-8') '\xe4\xbd\xa0\xe5\xa5\xbd' which matches your results. Likewise for this example: py> s = u'??V' # make sure to use Unicode u'...' py> for c in s: ... print unicodedata.name(c) ... FEMININE ORDINAL INDICATOR LATIN SMALL LETTER I WITH CIRCUMFLEX LATIN CAPITAL LETTER V py> s.encode('utf8') '\xc2\xaa\xc3\xaeV' which matches yours: > >>> o = '??V' > >>> o > '\xc2\xaa\xc3\xaeV' Obviously all this is confusing and harmful. In Python 3, the interpeter defaults to Unicode text strings, so that this issue goes away. -- Steve From breamoreboy at yahoo.co.uk Wed Jan 28 13:27:09 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 28 Jan 2015 12:27:09 +0000 Subject: [Tutor] Using if statement with csv file In-Reply-To: <1422398450.1132831.219724005.5FC4DC69@webmail.messagingengine.com> References: <1422398450.1132831.219724005.5FC4DC69@webmail.messagingengine.com> Message-ID: On 27/01/2015 22:40, dw wrote: > Hi Tammy, > I wonder how big your csv file is? > I have ever read a small csv file into one variable. > Even a csv file with 100 rows. > And then split it into identified fields from there. > I look at the csv file with Notepad++ to see if the data rows end with a > \r or a \n. > I then split that into a list and each row is an element in the list. > I can then split each row by the comma delimiter, to resolve down to > each field. > Just an idea. > I let the csv DictReader described here https://docs.python.org/3/library/csv.html#csv.DictReader do the work for me. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From sunil.techspk at gmail.com Wed Jan 28 13:52:13 2015 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 28 Jan 2015 18:22:13 +0530 Subject: [Tutor] Decode and Encode In-Reply-To: <20150128112650.GV20517@ando.pearwood.info> References: <20150128112650.GV20517@ando.pearwood.info> Message-ID: Thank you for all your replies?? On Wed, Jan 28, 2015 at 4:56 PM, Steven D'Aprano wrote: > On Wed, Jan 28, 2015 at 03:05:58PM +0530, Sunil Tech wrote: > > Hi All, > > > > When i copied a text from web and pasted in the python-terminal, it > > automatically coverted into unicode(i suppose) > > > > can anyone tell me how it does? > > Eg: > > >>> p = "??" > > >>> p > > '\xe4\xbd\xa0\xe5\xa5\xbd' > > It is hard to tell exactly, since we cannot see what p is supposed to > be. I am predicting that you are using Python 2.7, which uses > byte-strings by default, not Unicode text-strings. > > To really answer your question correctly, we need to know the operating > system and which terminal you are using, and the terminal's encoding. I > will guess a Linux system, with UTF-8 encoding in the terminal. > > So, when you paste some Unicode text into the terminal, the terminal > receives the UTF-8 bytes, and displays the characters: > > ?? > > On my system, they display like boxes, but I expect that they are: > > CJK UNIFIED IDEOGRAPH-4F60 > CJK UNIFIED IDEOGRAPH-597D > > But, because this is Python 2, and you used byte-strings "" instead of > Unicode strings u"", Python sees the raw UTF-8 bytes. > > py> s = u'??' # Note this is a Unicode string u'...' > py> import unicodedata > py> for c in s: > ... print unicodedata.name(c) > ... > CJK UNIFIED IDEOGRAPH-4F60 > CJK UNIFIED IDEOGRAPH-597D > py> s.encode('UTF-8') > '\xe4\xbd\xa0\xe5\xa5\xbd' > > which matches your results. > > Likewise for this example: > > py> s = u'??V' # make sure to use Unicode u'...' > py> for c in s: > ... print unicodedata.name(c) > ... > FEMININE ORDINAL INDICATOR > LATIN SMALL LETTER I WITH CIRCUMFLEX > LATIN CAPITAL LETTER V > py> s.encode('utf8') > '\xc2\xaa\xc3\xaeV' > > > which matches yours: > > > >>> o = '??V' > > >>> o > > '\xc2\xaa\xc3\xaeV' > > > Obviously all this is confusing and harmful. In Python 3, the interpeter > defaults to Unicode text strings, so that this issue goes away. > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From philipholveck at hotmail.com Thu Jan 29 06:37:41 2015 From: philipholveck at hotmail.com (Phil H) Date: Wed, 28 Jan 2015 23:37:41 -0600 Subject: [Tutor] webservice question Message-ID: Looking for a little help. I'm working on a little project and think using python would be the best way to do it. I am a novice but have read a few beginners books. Well to not waste everyones time i'll just get to it. I'm looking to use web services to get and post data from a server with a java rest interface This is what I have been given from the Java end Java method public java.lang.String getSettings (java.lang.String username, java.lang.String pass, java.lang.String key, java.lang.string tag) url example http://localhost:8080/gettag/tag (retrieve a tag from a DB) i'm told it should return something like this [tag''s value] So for what is working -------------------------------- import urllib2 import requests url = 'http://localhost:8080/gettag/testconnection' response = urllib2.urlopen(url) .read() print response ------------------------------ with this I get the expected response from the server then I have a test to authenticate user and pass url = 'http://localhost:8080/gettag/testauth?username=testuser&pass=123456' and this works This is where I get confused, how do I pass the variable key's value and return the variable tag's value. Thanks in advance for any help, I've tried a bunch of stuff and its just not working. Phil From alan.gauld at btinternet.com Thu Jan 29 09:34:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 29 Jan 2015 08:34:23 +0000 Subject: [Tutor] webservice question In-Reply-To: References: Message-ID: On 29/01/15 05:37, Phil H wrote: > public java.lang.String getSettings (java.lang.String username, java.lang.String pass, java.lang.String key, java.lang.string tag) > i'm told it should return something like this > [tag''s value] > then I have a test to authenticate user and pass > > url = 'http://localhost:8080/gettag/testauth?username=testuser&pass=123456' > and this works > > This is where I get confused, how do I pass the variable key's value > and return the variable tag's value. > Thanks in advance for any help, I've tried a bunch of stuff and its just not working. It would probably help if you'd shown us at least one of your attempts so we can see where your thinking has been going... also the response back. But at a guess I'd have thought you used a URL of: url = 'http://localhost:8080/gettag/getSettings?username=testuser&pass=123456&key=&tag=' Since that seems to be the API signature? But I'm no expert on Restful web services so I could well be wrong. Is that close to what you tried? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Thu Jan 29 20:56:10 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 29 Jan 2015 11:56:10 -0800 Subject: [Tutor] webservice question In-Reply-To: References: Message-ID: On Wed, Jan 28, 2015 at 9:37 PM, Phil H wrote: > Looking for a little help. I'm working on a little project and think using python would be the best way to do it. I am a novice but have read a few beginners books. Well to not waste everyones time i'll just get to it. I'm looking to use web services to get and post data from a server with a java rest interface I think the question needs a little clarification here. You're mentioning both clients and servers in the same question, so it's a little unclear what you're aiming for. Are you writing a client, or a server? Or both? From dyoo at hashcollision.org Thu Jan 29 22:48:13 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 29 Jan 2015 13:48:13 -0800 Subject: [Tutor] Fwd: webservice question In-Reply-To: References: Message-ID: Hi Phil, Let me forward your response to tutor. My apologies; I'm right in the middle of work, and can't respond promptly at the moment. Please use Reply to All in the future on Tutor so that responses can distribute across the list, rather than run into hotspots. ---------- Forwarded message ---------- From: Phil H Date: Thu, Jan 29, 2015 at 12:55 PM Subject: Re: [Tutor] webservice question To: Danny Yoo Danny, I was writing the client in Python to talk to the server in Java. I believe I have figured it out, the java doc had typoes in it and once I got that fixed it is returning the data I expected to see Sent from my iPhone > On Jan 29, 2015, at 1:56 PM, "Danny Yoo" wrote: > >> On Wed, Jan 28, 2015 at 9:37 PM, Phil H wrote: >> Looking for a little help. I'm working on a little project and think using python would be the best way to do it. I am a novice but have read a few beginners books. Well to not waste everyones time i'll just get to it. I'm looking to use web services to get and post data from a server with a java rest interface > > > I think the question needs a little clarification here. You're > mentioning both clients and servers in the same question, so it's a > little unclear what you're aiming for. > > Are you writing a client, or a server? Or both? From tallengs at gmail.com Thu Jan 29 18:16:37 2015 From: tallengs at gmail.com (Tallen Grey Smith) Date: Thu, 29 Jan 2015 10:16:37 -0700 Subject: [Tutor] Umm.. I need help on changing Global Variables. Message-ID: <8ED3F2BE-0D6A-4CFD-8F7A-C584AAD6A443@gmail.com> So, I?m trying to make a very simple game that involves time management properly, but I?m having an issue. level = 1 player_health = 100 enemy_health = 100 steps = 10 civilians = 20 charge = 0 name_2 = 'Bob' def game(): global level global player_health global enemy_health global steps global civilians global charge print "\n" * 80 print "Level " + str(level) print name_2 +": " + str(player_health) +" HP" print "Centurion: " + str(enemy_health) + " HP" print "Distance: " + str(steps) + " feet" print "Weapon Charge: " + str(charge) print "Civilians Remaining: " + str(civilians) print "A Centurion lands near the gate! Prepare the Laser!" action_1 = raw_input("Do you want to charge the laser or fire?") action_2 = action_1.lower() if action_2 == "charge": charge == charge+10 steps == steps-1 civilians == civilians -1 charge_1() def charge_1(): level player_health enemy_health steps civilians charge print "\n" * 80 print "Level " + str(level) print name_2 +": " + str(player_health) +" HP" print "Centurion: " + str(enemy_health) + " HP" print "Distance: " + str(steps) + " feet" print "Weapon Charge: " + str(charge) print "Civilians Remaining: " + str(civilians) print "The Centurion moves closer! Hurry!" action_1 = raw_input("Do you want to charge the laser or fire?") action_2 = action_1.lower() if action_2 == "charge": charge = charge+10 steps = steps-1 civilians = civilians -1 charge_1() game() thats my code, and I want it to where if I type charge it?ll make my charge go up 10, my steps go down 1, my divs going down 1, and it to go to my charge_1 function, which should do the same thing but with a tweaked dialog box. But no matter how hard i try, once it gets to the charge_1, it always says that the variables that I changed where referenced in previous functions and it can?t pull them. How can I change this to get a variable that when changed in my If statement, would be useable in other functions? Thanks. From alan.gauld at btinternet.com Thu Jan 29 23:26:11 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 29 Jan 2015 22:26:11 +0000 Subject: [Tutor] Umm.. I need help on changing Global Variables. In-Reply-To: <8ED3F2BE-0D6A-4CFD-8F7A-C584AAD6A443@gmail.com> References: <8ED3F2BE-0D6A-4CFD-8F7A-C584AAD6A443@gmail.com> Message-ID: On 29/01/15 17:16, Tallen Grey Smith wrote: > def game(): > > global level > global player_health > global enemy_health > global steps > global civilians > global charge > This is fine. But it only tells this function to treat them as globals. > def charge_1(): > > level > player_health > enemy_health > steps > civilians > charge This does nothing useful. You need to tell the function that they are global just as you did above. Global variables are considered bad practice so Python doesn't make it easy to use them. (Although a lot easier than some languages) There are quite a few other things we could comment on in your code but this should resolve the immediate issue. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From guruprasad.br at thomsonreuters.com Fri Jan 30 07:50:26 2015 From: guruprasad.br at thomsonreuters.com (guruprasad.br at thomsonreuters.com) Date: Fri, 30 Jan 2015 06:50:26 +0000 Subject: [Tutor] Python - Rules engine Message-ID: Hello, Any suggestions for a Python module implementing Rules Engine functionality? I came across ?PyKE?, but not sure if it is being maintained actively. Any details on this will be very helpful. Thanks in advance. Best Regards, Guru From steve at pearwood.info Fri Jan 30 13:40:48 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 30 Jan 2015 23:40:48 +1100 Subject: [Tutor] Python - Rules engine In-Reply-To: References: Message-ID: <20150130124047.GI2498@ando.pearwood.info> On Fri, Jan 30, 2015 at 06:50:26AM +0000, guruprasad.br at thomsonreuters.com wrote: > Hello, > > Any suggestions for a Python module implementing Rules Engine > functionality? I came across ?PyKE?, but not sure if it is being > maintained actively. Any details on this will be very helpful. I'm not sure what "Rules Engine" means. Care to explain? It is such a generic term it could be referring to "business rules", A.I., Prolog-like logic programming, or more. Have you googled? https://www.google.com.au/search?q=python+%22rules+engine%22 https://duckduckgo.com/?q=python%20%22rules%20engine%22 If you mean something like Prolog, then Pyke appears to be a very popular choice, but it doesn't look like there is a huge amount of development activity going on. Perhaps that means it is a stable product and doesn't need much on-going development? For business rules, Intellect seems to be a popular choice. By the way, emailing "webmaster at python.org" is completely inappropriate for this. The webmaster is responsible for maintenance of the Python.org website, not answering random questions about third-party libraries. -- Steven From breamoreboy at yahoo.co.uk Fri Jan 30 13:48:44 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 30 Jan 2015 12:48:44 +0000 Subject: [Tutor] Python - Rules engine In-Reply-To: References: Message-ID: On 30/01/2015 06:50, guruprasad.br at thomsonreuters.com wrote: > Hello, > > Any suggestions for a Python module implementing Rules Engine functionality? I came across ?PyKE?, but not sure if it is being maintained actively. Any details on this will be very helpful. > > Thanks in advance. > > Best Regards, > Guru > This is probably not the best list for asking such a question, but having said that this http://catherinedevlin.blogspot.co.uk/2009/06/dont-need-no-stinking-rules-engine.html makes an interesting read. There's another useful link here http://billbreitmayer.com/static/drupal/node/179.html As for PyKE maybe it's so good it doesn't need maintaining, I just don't know? I'd certainly prefer using something that's got past a 1.0 release, as opposed to a new project that looks active at (say) 0.3 and is dead before 0.5. What else if anything have you found by searching? I tend to find that trying packages from the first hits to compare them is really easy. Just use "pip install xyz" and away you go, especially when testing small snippets from the interactive interpreter. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Sat Jan 31 01:39:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 31 Jan 2015 00:39:46 +0000 Subject: [Tutor] Lost message re serial comms - oops! Message-ID: While managing the moderation queue I saw a message about using Python for serial comms using a RaspberryPi. It came from a C/C++ programmer wanting to use python. I think I accidentally hit reject instead of accept. If you recognise what I'm talking about please resend your post. Apologies. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jkmberia at gmail.com Sat Jan 31 14:37:39 2015 From: jkmberia at gmail.com (J Mberia) Date: Sat, 31 Jan 2015 16:37:39 +0300 Subject: [Tutor] Assistance with UnicodeDecodeError Message-ID: Hi, I am teaching myself programming in python and assistance with UnicodeDecodeError I am trying to scrap text from a website using Python 2.7 in windows 8 and i am getting this error *"**UnicodeDecodeError: 'charmap codec can't encode character u'\u2014 in position 11231 character maps to "* *How do i resolve? Pls assist.* *Jerry* From alan.gauld at btinternet.com Sat Jan 31 18:08:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 31 Jan 2015 17:08:27 +0000 Subject: [Tutor] Lost message re serial comms - oops! In-Reply-To: References: Message-ID: On 31/01/15 00:39, Alan Gauld wrote: > While managing the moderation queue I saw a message about using Python > for serial comms using a RaspberryPi. It came from a C/C++ programmer > wanting to use python. > > I think I accidentally hit reject instead of accept. The OP resent the post and I definitely approved it this time but it still hasn't come through. Could the OP please mail me direct so I can figure out what's going wrong. apologies, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From davea at davea.name Sat Jan 31 23:34:49 2015 From: davea at davea.name (Dave Angel) Date: Sat, 31 Jan 2015 17:34:49 -0500 Subject: [Tutor] Umm.. I need help on changing Global Variables. In-Reply-To: <8ED3F2BE-0D6A-4CFD-8F7A-C584AAD6A443@gmail.com> References: <8ED3F2BE-0D6A-4CFD-8F7A-C584AAD6A443@gmail.com> Message-ID: <54CD5889.20900@davea.name> On 01/29/2015 12:16 PM, Tallen Grey Smith wrote: > So, I?m trying to make a very simple game that involves time management properly, but I?m having an issue. > > > thats my code, and I want it to where if I type charge it?ll make my charge go up 10, my steps go down 1, my divs going down 1, and it to go to Python (like any modern procedural language) does not have a goto command. You're calling the other function, which means that eventually the other function will return back to game(). That's probably a big mistake, but it won't matter for the moment. > my charge_1 function, which should do the same thing but with a tweaked dialog box I don't see any dialog boxes in that code. > But no matter how hard i try, once it gets to the charge_1, it always says > that the variables that I changed where referenced in previous functions and it can?t pull them. Don't paraphrase the effect. Show just what got displayed. I've never seen an exception called "it can't pull them" > How can I change this to get a variable that when changed in my If statement, would be useable in other functions? > Thanks. Use of global variables is thoroughly discouraged. I'd suggest making a Game class, and making all these "variables" attributes of an instance of Game. Then you just pass that instance around between the various functions, as a formal parameter. -- DaveA From davea at davea.name Sat Jan 31 23:44:57 2015 From: davea at davea.name (Dave Angel) Date: Sat, 31 Jan 2015 17:44:57 -0500 Subject: [Tutor] Assistance with UnicodeDecodeError In-Reply-To: References: Message-ID: <54CD5AE9.40604@davea.name> On 01/31/2015 08:37 AM, J Mberia wrote: > Hi, > Welcome to Python tutor. Thanks for posting using text email, and for specifying both your Python version and Operating system. > I am teaching myself programming in python and assistance with > UnicodeDecodeError > > I am trying to scrap text from a website using Python 2.7 in windows 8 and > i am getting this error *"**UnicodeDecodeError: 'charmap codec can't encode > character u'\u2014 in position 11231 character maps to "* > > *How do i resolve? Pls assist.* > You can start by posting the whole error message, including the stack trace. Then you probably should include an appropriate segment of your code. The message means that you've got some invalid characters that you're trying to convert. That can either be that the data is invalid, or that you're specifying the wrong encoding, directly or implicitly. -- DaveA