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.