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: <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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 <dyoo at hashcollision.org> 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: <a330136db3ca495ee185d41756e75b15@sonic.net>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
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: <CAEsvOwsW3Z8oWiHuESzdVbyqzaLDbVvkLhxOFp1Krnjew_vYUg@mail.gmail.com>
References: <CAEsvOwsW3Z8oWiHuESzdVbyqzaLDbVvkLhxOFp1Krnjew_vYUg@mail.gmail.com>
Message-ID: <CAEsvOwtNSTNrdPv=KbQTYoZy=3QfGpLPDuGeP_uU+DjrVHQX4Q@mail.gmail.com>

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? <Y/N>: ")
                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 <Y/N>: ")
                    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? <Y/N>: ")
                    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 <Y/N>: ").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? <Y/N>: ")
                    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 <module>
    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 <module>
    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: <mailman.101803.1420052428.18129.tutor@python.org>
References: <mailman.101803.1420052428.18129.tutor@python.org>
Message-ID: <COL125-W311DB2564918937E895539FA5C0@phx.gbl>

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 <coolshwetu at gmail.com>
> To: Tutor at python.org
> Subject: [Tutor] Convert string to bytes
> Message-ID:
> 	<CAM--9s6oY=YYfkdQNhSr-+sM5DhdvrPgy-zZhDDyBJ2prjO_-g at mail.gmail.com>
> 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 <tgmiller5 at hotmail.com>
> To: "tutor at python.org" <tutor at python.org>
> Subject: [Tutor] Help on Python drop-down list options
> Message-ID: <COL125-W488336EB344D6D2F4D6A6BFA5F0 at phx.gbl>
> 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 <wolfrage8765 at gmail.com>
> 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 <wolfrage8765 at gmail.com>
> 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 <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Help on Python drop-down list options
> Message-ID: <m81d2r$njo$1 at ger.gmane.org>
> 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 <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Convert string to bytes
> Message-ID: <m81deb$t41$1 at ger.gmane.org>
> 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 <alan.gauld at btinternet.com>
> To: shweta kaushik <coolshwetu at gmail.com>
> 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: <CAEsvOwsW3Z8oWiHuESzdVbyqzaLDbVvkLhxOFp1Krnjew_vYUg@mail.gmail.com>
 <CAEsvOwtNSTNrdPv=KbQTYoZy=3QfGpLPDuGeP_uU+DjrVHQX4Q@mail.gmail.com>
Message-ID: <m845r1$s4d$1@ger.gmane.org>

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 <module> 
>      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: <COL125-W311DB2564918937E895539FA5C0@phx.gbl>
References: <mailman.101803.1420052428.18129.tutor@python.org>
 <COL125-W311DB2564918937E895539FA5C0@phx.gbl>
Message-ID: <m84gag$i98$1@ger.gmane.org>

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: <CAEsvOwtNSTNrdPv=KbQTYoZy=3QfGpLPDuGeP_uU+DjrVHQX4Q@mail.gmail.com>
References: <CAEsvOwsW3Z8oWiHuESzdVbyqzaLDbVvkLhxOFp1Krnjew_vYUg@mail.gmail.com>
 <CAEsvOwtNSTNrdPv=KbQTYoZy=3QfGpLPDuGeP_uU+DjrVHQX4Q@mail.gmail.com>
Message-ID: <m84h3t$t6t$1@ger.gmane.org>

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 <module>
 >     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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net>
Message-ID: <m84sli$o3g$1@ger.gmane.org>

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: <m84sli$o3g$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <m84sli$o3g$1@ger.gmane.org>
Message-ID: <m84tum$84m$1@ger.gmane.org>

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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>

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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
Message-ID: <857fx5zbgf.fsf@benfinney.id.au>

Brandon Dorsey <brandontdr at gmail.com> 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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
References: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
References: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <CAGZkoWD3adTdvYF4+Z810DTPLWVS+cxcAXU0TtafR0TnZ3Bmfg@mail.gmail.com>
References: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
 <20150102113458.GG15262@ando.pearwood.info>
 <CAGZkoWD3adTdvYF4+Z810DTPLWVS+cxcAXU0TtafR0TnZ3Bmfg@mail.gmail.com>
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 <steve at pearwood.info> 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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <m86dvd$bb5$1@ger.gmane.org>

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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
 <20150102113458.GG15262@ando.pearwood.info>
Message-ID: <CAGZkoWD3adTdvYF4+Z810DTPLWVS+cxcAXU0TtafR0TnZ3Bmfg@mail.gmail.com>

On Fri, Jan 2, 2015 at 6:34 AM, Steven D'Aprano <steve at pearwood.info> 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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
 <857fx5zbgf.fsf@benfinney.id.au>
Message-ID: <CAGZkoWA6Mm5j+xQMaE72TrzVmj4q1YX_xMOkqFg0FTP2M50ONA@mail.gmail.com>

On Fri, Jan 2, 2015 at 6:08 AM, Ben Finney <ben+python at benfinney.id.au>
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: <CAGZkoWAJTBRwHGiLXYPdsNw5Bp-v1fuVz0M6s1B-hmMtMFpGDw@mail.gmail.com>
 <54A68093.6060904@davea.name>
Message-ID: <CAGZkoWCU01rUrfGn6BGjMobVUBTV4gRPdgtW5vH_b6=F_3v2FA@mail.gmail.com>

On Fri, Jan 2, 2015 at 6:27 AM, Dave Angel <davea at davea.name> 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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <m86dvd$bb5$1@ger.gmane.org>
References: <54A6AFFA.7050001@gmail.com> <m86dvd$bb5$1@ger.gmane.org>
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> <m86dvd$bb5$1@ger.gmane.org>
 <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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <m84sli$o3g$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <m84sli$o3g$1@ger.gmane.org>
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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <m84sli$o3g$1@ger.gmane.org>
 <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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <CAJdaWS5VTubTO8d++Zn-a853svOu5uVvkExOt2+4nx9EB3U0ww@mail.gmail.com>
References: <CAJdaWS5VTubTO8d++Zn-a853svOu5uVvkExOt2+4nx9EB3U0ww@mail.gmail.com>
Message-ID: <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>

---------- Forwarded message ----------
From: "Rohan Ds" <rohan0495 at gmail.com>
Date: 2 Jan 2015 23:46
Subject: Newbie
To: <tutors at python.org>
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: <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
References: <CAJdaWS5VTubTO8d++Zn-a853svOu5uVvkExOt2+4nx9EB3U0ww@mail.gmail.com>
 <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
Message-ID: <m86qon$ecs$1@ger.gmane.org>

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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <m86r06$ecs$2@ger.gmane.org>

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: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>

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:

<pseudo python>

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

</pseudo python>

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: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
References: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
Message-ID: <m871vn$qd4$1@ger.gmane.org>

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?

> <pseudo python>

> 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
>
> </pseudo python>

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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <m84sli$o3g$1@ger.gmane.org>
 <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: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
References: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
 <005801d026cc$39c351b0$ad49f510$@gmail.com>
Message-ID: <CANWBxgas0OtrT3+x5XRnNO3EjpDCXzD14ofqO=wnYfD1E7nGqQ@mail.gmail.com>

First, thanks Joseph for taking the time to reply.

My comments interspersed below:

On Fri, Jan 2, 2015 at 2:39 PM, Joseph Lee <joseph.lee22590 at gmail.com>
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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <m87kmt$tjm$1@ger.gmane.org>

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: <m87kmt$tjm$1@ger.gmane.org>
References: <54A74D36.5090308@gmail.com> <m87kmt$tjm$1@ger.gmane.org>
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: <m871vn$qd4$1@ger.gmane.org>
References: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
 <m871vn$qd4$1@ger.gmane.org>
Message-ID: <CANWBxgZbs6mMnf8-iuDYrh8L1-mE28-tCtGX+hdDXfmuz9+1Pg@mail.gmail.com>

On Fri, Jan 2, 2015 at 3:18 PM, Alan Gauld <alan.gauld at btinternet.com>
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.



>
>  <pseudo python>
>>
>
>  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
>>
>> </pseudo python>
>>
>
> 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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.gmail.com>
 <a330136db3ca495ee185d41756e75b15@sonic.net>
 <20150101001844.GI24472@ando.pearwood.info>
 <4836cd95c7abd9180c69abbb3f05c353@sonic.net> <m84sli$o3g$1@ger.gmane.org>
 <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: <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
References: <CAJdaWS5VTubTO8d++Zn-a853svOu5uVvkExOt2+4nx9EB3U0ww@mail.gmail.com>
 <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
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: <CANWBxgbStYzDwwaGb+2G6dsD=nCXfLD4DD4q1qawH4f6OKKJvw@mail.gmail.com>
 <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: <CAAqnBO9BgjtzNWrn5DwQLnrV3doLpq4zQVZ9r=kGJG51V3ywjw@mail.gmail.com>

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: <CAAqnBO9BgjtzNWrn5DwQLnrV3doLpq4zQVZ9r=kGJG51V3ywjw@mail.gmail.com>
References: <CAAqnBO9BgjtzNWrn5DwQLnrV3doLpq4zQVZ9r=kGJG51V3ywjw@mail.gmail.com>
Message-ID: <m88q9u$i03$1@ger.gmane.org>

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:
<SNIP>
>
> 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: <CAAqnBO_f4ZgDU25E2drYorRxzBpu53hzpViBkSZsv3PSyf9mug@mail.gmail.com>
References: <mailman.102192.1420297774.18129.tutor@python.org>	<CAAqnBO9vcHacgnYbxVJYs=vVJPg9Mwc982r9QqY2=omxNX8kiw@mail.gmail.com>
 <CAAqnBO_f4ZgDU25E2drYorRxzBpu53hzpViBkSZsv3PSyf9mug@mail.gmail.com>
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 <module>
> 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 <host> <port>



-- 
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: <m89bt8$g1v$1@ger.gmane.org>

On 03/01/15 16:14, WolfRage wrote:

>>>      def check_total_and_eliminate(self, first, second, third):
<snip>

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:
<snip>

> 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: <mailman.102192.1420297774.18129.tutor@python.org>
References: <mailman.102192.1420297774.18129.tutor@python.org>
Message-ID: <CAAqnBO9vcHacgnYbxVJYs=vVJPg9Mwc982r9QqY2=omxNX8kiw@mail.gmail.com>

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 <module>
    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, <tutor-request at python.org> 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 <davea at davea.name>
> 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 <pramod.sp78 at gmail.com>
> To: tutor at python.org
> Subject: [Tutor] Socket programming
> Message-ID:
>         <CAAqnBO9BgjtzNWrn5DwQLnrV3doLpq4zQVZ9r=
> 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 <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Socket programming
> Message-ID: <m88q9u$i03$1 at ger.gmane.org>
> 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 <steve at pearwood.info>
> 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: <D0640201D2A2415FA72EE5D723033A18@TedHP>

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: <D0640201D2A2415FA72EE5D723033A18@TedHP>
References: <D0640201D2A2415FA72EE5D723033A18@TedHP>
Message-ID: <m89dev$6oc$1@ger.gmane.org>

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: <mailman.102192.1420297774.18129.tutor@python.org>	<CAAqnBO9vcHacgnYbxVJYs=vVJPg9Mwc982r9QqY2=omxNX8kiw@mail.gmail.com>
 <CAAqnBO_f4ZgDU25E2drYorRxzBpu53hzpViBkSZsv3PSyf9mug@mail.gmail.com>
 <54A82FFB.5060709@btinternet.com>
Message-ID: <m89dh5$6oc$2@ger.gmane.org>

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: <D0640201D2A2415FA72EE5D723033A18@TedHP>
 <m89dev$6oc$1@ger.gmane.org> <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)
<zip object at 0xb7bf238c>
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: <m89vbq$v38$1@ger.gmane.org>

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)
> <zip object at 0xb7bf238c>
> 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: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>

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: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
References: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
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: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
References: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
Message-ID: <m8bnq8$jkm$1@ger.gmane.org>

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: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
 <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: <D0640201D2A2415FA72EE5D723033A18@TedHP>
References: <D0640201D2A2415FA72EE5D723033A18@TedHP>
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: <B17407D4AA1C4019A01ADE96BD5F8697@TedHP>
 <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: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>

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: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
References: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
Message-ID: <m8c2mo$itr$1@ger.gmane.org>

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: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
References: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
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: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
 <20150105023957.GV27426@ando.pearwood.info>
Message-ID: <CANDiX9+-O1-P-AZRPg=eN=RH_E_4SnZXkA8UREBdVXKoaotYnw@mail.gmail.com>

On Sun, Jan 4, 2015 at 8:39 PM, Steven D'Aprano <steve at pearwood.info> 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: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>

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.

<python>

#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()

</python>

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: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
 <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 <akleider at sonic.net> 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 <cs at zip.com.au>

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: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>
References: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>
Message-ID: <20150105063901.GA89330@cskk.homeip.net>

On 04Jan2015 23:19, Rance Hall <ranceh at gmail.com> 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 <cs at zip.com.au>

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: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>
References: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>
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.

<python>

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

</python>

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: <CANDiX9+-O1-P-AZRPg=eN=RH_E_4SnZXkA8UREBdVXKoaotYnw@mail.gmail.com>
References: <BLU437-SMTP96460226EF81FCC9D7FE31BB5B0@phx.gbl>
 <20150105023957.GV27426@ando.pearwood.info>
 <CANDiX9+-O1-P-AZRPg=eN=RH_E_4SnZXkA8UREBdVXKoaotYnw@mail.gmail.com>
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 <steve at pearwood.info> 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: <CANWBxgbkq0p-qHAveqgY8Qqvm1Spo3TbKmFV_kCxqJ8_ty2xHA@mail.gmail.com>
 <20150105063901.GA89330@cskk.homeip.net>
Message-ID: <CANWBxgato_P2Y+ZtnBPXqDWXC69cK+Cr5r0N_Wksbp3yjLhjqw@mail.gmail.com>

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 <cs at zip.com.au> wrote:

> On 04Jan2015 23:19, Rance Hall <ranceh at gmail.com> 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 <cs at zip.com.au>
>
> 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: <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
References: <CAJdaWS5VTubTO8d++Zn-a853svOu5uVvkExOt2+4nx9EB3U0ww@mail.gmail.com>
 <CAJdaWS7cVbXUhEN36ttRz7kUZwUcD1yEa=uxFUvW31VV-o6TrQ@mail.gmail.com>
Message-ID: <m8er08$lmi$1@ger.gmane.org>

On 02/01/2015 18:21, Rohan Ds wrote:
> ---------- Forwarded message ----------
> From: "Rohan Ds" <rohan0495 at gmail.com>
> Date: 2 Jan 2015 23:46
> Subject: Newbie
> To: <tutors at python.org>
> 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: <m8f0os$p1r$1@ger.gmane.org>

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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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: <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>

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: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>

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: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
References: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
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: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
References: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
Message-ID: <m8fanu$hb1$1@ger.gmane.org>

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: <m8fanu$hb1$1@ger.gmane.org>
References: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
 <m8fanu$hb1$1@ger.gmane.org>
Message-ID: <CAM--9s6BZk=qLAfpxEAh8v1E3FQQL7xq4sX746wZK6ayxv2O3g@mail.gmail.com>

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" <alan.gauld at btinternet.com> 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: <CAM--9s6BZk=qLAfpxEAh8v1E3FQQL7xq4sX746wZK6ayxv2O3g@mail.gmail.com>
References: <CAM--9s4mYW3yfiU3oLay0OXtYkdXm2qf2DXg4d9NWYYGaiMYhg@mail.gmail.com>
 <m8fanu$hb1$1@ger.gmane.org>
 <CAM--9s6BZk=qLAfpxEAh8v1E3FQQL7xq4sX746wZK6ayxv2O3g@mail.gmail.com>
Message-ID: <CAM--9s5pqYyo81yuB64xjoESsz7oiEOj0q-JjjFWKKs8hWHPxg@mail.gmail.com>

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" <coolshwetu at gmail.com> 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" <alan.gauld at btinternet.com> 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: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>

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: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>
References: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>
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: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>
Message-ID: <m8gqqj$v2s$1@ger.gmane.org>

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 
<https://docs.python.org/dev/library/re.html#regular-expression-syntax>:

"""
\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: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>
References: <CAKgQ7ULxGAn8X50jgF8dUPOmcXwEZq-6YBzQo3483PWZs+drBw@mail.gmail.com>
Message-ID: <20150106212235.GA6327@cskk.homeip.net>

On 06Jan2015 11:43, Norman Khine <norman at khine.net> 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 <cs at zip.com.au>

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 <bryanlaws at aol.com>

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: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>

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: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>
References: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>
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: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>
References: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>
Message-ID: <CAGZAPF5sJUZfX5wXv3__KwxcBs1GHibf2f1vsG0A2u+mp-Stcw@mail.gmail.com>

On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith <sanelson at gmail.com> 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: <CAGZAPF5sJUZfX5wXv3__KwxcBs1GHibf2f1vsG0A2u+mp-Stcw@mail.gmail.com>
References: <CABqtqVSrtEHMMyPffMQhbY4Dea1gKwpirFdsa9C_Rwevg6n6Cw@mail.gmail.com>
 <CAGZAPF5sJUZfX5wXv3__KwxcBs1GHibf2f1vsG0A2u+mp-Stcw@mail.gmail.com>
Message-ID: <CABqtqVSdv+mrYv08a0eP84jn8ZzNoDGvgDRSB6aZQ35nQ0+bNw@mail.gmail.com>

Hi Danny,

On Tue, Jan 6, 2015 at 10:07 PM, Danny Yoo <dyoo at hashcollision.org> wrote:

> On Tue, Jan 6, 2015 at 1:46 PM, Stephen Nelson-Smith <sanelson at gmail.com>
> 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: <mailman.13.1420628401.21674.tutor@python.org>
References: <mailman.13.1420628401.21674.tutor@python.org>
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 <sanelson at gmail.com> 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: <m8js09$64m$1@ger.gmane.org>

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: <m8jsj9$fgq$1@ger.gmane.org>

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: <m8jsj9$fgq$1@ger.gmane.org>
References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com>
 <m8jsj9$fgq$1@ger.gmane.org>
Message-ID: <CAPM-O+zy3nS5D7w35_9H1n-fzbZX_oc8GFDZ9qKsRRb4pR3MZg@mail.gmail.com>

On Wed, Jan 7, 2015 at 1:06 PM, Alan Gauld <alan.gauld at btinternet.com>
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: <CAPM-O+zy3nS5D7w35_9H1n-fzbZX_oc8GFDZ9qKsRRb4pR3MZg@mail.gmail.com>
References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com>
 <m8jsj9$fgq$1@ger.gmane.org>
 <CAPM-O+zy3nS5D7w35_9H1n-fzbZX_oc8GFDZ9qKsRRb4pR3MZg@mail.gmail.com>
Message-ID: <CAGZAPF5gVR3tTtdpCAYRWbEC5YEezrkYpbsgb7xei3wNuDGurA@mail.gmail.com>

>>> 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: <mailman.13.1420628401.21674.tutor@python.org>
 <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 <sanelson at gmail.com> 
>> 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: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>

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: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
Message-ID: <CAGZAPF5B5dE_gaB=TFWDBxbCXH6_4Ts316yTFzQ1gJLKM2VNqw@mail.gmail.com>

On Thu, Jan 8, 2015 at 9:32 PM, Crusier <crusier at gmail.com> 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: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
Message-ID: <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>

> 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: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
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: <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
 <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>
Message-ID: <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>

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 <dyoo at hashcollision.org> 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: <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
 <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>
 <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>
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: <CAGZAPF5gVR3tTtdpCAYRWbEC5YEezrkYpbsgb7xei3wNuDGurA@mail.gmail.com>
References: <54ad4dde.434cc20a.5060.ffffddc7@mx.google.com>
 <m8jsj9$fgq$1@ger.gmane.org>
 <CAPM-O+zy3nS5D7w35_9H1n-fzbZX_oc8GFDZ9qKsRRb4pR3MZg@mail.gmail.com>
 <CAGZAPF5gVR3tTtdpCAYRWbEC5YEezrkYpbsgb7xei3wNuDGurA@mail.gmail.com>
Message-ID: <CAMxbqSMkBA2afNbi9bMbJi=JXQRmcmLdQ2FDpL+QLpgmu4yEJg@mail.gmail.com>

:)

On Thu, Jan 8, 2015 at 3:02 AM, Danny Yoo <dyoo at hashcollision.org> 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: <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>
References: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
 <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>
 <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>
Message-ID: <CAGZAPF6caWv13AKdiPST5NYnBbXYZtj-58RfjjizV7-QGb2ZdQ@mail.gmail.com>

> 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: <CAC7HCj8vcyLATWTo==QBg_dzsY=kpt8itvkwsEcEZz5U_prmRg@mail.gmail.com>
 <CAGZAPF5x+6pyr7tjQpoz13jDEeEdjqZLhGLsxQmkH5taXK9zMw@mail.gmail.com>
 <CAC7HCj_sH+dqhjDfyFBJMzXoBJdX58E2NSrEML2+Nh4AzyitgA@mail.gmail.com>
Message-ID: <m8oj3v$n5s$1@ger.gmane.org>

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: <A79E0AC1-9A1A-4552-AEB2-0584C41B1169@gmail.com>

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: <A79E0AC1-9A1A-4552-AEB2-0584C41B1169@gmail.com>
References: <A79E0AC1-9A1A-4552-AEB2-0584C41B1169@gmail.com>
Message-ID: <m8qlm1$1kh$1@ger.gmane.org>

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: <A79E0AC1-9A1A-4552-AEB2-0584C41B1169@gmail.com>
References: <A79E0AC1-9A1A-4552-AEB2-0584C41B1169@gmail.com>
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: <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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: <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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: <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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 <module>
     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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
Message-ID: <m91fd0$5v2$1@ger.gmane.org>

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 <module>
>      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>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com>
Message-ID: <m91g4t$i35$1@ger.gmane.org>

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: <m91fd0$5v2$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <m91fd0$5v2$1@ger.gmane.org>
Message-ID: <54B450C2.5020400@gmail.com>

<SNIP>
>
> 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: <m91g4t$i35$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com>
 <m91g4t$i35$1@ger.gmane.org>
Message-ID: <54B459C7.7090704@gmail.com>

On 01/12/2015 05:00 PM, Alan Gauld wrote:
<SNIP>
> 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: <m91g4t$i35$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com>
 <m91g4t$i35$1@ger.gmane.org>
Message-ID: <54B461A7.7030808@gmail.com>

On 01/12/2015 05:00 PM, Alan Gauld wrote:
<SNIP>
> __str__methodf of the grid.
> Then the draw method becomes print(self)
>
> And you can also just use print(aGrid) etc.
<SNIP>

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: <m91g4t$i35$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <54B428C9.3050109@gmail.com> <54B42E71.4070202@gmail.com>
 <m91g4t$i35$1@ger.gmane.org>
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: <CAPuc=9Sk8W5fV_PO6dFOWXXGp03E3=6Ka-kqpFVUUJLJgTG+ZQ@mail.gmail.com>

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: <CAPuc=9Sk8W5fV_PO6dFOWXXGp03E3=6Ka-kqpFVUUJLJgTG+ZQ@mail.gmail.com>
References: <CAPuc=9Sk8W5fV_PO6dFOWXXGp03E3=6Ka-kqpFVUUJLJgTG+ZQ@mail.gmail.com>
Message-ID: <CAGZAPF6-94DjCDBRAERWQOaExUjnjNW_zC5UwcKXvRXDUWLXPA@mail.gmail.com>

On Tue, Jan 13, 2015 at 9:13 AM, Arvind Ramachandran
<arvind.ramachandran at sial.com> 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: <CAGZAPF6-94DjCDBRAERWQOaExUjnjNW_zC5UwcKXvRXDUWLXPA@mail.gmail.com>
References: <CAPuc=9Sk8W5fV_PO6dFOWXXGp03E3=6Ka-kqpFVUUJLJgTG+ZQ@mail.gmail.com>
 <CAGZAPF6-94DjCDBRAERWQOaExUjnjNW_zC5UwcKXvRXDUWLXPA@mail.gmail.com>
Message-ID: <CAGZAPF7wqPZyjsTB_YQt9Hs1Hxk_Q+_raX_6GTb_-sOXZcyK4Q@mail.gmail.com>

> 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: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>

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: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
References: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
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: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
References: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
Message-ID: <CAGZAPF6Yj0f1nnVDCqkHb2wyZGXhPecx35_Pj+ay50=X37_xYQ@mail.gmail.com>

Hi Paul,

On Wed, Jan 14, 2015 at 1:48 PM, Paul LaBerge <paul at labergedaylight.com> 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: <CAGZAPF6Yj0f1nnVDCqkHb2wyZGXhPecx35_Pj+ay50=X37_xYQ@mail.gmail.com>
References: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
 <CAGZAPF6Yj0f1nnVDCqkHb2wyZGXhPecx35_Pj+ay50=X37_xYQ@mail.gmail.com>
Message-ID: <CAGZAPF5jsDao5AXLRvqWDDLHNWO7Z10+7QA4HYv=3GDR1+TN8w@mail.gmail.com>

> 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: <D6C0935E-6D26-4D6D-80A7-BD47381C379E@labergedaylight.com>
Message-ID: <85oaq0u13d.fsf@benfinney.id.au>

Paul LaBerge <paul at labergedaylight.com> 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: <CAGPegVjdwd1pPU0GrBDZxx4JH2rc2Qthec-61+jtHufGXy0OBQ@mail.gmail.com>

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: <m98r99$fdn$1@ger.gmane.org>

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: <m99051$su6$1@ger.gmane.org>

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: <CAGPegVjdwd1pPU0GrBDZxx4JH2rc2Qthec-61+jtHufGXy0OBQ@mail.gmail.com>
Message-ID: <m9915v$iic$1@ger.gmane.org>

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: <m98r99$fdn$1@ger.gmane.org>
References: <1421330848.452379.214283741.1B852BBB@webmail.messagingengine.com>
 <m98r99$fdn$1@ger.gmane.org>
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: <mailman.18.1421319602.19670.tutor@python.org>
References: <mailman.18.1421319602.19670.tutor@python.org>
Message-ID: <DDADA9E6-20DC-4677-BB23-07F552B9B0A2@labergedaylight.com>

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: <DDADA9E6-20DC-4677-BB23-07F552B9B0A2@labergedaylight.com>
References: <mailman.18.1421319602.19670.tutor@python.org>
 <DDADA9E6-20DC-4677-BB23-07F552B9B0A2@labergedaylight.com>
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: <mailman.18.1421319602.19670.tutor@python.org>
 <DDADA9E6-20DC-4677-BB23-07F552B9B0A2@labergedaylight.com>
 <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 <steve at pearwood.info> 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: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>

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: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
Message-ID: <85fvbbt8f8.fsf@benfinney.id.au>

CL Talk <cltalk at gmail.com> 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?
<URL:https://en.wikipedia.org/wiki/Profiling_%28computer_programming%29>.

Python has profilers installed by default in the standard library
<URL:https://docs.python.org/3/library/profile.html>. 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: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
References: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
Message-ID: <m9ajgm$6gi$1@ger.gmane.org>

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: <m9ajgm$6gi$1@ger.gmane.org>
References: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
 <m9ajgm$6gi$1@ger.gmane.org>
Message-ID: <m9al5u$tqb$1@ger.gmane.org>

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: <m91fd0$5v2$1@ger.gmane.org>
References: <549B318A.8030909@gmail.com>
 <CAGZAPF4_w4ztbWwOXjyJ2no6CTfbK+NJw43Bwop+8S9uwSd8wQ@mail.gmail.com>
 <54A2F355.9050607@gmail.com>
 <CAGZAPF5H_bNbnP2LjVrx-pYjyNmL1RvmEYALVZxNmPDaFB6k0Q@mail.gmail.com>
 <CAOhNYvmeQSGmw39xqQRNdbW50CaHzCqN413g1N8WGwsGYBzSXw@mail.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>
 <CAGZAPF7+Szefu_C63kPocrF-v2Hq=s3ehDwgiiuVZdL=jLSeYw@mail.gmail.com>
 <54B3141E.7040500@gmail.com> <54B421FF.5050902@gmail.com>
 <m91fd0$5v2$1@ger.gmane.org>
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: <m9al5u$tqb$1@ger.gmane.org>
References: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
 <m9ajgm$6gi$1@ger.gmane.org> <m9al5u$tqb$1@ger.gmane.org>
Message-ID: <m9blj3$gcp$1@ger.gmane.org>

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: <mailman.105677.1421358634.18129.tutor@python.org>
References: <mailman.105677.1421358634.18129.tutor@python.org>
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 <emile at fenx.com>
> 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: <mailman.105677.1421358634.18129.tutor@python.org>
 <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 <emile at fenx.com>
> > 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 '<some python snippet here>'

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: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
References: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
Message-ID: <CAGZAPF6E9NXteBA0H8LfNnr17_fmP6Vwt4nGNgei6=jKkS5Evw@mail.gmail.com>

On Thu, Jan 15, 2015 at 9:02 PM, CL Talk <cltalk at gmail.com> 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: <F0E6F96E-D295-4580-ADC7-89D3AAFC8D8C@gmail.com>

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: <F0E6F96E-D295-4580-ADC7-89D3AAFC8D8C@gmail.com>
References: <F0E6F96E-D295-4580-ADC7-89D3AAFC8D8C@gmail.com>
Message-ID: <m9cfno$ae2$1@ger.gmane.org>

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: <CAGZAPF6E9NXteBA0H8LfNnr17_fmP6Vwt4nGNgei6=jKkS5Evw@mail.gmail.com>
References: <CAJ+_n+2zACczQycjYSmnZByyp5aVvZqVk=abF9mXtT29cicjLg@mail.gmail.com>
 <CAGZAPF6E9NXteBA0H8LfNnr17_fmP6Vwt4nGNgei6=jKkS5Evw@mail.gmail.com>
Message-ID: <CAJ+_n+0ygVzLZq9S3cAt+xYA83DAY9cHVSHu3ASkWDhJJB5CEg@mail.gmail.com>

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 <dyoo at hashcollision.org> wrote:
> On Thu, Jan 15, 2015 at 9:02 PM, CL Talk <cltalk at gmail.com> 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: <m9cfno$ae2$1@ger.gmane.org>
References: <F0E6F96E-D295-4580-ADC7-89D3AAFC8D8C@gmail.com>
 <m9cfno$ae2$1@ger.gmane.org>
Message-ID: <m9d8mr$rgo$1@ger.gmane.org>

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: <CAJ+_n+0ygVzLZq9S3cAt+xYA83DAY9cHVSHu3ASkWDhJJB5CEg@mail.gmail.com>
References: <CAJ+_n+0ygVzLZq9S3cAt+xYA83DAY9cHVSHu3ASkWDhJJB5CEg@mail.gmail.com>
Message-ID: <738103132.586307.1421495144812.JavaMail.yahoo@jws10751.mail.gq1.yahoo.com>





----- Original Message -----
> From: CL Talk <cltalk at gmail.com>
> To: Danny Yoo <dyoo at hashcollision.org>
> Cc: Python Tutor Mailing List <tutor at python.org>
> 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 <python snippet here>

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: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>

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: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
References: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
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: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
References: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
Message-ID: <m9f2or$vv1$1@ger.gmane.org>

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: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
Message-ID: <m9f9s4$ng$1@ger.gmane.org>

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: <m9gao8$7ct$1@ger.gmane.org>

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: <m9gao8$7ct$1@ger.gmane.org>
References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com>
 <m9gao8$7ct$1@ger.gmane.org>
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>
 <m9gao8$7ct$1@ger.gmane.org> <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>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
Message-ID: <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.com>

On Sun, Jan 18, 2015 at 6:50 PM, Sydney Shall <s.shall at virginmedia.com>
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>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
Message-ID: <m9gkmp$t8v$1@ger.gmane.org>

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>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
Message-ID: <m9gl2i$1gk$1@ger.gmane.org>

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: <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.com>
References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com>	<m9gao8$7ct$1@ger.gmane.org>	<54BBB326.5010203@virginmedia.com>
 <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.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 <s.shall at virginmedia.com
> <mailto:s.shall at virginmedia.com>> 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: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
References: <CAB80X9Ffuf0aog2T-MrD-p+TMbuVB7RTfBuy+U6whH6ivpL=Fg@mail.gmail.com>
Message-ID: <m9grai$40a$1@ger.gmane.org>

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: <m9f9s4$ng$1@ger.gmane.org>
References: <m9f9s4$ng$1@ger.gmane.org>
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>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
 <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.com>
 <54BBE2BE.3020601@virginmedia.com>
Message-ID: <CAGZAPF5bcQ3a51PD0Wzwc3BnWa60+3Kut3DaV=mo9PgcQvz8gw@mail.gmail.com>

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: <CAGZAPF5bcQ3a51PD0Wzwc3BnWa60+3Kut3DaV=mo9PgcQvz8gw@mail.gmail.com>
References: <25934296.645990.1421584163461.JavaMail.yahoo@jws10789.mail.gq1.yahoo.com>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
 <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.com>
 <54BBE2BE.3020601@virginmedia.com>
 <CAGZAPF5bcQ3a51PD0Wzwc3BnWa60+3Kut3DaV=mo9PgcQvz8gw@mail.gmail.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: <m9j6l7$c2t$1@ger.gmane.org>

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>
 <m9gao8$7ct$1@ger.gmane.org> <54BBB326.5010203@virginmedia.com>
 <CAJAvg=HMy9H7JQ=m06OXtHhYr50x1HY3cZnZbo+J9Xh=inQf2g@mail.gmail.com>
 <54BBE2BE.3020601@virginmedia.com>
 <CAGZAPF5bcQ3a51PD0Wzwc3BnWa60+3Kut3DaV=mo9PgcQvz8gw@mail.gmail.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: <m9lt4f$6b3$1@ger.gmane.org>

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: <CAGZAPF7uprQFhyZ1zq3XPeqMX7uMqcSCLdq5SnC4tEt3Lod7cw@mail.gmail.com>

On Tue, Jan 20, 2015 at 10:57 AM, Ron Brinton
<ronykpa at yahoo.com.dmarc.invalid> 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: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>

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: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
References: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
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: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
 <20150121160434.GC18556@ando.pearwood.info>
Message-ID: <CALMxxxkif_weWHjQsgRDhu2PqMaDEYAJsmD1C4DhnzDxuRXcWQ@mail.gmail.com>

On Wed, Jan 21, 2015 at 8:04 AM, Steven D'Aprano <steve at pearwood.info> 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: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
References: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
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: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
 <20150121161038.GD18556@ando.pearwood.info>
Message-ID: <CALMxxxkXAyN+7tjbFYRJZQ8bxOg-gmMxKtnfgWdYVvRjD5dmcA@mail.gmail.com>

On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano <steve at pearwood.info> 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: <CALMxxxkXAyN+7tjbFYRJZQ8bxOg-gmMxKtnfgWdYVvRjD5dmcA@mail.gmail.com>
References: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
 <20150121161038.GD18556@ando.pearwood.info>
 <CALMxxxkXAyN+7tjbFYRJZQ8bxOg-gmMxKtnfgWdYVvRjD5dmcA@mail.gmail.com>
Message-ID: <m9on8l$2uf$2@ger.gmane.org>

On 21/01/2015 16:42, Richard D. Moores wrote:
> On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano <steve at pearwood.info> 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: <CALMxxxkXAyN+7tjbFYRJZQ8bxOg-gmMxKtnfgWdYVvRjD5dmcA@mail.gmail.com>
References: <CALMxxxnBmJO1JCfj7CSqu55wAu-s7Rneu9o-VMNWmkNwezyPdw@mail.gmail.com>
 <20150121161038.GD18556@ando.pearwood.info>
 <CALMxxxkXAyN+7tjbFYRJZQ8bxOg-gmMxKtnfgWdYVvRjD5dmcA@mail.gmail.com>
Message-ID: <m9osha$r7$1@ger.gmane.org>

On 21/01/15 16:42, Richard D. Moores wrote:
> On Wed, Jan 21, 2015 at 8:10 AM, Steven D'Aprano <steve at pearwood.info> 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: <m9pdbm$tln$1@ger.gmane.org>

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: <CAGZAPF51fnRi+S16SsiRCXEzd+OqdDF5wO2EfwjnWx-GMyxGmQ@mail.gmail.com>

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: <m9q7o4$246$1@ger.gmane.org>

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: <CAGZAPF6-pT9jUuK7g7ch8J0njcfaU=4BWM5ieqJTaHZWgjtAGQ@mail.gmail.com>

On Thu, Jan 22, 2015 at 8:11 AM, jarod_v6 at libero.it <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>
 <CAGZAPF51fnRi+S16SsiRCXEzd+OqdDF5wO2EfwjnWx-GMyxGmQ@mail.gmail.com>
 <1421941762.257799.217438729.12510CA1@webmail.messagingengine.com>
Message-ID: <CAGZAPF48oSPrBuABqf5PJvRwTN65LAO80A8F=ArqsS4yv+EGhA@mail.gmail.com>

---------- Forwarded message ----------
From: dw <bw_dw at fastmail.fm>
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 <dyoo at hashcollision.org>


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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>

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 <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 <cs at zip.com.au>

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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
References: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
Message-ID: <m9ruts$8mp$1@ger.gmane.org>

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: <m9rv21$8mp$2@ger.gmane.org>

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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
Message-ID: <85iofyo0t7.fsf@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> 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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
References: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
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?

<ipython-input-83-a3c57022a089> in <module>()
----> 1 rna.show()

<ipython-input-79-b1a3b6d221ae> 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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <85iofyo0t7.fsf@benfinney.id.au>
Message-ID: <CANDiX9+cToB6Cwa+G4ScJt+-x5TWFMa+iTiUeuEc0hb3pL8UNg@mail.gmail.com>

On Thu, Jan 22, 2015 at 5:25 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
> boB Stepp <robertvstepp at gmail.com> 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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <20150122234528.GG18556@ando.pearwood.info>
Message-ID: <CANDiX9JhYGEV_HuXt4WmtF=T_jap6B4zQk=5WTq9JtzBYReh-Q@mail.gmail.com>

On Thu, Jan 22, 2015 at 5:45 PM, Steven D'Aprano <steve at pearwood.info> 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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <85iofyo0t7.fsf@benfinney.id.au>
 <CANDiX9+cToB6Cwa+G4ScJt+-x5TWFMa+iTiUeuEc0hb3pL8UNg@mail.gmail.com>
Message-ID: <85vbjym2xg.fsf@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> 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
<URL:https://docs.python.org/3/glossary.html#term-docstring>.

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 <URL:https://www.python.org/dev/peps/pep-0257/> 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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <85iofyo0t7.fsf@benfinney.id.au>
 <CANDiX9+cToB6Cwa+G4ScJt+-x5TWFMa+iTiUeuEc0hb3pL8UNg@mail.gmail.com>
 <85vbjym2xg.fsf@benfinney.id.au>
Message-ID: <85ppa6m134.fsf@benfinney.id.au>

Ben Finney <ben+python at benfinney.id.au> 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 <URL:https://www.python.org/dev/peps/pep-0257/> 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 <ben+python at benfinney.id.au>
    #
    # 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
        <URL:https://example.com/dingle/dangle/> 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: <CA+HoNsxAKhMcnH4-XUkJAtwLAy-AJ3ZQSZHN66h8yY_H4y10Vg@mail.gmail.com>

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 <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: <CAGZAPF4NbpuN7hFCnui7CNCTtt813Rwy1ZogfUjYcHQHFWb5Sw@mail.gmail.com>

>     #@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: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <85iofyo0t7.fsf@benfinney.id.au>
 <CANDiX9+cToB6Cwa+G4ScJt+-x5TWFMa+iTiUeuEc0hb3pL8UNg@mail.gmail.com>
 <85vbjym2xg.fsf@benfinney.id.au> <85ppa6m134.fsf@benfinney.id.au>
Message-ID: <m9t0sl$8bj$1@ger.gmane.org>

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 <ben+python at benfinney.id.au>
>      #
>      # 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: <CANDiX9JhYGEV_HuXt4WmtF=T_jap6B4zQk=5WTq9JtzBYReh-Q@mail.gmail.com>
References: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <20150122234528.GG18556@ando.pearwood.info>
 <CANDiX9JhYGEV_HuXt4WmtF=T_jap6B4zQk=5WTq9JtzBYReh-Q@mail.gmail.com>
Message-ID: <m9t1c9$fac$1@ger.gmane.org>

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: <CAGZAPF7onCFXzAW1rkHmKzEt3TVXaR+_NVMLDe_zEBW88YuVOA@mail.gmail.com>

On Fri, Jan 23, 2015 at 12:37 AM, jarod_v6 at libero.it <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"<jarod_v6 at libero.it>
>Cc: "Python Tutor Mailing List"<tutor at python.org>
>Ogg: Re: Re: [Tutor] Class learning
>
>On Fri, Jan 23, 2015 at 12:37 AM, jarod_v6 at libero.it <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: <m9t7li$i76$1@ger.gmane.org>

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: <m9t8aa$2li$1@ger.gmane.org>

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: <CAGZAPF6OH0CTOYNJXcGQwLOXahebfUSn0+rTuM_1iVzMAHymOA@mail.gmail.com>

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: <m9rv21$8mp$2@ger.gmane.org>
References: <54C0F37E.5070209@virginmedia.com> <m9rv21$8mp$2@ger.gmane.org>
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: <m9u40q$mhq$1@ger.gmane.org>

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?
>
> <ipython-input-83-a3c57022a089> in <module>()
> ----> 1 rna.show()
>
> <ipython-input-79-b1a3b6d221ae> 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: <m9ub6v$f0m$1@ger.gmane.org>

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: <m9ubdp$i13$1@ger.gmane.org>

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: <m9ubdp$i13$1@ger.gmane.org>
References: <m9ubdp$i13$1@ger.gmane.org>
Message-ID: <20150124003710.GA7360@cskk.homeip.net>

On 23Jan2015 20:37, Alan Gauld <alan.gauld at btinternet.com> 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 <cs at zip.com.au>

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: <m9ubdp$i13$1@ger.gmane.org>
 <20150124003710.GA7360@cskk.homeip.net>
Message-ID: <m9uq22$oq3$1@ger.gmane.org>

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: <m9uq22$oq3$1@ger.gmane.org>
References: <m9ubdp$i13$1@ger.gmane.org>
 <20150124003710.GA7360@cskk.homeip.net>
 <m9uq22$oq3$1@ger.gmane.org>
Message-ID: <CAGZAPF5Yab-a=TXD8y7STWb03B9ZOB24nkFSGvdyVEGioL5g-w@mail.gmail.com>

>
> 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: <m9uq22$oq3$1@ger.gmane.org>
References: <m9uq22$oq3$1@ger.gmane.org>
Message-ID: <20150124015040.GA69318@cskk.homeip.net>

On 24Jan2015 00:47, Alan Gauld <alan.gauld at btinternet.com> 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 <cs at zip.com.au>

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: <m9uq22$oq3$1@ger.gmane.org>
 <20150124015040.GA69318@cskk.homeip.net>
Message-ID: <m9vntr$j3f$1@ger.gmane.org>

On 24/01/15 01:50, Cameron Simpson wrote:
> On 24Jan2015 00:47, Alan Gauld <alan.gauld at btinternet.com> 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: <m9vntr$j3f$1@ger.gmane.org>
References: <m9vntr$j3f$1@ger.gmane.org>
Message-ID: <20150124113231.GA61910@cskk.homeip.net>

On 24Jan2015 09:16, Alan Gauld <alan.gauld at btinternet.com> wrote:
>On 24/01/15 01:50, Cameron Simpson wrote:
>>On 24Jan2015 00:47, Alan Gauld <alan.gauld at btinternet.com> 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 <cs at zip.com.au>

... 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: <CANDiX9JhYGEV_HuXt4WmtF=T_jap6B4zQk=5WTq9JtzBYReh-Q@mail.gmail.com>
References: <CANDiX9Jfp=UiUCY0esaXvf1of0pGfBCr7NJEWf4CeA17pZ6XVA@mail.gmail.com>
 <20150122234528.GG18556@ando.pearwood.info>
 <CANDiX9JhYGEV_HuXt4WmtF=T_jap6B4zQk=5WTq9JtzBYReh-Q@mail.gmail.com>
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 <steve at pearwood.info> 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: <m9uq22$oq3$1@ger.gmane.org>
 <20150124015040.GA69318@cskk.homeip.net>
Message-ID: <ma0c7m$bj$1@ger.gmane.org>

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: <ma0c7m$bj$1@ger.gmane.org>
References: <ma0c7m$bj$1@ger.gmane.org>
Message-ID: <20150124202018.GA50479@cskk.homeip.net>

On 24Jan2015 15:03, Mark Lawrence <breamoreboy at yahoo.co.uk> 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 <cs at zip.com.au>

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: <mailman.107897.1422130822.18129.tutor@python.org>
References: <mailman.107897.1422130822.18129.tutor@python.org>
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: <urlopen error [Errno 11004] getaddrinfo failed>

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: <ma0c7m$bj$1@ger.gmane.org>
 <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: <CAMGeA2VS24LqQnkrFxqY-EJoY6sf-EpikjsPF0ncrBq7W7qtSw@mail.gmail.com>

> Message: 1
> Date: Mon, 26 Jan 2015 11:48:52 +0100 (CET)
> From: "jarod_v6 at libero.it" <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__', <bound method Rna.__init__ of <__main__.Rna object at
0x02E39E70>>), ('align', <bound method Rna.align of <__main__.Rna
object at 0x02E39E70>>), ('trim', <bound method Rna.trim of
<__main__.Rna object at 0x02E39E70>>)]

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: <CAMGeA2UGhC88WPzt_P6ZXpi_wY3UZHJsHB1ugbo9Kq0udM_0Dw@mail.gmail.com>

2015-01-26 14:54 GMT+01:00 jarod_v6 at libero.it <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: <ma5mav$kvm$1@ger.gmane.org>

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: <CAE8mjFK60194gMNVQdChXW2Urh5BWnhUrN6SzSA4jZJCeckJCg@mail.gmail.com>

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: <CAEywD5Btime4TEo4M3gm-TiRiGdTVLaCcrJuJHK4EnAizN7wWg@mail.gmail.com>

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: <CAEywD5Btime4TEo4M3gm-TiRiGdTVLaCcrJuJHK4EnAizN7wWg@mail.gmail.com>
References: <CAEywD5Btime4TEo4M3gm-TiRiGdTVLaCcrJuJHK4EnAizN7wWg@mail.gmail.com>
Message-ID: <alpine.LSU.2.11.1501261017390.2188@znpeba>


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: <CAE8mjFK60194gMNVQdChXW2Urh5BWnhUrN6SzSA4jZJCeckJCg@mail.gmail.com>
References: <CAE8mjFK60194gMNVQdChXW2Urh5BWnhUrN6SzSA4jZJCeckJCg@mail.gmail.com>
Message-ID: <CAGZAPF6U=8NqBQzbLGM_Z4Hz-XDzbm1pq=LJYNohKDDzz7uLnw@mail.gmail.com>

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 <agarwal7781 at gmail.com> 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: <CAMGeA2UGhC88WPzt_P6ZXpi_wY3UZHJsHB1ugbo9Kq0udM_0Dw@mail.gmail.com>
References: <CAMGeA2UGhC88WPzt_P6ZXpi_wY3UZHJsHB1ugbo9Kq0udM_0Dw@mail.gmail.com>
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 <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: <CAGZAPF6WKEQcQM8_Hsd+h06CVvbsWjdYfM=G==zaOydckDHU5Q@mail.gmail.com>

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: <CALcsL=HB4H0HrX0Un4yMrYjnJ0Ho_oekd64PyyES2qEMdSVi5A@mail.gmail.com>

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: <CALcsL=HB4H0HrX0Un4yMrYjnJ0Ho_oekd64PyyES2qEMdSVi5A@mail.gmail.com>
References: <CALcsL=HB4H0HrX0Un4yMrYjnJ0Ho_oekd64PyyES2qEMdSVi5A@mail.gmail.com>
Message-ID: <ma6pm3$aln$1@ger.gmane.org>

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: <ma6pm3$aln$1@ger.gmane.org>
References: <CALcsL=HB4H0HrX0Un4yMrYjnJ0Ho_oekd64PyyES2qEMdSVi5A@mail.gmail.com>
 <ma6pm3$aln$1@ger.gmane.org>
Message-ID: <CAGZAPF51NSN2QS_foTQBQB7dyo84ttKSaHXGn7GqhTwk6L0GxA@mail.gmail.com>

>> 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 "<ipython console>", line 1, in <module>
  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 <module>
    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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>

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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
Message-ID: <85wq48loq6.fsf@benfinney.id.au>

Alex Kleider <akleider at sonic.net> 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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
References: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
Message-ID: <ma7hf5$kon$1@ger.gmane.org>

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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
References: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
 <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: <CAN89AcooChGKkN1LO5BXku4jy_LRUZ_HG-+C=iPNbLh+CVgeAw@mail.gmail.com>
References: <CAN89Acqpsx-qqUn-szsoX8sY__AUH0Q3y3e_362dzthymUUu0g@mail.gmail.com>
 <CAN89AcooChGKkN1LO5BXku4jy_LRUZ_HG-+C=iPNbLh+CVgeAw@mail.gmail.com>
Message-ID: <CAN89AcoUiu3-0YkNO9+TChwRmLNx5=wj-trXYbTKkcezdRt-XA@mail.gmail.com>

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: <CAN89AcoUiu3-0YkNO9+TChwRmLNx5=wj-trXYbTKkcezdRt-XA@mail.gmail.com>
References: <CAN89Acqpsx-qqUn-szsoX8sY__AUH0Q3y3e_362dzthymUUu0g@mail.gmail.com>
 <CAN89AcooChGKkN1LO5BXku4jy_LRUZ_HG-+C=iPNbLh+CVgeAw@mail.gmail.com>
 <CAN89AcoUiu3-0YkNO9+TChwRmLNx5=wj-trXYbTKkcezdRt-XA@mail.gmail.com>
Message-ID: <CA+HoNsyeoNGSXK_BsSmcpQVeHx4hd_QFFDS4eQ0kefoT5WQDgA@mail.gmail.com>

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 <reuben.dlink at gmail.com> 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: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>

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: <CAN89AcoUiu3-0YkNO9+TChwRmLNx5=wj-trXYbTKkcezdRt-XA@mail.gmail.com>
References: <CAN89Acqpsx-qqUn-szsoX8sY__AUH0Q3y3e_362dzthymUUu0g@mail.gmail.com>
 <CAN89AcooChGKkN1LO5BXku4jy_LRUZ_HG-+C=iPNbLh+CVgeAw@mail.gmail.com>
 <CAN89AcoUiu3-0YkNO9+TChwRmLNx5=wj-trXYbTKkcezdRt-XA@mail.gmail.com>
Message-ID: <ma8kq1$7ln$1@ger.gmane.org>

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: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
References: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
Message-ID: <ma8ksa$7ln$2@ger.gmane.org>

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: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
References: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
Message-ID: <CAGZAPF6kGEYfndU5k+Os2sKvuH2-vTKCA2-L7OMbMUFY_-ouAQ@mail.gmail.com>

On Tue, Jan 27, 2015 at 5:04 AM, Tammy Miller <tgmiller5 at hotmail.com> 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: <CAGZAPF6kGEYfndU5k+Os2sKvuH2-vTKCA2-L7OMbMUFY_-ouAQ@mail.gmail.com>
References: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
 <CAGZAPF6kGEYfndU5k+Os2sKvuH2-vTKCA2-L7OMbMUFY_-ouAQ@mail.gmail.com>
Message-ID: <CAGZAPF4fc2WFpBNf3RSGF54m2kAjD7H6CCPaFjozZyO1YG=LKA@mail.gmail.com>

>
> 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: <CAGZAPF6kGEYfndU5k+Os2sKvuH2-vTKCA2-L7OMbMUFY_-ouAQ@mail.gmail.com>
References: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
 <CAGZAPF6kGEYfndU5k+Os2sKvuH2-vTKCA2-L7OMbMUFY_-ouAQ@mail.gmail.com>
Message-ID: <ma8n71$kkj$1@ger.gmane.org>

On 27/01/2015 18:20, Danny Yoo wrote:
> On Tue, Jan 27, 2015 at 5:04 AM, Tammy Miller <tgmiller5 at hotmail.com> 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 "<stdin>", line 1, in <module>
TypeError: unorderable types: int() > str()
 >>> '10' > 10
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
 <85wq48loq6.fsf@benfinney.id.au>
Message-ID: <79f883c29c0f3ea356cc2130e6d15d46@sonic.net>

On 2015-01-26 22:30, Ben Finney wrote:
> Alex Kleider <akleider at sonic.net> 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: <ma7hf5$kon$1@ger.gmane.org>
References: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
 <ma7hf5$kon$1@ger.gmane.org>
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: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>

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: <CAJq2tVutQ=9nMQWTDcELZA5_-k2=GM9TE0Ap0oukQd=b_10-ig@mail.gmail.com>

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: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
References: <COL125-W475A99464F0DBC7C9C9E77FA320@phx.gbl>
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 "<stdin>", line 1, in <module>
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)
   .....:     
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>
?
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: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>
References: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>
Message-ID: <ma95r9$ct6$1@ger.gmane.org>

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: <CAGZAPF7uhYM48BAAjfNFfb1Q0jrBJHz9YfjQU5Xmx9w7ijGBuw@mail.gmail.com>

On Tue, Jan 27, 2015 at 2:47 PM, jarod_v6 at libero.it <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: <CAJq2tVutQ=9nMQWTDcELZA5_-k2=GM9TE0Ap0oukQd=b_10-ig@mail.gmail.com>
References: <CAJq2tVutQ=9nMQWTDcELZA5_-k2=GM9TE0Ap0oukQd=b_10-ig@mail.gmail.com>
Message-ID: <ma963c$hbc$1@ger.gmane.org>

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: <ma974c$2jn$1@ger.gmane.org>

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: <CAJq2tVutQ=9nMQWTDcELZA5_-k2=GM9TE0Ap0oukQd=b_10-ig@mail.gmail.com>
References: <CAJq2tVutQ=9nMQWTDcELZA5_-k2=GM9TE0Ap0oukQd=b_10-ig@mail.gmail.com>
Message-ID: <CAGZAPF6j719K2cczrLF-MSaEJHoWpsaTnP76=TNnPtnsfHZv2A@mail.gmail.com>

On Tue, Jan 27, 2015 at 2:07 PM, joseph dorsten <jfdorsten at gmail.com> 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: <ma95r9$ct6$1@ger.gmane.org>
References: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>
 <ma95r9$ct6$1@ger.gmane.org>
Message-ID: <ma99c3$4nd$1@ger.gmane.org>

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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
 <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: <d52ad4e78efef6bcec5bfed7e4ab778f@sonic.net>
 <20150127111835.GR20517@ando.pearwood.info>
 <6ee3221cdce0a0bd9a63bfde9582d4ba@sonic.net>
 <20150128001010.GT20517@ando.pearwood.info>
Message-ID: <fe2b3b4b21eb27c80f5a34b9ea955c14@sonic.net>

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: <ma99c3$4nd$1@ger.gmane.org>
References: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>
 <ma95r9$ct6$1@ger.gmane.org> <ma99c3$4nd$1@ger.gmane.org>
Message-ID: <ma9e0e$b0t$1@ger.gmane.org>

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: <ma9e0e$b0t$1@ger.gmane.org>
References: <C7E614BA-0A56-4007-B6AE-4349D3091E67@gmail.com>
 <ma95r9$ct6$1@ger.gmane.org> <ma99c3$4nd$1@ger.gmane.org>
 <ma9e0e$b0t$1@ger.gmane.org>
Message-ID: <ma9uli$1et$1@ger.gmane.org>

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: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>

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: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>
References: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>
Message-ID: <CAMw+j7LZmJX3e-571V9jJHK_6Sr9UdraBxjR57GzVwtqc0k3wg@mail.gmail.com>

On Wed, Jan 28, 2015 at 10:35 AM, Sunil Tech <sunil.techspk at gmail.com> 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 <https://chriswarrick.com/>
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: <maadna$k85$1@ger.gmane.org>

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: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>
References: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>
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: <maakj6$ajh$1@ger.gmane.org>

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: <CAExJxTNW+FHvG271NeWnL6Ja+Vh=Aqj0EnOOn7=q4JRO2ZN35Q@mail.gmail.com>
 <20150128112650.GV20517@ando.pearwood.info>
Message-ID: <CAExJxTMHGgGoXFPOBTHdO9vQoZEWzFeAGq2E4=4GDF0EK9tQjA@mail.gmail.com>

Thank you for all your replies??


On Wed, Jan 28, 2015 at 4:56 PM, Steven D'Aprano <steve at pearwood.info>
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: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>

 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
<?xml version="1.0" encoding="UTF-8" ?> <gettag> <response><tag> [tag''s value] </tag> </response> </gettag> 
 
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: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>
References: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>
Message-ID: <macraa$oc7$1@ger.gmane.org>

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
> <?xml version="1.0" encoding="UTF-8" ?> <gettag> <response><tag> [tag''s value] </tag> </response> </gettag>


> 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=<keyvalue>&tag=<tagname>'

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: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>
References: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>
Message-ID: <CAGZAPF51vAQ4WGDRZgFzipxwLG5O6mFrAuUS2R4Tp-7+1r2CFA@mail.gmail.com>

On Wed, Jan 28, 2015 at 9:37 PM, Phil H <philipholveck at hotmail.com> 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: <BLU406-EAS2931CBDC5021E95B3BF926CBB300@phx.gbl>
References: <BLU181-W74DFB87837206F90963409BB300@phx.gbl>
 <CAGZAPF51vAQ4WGDRZgFzipxwLG5O6mFrAuUS2R4Tp-7+1r2CFA@mail.gmail.com>
 <BLU406-EAS2931CBDC5021E95B3BF926CBB300@phx.gbl>
Message-ID: <CAGZAPF6E8sJ8OhsCauQR9tfmSFigjmU0W7gJhCMdJYdm4Quhiw@mail.gmail.com>

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 <philipholveck at hotmail.com>
Date: Thu, Jan 29, 2015 at 12:55 PM
Subject: Re: [Tutor] webservice question
To: Danny Yoo <dyoo at hashcollision.org>


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" <dyoo at hashcollision.org> wrote:
>
>> On Wed, Jan 28, 2015 at 9:37 PM, Phil H <philipholveck at hotmail.com> 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: <maec1u$qu5$1@ger.gmane.org>

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: <BBE64C80D9D2B04FADBDAA2E9FB80A0EF0FE85F4@BIAP-ERFMMBS10.ERF.thomson.com>

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: <BBE64C80D9D2B04FADBDAA2E9FB80A0EF0FE85F4@BIAP-ERFMMBS10.ERF.thomson.com>
References: <BBE64C80D9D2B04FADBDAA2E9FB80A0EF0FE85F4@BIAP-ERFMMBS10.ERF.thomson.com>
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: <BBE64C80D9D2B04FADBDAA2E9FB80A0EF0FE85F4@BIAP-ERFMMBS10.ERF.thomson.com>
References: <BBE64C80D9D2B04FADBDAA2E9FB80A0EF0FE85F4@BIAP-ERFMMBS10.ERF.thomson.com>
Message-ID: <mafujm$rhj$1@ger.gmane.org>

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: <mah88d$liv$1@ger.gmane.org>

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: <CAAotMnQ3wGWhaiij5p4Y5va2u5+2kcuo8YX+WBGguFNdYVvKSw@mail.gmail.com>

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 <undefined>"*

*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: <mah88d$liv$1@ger.gmane.org>
References: <mah88d$liv$1@ger.gmane.org>
Message-ID: <maj265$h21$1@ger.gmane.org>

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

>
> 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: <CAAotMnQ3wGWhaiij5p4Y5va2u5+2kcuo8YX+WBGguFNdYVvKSw@mail.gmail.com>
References: <CAAotMnQ3wGWhaiij5p4Y5va2u5+2kcuo8YX+WBGguFNdYVvKSw@mail.gmail.com>
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 <undefined>"*
>
> *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