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

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

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.