Click here to Skip to main content
15,895,011 members
Articles / Desktop Programming / MFC

Name genderization

Rate me:
Please Sign up or sign in to vote.
4.80/5 (6 votes)
22 Apr 2002CPOL3 min read 111.9K   2.4K   19  
Extrapolate the gender of a person based on their first name
// CFPSGenderize
// Author:	Matt Gullett
//			gullettm@yahoo.com
// Copyright (c) 2000
//
// This is a back-end utility class implementing support for name
// genderization services.  It is an extremely simple class with
// a map of names and genders.
//
// This class is highly dependent on the list of names/genders 
// available.
//
// You may freely use this source code in personal, freeware, shareware
// or commercial applications provided that 1) my name is recognized in the
// code and if this code represents a substantial portion of the application
// that my name be included in the credits for the application (about box, etc)
//
// Use this code at your own risk.  This code is provided AS-IS.  No warranty
// is granted as to the correctness, usefulness or value of this code.
//
// *******************************************************************
// TECHNICAL NOTES:
//
// See .cpp file for tech notes
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Genderizer.h"
#include "FPSGenderizer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFPSGenderizer::CFPSGenderizer()
{
	// set the default table name
	memset(m_szTableName, 0, MAX_PATH);
	SetTableName(FPSGENDER_DEFAULT_TABLENAME);

	// lets initialize our hash table to a size of 8001
	// this should give us optimum performance
	m_mapNames.InitHashTable(FPSGENDER_DEFAULT_HASHTABLESIZE);
}

CFPSGenderizer::~CFPSGenderizer()
{
	// cleanup (not really necessary, just habit)
	m_mapNames.RemoveAll();
}

// Load the name/gender data from a database table.
// The table should have at least 2 columns both of a string
// data type.  The names of these columns should be 'NM' and 'GNDR'
// the Table name can be overiiden
BOOL CFPSGenderizer::Load(_ConnectionPtr &pConnection)
{
	BOOL bReturn = TRUE;
	VARIANT varRecords;
	_bstr_t bstrSQL = "SELECT NM, GNDR FROM ";
	bstrSQL += m_szTableName;
	bstrSQL += " ORDER BY NM";

	::VariantInit(&varRecords);

	try
	{
		_RecordsetPtr pRecordset = pConnection->Execute(bstrSQL, &varRecords, 0);

		while (!pRecordset->A_EOF)
		{
			VARIANT varNameIndex;
			VARIANT varGenderIndex;

			::VariantInit(&varNameIndex);
			::VariantInit(&varGenderIndex);

			varNameIndex.vt = VT_I4;
			varGenderIndex.vt = VT_I4;
			varNameIndex.lVal = 0;
			varGenderIndex.lVal = 1;

			_variant_t varName = pRecordset->GetFields()->GetItem(varNameIndex)->Value;
			_variant_t varGender = pRecordset->GetFields()->GetItem(varGenderIndex)->Value;

			if (varName.vt == VT_BSTR && varGender.vt == VT_BSTR)
			{
				CString strName = varName.bstrVal;
				CString strGender = varGender.bstrVal;

				AddName(strName, strGender);
			}

			pRecordset->MoveNext();
		}

		pRecordset->Close();
	}
	catch(...)
	{
		ASSERT(FALSE);
		bReturn = FALSE;
		throw;
	}

	return bReturn;
}

// Load the list from a file (MFC Archive file)
BOOL CFPSGenderizer::Load(LPCTSTR lpszFileName)
{
	ASSERT(lpszFileName && AfxIsValidString(lpszFileName));

	BOOL bReturn = FALSE;
	CFile fp;

	if (lpszFileName && AfxIsValidString(lpszFileName))
	{
		try
		{
			if (fp.Open(lpszFileName, CFile::modeRead | CFile::shareDenyWrite))
			{
				CArchive ar(&fp, CArchive::load);

				bReturn = Load(ar);

				ar.Close();
				fp.Close();
			}
		}
		catch(...)
		{
			ASSERT(FALSE);
			bReturn = FALSE;
			throw;
		}
	}

	return bReturn;
}

// load data from an MFC CArchive stream
BOOL CFPSGenderizer::Load(CArchive &ar)
{
	BOOL bReturn = FALSE;

	if (ar.IsLoading())
	{
		long lCount = 0;

		ar >> lCount;

		for (int iX = 0; iX < lCount; iX++)
		{
			CString strName;
			CString strGender;

			ar >> strName;
			ar >> strGender;

			AddName(strName, strGender);
		}

		bReturn = TRUE;
	}

	return bReturn;
}

// overide the default table name
BOOL CFPSGenderizer::SetTableName(LPCTSTR lpszName)
{
	ASSERT(lpszName && AfxIsValidString(lpszName));

	BOOL bReturn = TRUE;

	if (lpszName && AfxIsValidString(lpszName) && lstrlen(lpszName) < MAX_PATH)
	{
		strcpy(m_szTableName, lpszName);
	}
	else
	{
		ASSERT(FALSE);
		bReturn = FALSE;
	}

	return bReturn;
}

// add a name to our gender list (typically a map of 
// string-to-strings)
void CFPSGenderizer::AddName(LPCTSTR lpszName, LPCTSTR lpszGender)
{
	ASSERT(lpszName && AfxIsValidString(lpszName));
	ASSERT(lpszGender && AfxIsValidString(lpszGender));

	if (lpszName && AfxIsValidString(lpszName) &&
		lpszGender && AfxIsValidString(lpszGender))
	{
		CString strName = lpszName;
		strName.TrimLeft();
		strName.TrimRight();
		strName.MakeUpper();

		CString strGender = lpszGender;
		strGender.TrimLeft();
		strGender.TrimRight();
		strGender.MakeUpper();

		if (strName.GetLength() > 0 && strGender.GetLength() == 1 && (strGender == "M" || strGender == "F" || strGender == "U"))
			m_mapNames.SetAt(strName, strGender);
	}
}

// see if we have a gender record for the specified name
char CFPSGenderizer::Genderize(LPCTSTR lpszName)
{
	ASSERT(lpszName && AfxIsValidString(lpszName));

	char cReturn = 'U';

	if (lpszName && AfxIsValidString(lpszName))
	{
		CString strName = lpszName;
		CString strGender;

		strName.TrimLeft();
		strName.TrimRight();
		strName.MakeUpper();

		if (m_mapNames.Lookup(strName, strGender))
		{
			ASSERT(strGender.GetLength() == 1);
			cReturn = strGender[0];
		}
	}

	return cReturn;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions