Ok I will post all of the code at the bottom, first thing however is the loop below starts at 0, then increments to 1, but never increments any further.

for counter1 in range(fieldlength):
          if self.__fields[counter1] == field:
            for counter2 in range(rowlength):
              #print self.__rows[counter2][counter1]
              if self.__rows[counter2][counter1] == value:
                return1 = counter2
                matchcount = matchcount + 1
                print "The Match count is INSIDE THE LOOP: " + str(matchcount)
              counter2 = counter2 + 1
          counter1 = counter1 + 1

This is the test code that should cause the loop to go above 1:

T = SDBTable('id=ui', 'last', 'first', 'age=i', 'married=b', 'salary=f')
print T

print '# insert 6 rows'
T.insert(1, 'Jones', 'Bobby', 55, True, 98765.43)
T.insert(2, 'Jones', 'Jack', 15, False, 0.0)
T.insert(3, 'Smith', 'Jack', 66, True, 88.88)
T.insert(4, 'Jones', 'Mark', 50, True, 100.0)
T.insert(5, 'Smith', 'Mark', 5, False, 10000.00)
T.insert(6, 'Jones', 'Dave', 9, False, 123.45)

print '# get works:'
print T.get('first', 'Bobby')

print '# get fails'
try:
    T.get('last', 'Jones')
except SDBError, e:
    print e

Any ideas on how to solve matchcounters fear of numbers larger than 1?

Shell output:

$ python test.py 
# create table
TABLE<id,last,first,age,married,salary>
# insert 6 rows
# get works:
The Match count is INSIDE THE LOOP: 1
The Match count is : 1
ROW<1,Jones,Bobby,55,True,98765.43>
# get fails
The Match count is INSIDE THE LOOP: 1
The Match count is : 1

sdb.py:

#!/usr/bin/env python
# encoding: utf-8
"""
sdb.py
Simple DB

Created by Christopher King on 2008-10-29.
Copyright (c) 2008 NCSU. All rights reserved.
"""

# Error classes.  One base class and 4 derived classes.
# NOTE: there is no need to modify any of the error classes
#

import sys, string, operator, types
class SDBError(Exception):
    """Base class for SDB.
    """
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class SDBInsertError(SDBError):
    """Insertion error class.
    Attribute: msg.
    """
    pass

class SDBUpdateError(SDBError):
    """Update error class.
    Attributes: field, msg.
    """
    def __init__(self, field, msg):
        self.field, self.msg = field, msg
    def __str__(self):
        return self.field + ": " + self.msg

class SDBFetchError(SDBError):
    """Fetch error class.
    Attribute: msg.
    """
    pass

class SDBUsageError(SDBError):
    """Usage error class.
    Attribute: msg.
    """
    pass

# the primary db class
#
class SDBTable:
    """Class for SDB table.
    """

    # suggested private variables
    __rows = []                 # stores SDBRows
    __fields = []               # stores field names
    __specs = []                # stores specification of each field
                                #   which is a tuple(bool, type)
                                #   tuple[0] answers is unique?
                                #   tuple[1] answers what type?
    # NOTE: len(__fields) == len(__specs)

    def __init__(self, *fields):
        """
        Create a table.  The parameters define valid fields/columns in
        the table.  There is at least one parameter.

        Field specifiers have a name and an option attribute.  

        Name is a valid Python string.

        Attribute list begins with a '=' has one or two attribute values.

        Attributes:
        s,i,f,b = type: str, int, float, bool [default: str]
        u = unique (ie, a key field) [default: false]
        
        Example: field specifier:
        
        first_name	# string field
        id=iu		# unique integer field
        age=i		# integer field
        program=u	# unique string
        salary=uf	# unique float
        """
        counter = 0
        for f in fields:
            # test the format and determine name, unique, and type
            # ...
            #print fields[counter].count("=")
            splitfield = fields[counter].split('=')
            if fields[counter].count("=") == 0:
              self.__fields.append(str(splitfield[0]))
              self.__specs.append((False, str))
            else:
              self.__fields.append(str(splitfield[0]))
              if str(splitfield[1]).count("s") == 1:
                if str(splitfield[1]).count("u") == 1:
                  self.__specs.append((True, str))
                else:
                  self.__specs.append((False, str))
              elif str(splitfield[1]).count("i"):
                if str(splitfield[1]).count("u") == 1:
                  self.__specs.append((True, int))
                else:
                  self.__specs.append((False, int))
              elif str(splitfield[1]).count("f"):
                if str(splitfield[1]).count("u") == 1:
                  self.__specs.append((True, float))
                else:
                  self.__specs.append((False, float))
              elif str(splitfield[1]).count("b"):
                if str(splitfield[1]).count("u") == 1:
                  self.__specs.append((True, bool))
                else:
                  self.__specs.append((False, bool))
            counter = counter + 1

    def get(self, field, value):
        #del self.__rows[self.__rows.index(row)]
        """
        Returns the row in which field=value.
        Returns None if no match.
        Raises SDBFetchError if more than 1 row matches.
        """
        
        rowlength = (self.size())
        rowlength = rowlength / len(self.__fields)
        fieldlength = len(self.__fields)
        counter1 = 0
        counter2 = 0
        return1 = 0
        matchcount = 0
        for counter1 in range(fieldlength):
          if self.__fields[counter1] == field:
            for counter2 in range(rowlength):
              #print self.__rows[counter2][counter1]
              if self.__rows[counter2][counter1] == value:
                return1 = counter2
                matchcount = matchcount + 1
                print "The Match count is INSIDE THE LOOP: " + str(matchcount)
              counter2 = counter2 + 1
          counter1 = counter1 + 1
        print "The Match count is : " + str(matchcount)
        if (matchcount > 1):
          raise SDBFetchError(matchcount)
        else:
          return self.__rows[return1]
        pass

    def filter(self, compare):
        """
        Returns list of all rows that match compare.
        Two kinds of comparisons.

        Simple is equality on one field.  Value is of parameter must be
        a string that is field=value (no spaces).

        The parameter for complex compare is a function that accepts
        a tuple as its only parameter and returns a boolean whether the 
        row matches.
        
        Raises SDBUsageError if there is any problem with the parameters.
        """

        if compare.__class__ == str:
            # do a simple filter
            pass
        else:
            # do a complex filter
            pass

    def insert(self, *values):
        """
        Inserts a row into the table.  The number of parameters must
        match the number the defined for the table.

        This method checks that the values are the proper type and,
        if necessary, whether it is unique.

        Raises SDBInsertError if the is a problem.

        On success, returns the newly created SDBRow
        """
        
        # check all the values
        counter = 0
        arglength = len(values)
        tablelength = len(self.__fields)
        #existingtype = type(self.__specs[3][1])
        #existingtype = existingtype.__name__
        existingtype = self.__specs[1][1].__name__
        #print existingtype
        counter = 0
        if (arglength == tablelength):
          
          for f in values:
            #print f
            existingtype = self.__specs[counter][1].__name__
            valuetype = type(values[counter])
            valuetype = valuetype.__name__
            if valuetype == existingtype:
              
              #print "Input value Type: " + valuetype
              #print "Existing value Type: " + existingtype
              #print "Counter is presently: " + str(counter)
              counter = counter + 1
              row = SDBRow(self, values)
              self.__rows.append(row)
              return row
            else:
              SDBInsertError()
          
        else:
          raise SDBInsertError()
        

    def remove(self, row):
        """
        Removes row from table.

        Raise exception if row is not in table.
        """
        errorcount = 0
        rowlength = (self.size())
        rowlength = rowlength / len(self.__fields)
        while counter < rowlength:
          if self.__rows[counter] == row:
            errorcount = 20
            del self.__rows[self.__rows.index(row)]
        if (errorcount != 20):
          raise SDBUsageError()

    def field_index(self, field):
        """
        returns the index and the specifier for field.
        """
        return self.__fields.index(field)

    def field_specs(self, idx):
        """
        returns the index and the specifier for field.
        """
        return self.__specs[idx]

    def size(self):
        return len(self.__rows)

    def __str__(self):
        return "TABLE<" + ','.join(self.__fields) + ">" 

# the row class
# NOTE: there is no need to change this
#
class SDBRow:
    """Class for SDB row.
    """

    __table = None
    __values = None

    def __init__(self, table, values):
        """Initialize a row.  Save a reference to the table it belongs to.
        Store values as a list
        """
        self.__table = table
        self.__values = list(values)

    def set(self, field, value):
        """Set a field in an existing row.
        Must look up the field name and specification in self.__table.
        """
        idx = self.__table.field_index(field)
        specs = self.__table.field_specs(idx)
        if specs[1] != value.__class__:
            raise SDBException, "wrong type for %s" % field
        if specs[0]:        
            # must be unique, use table's get method
            try: 
                if self.__table.get(field, value):
                    raise SDBUpdateError(field, "value is not unique")
            except SDBFetchError:
                # multiple entries
                raise SDBUpdateError(field, "value is not unique")
        self.__values[idx] = value

    def __getitem__(self, idx):
        if type(idx) == int:
            return self.__values[idx]
        else:
            return self.__values[self.__table.field_index(idx)]

    def __str__(self):
        return "ROW<" + ','.join([str(v) for v in self.__values]) + ">"

test.py:

#!/usr/bin/python

from sdb import SDBTable, SDBError

# create a table and insert
print '# create table'
T = SDBTable('id=ui', 'last', 'first', 'age=i', 'married=b', 'salary=f')
print T

print '# insert 6 rows'
T.insert(1, 'Jones', 'Bobby', 55, True, 98765.43)
T.insert(2, 'Jones', 'Jack', 15, False, 0.0)
T.insert(3, 'Smith', 'Jack', 66, True, 88.88)
T.insert(4, 'Jones', 'Mark', 50, True, 100.0)
T.insert(5, 'Smith', 'Mark', 5, False, 10000.00)
T.insert(6, 'Jones', 'Dave', 9, False, 123.45)

print '# get works:'
print T.get('first', 'Bobby')

print '# get fails'
try:
    T.get('last', 'Jones')
except SDBError, e:
    print e

print '# filter finds 4'
for r in T.filter('last=Jones'):
    print r
print '# filter finds 2'
for r in T.filter('first=Mark'):
    print r
print '# filter finds 0'
for r in T.filter('last=jones'):
    print r

print '# lambda filter finds 2'
for r in T.filter(lambda row: row[5] > 80.0 and row[5] < 101):
    print r['last'], r['first']

print '# row operations'
r = T.get('id', 1)
print 'last:',  r[1], r['last']
print 'test set'
print r
r.set('last', 'Merkel')
print r
print '# test set unique'
try:
    r.set('id', 2)
except SDBError, e:
    print e

print '# test remove, size'
print 'size', T.size()
T.remove(r)
print 'row?', T.get('id', 1)
print 'size', T.size()

Thanks in advance.

Recommended Answers

All 2 Replies

I would suggest the following print statements to clarify things.

print "length of self.__fields =", fieldlength
for counter1 in range(fieldlength):
          if self.__fields[counter1] == field:
            print "counter1 == field"
            for counter2 in range(rowlength):
              #print self.__rows[counter2][counter1]
              if self.__rows[counter2][counter1] == value:
                return1 = counter2
                matchcount = matchcount + 1
                print "The Match count is INSIDE THE LOOP: " + str(matchcount)
##              counter2 = counter2 + 1         Has no effect
          else:
             print "counter1 & field NOT equal"
##          counter1 = counter1 + 1   ## this statement does nothing

Note that the last statement is commented because it has no effect. Run the following code to see for yourself. This is because the statement "for ctr in range(0, 10)" generates a list [0, 1, 2...9] and iterates over this list so you increment the current value when incrementing the counter but don't change the list so there is no effect on the for() loop.

for ctr in range(0, 10):
   print "loop's counter =", ctr
   ctr += 5
   print "     ", ctr, "= incremented but doesn't have any effect"

Thanks for that. I was able to resolve the issue. I will be posting the solution to this problem a bit later(deadline is pressing at the moment)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.