Laboratoria nr 15 program nr 1

Projektowanie klas i programowanie obiektowe na przykładzie aplikacji do przetwarzanie tekstu.

Poniżej został zaprezentowany szkielet aplikacji do przetwarzania tekstu, który będzie rozbudowywany i omawiany wraz z nowymi laboratoriami. Przedstawiane zagadnienia będą obejmowały zawansowane aspekty programowania w c++. Czytelnicy nabiorą biegłości w wykorzystaniu biblioteki standardowej STL oraz Boost. Zapoznają się z szablonami oraz metodami projektowania klas. Wszytko zostanie przedstawione na podstawie projektowania i implementacji programu do przetwarzania tekstu.

Poniżej zaprezentowano interfejsy jak i ich implementacja klas które będą omawiane, refaktoryzowane i stosowane podczas omawiania ww. materiału. Podstawowy szkielet aplikacji składa się z następujących plików:

– agencyText.cpp – zawiera kod wykonawczy programu oraz testy zaprojektowanych i zaimplementowanych interfejsów,

– textAgent.h oraz textAgent.cpp – interfejs oraz jego implementacja do rejestrowania i użytkowania modułu do przetwarzania tekstu,

– textTool.h oraz textTool.cpp – interfejs oraz jego implementacja do przetwarzania strumienia tekstowego.

Kod aplikacji wykorzystujący utworzone interfejsy przedstawia listing poniżej:

agencyText.cpp 

//============================================================================
// Name        : agencyText.cpp
// Author      : Marcin Mirończuk
// Version     : 1.0
// Copyright   : GPL
// Description : The agency to text retrive
//============================================================================

/**
 * Rejestracja bibliotek
 */
#include <iostream>
#include <string>
#include <vector>
#include "textAgent.h"

/**
 * Rejestracja przestrzeni nazw
 */
using namespace std;
using namespace ta;

/**
 * Program glowny
 */
int main() {

	/**
	 * Wystartowanie kilku agentow dynamicznych oraz statycznych, nazwanych jak i nienazwanych (anonimowych)
	 */
	ta::textAgent agentStatyczny(1220, 1, "przetwarzacz tekstu 1", "Agent T1");
	ta::textAgent niezweryfikowanyAgentStatyczny;

	textAgent *agentDynamiczny = new textAgent(12330, 2, "przetwarzacz tekstu 2", "Agnet T2");
	textAgent *niezweryfikowanyAgentDynamiczny = new textAgent();

	try {

		/**
		 * Pokazanie informacji o rezydujacych agentach
		 */
		cout << "Zarejestrowany agent i jego dane:" << endl;
		agentStatyczny.showData();

		cout << endl;

		cout << "Agent oczekujacy na rejestracje:" << endl;
		niezweryfikowanyAgentStatyczny.showData();

		cout << endl;

		cout << "Agent dynamiczny zarejstrowany:" << endl;
		agentDynamiczny->showData();

		cout << endl;

		cout << "Agent dynamiczny niezweryfikowany:" << endl;
		niezweryfikowanyAgentDynamiczny->showData();

		cout << endl;

		/**
		 * Rejestracja modulu (przybornika) do przetwarzania tekstow
		 */
		tt::textTool tt;

		/**
		 * Rejestracja przybornika dla agenta dynamicznego
		 */
		agentDynamiczny->rejestrTextTool(tt);
		agentDynamiczny->rejestrTextTool().extractSegments("Ala ma kota.");

		cout << "Ilosc zliczonych segmentow: " <<  agentDynamiczny->rejestrTextTool().getCountSegments() << endl;
		cout << "Pokaz jakie segmenty zliczyles: " << endl;
		agentDynamiczny->rejestrTextTool().showSegments();

		cout << endl;

		/**
		 * Rejestracja przybornika dla agenta statycznego
		 */
		agentStatyczny.rejestrTextTool(tt);
		agentStatyczny.rejestrTextTool().extractSegments("A ja mam kota. I wiecej tekstu.");

		cout << "Ilosc zliczonych segmentow: " << agentStatyczny.rejestrTextTool().getCountSegments() << endl;
		cout << "Pokaz jakie segmenty zliczyles: " << endl;
		agentStatyczny.rejestrTextTool().showSegments();

		cout << endl;

		cout << "Testowanie usowania spacji:" << endl;

		std::string testString1 = " kota ";
		cout << "- Tekst przed filtracja: " << testString1 << endl;
		cout << "- Filtracja: " << "Tekst odfiltrowany: " << agentStatyczny.rejestrTextTool().stripWhiteSpace(testString1) << endl;
		cout << "- Filtracja: " << "Tekst pierwotny " << testString1 << endl;

		std::string *pTestString1 = &testString1;
		cout << "- Tekst przed filtracja wskaznik / zmienna: " << *pTestString1 << " / " << testString1 << endl;
		agentStatyczny.rejestrTextTool().stripWhiteSpace(pTestString1);
		cout << "- Filtracja: " << "Tekst odfiltrowany " << *pTestString1 << endl;
		cout << "- Filtracja: " << "Tekst pierwotny " << testString1 << endl;

		cout << endl;

		cout << "Testowanie tokenizacji:" << endl;
		std::string testString2 = "Ala ma kota. A kot ma na imie Ala.";
		cout << "- Tekst podlegajacy tokenizacji: " << testString2 << endl;
		agentStatyczny.rejestrTextTool().tokenize(testString2);
		cout << "- Ilosc tokenow: " <<  agentStatyczny.rejestrTextTool().getCountTokens() << endl;
		cout << "- Ilosc unikatowych tokenow: " <<  agentStatyczny.rejestrTextTool().getCountUniqueTokens();

		delete niezweryfikowanyAgentDynamiczny;
		delete agentDynamiczny;

	} catch (std::string exception) {
		cout<<"Wyjatek: "<< exception;

		delete niezweryfikowanyAgentDynamiczny;
		delete agentDynamiczny;
	}

	return 0;
}

Interfejs agenta który rejestruje moduł do przetwarzania tekstu i za pośrednictwem którego odbywają się wszelkie modyfikacja przedstawia listing poniżej:

/*
 * textAgent.h
 *
 *  Created on: 21-12-2011
 *  Author: Marcin Mirończuk
 *  Licenc: GPL
 *
 *  Klas modelujaca podstawowe elementy agenta do przetwarzania tekstu.
 *  Agent ma mozliwosc rejestrowania u siebie modulu do przetwarzania tekstu za omoca ktorego przetwarza tekst.
 *
 */

#include <string>
#include "textTool.h"

#ifndef TA_H_
#define TA_H_

/**
 * Definicja przestrzeni nazw
 */
namespace ta {

	/**
	 *  Definicja klasy
	 */
	class textAgent {

		/**
		 * Skladowe i metody prywatne klasy
		 */
		private:

			/**
			 * @type int timeCreate Czas w sekundach  Unix timestamp
			 */
			int timeCreate;

			/**
			 * @type float priority Priorytet agebta
			 */
			int priority;

			/**
			 * @type string task Zadanie/praca do wykonania przez agebta
			 */
			std::string task;

			/**
			 * @type string name Nazwa agenta
			 */
			std::string name;

			/**
			 * @type bool isTextTool Flaga rejestracji modulu tekstu
			 */
			bool isTextTool;

			/**
			 * @type textTool textTool Uchwyt do modulu przetwarzajacego tekst
			 */
			tt::textTool textTool;

		/**
		 * Skladowe i metody publiczne klasy
		 */
		public:

			/**
			 * Konstruktor podstawowy domyslny
			 */
			textAgent();

			/**
			 * Konstruktor rozszerzony
			 */
			textAgent(float ptimeCreate, float ppriority, std::string ptask, std::string pname);

			/**
			 * Pobranie wieku agenta
			 *
			 * @return float
			 */
			int getTimeCreate();

			/**
			 * Pobranie wagi agenta
			 *
			 * @return float
			 */
			int getPriority();

			/**
			 * Pobranie zadania agenta
			 *
			 * @return string
			 */
			std::string getTask();

			/*
			 * Pobranie nazwy agenta
			 *
			 * @return string
			 */
			std::string getName();

			/**
			 * Pokazanie danych o agencie
			 *
			 * @return void
			 */
			void showData();

			/**
			 * Rejestracja modulu do przetwarzania tekstu
			 *
			 * @return tt::textTool
			 */
			const tt::textTool & rejestrTextTool(tt::textTool tt);

			/**
			 * Rejestracja, pobranie modulu do przetwarzania tekstu
			 *
			 * @return tt::textTool
			 * @thorw exception
			 */
			tt::textTool & rejestrTextTool();

			/**
			 * Destruktor
			 */
			virtual ~textAgent();
	};

} /* namespace textagent */
#endif /* TA_H_ */

Interfejs programu (modułu) do przetwarzania strumienia danych tekstowych przedstawia listing poniżej:

/*
 * textAgent.cpp
 *
 *  Created on: 21-12-2011
 *  Author: Marcin Mirończuk
 *  Licenc: GPL
 *
 *  Implementacja interfejsu agenta do przetwarzania tekstu @see textAgent.h
 *
 */

#include <iostream>
#include "textAgent.h"
#include "textTool.h"

namespace ta {

	textAgent::textAgent() {
		this->timeCreate = 0;
		this->priority = 0;
		this->task = "unknown";
		this->name = "inkognito";

		this->isTextTool = false;
	}

	textAgent::textAgent(float ptimeCreate, float ppriority, std::string ptask, std::string pname) {
		this->timeCreate = ptimeCreate;
		this->priority = ppriority;
		this->task = ptask;
		this->name = pname;

		this->isTextTool = false;
	}

	int textAgent::getTimeCreate() {
		return this->timeCreate;
	}

	int textAgent::getPriority() {
		return this->priority;
	}

	std::string textAgent::getTask() {
		return this->task;
	}

	std::string textAgent::getName() {
		return this->name;
	}

	void textAgent::showData() {
		std::cout << "Time create: " << this->timeCreate << std::endl;
		std::cout << "Priority: " << this->priority << std::endl;
		std::cout << "Name: " << this->name << std::endl;
		std::cout << "Task: " << this->task << std::endl;
	}

	const tt::textTool & textAgent::rejestrTextTool(tt::textTool tt) {
		if(this->isTextTool == false) {
			this->textTool = tt;

			this->isTextTool = true;

			return this->textTool;
		} else {
			return this->textTool;
		}
	}

	tt::textTool & textAgent::rejestrTextTool() {
		if(this->isTextTool == false) {
			std::string exception = "Unregister text tool!";

			throw exception;
		} else {
			return this->textTool;
		}
	}

	textAgent::~textAgent() {

	}

} /* namespace ta */

Implementację interfejsu programu do przetwarzania tekstu zawiera listing poniżej:

/*
 * textTool.h
 *
 *  Created on: 21-12-2011
 *  Author: Marcin Mirończuk
 *  Licenc: GPL
 *
 *  Klas modelujaca modul (przybornik) do przetwarzania tekstu.
 *
 */

#include <map>
#include <vector>
#include <string>

#ifndef TT_H_
#define TT_H_

/**
 * Definicja przestrzeni nazw
 */
namespace tt {

	/**
	 *  Definicja klasy
	 */
	class textTool {

		/**
		 * Skladowe i metody prywatne klasy
		 */
		private:

			/**
			 * @type vector<string> segment Wektor segmentow
			 */
			std::vector<std::string> segments;

			/**
			 * @type vector<string> tokens Wektor tokenow (wyrazen)
			 */
			std::vector<std::string> tokens;

			/**
			 * @type vector<string> uniqueTokens Wektor unikalnych tokenow (wyrazen)
			 */
			std::vector<std::string> uniqueTokens;

			/**
			 * @type vector<string, int> tokensFrequ Tablica klucz=wartosc czestotliwosci wyrazen
			 */
			std::map<std::string, int> tokensFrequ;

			/**
			 * Usowanie duplikatow wyrazen z wektora wyrazen
			 *
			 * @see http://learningcppisfun.blogspot.com/2008/04/remove-duplicates-from-vector.html
			 * @see http://stackoverflow.com/questions/1041620/most-efficient-way-to-erase-duplicates-and-sort-a-c-vector
			 *
			 * @param vector<string> vec
			 *
			 * @return vector<string>
			 */
			std::vector<std::string> removeDuplicates(std::vector<std::string> vec);

		public:

			/**
			 * Domyslny konstruktor
			 */
			textTool();

			/**
			 * Wydobywanie segmentow z tekstu.
			 *
			 * @param string &text
			 *
			 * @return vector<string>
			 */
			std::vector<std::string> extractSegments(const std::string &text);

			/**
			 * Pobranie ilosci wydobytych segmentow z tekstu.
			 *
			 * @return int
			 */
			int getCountSegments();

			/**
			 * Pokazanie wydobytych segmentow z tekstu.
			 *
			 * @return void
			 */
			void showSegments();

			/**
			 * Usuniecie spacji z poczatku jak i z konca lancucha znakow.
			 *
			 * @param string text
			 *
			 * @return string
			 */
			std::string stripWhiteSpace(std::string text);

			/**
			 * Przeciazona wersja usuniecia spacji z poczatku jak i z konca lancucha znakow.
			 *
			 * @param string *text
			 *
			 * @return void
			 */
			void stripWhiteSpace(std::string *text);

			/**
			 * Kalkulacja, wyznaczanie macierzy czetotliwosci wystepowania wyrazen w pojedynczym dokumencie tekstowym.
			 *
			 * @param string &text
			 *
			 * @return map<string, int>
			 */
			std::map<std::string, int> computeTokensFrequ(const std::string &text);

			/**
			 * Tokenizacja tekstu tj. rozbicie tekstu na wektor wyrazen.
			 * @see http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
			 *
			 * @param string &text
			 *
			 * @return vector<string>
			 */
			std::vector<std::string> tokenize(const std::string &text);

			/**
			 * Pobranie ilosci wyrazen.
			 *
			 * @return int
			 */
			int textTool::getCountTokens();

			/**
			 * Pobranie ilosci unikalnych wyrazen.
			 *
			 * @return int
			 */
			int textTool::getCountUniqueTokens();

			/**
			 * Domyslny destruktor
			 */
			virtual ~textTool();
		};

	} /* namespace tt */
#endif /* TT_H_ */

Implementację powyżej zaprezentowanego interfejsu programu do przetwarzania tekstu zawiera listing poniżej:

/*
 * textTool.cpp
 *
 *  Created on: 21-12-2011
 *  Author: Marcin Mirończuk
 *  Licenc: GPL
 *
 *  Implementacja interfejsu modulu do przetwarzania tekstu @see textTool.h
 *
 */

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include "textTool.h"

namespace tt {

	textTool::textTool() {
	}

	/**
	 * Bardzo naiwna, prezentacyja wersji algorytmu do rozbijania tekstu na segmenty (zdania)
	 */
	std::vector<std::string> textTool::extractSegments(const std::string &text) {

		std::string tempSegment;

		for(int i = 0; i < text.length(); i++) {
			if(text[i] == '.' || text[i] == '?' || text[i] == '!') {
				tempSegment = (std::string) tempSegment;
				this->segments.push_back(this->stripWhiteSpace(tempSegment));
				tempSegment.clear();
			} else {
				tempSegment += text[i];
			}
		}

		return this->segments;
	}

	int textTool::getCountSegments() {
		return this->segments.size();
	}

	std::string textTool::stripWhiteSpace(std::string text) {

		if(text[0] == ' ') {
			text.replace(0, 1, "");
		}

		if(text[text.length()-1] == ' ') {
			text.replace(text.length()-1, 1, "");
		}

		return text;
	}

	void textTool::stripWhiteSpace(std::string *text) {
		std::string::iterator it;

		it = text->begin();

		if(*it == ' ') {
			text->replace(0, 1, "");
		}

		it = text->end();

		if(*(it-1) == ' ') {
			text->replace(text->length()-1, 1, "");
		}
	}

	void textTool::showSegments() {
		for(int i = 0; i < this->segments.size(); i++) {
			std::cout << this->segments[i] << std::endl;
		}
	}

	std::map<std::string, int> textTool::computeTokensFrequ(const std::string &text) {
		this->tokenize(text);
		this->removeDuplicates(this->tokens);

		std::vector<std::string>::iterator it;

		for (it = this->uniqueTokens.begin(); it < this->uniqueTokens.end(); it++) {
		    std::cout << " " << *it;
		}

		return this->tokensFrequ;
	}

	std::vector<std::string> textTool::tokenize(const std::string &text) {

		// Buforowany string
	    std::string buf;

	    // Wstawienie stringu z potoku
	    std::stringstream ss(text);

	    while (ss >> buf) {
	    	this->tokens.push_back(buf);
		}

		return this->tokens;
	}

	int textTool::getCountTokens() {
		return this->tokens.size();
	}

	int textTool::getCountUniqueTokens() {
		if(this->tokens.size() != 0 && this->uniqueTokens.size() == 0) {
			this->removeDuplicates(this->tokens);

			return this->uniqueTokens.size();
		} else {
			return this->uniqueTokens.size();
		}
	}

	std::vector<std::string> textTool::removeDuplicates(std::vector<std::string> vec) {
		 std::sort(vec.begin(), vec.end());
	     vec.erase(std::unique(vec.begin(), vec.end()), vec.end());

	     this->uniqueTokens = vec;

	     return this->uniqueTokens;
	 }

	textTool::~textTool() {

	}

} /* namespace tt */

Skomentuj ten wpis