<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hdelossantos.com&#187; Blog</title>
	<atom:link href="http://www.hdelossantos.com/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hdelossantos.com</link>
	<description>Tales of the Wisconsin Experience</description>
	<lastBuildDate>Sat, 21 Jan 2012 19:54:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Creating a Register File using Behavioral Verilog</title>
		<link>http://www.hdelossantos.com/2010/10/18/creating-a-register-file-using-behavioral-verilog/</link>
		<comments>http://www.hdelossantos.com/2010/10/18/creating-a-register-file-using-behavioral-verilog/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 17:58:56 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Sample Work]]></category>
		<category><![CDATA[behavioral verilog]]></category>
		<category><![CDATA[hardware description language]]></category>
		<category><![CDATA[hdl]]></category>
		<category><![CDATA[register]]></category>
		<category><![CDATA[register file]]></category>
		<category><![CDATA[Verilog]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=701</guid>
		<description><![CDATA[Behavioral Verilog is the most abstract style of Verilog code. The code looks very similar to C, but one has to remember that in hardware operations occur in parallel, and everything is running at once. This sample register file will be a 16 entries by 8-bits per entry. It will have 2 synchronous write ports, [...]]]></description>
			<content:encoded><![CDATA[<p>Behavioral Verilog is the most abstract style of Verilog code. The code looks very similar to C, but one has to remember that in hardware operations occur in parallel, and everything is running at once. </p>
<p>This sample register file will be a 16 entries by 8-bits per entry. It will have 2 synchronous write ports, and an asynchronous read port as well as an active low asynchronous reset.<br />
<span id="more-701"></span><br />
We begin with our module header, parameters, and i/o declarations.</p>
<pre class="brush: verilog; title: ; notranslate">
module register_file(data_out, clk, wr_en_1, wr_en_2, rst, data_in_1, data_in_2,	wr_addr_1, wr_addr_2, rd_addr);

	parameter ENTRIES = 16;
	parameter REG_OFFSET = 8;
	integer i;

	input clk, wr_en_1, wr_en_2, rst;
	input [7:0] data_in_1, data_in_2;
	input [2:0] wr_addr_1, wr_addr_2;
	input [3:0] rd_addr;
	output reg [7:0] data_out;

	reg [7:0] registers [ENTRIES - 1:0];
</pre>
<p>By using parameters we can easily create register files of different sizes by passing new parameter values during instantiation. This can be done as such:</p>
<pre class="brush: verilog; title: ; notranslate">
register_file #(16, 32) reg_file(data_out, clk, wr_en_1, wr_en_2, rst, data_in_1, data_in_2,	wr_addr_1, wr_addr_2, rd_addr);
</pre>
<p>This will instantiate the same module with 16 32-bit entries.</p>
<p>Inside our module in an always block we declare that we want it to execute only in case of a clock&#8217;s positive edge, or a reset&#8217;s negative edge. Since the rest is active low, it will change states from 1->0 (negative edge).</p>
<pre class="brush: verilog; title: ; notranslate">
always @(posedge clk, negedge rst) begin
</pre>
<p>We then take care of our two write ports and reset. If reset is equal to 0, then we need to reset all of the values in the register file. Otherwise if wr_en_1 is 1, we want to write to write port 1, else we want to write to write port 2.</p>
<pre class="brush: verilog; title: ; notranslate">
always @(posedge clk, negedge rst) begin
		if(rst == 1'b0) begin
			for(i = 0; i &lt; ENTRIES; i = i + 1) begin
				registers[i] &lt;= 7'b0;
			end
		end

		else if(wr_en_1)
			registers[wr_addr_1] &lt;= data_in_1;
		else
			registers[REG_OFFSET + wr_addr_2] &lt;= data_in_2;
end
</pre>
<p>That take care of the two synchronous write ports. Since hardware operations occur in parallel, we can have multiple always blocs which will all execute at the same time. For the write port we simply want the always block to be triggered every time the read address (<b>read_addr</b>) changes.</p>
<pre class="brush: verilog; title: ; notranslate">
always @(rd_addr) begin
		data_out = registers[rd_addr];
end
</pre>
<p>And this is the complete code for the register file:<br />
<b>register_file.v</b>:</p>
<pre class="brush: verilog; title: ; notranslate">
module register_file(data_out, clk, wr_en_1, wr_en_2, rst, data_in_1, data_in_2,	wr_addr_1, wr_addr_2, rd_addr);

	parameter ENTRIES = 16;
	parameter REG_OFFSET = 8;
	integer i;

	input clk, wr_en_1, wr_en_2, rst;
	input [7:0] data_in_1, data_in_2;
	input [2:0] wr_addr_1, wr_addr_2;
	input [3:0] rd_addr;
	output reg [7:0] data_out;

	reg [7:0] registers [ENTRIES - 1:0];

	always @(posedge clk, negedge rst) begin
		if(rst == 1'b0) begin
			for(i = 0; i &lt; ENTRIES; i = i + 1) begin
				registers[i] &lt;= 7'b0;
			end
		end

		else if(wr_en_1)
			registers[wr_addr_1] &lt;= data_in_1;
		else
			registers[REG_OFFSET + wr_addr_2] &lt;= data_in_2;
	end

	always @(rd_addr) begin
		data_out = registers[rd_addr];
	end

endmodule
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2010/10/18/creating-a-register-file-using-behavioral-verilog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mean Median and Mode in C++</title>
		<link>http://www.hdelossantos.com/2010/10/16/mean-median-and-mode-in-c/</link>
		<comments>http://www.hdelossantos.com/2010/10/16/mean-median-and-mode-in-c/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 18:01:28 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[mean]]></category>
		<category><![CDATA[median]]></category>
		<category><![CDATA[mode]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=688</guid>
		<description><![CDATA[Yesterday I had to complete a programming exercise as part of a research internship I will be starting Nov. 2nd. I had to create a simple C++ program which would take the mean, median, and mode of a set of numbers of unknown length. I was free to implement it any which way, with the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I had to complete a programming exercise as part of a research internship I will be starting Nov. 2nd. I had to create a simple C++ program which would take the mean, median, and mode of a set of numbers of unknown length. I was free to implement it any which way, with the exception of using arithmetic libraries to do my mean, median, and mode computations.<br />
<span id="more-688"></span><br />
I chose to retrieve data from a file into a Vector of integers. The vector is then passed to the 3 functions to perform their corresponding operation. The result is returned and printed.</p>
<p>The <b>mode</b> function sorts the vector and iterates through it keeping a count of how many times the current value appears. Since the array is in sorted order, we know that if the next value is greater than the current, then we must be done counting the current, so it can be added to a temporary vector. If a new value is found, which has a greater count than the current highest, then the vector is cleared and the new value is added. If the new value has a count equal to that of the current high count, it is added to the temporary vector. The temporary vector is returned at the end.<br />
</p>
<h4>Function Descriptions: </h4>
<p>The <b>median</b> function check to see if the vector has an even number of items. If it does, then the median is computed as the average of the two medians of the vector in sorted order. Otherwise, the median is the result of the middle value. The return type for this function is float because of the need to represent decimals in cases when the average must be taken.</p>
<p>The <b>mean</b> function iterates through the vector taking the sum of all the values, then divides them by the total number of items in the vector. The return type is a double for large numbers which require greater precision than a float can provide.</p>
<p>Header File:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;
#include &lt;fstream&gt;

using namespace std;

template &lt;typename T&gt; vector&lt;int&gt; mode(vector&lt;T&gt; &amp;data);
template &lt;typename T&gt; float median(vector&lt;T&gt; &amp;data);
template &lt;typename T&gt; double mean(vector&lt;T&gt; &amp;data);
</pre>
<p>Main:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &quot;mean_median_mode.h&quot;

int main(int argc, char *argv[]) {
	// Function declaration

	vector&lt;int&gt; data;

	// Load a small set of variables into the vector

	int input_int;
	ifstream infile(argv[1]);

	if(!infile) {
		if(argv[1] != NULL) {
			// There was an error opening the file
			cout &lt;&lt; &quot;There was an error opening &quot;
				&lt;&lt; argv[1]
				&lt;&lt; &quot; for reading.&quot;
				&lt;&lt; endl;
		}
		else {
			cout &lt;&lt; &quot;Syntax error. mean_median_mode &lt;input file name&gt;&quot; &lt;&lt; endl;
		}

	}

	else {
		while (infile &gt;&gt; input_int) {
			data.push_back(input_int);
		}

		sort(data.begin(), data.end());
		cout &lt;&lt; &quot;Data Set: &quot;;
		int j;
		for (j = 0; j &lt; data.size(); j++) {
			printf(&quot;%i &quot;, data[j]);
		}
		cout &lt;&lt; endl;

		printf(&quot;Mean: %f Median: %f, Mode: &quot;, mean(data), median(data));
		vector&lt;int&gt; tmp = mode(data);
		int i;

		for(i = 0; i &lt; tmp.size(); i++) {
			printf(&quot;%i &quot;, tmp[i]);
		}
		printf(&quot;\n&quot;);
	}

	return 0;
}

template &lt;typename T&gt; vector&lt;int&gt; mode(vector&lt;T&gt; &amp;data) {
	vector&lt;int&gt; tmp_vector;

	if(data.size() &gt; 0) {
		sort(data.begin(), data.end());
		vector&lt;int&gt;::iterator i;
		i = data.begin();

		int highest_mode = 0;
		int highest_mode_count = 0;
		int current_mode = 0;
		int current_count = 0;

		// Iterate through the vector
		while(i != data.end()) {
			int tmp = *i;

			if(current_count == 0) {
				current_mode = tmp;
			}

			if(tmp == current_mode) {
				current_count++;
			}
			else if(tmp &gt; current_mode) {

				// Check if the current mode is greater than the highest
				if(current_count &gt; highest_mode_count) {
					// Make the current mode the highest
					highest_mode = current_mode;
					highest_mode_count = current_count;

					// Clear the vector
					tmp_vector.clear();

					// Add the highest value to the vector
					tmp_vector.push_back(highest_mode);

					// Set current to tmp
					current_mode = tmp;
					current_count = 1;
				}

				// In case multiple modes
				else if(current_count == highest_mode_count) {
					// Set the highest mode to current
					highest_mode = current_mode;
					highest_mode_count = current_count;

					// Add the current mode to the vector
					tmp_vector.push_back(current_mode);

					current_mode = tmp;
					current_count = 1;
				}

				else {
					// Set tmp to current
					current_mode = tmp;
					current_count = 1;
				}
			}
			else {
				// Shouldn't need to do anything if tmp &lt; current_mode
			}

			i++;
		}
	}

	return tmp_vector;
}

template &lt;typename T&gt; float median(vector&lt;T&gt; &amp;data) {
	if(data.size() &gt; 0) {
		// Sort the data
		sort(data.begin(), data.end());

		// Handle the even cases
		if((data.size() % 2) == 0) {
			// To get the median value sum the 2 medians and get the average
			float sum = 0;

			sum += data[data.size()/2];
			sum += data[(data.size()/2) - 1];

			return (sum/2);
		}

		// Handle the odd cases
		else {
			return data[data.size()/2];
		}
	}

	return 0;
}

template &lt;typename T&gt; double mean(vector&lt;T&gt; &amp;data) {
	if(data.size() &gt; 0) {
		vector&lt;int&gt;::iterator i;
		double sum = 0;

		// Iterate through all of the elements in the vector and sum them
		for(i = data.begin(); i != data.end(); i++) {
			sum += *i;
		}

		return sum/data.size();
	}

	return 0;
}
</pre>
<p>Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
all: mean_median_mode

mean_median_mode: mean_median_mode.h mean_median_mode.cpp
	g++ -o mean_median_mode mean_median_mode.cpp

clean:
	rm mean_median_mode
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2010/10/16/mean-median-and-mode-in-c/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Verilog SyntaxHighlighter Brush</title>
		<link>http://www.hdelossantos.com/2010/05/20/verilog-syntaxhighlighter-brush/</link>
		<comments>http://www.hdelossantos.com/2010/05/20/verilog-syntaxhighlighter-brush/#comments</comments>
		<pubDate>Fri, 21 May 2010 00:40:27 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[hanly de los santos]]></category>
		<category><![CDATA[hdelossantos]]></category>
		<category><![CDATA[hdelossantos.com]]></category>
		<category><![CDATA[highlighter]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[plug-in]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[syntaxhighlighter]]></category>
		<category><![CDATA[Verilog]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=570</guid>
		<description><![CDATA[I was trying to add some sample Verilog code on my website, but the code syntax highlighter I use did not have a brush. I made my own Verilog brush for Alex Gorbatchev&#8217;s SyntaxHighlighter. Feel free to modify and improve the code. The only thing that I ask is that you share the modifications. You [...]]]></description>
			<content:encoded><![CDATA[<p>I was trying to add some sample Verilog code on my website, but the code syntax highlighter I use did not have a brush. I made my own Verilog brush for Alex Gorbatchev&#8217;s<a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"> SyntaxHighlighter</a>. Feel free to modify and improve the code. The only thing that I ask is that you share the modifications.<br />
<span id="more-570"></span></p>
<pre class="brush: jscript; title: ; notranslate">
/**
 * SyntaxHighlighter Verilog Brush
 * http://hdelossantos.com/
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
 *
 * @version
 * 1.0.0 (May 20, 2010)
 *
 * @copyright
 * Copyright (C) 2010 Hanly De Los Santos.
 *
 * @license
 * This file is a SyntaxHighlighter brush and is licensed under
 * the same license as SyntaxHighlighter.
 *
 * SyntaxHighlighter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * SyntaxHighlighter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SyntaxHighlighter.  If not, see &lt;http://www.gnu.org/copyleft/lesser.html&gt;.
 */
SyntaxHighlighter.brushes.Verilog = function() {
	var keywords = 'always end ifnone or rpmos tranif1 and endcase ' +
			  'initial output rtran tri assign endmodule inout ' +
			  'parameter rtranif0 tri0 begin endfunction input ' +
			  'pmos rtranif1 tri1 buf endprimitive integer ' +
			  'posedge scalared triand bufif0 endspecify join ' +
			  'primitive small trior bufif1 endtable large pull0 ' +
			  'specify trireg case endtask macromodule pull1 ' +
			  'specparam vectored casex event medium pullup ' +
			  'strong0 wait casez for module pulldown strong1 ' +
			  'wand cmos force nand rcmos supply0 weak0 deassign ' +
			  'forever negedge real supply1 weak1 default for ' +
			  'nmos realtime table while defparam function nor ' +
			  'reg task wire disable highz0 not release time wor ' +
			  'edge highz1 notif0 repeat tran xnor else if ' +
			  'notif1 rnmos tranif0 xor';
	var sysTasks = '$display $monitor $dumpall $dumpfile $dumpflush ' +
			  '$dumplimit $dumpoff $dumpon $dumpvars $fclose ' +
			  '$fdisplay $fopen $finish $fmonitor $fstrobe ' +
			  '$fwrite $fgetc $ungetc $fgets $fscanf $fread ' +
			  '$ftell $fseek $frewind $ferror $fflush $feof ' +
			  '$random $readmemb $readmemh $readmemx $signed ' +
			  '$stime $stop $strobe $time $unsigned $write';
	var macros = 'default-net define celldefine default_nettype ' +
			  'else elsif endcelldefine endif ifdef ifndef ' +
			  'include line nounconnected_drive resetall ' +
			  'timescale unconnected_drive undef';

	this.regexList = [
		{ regex: SyntaxHighlighter.regexLib.singleLineCComments,	css: 'comments' },
		{ regex: /\/\*([^\*][\s\S]*)?\*\//gm,						css: 'comments' },
		{ regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm,					css: 'preprocessor' },
		{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,		css: 'string' },
		{ regex: SyntaxHighlighter.regexLib.singleQuotedString,		css: 'string' },
		{ regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi,			css: 'value' },
		{ regex: /(?!\@interface\b)\@[\$\w]+\b/g,			css: 'color1' },
		{ regex: /\@interface\b/g,					css: 'color2' },
		{ regex: new RegExp(this.getKeywords(keywords), 'gm'),		css: 'keyword' },
		{ regex: new RegExp(this.getKeywords(macros), 'gm'),		css: 'keyword' },
		{ regex: new RegExp(this.getKeywords(sysTasks), 'gm'),		css: 'keyword' }
];

};

SyntaxHighlighter.brushes.Verilog.prototype = new SyntaxHighlighter.Highlighter();
SyntaxHighlighter.brushes.Verilog.aliases = ['verilog', 'v'];
</pre>
<p>You can download the WordPress plugin below. You must have the SyntaxHighlighter plugin installed and active.</p>
<p>[ad#Google Adsense Text Ad Post]<br />
<a href="/school_content/sample_code/syntaxhighlighter-brush-verilog.zip"><img src="/images/download_now.png" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2010/05/20/verilog-syntaxhighlighter-brush/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using a SQLite Database in Android</title>
		<link>http://www.hdelossantos.com/2010/01/07/using-a-sqlite-database-in-android/</link>
		<comments>http://www.hdelossantos.com/2010/01/07/using-a-sqlite-database-in-android/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 04:08:42 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[database adapter]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[step-by-step]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[tv]]></category>
		<category><![CDATA[using database adapter]]></category>
		<category><![CDATA[using dbadapter]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=518</guid>
		<description><![CDATA[This tutorial will demonstrate how to use the database adapter created in &#8220;Creating a SQLite Database in Android&#8221; to add and get data to and from the database to populate a ListView. DatabaseQuery.java : We must first create a class to handle the formatting for the queries. The database adapter takes ArrayLists of String objetcs [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will demonstrate how to use the database adapter created in <a href="/2009/12/23/creating-a-sqlite-database-in-android">&#8220;Creating a SQLite Database in Android&#8221;</a> to add and get data to and from the database to populate a ListView.<br />
<span id="more-518"></span></p>
<h3><strong>DatabaseQuery.java :</strong></h3>
<p>We must first create a class to handle the formatting for the queries. The database adapter takes ArrayLists of String objetcs to add rows to the database, however you will probably want a method to add one cell at a time, then when the contents of the row are completed, add the entire row to the database. We begin by declaring the variables for the ArrayLists.</p>
<pre class="brush: java; title: ; notranslate">
import java.util.ArrayList;
import android.content.Context;
import android.database.Cursor;

/**
 * This class adds multiple entries to the database and pulls them back
 * out.
 */
public class DatabaseQuery {
	// Variables area
	private ArrayList&lt;String&gt; arrayKeys = null;
	private ArrayList&lt;String&gt; arrayValues = null;
	private ArrayList&lt;String&gt; databaseKeys = null;
	private ArrayList&lt;String&gt; databaseKeyOptions = null;
	private DBAdapter database;
</pre>
<p>We then create the constructor which will call the DBAdapter class and create the database.</p>
<pre class="brush: java; title: ; notranslate">
/**
	 * Initialize the ArrayList
	 * @param context Pass context from calling class.
	 */
	public DatabaseQuery(Context context) {
		// Create an ArrayList of keys and one of the options/parameters
		// for the keys.
		databaseKeys = new ArrayList&lt;String&gt;();
		databaseKeyOptions = new ArrayList&lt;String&gt;();
		databaseKeys.add(&quot;Title&quot;);
		databaseKeyOptions.add(&quot;text not null&quot;);

		// Call the database adapter to create the database
		database = new DBAdapter(context, &quot;testTable&quot;, databaseKeys, databaseKeyOptions);
        database.open();
		arrayKeys = new ArrayList&lt;String&gt;();
		arrayValues = new ArrayList&lt;String&gt;();

	}
</pre>
<p><strong>databaseKeys</strong> is an ArrayList of all of the column names the database will contain.<br />
<strong>databaseKeyOptions</strong> is an ArrayList of the options for the column names. This can be a field type such as &#8220;text&#8221; or &#8220;integer&#8221;.</p>
<p>In this example I have only added one key here. The DBAdapter class also adds a timeStamp column when a new row is inserted. This makes it easy to sort by time later on. The context is passed from the applications main activity, which we will create at the end. After the DBAdapter object has been created, we then use it to open the pipeline to the database. Now we can query the database.</p>
<p>In the constructor we also initialized two arrays &#8220;arrayKeys&#8221; and &#8220;arrayValues&#8221; which will hold all of the data that constitutes one row. This data is appended to the arrays in the appendData method. Once all of the keys and their values have been appended, then the addRow method is called to insert the row to the database.</p>
<pre class="brush: java; title: ; notranslate">
/**
	 * Append data to an ArrayList to then submit to the database
	 * @param key Key of the value being appended to the Array.
	 * @param value Value to be appended to Array.
	 */
	public void appendData(String key, String value){
		arrayKeys.add(key);
		arrayValues.add(value);
	}

	/**
	 * This method adds the row created by appending data to the database.
	 * The parameters constitute one row of data.
	 */
	public void addRow(){
		database.insertEntry(arrayKeys, arrayValues);
	}
</pre>
<p>To run a query and get data from the database, we can specify parameters to sort all of the data in the database.</p>
<p><strong>keys</strong> is a String[] of the column headers to return in the results<br />
<strong>selection</strong> is a String to search for in the columns. Only columns with matching string are returned.<br />
<strong>selectionArgs</strong> is a String[] with arguments for the selection.<br />
<strong>groupBy</strong> is the String to group results by.<br />
<strong>having</strong> is a filter to declare which row groups to include in the cursor.<br />
<strong>sortBy</strong> is a key to sort the results by.<br />
<strong>sortOption</strong> specifies the way to sort the data.</p>
<pre class="brush: java; title: ; notranslate">
/**
	 * Get data from the table.
	 */
	public ArrayList&lt;String&gt; getData(String[] keys, String selection, String[]
	  selectionArgs, String groupBy, String having, String sortBy, String sortOption){

		ArrayList&lt;String&gt; list = new ArrayList&lt;String&gt;();
		Cursor results = database.getAllEntries(keys, selection,
				selectionArgs, groupBy, having, sortBy, sortOption);
		while(results.moveToNext())
			list.add(results.getString(results.getColumnIndex(sortBy)));
		return list;

	}
</pre>
<p>In this example I only wanted the results to include one field, &#8220;Title&#8221;. I set the parameters for this in my main class. This returns an ArrayList, with only the column title. This is obtained by selecting the string to add to the ArrayList.</p>
<pre class="brush: java; title: ; notranslate">
list.add(results.getString(results.getColumnIndex(sortBy)));
</pre>
<p>You can use results.get[String, Integer, etc.] in order to obtain the data in a specific format. You must supply it with a column index number, which can be obtained by results.getColumnIndex(&#8220;Title&#8221;). In my case sortBy has &#8220;Title&#8221; since I will be sorting by that key value as well. As it is this code will only return the results of one column of data for many rows. Modifications can be made to return more. One way to achieve this is to create an object and return an array of those objects.</p>
<p>Once we are all done, the pipe to the database must be closed.</p>
<pre class="brush: java; title: ; notranslate">
/**
	 * Destroy the reporter.
	 * @throws Throwable
	 */
	public void destroy() throws Throwable{
        database.close();
	}
}
</pre>
<p>This attempts to close the database and returns an exception if it encounters an error.</p>
<h3><strong>DBAdapterTest.java :</strong></h3>
<p>This is the main class and will extend ListActivity in order to populate a list of the elements obtained from the database.</p>
<pre class="brush: java; title: ; notranslate">
import java.util.ArrayList;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class DBAdapterTest extends ListActivity {
	private ArrayList&lt;String&gt; queryString;
	private DatabaseQuery query;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        query = new DatabaseQuery(this);

        // Populate the database
        query.appendData(&quot;Title&quot;, &quot;Row One&quot;);
        query.addRow();
        query.appendData(&quot;Title&quot;, &quot;Row Two&quot;);
        query.addRow();

        // Pull the data from the database
        queryString = query.getData(new String[] {&quot;Title&quot;}, null, null, null, null, &quot;Title&quot;, &quot; ASC&quot;);
        try {
			query.destroy();
		} catch (Throwable e) {
			e.printStackTrace();
		}

        // Set the ListView
        setListAdapter(new ArrayAdapter&lt;String&gt;(this,
                android.R.layout.simple_list_item_1, queryString));
        getListView().setTextFilterEnabled(true);

    }
}
</pre>
<p>A new instance of DatabaseQuery is instantiated and data is added to the database. Once the data has been added, a query is run to pull the data out of the database and populate a ListView. This application adds the same two entries every time it is run. This is simply an quick example of how to use the DBAdapter and changes should be made depending on the needs of your application.</p>
<div id="attachment_530" class="wp-caption aligncenter" style="width: 210px"><a class="lightview" href="http://www.hdelossantos.com/blog/wp-content/uploads/2010/01/DBAdaptrTest.png"><img class="size-full wp-image-530" title="DBAdaptrTest" src="http://www.hdelossantos.com/blog/wp-content/uploads/2010/01/DBAdaptrTest.png" alt="The sorting is done alphabetically on text. Therefore &quot;Row One&quot; comes before &quot;Row Two&quot;. However, if &quot;Row Four&quot; were to be used, that would preceed the other two." width="100" height="150" /></a><p class="wp-caption-text">The sorting is done alphabetically on text. Therefore &quot;Row One&quot; comes before &quot;Row Two&quot;. However, if &quot;Row Four&quot; were to be used, that would precede the other two.</p></div>
<p>You can download the full Eclipse project folder below.<br />
[ad#Google Adsense Text Ad Post]<br />
<a href="/school_content/sample_code/DBAdapterTest.zip"><img src="/images/download_now.png" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2010/01/07/using-a-sqlite-database-in-android/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Quick and easy Android HTTP POST of JSON string</title>
		<link>http://www.hdelossantos.com/2009/12/24/quick-and-easy-android-http-post-of-json-string/</link>
		<comments>http://www.hdelossantos.com/2009/12/24/quick-and-easy-android-http-post-of-json-string/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 19:23:05 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[show]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=506</guid>
		<description><![CDATA[There are several ways to send data across the internet to a server on the Android. I was recently working on a project and needed to send a JSON string to the server to add data to a database. Additionally in certain cases I wanted to receive data back from the server. The fastest and [...]]]></description>
			<content:encoded><![CDATA[<p>There are several ways to send data across the internet to a server on the Android. I was recently working on a project and needed to send a JSON string to the server to add data to a database. Additionally in certain cases I wanted to receive data back from the server. The fastest and easiest way to do this was to use HTTP POST android library and capture the response from the server using a response handler. On the server side the response was simply generated by echoing a JSON string.<br />
<span id="more-506"></span></p>
<pre class="brush: java; title: ; notranslate">
public ArrayList&lt;String&gt; getServerData() throws JSONException, ClientProtocolException, IOException {
	    ArrayList&lt;String&gt; stringData = new ArrayList&lt;String&gt;();
	    DefaultHttpClient httpClient = new DefaultHttpClient();
		ResponseHandler &lt;String&gt; resonseHandler = new BasicResponseHandler();
		HttpPost postMethod = new HttpPost(URL_TO_PHP_FILE_TO_HANDLE_POST);
		List&lt;NameValuePair&gt; nameValuePairs = new ArrayList&lt;NameValuePair&gt;(2);

		JSONObject jsonObject = new JSONObject();
		jsonObject.put(&quot;someKey&quot;, someData); //Data being sent to the server, which should produce a reply

		nameValuePairs.add(new BasicNameValuePair(&quot;jsonString&quot;, jsonObject.toString()));
		postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
		String response = httpClientexecute(postMethod,resonseHandler);

		JSONObject jsonResponse = new JSONObject(response);

		JSONArray serverData1 = jsonResponse.getJSONArray(&quot;data1&quot;);
		JSONArray serverData2 = jsonResponse.getJSONArray(&quot;data2&quot;);
		for(int i = 0; i &lt; serverData1.length() &amp;&amp; i &lt; serverData2.length(); i++) {
			//Do something with the data
		}

		return //the data;
   }
</pre>
<p>The code above shows the receipt of those two JSON encoded arrays. In my case I had to get a little creative with the server side code since I wanted to send two arrays encoded in JSON. However, the PHP library&#8217;s JSON encoding differs from that of Android so I had to encode the two arrays I needed to send using loops. </p>
<pre class="brush: plain; title: ; notranslate">
// Android expects to receive JSON arrays like so
{&quot;array_name&quot;:[data, data1, data2], &quot;array2_name&quot;:[data, data1, data2]}
</pre>
<p>The PHP code I wrote to format my arrays in a JSON format Android would understand is below.</p>
<pre class="brush: php; title: ; notranslate">
// Create the JSON string
        while($row = mysql_fetch_array($results, MYSQL_ASSOC)) {
            $data1[] = $row['data1'];
            $data2[] = $row['data2'];
        }

        mysql_close($handle);

        $json = '{&quot;data1&quot;:[';

        for($i = 0; $i &lt; sizeof($data1); $i++) {
            $json = $json . $data1[$i];

            if($i &lt; sizeof($data1) - 1)
                $json = $json . ',';
        }

        $json = $json . '],&quot;data2&quot;:[';

        for($i = 0; $i &lt; sizeof($data2); $i++) {
            $json = $json . $data2[$i];

             if($i &lt; sizeof($data2) - 1)
                $json = $json . ',';
        }

        $json = $json . ']}';

        // Send the client a JSON string with the result
        echo ($json);
</pre>
<p>[ad#Google Adsense Text Ad Post]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/12/24/quick-and-easy-android-http-post-of-json-string/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Creating a SQLite database in Android</title>
		<link>http://www.hdelossantos.com/2009/12/23/creating-a-sqlite-database-in-android/</link>
		<comments>http://www.hdelossantos.com/2009/12/23/creating-a-sqlite-database-in-android/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 07:40:49 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[android project]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[database adapter]]></category>
		<category><![CDATA[database table]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[show]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[step-by-step]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=477</guid>
		<description><![CDATA[This example will show you how to create a somewhat abstracted SQLite adapter on Android. This adapter can then be utilized by your program to do common database functions such as, querying and searching. I start by creating the class DBAdapter in my Android project and declaring the variable data necessary to create the database. [...]]]></description>
			<content:encoded><![CDATA[<p>This example will show you how to create a somewhat abstracted SQLite adapter on Android. This adapter can then be utilized by your program to do common database functions such as, querying and searching. I start by creating the class DBAdapter in my Android project and declaring the variable data necessary to create the database.</p>
<p><span style="color: #B20000;">EDIT: The code has been modified since it originally assumed that a key option would be passed for every key. It will now work if no key options are passed. Additionally, &#8220;null&#8221; can also be passed to it if no key options are desired.</span></p>
<p><span id="more-477"></span></p>
<pre class="brush: java; title: ; notranslate">
public class DBAdapter{

	private static final String DATABASE_NAME = &quot;example.db&quot;;
	private String DATABASE_TABLE;

	private static final int DATABASE_VERSION = 1;
</pre>
<p><strong>DATABASE_NAME</strong> is of course the name of the database we will be creating. This is usually done one database per program. The database can be found in /data/data/<br />
/databases/.<br />
<strong>DATABASE_TABLE</strong> will be the name of the table you will be creating. We will make it so that wen a new instance of the database is created, the table name has to be passed so that new tables can be created without the need to create a new class, or creating static table assignments.<br />
<strong>DATABASE_VERSION</strong> is the version of the database we will be creating; 1 is fine here.</p>
<p>Now we must create the variables to set our table structure.</p>
<pre class="brush: java; title: ; notranslate">
// Index Key column
public static final String KEY_ID = &quot;_id&quot;;

// Name of the column index of each column in DB
public  ArrayList&lt;String&gt; TABLE_KEYS =  new ArrayList&lt;String&gt;();
public  ArrayList&lt;String&gt; TABLE_OPTIONS = new ArrayList&lt;String&gt;();
public  final String KEY_TIMESTAMP = &quot;timeStamp&quot;;
public  final int TIMESTAMP_COLUMN = 1;
</pre>
<p>We first create our primary key value which will have the row numbers of the data entered in our table. This is the <strong>KEY_ID</strong> string, which contains &#8220;_id&#8221;. The actual column heading that will show up on the table will be &#8220;_id&#8221;. In order to abstract this helper as much as possible, the keys and options for the keys will be passed in as ArrayLists of string objects from the class that calls the DBAdapter. <strong>TABLE_KEYS</strong> refers to the column name, and <strong>TABLE_OPTIONS</strong> refers to the options for that column (these can be &#8220;text not null&#8221;, setting the column type to &#8220;integer&#8221;, etc.). I always like creating a column which contains a timestamp in case I want to sort the data by time, which is what the <strong>KEY_TIMESTAMP</strong> is. <strong>TIMESTAMP_COLUMN</strong> sets the column number of the timestamp column to 1, which makes it easier to select data later on. This is not necessary since you can get the column numbers by searching for the column name (I&#8217;ll go over this later).</p>
<pre class="brush: java; title: ; notranslate">
// Create new database
	private String DATABASE_CREATE;

	// Variable to hold database instant
	private SQLiteDatabase db;

	// Database open/upgrade helper
	private myDBHelper dbHelper;
</pre>
<p><strong>DATABASE_CREATE</strong> This variable will contain the string we will use to create the database. This is where we will set our parameters and key names.<br />
<strong>db</strong> is the database instance we will create.<br />
<strong>dbHelper</strong> is an instance of the class myDBHelper which we will create later within this class. This is what actually initiates the database and creates tables if needed, etc. (This extends SQLiteOpenHelper).</p>
<pre class="brush: java; title: ; notranslate">
	public DBAdapter(Context context, String table, ArrayList&lt;String&gt; keys, ArrayList&lt;String&gt; options){
		// Start initializing all of the variables
		DATABASE_TABLE = table;
		TABLE_KEYS = (ArrayList&lt;String&gt;)keys.clone();
		TABLE_OPTIONS = options;

		String keyString = &quot;&quot;;
		for(int i = 0; TABLE_KEYS.size() &gt; i; i++){

			// Add commas to the options elements if there is a next value.
			if(i + 1 &lt; TABLE_OPTIONS.size() &amp;&amp; TABLE_OPTIONS.get(i) != null){
				TABLE_OPTIONS.set(i, TABLE_OPTIONS.get(i) + &quot;,&quot;);
			}else if (i + 1 == TABLE_OPTIONS.size() &amp;&amp; TABLE_OPTIONS.get(i) != null) {
				if(i + 1 &lt; TABLE_KEYS.size()){
					TABLE_OPTIONS.set(i, TABLE_OPTIONS.get(i) + &quot;,&quot;);
				}else {
					TABLE_KEYS.set(i, TABLE_KEYS.get(i) + &quot;&quot;);
				}
			}else if (i + 1 != TABLE_KEYS.size()) {
				TABLE_KEYS.set(i, TABLE_KEYS.get(i) + &quot;,&quot;);
			}else {
				TABLE_KEYS.set(i, TABLE_KEYS.get(i) + &quot;&quot;);
			}

			System.out.println(TABLE_OPTIONS.toString());
			System.out.println(TABLE_KEYS.toString());

			if(i + 1 &lt;= TABLE_OPTIONS.size() &amp;&amp; TABLE_OPTIONS.get(i) != null)
				keyString = keyString + &quot; &quot; + TABLE_KEYS.get(i) + &quot; &quot; + TABLE_OPTIONS.get(i);
			else if(i + 1 &gt; TABLE_OPTIONS.size() || TABLE_OPTIONS.get(i) == null){
				keyString = keyString + &quot; &quot; + TABLE_KEYS.get(i);
			}
		}

		// Create the database creation string.
		DATABASE_CREATE = &quot;CREATE TABLE IF NOT EXISTS &quot; + DATABASE_TABLE + &quot; (&quot;
		+ &quot;_id&quot; + &quot; INTEGER PRIMARY KEY AUTOINCREMENT, &quot; + KEY_TIMESTAMP + &quot;,&quot; + keyString + &quot;);&quot;;

		// Create a new Helper
		dbHelper = new myDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION,
				DATABASE_TABLE, DATABASE_CREATE);
	}
</pre>
<p>This is the constructor for DBAdapter, which sets up all of the variables for further calls to other methods in this class. This opens the database if it exists or create it if it doesn&#8217;t. Additionally checks if the<br />
table exists and creates it if it doesn&#8217;t. The ArrayLists of string objects for the key names and options are parsed, and commas are added where they need to be so that the <strong>DATABASE_CREATE</strong> creation string can be created. A clone of the keys ArrayList is created so that the changes we make (adding commas at the end of options and keys if there will be something following them) here will no affect the variable when we call it later. The last thing we do is instantiate the database by calling our dbHelper, which is the actual function that creates the database with the parameters which we have given it in our creation string, the database name, table name, etc.).</p>
<pre class="brush: java; title: ; notranslate">
public DBAdapter open() throws SQLException {
		db = dbHelper.getWritableDatabase();
		return this;
	}

public void close() {
		db.close();
	}
</pre>
<p>These function allow opening and closing of the database. It is necessary to open the database before data can be written or read from it. Likewise it is necessary to close the database once one has finished with it, otherwise memory leaks occur.</p>
<pre class="brush: java; title: ; notranslate">
public long insertEntry(ArrayList&lt;String&gt; key, ArrayList&lt;String&gt; value) {
		String timeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis()).toString();
		ContentValues contentValues = new ContentValues();
		for(int i = 0; key.size() &gt; i; i++){
			contentValues.put(key.get(i), value.get(i));
		}
		contentValues.put(KEY_TIMESTAMP, timeStamp);
		return db.insert(DATABASE_TABLE, null, contentValues);
	}
</pre>
<p>This method is used to insert and entry into the database. It takes in two variables of ArraList of string objects which contain the column names or keys and the data to be added into each key. When an entry is inserted this method also sets the timestamp value automatically.</p>
<pre class="brush: java; title: ; notranslate">
public boolean removeEntry(long rowIndex) {
		return db.delete(DATABASE_TABLE, KEY_ID + &quot;=&quot; + rowIndex, null) &gt; 0;
	}
</pre>
<p>This method removes a row of data from the database. The <strong>rowIndex</strong> must be provided. This can be acquired by running a query and getting the <strong>_id</strong> field from the result.</p>
<pre class="brush: java; title: ; notranslate">
public Cursor getAllEntries(String[] columns, String selection, String[] selectionArgs,
			String groupBy, String having, String sortBy, String sortOption) {
		return db.query(DATABASE_TABLE, columns, selection, selectionArgs, groupBy,
				having, sortBy + &quot; &quot; + sortOption);
	}
</pre>
<p>This method runs a query and returns a cursor through all of the matching results.<br />
<strong>columns</strong> is an string array of columns to be included in the result.<br />
<strong>selection</strong> is the value to look for in the columns. A null will return all results.<br />
<strong>selectionArgs</strong> is a string array of arguments for the selection. Can be null.<br />
<strong>groupBy</strong> option to group the results by. Can be set to null.<br />
<strong>having</strong> a filter declare which row groups to include in the cursor. Can be null.<br />
<strong>sortBy</strong> column to sort the results by.<br />
<strong>sortOption</strong> is how to sort the results, ASC for ascending, DESC for descending.</p>
<pre class="brush: java; title: ; notranslate">
public int updateEntry(long rowIndex, ArrayList&lt;String&gt; key, ArrayList&lt;String&gt; value) {
		String timeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis()).toString();
		String where = KEY_ID + &quot;=&quot; + rowIndex;
		ContentValues contentValues = new ContentValues();
		for(int i = 0; key.size() &gt; i; i++){
			contentValues.put(key.get(i), value.get(i));
		}
		contentValues.put(KEY_TIMESTAMP, timeStamp);
		return db.update(DATABASE_TABLE, contentValues, where, null);
	}
</pre>
<p>This method updates a row in the database. This takes in the same parameters as the method to insert a new row, with the additional rowIndex variable, which is the number of the row to update.</p>
<pre class="brush: java; title: ; notranslate">
public boolean clearTable() {
		return db.delete(DATABASE_TABLE, null, null) &gt; 0;
	}
</pre>
<p>I&#8217;m not particularly fond of this method since it can cause more harm than good. However, I think that it&#8217;s good to have it for testing purposes. This of course clears all of the contents of a table.</p>
<pre class="brush: java; title: ; notranslate">
private static class myDBHelper extends SQLiteOpenHelper {
		private String creationString;
		private String tableName;
		@SuppressWarnings(&quot;unused&quot;)
		SQLiteDatabase db;

		/**
		 * Creates a myDBHelper object.
		 * @param context The context where the access is needed
		 * @param name Name of database file
		 * @param factory A CursorFactory, or null to use default CursorFactory
		 * @param version Database version
		 * @param tableName Name of table within database
		 * @param creationString SQL String used to create the database
		 */
		public myDBHelper(Context context, String name, CursorFactory factory,
				int version, String tableName, String creationString) {
			super(context, name, factory, version);
			this.creationString = creationString;
			this.tableName = tableName;
		}

		/**
		 * Creates the database table.
		 * @param db The database used by this helper to create the table in
		 */
		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(creationString);
		}

		/**
		 * This method determines if the database needs to be updated or not.
		 * @param db The database used by this helper
		 * @param oldVersion The old database version
		 * @param newVersion The new database version
		 */
		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			// Log the version upgrade
			Log.w(&quot;TaskDBAdapter&quot;, &quot;Upgrading from version &quot; + oldVersion +
					&quot; to &quot; + newVersion + &quot;, which will destroy all old data&quot;);

			db.execSQL(&quot;DROP TABLE IF EXISTS &quot; + tableName);
			onCreate(db);

		}

		/**
		 * Creates tables when the database is opened if the tables need to be created.
		 * @param db The database used by this helper
		 */
		@Override
		public void onOpen(SQLiteDatabase db) {
			db.execSQL(creationString);
		}

	}
}
</pre>
<p>This subclass is a helper for DBAdapter and does the job of creating the database and checking if the database needs an upgrade to new version depending on version number specified by DBAdapter.</p>
<p>For instructions on using this database adapter please continue to <a href="/2010/01/07/using-a-sqlite-database-in-android/">&#8220;Using a SQLite Database in Android&#8221;</a></p>
<p>You can download the full code below.</p>
<p>[ad#Google Adsense Text Ad Post]<br />
<a href="/school_content/sample_code/DBAdapter.java"><img src="/images/download_now.png" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/12/23/creating-a-sqlite-database-in-android/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Talking Twitter</title>
		<link>http://www.hdelossantos.com/2009/10/10/talking-twitter/</link>
		<comments>http://www.hdelossantos.com/2009/10/10/talking-twitter/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 05:58:43 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Computer Engineering]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Sample Work]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[c language]]></category>
		<category><![CDATA[code assignment]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[device programming]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[hanly de los santos]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[mobile device]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[product]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[register]]></category>
		<category><![CDATA[show]]></category>
		<category><![CDATA[speech recognition]]></category>
		<category><![CDATA[speech-to-text]]></category>
		<category><![CDATA[tea]]></category>
		<category><![CDATA[text-to-speech]]></category>
		<category><![CDATA[text2speech]]></category>
		<category><![CDATA[TTS library]]></category>
		<category><![CDATA[tv]]></category>
		<category><![CDATA[tweet]]></category>
		<category><![CDATA[tweets]]></category>
		<category><![CDATA[twitta]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=437</guid>
		<description><![CDATA[A week ago, for my mobile device programming class, I had to add text-to-speech and speech-to-text capabilities to a freely available Android program called Twitta. The features I added were very crudely superimposed on the Twitta interface, therefore this edit is by no means polished or intended for production usage. There are 3 button &#8220;S&#8221;, [...]]]></description>
			<content:encoded><![CDATA[<p>A week ago, for my mobile device programming class, I had to add text-to-speech and speech-to-text capabilities to a freely available Android program called <a href="http://code.google.com/p/twitta/">Twitta</a>. The features I added were very crudely superimposed on the Twitta interface, therefore this edit is by no means polished or intended for production usage.</p>
<p>There are 3 button &#8220;S&#8221;, &#8220;X&#8221;, and &#8220;R&#8221;. &#8220;S&#8221; starts the playback of all of the tweets which are currently displayed on the screen. Once the user scrolls down and new tweets appear on the screen the button can be pressed again and only the new ones will be read. &#8220;X&#8221; stops the playback of the messages. &#8220;R&#8221; prompts the user to speak their tweet. The google speech to text engine converts it to text and is displayed on the edit bar. If the message was wrong, pressing &#8220;R&#8221; again clears it and prompts for new speech. The message can also be edited with the keyboard. Below is a video of the application in action:</p>
<div align="center">
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/gnMUc1TuxpE&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/gnMUc1TuxpE&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></div>
<p><span id="more-437"></span></p>
<p>The source code is below. The sections edited by me are enclosed in comments.</p>
<pre class="brush: plain; title: ; notranslate">
/*
 * Copyright (C) 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dart.android.twitter;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.speech.*;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;

import com.dart.android.twitter.TwitterApi.ApiException;
import com.dart.android.twitter.TwitterApi.AuthException;
import com.google.android.photostream.UserTask;
import com.google.tts.TTS;
import com.google.tts.TTS.InitListener;

public class TwitterActivity extends BaseActivity implements InitListener{
  private static final String TAG = &quot;TwitterActivity&quot;;

  //BEGIN: Added by Hanly De Los Santos
  //Speech
  private static boolean ttsReady = false;
  private static TTS myTTS;
  private static ConcurrentLinkedQueue&lt;String&gt; tweetStrings;
  private Button speak;
  private Button stop;
  private Button reco;
  private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
  //END: Added by Hanly De Los Santos

  // Views.
  private ListView mTweetList;
  private TweetAdapter mTweetAdapter;

  private TweetEdit mTweetEdit;
  private ImageButton mSendButton;

  private TextView mProgressText;

  // State.
  private int mState;

  private static final int STATE_ALL = 0;
  private static final int STATE_REPLIES = 1;

  // Tasks.
  private UserTask&lt;Void, Void, RetrieveResult&gt; mRetrieveTask;
  private UserTask&lt;Void, Void, SendResult&gt; mSendTask;
  private UserTask&lt;Void, Void, RetrieveResult&gt; mFollowersRetrieveTask;

  // Refresh data at startup if last refresh was this long ago or greater.
  private static final long REFRESH_THRESHOLD = 5 * 60 * 1000;

  // Refresh followers if last refresh was this long ago or greater.
  private static final long FOLLOWERS_REFRESH_THRESHOLD = 12 * 60 * 60 * 1000;

  private static final String LAUNCH_ACTION = &quot;com.dart.android.twitter.TWEETS&quot;;
  private static final String NEW_TWEET_ACTION = &quot;com.dart.android.twitter.NEW&quot;;

  private static final String EXTRA_TEXT = &quot;text&quot;;

  public static Intent createIntent(Context context) {
    Intent intent = new Intent(LAUNCH_ACTION);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    return intent;
  }

  public static Intent createNewTaskIntent(Context context) {
    Intent intent = createIntent(context);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    return intent;
  }

  public static Intent createNewTweetIntent(String text) {
    Intent intent = new Intent(NEW_TWEET_ACTION);
    intent.putExtra(EXTRA_TEXT, text);

    return intent;
  }

  private boolean isReplies() {
    return mState == STATE_REPLIES;
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //BEGIN: Added by Hanly De Los Santos

    //Initialize TTS Service
    myTTS = new TTS(this, this, true);
    tweetStrings = new ConcurrentLinkedQueue&lt;String&gt;();

    //END: Added by Hanly De Los Santos

    if (!getApi().isLoggedIn()) {
      Log.i(TAG, &quot;Not logged in.&quot;);
      handleLoggedOut();
      return;
    }

    setContentView(R.layout.main);

    Intent intent = getIntent();
    String action = intent.getAction();

    mState = mPreferences.getInt(
        Preferences.TWITTER_ACTIVITY_STATE_KEY, STATE_ALL);

    mTweetList = (ListView) findViewById(R.id.tweet_list);

    mTweetEdit = new TweetEdit((EditText) findViewById(R.id.tweet_edit),
        (TextView) findViewById(R.id.chars_text));
    mTweetEdit.setOnKeyListener(tweetEnterHandler);

    if (NEW_TWEET_ACTION.equals(action)) {
      mTweetEdit.setText(intent.getStringExtra(EXTRA_TEXT));
    }

    mProgressText = (TextView) findViewById(R.id.progress_text);

    mSendButton = (ImageButton) findViewById(R.id.send_button);
    mSendButton.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        doSend();
      }
    });

    //BEGIN: Added by Hanly De Los Santos
    // Speak Button
    this.speak = (Button)this.findViewById(R.id.Speak);
    this.speak.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View v) {
			if(tweetStrings != null){
				new Thread(new Runnable(){
	        		public void run(){
		        		try{
		        			Speak startSpeak = new Speak();
		        	        while(!myTTS.isSpeaking()){
		        	        	for(int i=0; i&lt;tweetStrings.size(); i++){
		        	        		String speak = (String)tweetStrings.poll();
		        		        	startSpeak.speak(ttsReady, myTTS, speak);
		        		        	final String TAG = &quot;Hanly-Pop Out&quot;;
		        		            Log.v(TAG, speak);
		        		        }
		        	        }
		        		}
		        		catch(Exception e){}
	        		}
	        	}).start();
		    }
		}
    });

    this.stop = (Button)this.findViewById(R.id.Stop);
    this.stop.setOnClickListener(new OnClickListener() {

    	@Override
		public void onClick(View v) {
			Speak startSpeak = new Speak();
			startSpeak.stop(ttsReady, myTTS);
		}
    });

    //Start of speech recognition code
    this.reco = (Button)this.findViewById(R.id.Reco);
    this.reco.setOnClickListener(new OnClickListener(){

    	@Override
		public void onClick(View v) {
    		startVoiceRecognitionActivity();
		}
    });
    //END: Added by Hanly De Los Santos

    // Mark all as read.
    getDb().markAllTweetsRead();

    setupState();

    registerForContextMenu(mTweetList);

    boolean shouldRetrieve = false;

    long lastRefreshTime = mPreferences.getLong(
        Preferences.LAST_TWEET_REFRESH_KEY, 0);
    long nowTime = Utils.getNowTime();

    long diff = nowTime - lastRefreshTime;
    Log.i(TAG, &quot;Last refresh was &quot; + diff + &quot; ms ago.&quot;);

    if (diff &gt; REFRESH_THRESHOLD) {
      shouldRetrieve = true;
    } else if (Utils.isTrue(savedInstanceState, SIS_RUNNING_KEY)) {
      // Check to see if it was running a send or retrieve task.
      // It makes no sense to resend the send request (don't want dupes)
      // so we instead retrieve (refresh) to see if the message has posted.
      Log.i(TAG, &quot;Was last running a retrieve or send task. Let's refresh.&quot;);
      shouldRetrieve = true;
    }

    if (shouldRetrieve) {
      doRetrieve();
    }

    long lastFollowersRefreshTime = mPreferences.getLong(
        Preferences.LAST_FOLLOWERS_REFRESH_KEY, 0);

    diff = nowTime - lastFollowersRefreshTime;
    Log.i(TAG, &quot;Last followers refresh was &quot; + diff + &quot; ms ago.&quot;); 

    if (diff &gt; FOLLOWERS_REFRESH_THRESHOLD) {
      doRetrieveFollowers();
    }
  }

//BEGIN: Added by Hanly De Los Santos
  private void startVoiceRecognitionActivity() {
	  mTweetEdit.setText(&quot;&quot;);
	  Intent intent = new Intent(&quot;android.speech.action.RECOGNIZE_SPEECH&quot;);
	  startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == VOICE_RECOGNITION_REQUEST_CODE &amp;&amp; resultCode == RESULT_OK) {
          // Fill the list view with the strings the recognizer thought it could have heard
          ArrayList&lt;String&gt; matches = data.getStringArrayListExtra(
                  RecognizerIntent.EXTRA_RESULTS);
          try{
        	  Thread.currentThread().sleep(1000);//sleep for 1000 ms
        	}
        	catch(Exception ie){
        	//If this thread was interrupted by another thread
        	}
    	  Speak startSpeak = new Speak();
          String speak = &quot;Did you say &quot;+matches.toString();
          startSpeak.speak(ttsReady, myTTS, speak);
          mTweetEdit.setTextAndFocus(matches.toString().replaceAll(&quot;[\\]\\[]&quot;, &quot;&quot;));
          final String TAG = &quot;Hanly-Speak Result&quot;;
          Log.v(TAG, matches.toString());
      }

      super.onActivityResult(requestCode, resultCode, data);
  }
	//END: Added by Hanly De Los Santos
  @Override
  protected void onResume() {
    super.onResume();

    if (!getApi().isLoggedIn()) {
      Log.i(TAG, &quot;Not logged in.&quot;);
      handleLoggedOut();
      return;
    }
  }

  private void doRetrieveFollowers() {
    Log.i(TAG, &quot;Attempting followers retrieve.&quot;);

    if (mFollowersRetrieveTask != null
        &amp;&amp; mFollowersRetrieveTask.getStatus() == UserTask.Status.RUNNING) {
      Log.w(TAG, &quot;Already retrieving.&quot;);
    } else {
      mFollowersRetrieveTask = new FollowersTask().execute();
    }
  }

  private static final String SIS_RUNNING_KEY = &quot;running&quot;;

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    if (mRetrieveTask != null
        &amp;&amp; mRetrieveTask.getStatus() == UserTask.Status.RUNNING) {
      outState.putBoolean(SIS_RUNNING_KEY, true);
    } else if (mSendTask != null
        &amp;&amp; mSendTask.getStatus() == UserTask.Status.RUNNING) {
      outState.putBoolean(SIS_RUNNING_KEY, true);
    }
  }

  @Override
  protected void onRestoreInstanceState(Bundle bundle) {
    super.onRestoreInstanceState(bundle);

    mTweetEdit.updateCharsRemain();
  }

  @Override
  protected void onDestroy() {
    Log.i(TAG, &quot;onDestroy.&quot;);

    if (mSendTask != null &amp;&amp; mSendTask.getStatus() == UserTask.Status.RUNNING) {
      // Doesn't really cancel execution (we let it continue running).
      // See the SendTask code for more details.
      mSendTask.cancel(true);
    }

    if (mRetrieveTask != null
        &amp;&amp; mRetrieveTask.getStatus() == UserTask.Status.RUNNING) {
      mRetrieveTask.cancel(true);
    }

    // Don't need to cancel FollowersTask (assuming it ends properly).

    super.onDestroy();
  }

  // UI helpers.

  private void updateProgress(String progress) {
    mProgressText.setText(progress);
  }

  private void setupState() {
    Cursor cursor;

    if (isReplies()) {
      cursor = getDb().fetchReplies();
      setTitle(&quot;@&quot; + getApi().getUsername());
    } else {
      cursor = getDb().fetchAllTweets();
      setTitle(R.string.app_name);
    }

    startManagingCursor(cursor);

    mTweetAdapter = new TweetAdapter(this, cursor);
    mTweetList.setAdapter(mTweetAdapter);
  }

  private static final int CONTEXT_MORE_ID = 3;
  private static final int CONTEXT_REPLY_ID = 0;
  private static final int CONTEXT_RETWEET_ID = 1;
  private static final int CONTEXT_DM_ID = 2;

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
    Cursor cursor = (Cursor) mTweetAdapter.getItem(info.position);
    long userId = cursor.getLong(cursor
        .getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER_ID));
    String user = cursor.getString(cursor
        .getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER));

    menu.add(0, CONTEXT_MORE_ID, 0, user);
    menu.add(0, CONTEXT_REPLY_ID, 0, R.string.reply);
    menu.add(0, CONTEXT_RETWEET_ID, 0, R.string.retweet);

    MenuItem item = menu.add(0, CONTEXT_DM_ID, 0, R.string.dm);
    item.setEnabled(getDb().isFollower(userId));
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    Cursor cursor = (Cursor) mTweetAdapter.getItem(info.position);

    if (cursor == null) {
      Log.w(TAG, &quot;Selected item not available.&quot;);
      return super.onContextItemSelected(item);
    }

    switch (item.getItemId()) {
    case CONTEXT_MORE_ID:
      String who = cursor.getString(
          cursor.getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER));
      launchActivity(UserActivity.createIntent(who));

      return true;
    case CONTEXT_REPLY_ID:
      int userIndex = cursor.getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER);
      // TODO: this isn't quite perfect. It leaves extra empty spaces if you
      // perform the reply action again.
      String replyTo = &quot;@&quot; + cursor.getString(userIndex);
      String text = mTweetEdit.getText();
      text = replyTo + &quot; &quot; + text.replace(replyTo, &quot;&quot;);
      mTweetEdit.setTextAndFocus(text);

      return true;
    case CONTEXT_RETWEET_ID:
      String retweet = &quot;RT @&quot;
          + cursor.getString(cursor
              .getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER))
          + &quot; &quot;
          + cursor.getString(cursor
              .getColumnIndexOrThrow(TwitterDbAdapter.KEY_TEXT));
      mTweetEdit.setTextAndFocus(retweet);

      return true;
    case CONTEXT_DM_ID:
      String user = cursor.getString(cursor
          .getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER));
      launchActivity(DmActivity.createIntent(user));
      return true;
    default:
      return super.onContextItemSelected(item);
    }
  }

  private static class TweetAdapter extends CursorAdapter {

    public TweetAdapter(Context context, Cursor cursor) {
      super(context, cursor);

      mInflater = LayoutInflater.from(context);

      mUserTextColumn = cursor.getColumnIndexOrThrow(TwitterDbAdapter.KEY_USER);
      mTextColumn = cursor.getColumnIndexOrThrow(TwitterDbAdapter.KEY_TEXT);
      mProfileImageUrlColumn = cursor
          .getColumnIndexOrThrow(TwitterDbAdapter.KEY_PROFILE_IMAGE_URL);
      mCreatedAtColumn = cursor
          .getColumnIndexOrThrow(TwitterDbAdapter.KEY_CREATED_AT);
      mSourceColumn = cursor.getColumnIndexOrThrow(TwitterDbAdapter.KEY_SOURCE);

      mMetaBuilder = new StringBuilder();
    }

    private LayoutInflater mInflater;

    private int mUserTextColumn;
    private int mTextColumn;
    private int mProfileImageUrlColumn;
    private int mCreatedAtColumn;
    private int mSourceColumn;

    private StringBuilder mMetaBuilder;

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      View view = mInflater.inflate(R.layout.tweet, parent, false);

      ViewHolder holder = new ViewHolder();
      holder.tweetUserText = (TextView) view.findViewById(R.id.tweet_user_text);
      holder.tweetText = (TextView) view.findViewById(R.id.tweet_text);
      holder.profileImage = (ImageView) view.findViewById(R.id.profile_image);
      holder.metaText = (TextView) view.findViewById(R.id.tweet_meta_text);
      view.setTag(holder);

      return view;
    }

    private static class ViewHolder {
      public TextView tweetUserText;
      public TextView tweetText;
      public ImageView profileImage;
      public TextView metaText;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
      ViewHolder holder = (ViewHolder) view.getTag();

      holder.tweetUserText.setText(cursor.getString(mUserTextColumn));
      Utils.setTweetText(holder.tweetText, cursor.getString(mTextColumn));

    //BEGIN: Added by Hanly De Los Santos
      String say = cursor.getString(mUserTextColumn)+&quot; said &quot;+cursor.getString(mTextColumn);

      while(!tweetStrings.contains(say))
    	  tweetStrings.add(say); 

    // END: Added by Hanly De Los Santos

      String profileImageUrl = cursor.getString(mProfileImageUrlColumn);

      if (!Utils.isEmpty(profileImageUrl)) {
        holder.profileImage.setImageBitmap(TwitterApplication.mImageManager.get(
            profileImageUrl));
      }

      try {
        Date createdAt = TwitterDbAdapter.DB_DATE_FORMATTER.parse(cursor
            .getString(mCreatedAtColumn));
        holder.metaText.setText(Tweet.buildMetaText(mMetaBuilder, createdAt,
            cursor.getString(mSourceColumn)));
      } catch (ParseException e) {
        Log.w(TAG, &quot;Invalid created at data.&quot;);
      }
    }

    public void refresh() {
      getCursor().requery();
    }

  }

  private void draw() {
    mTweetAdapter.refresh();
  }

  private void goTop() {
    mTweetList.setSelection(0);
  }

  private void enableEntry() {
    mTweetEdit.setEnabled(true);
    mSendButton.setEnabled(true);
  }

  private void disableEntry() {
    mTweetEdit.setEnabled(false);
    mSendButton.setEnabled(false);
  }

  // Actions.

  private void doSend() {
    if (mSendTask != null &amp;&amp; mSendTask.getStatus() == UserTask.Status.RUNNING) {
      Log.w(TAG, &quot;Already sending.&quot;);
    } else {
      String status = mTweetEdit.getText().toString();

      if (!Utils.isEmpty(status)) {
        mSendTask = new SendTask().execute();
      }
    }
  }

  private enum SendResult {
    OK, IO_ERROR, AUTH_ERROR, CANCELLED
  }

  private class SendTask extends UserTask&lt;Void, Void, SendResult&gt; {
    @Override
    public void onPreExecute() {
      onSendBegin();
    }

    @Override
    public SendResult doInBackground(Void... params) {
      try {
        String status = mTweetEdit.getText().toString();
        JSONObject jsonObject = getApi().update(status);
        Tweet tweet = Tweet.create(jsonObject);

        if (!Utils.isEmpty(tweet.profileImageUrl)) {
          // Fetch image to cache.
          try {
            getImageManager().put(tweet.profileImageUrl);
          } catch (IOException e) {
            Log.e(TAG, e.getMessage(), e);
          }
        }

        getDb().createTweet(tweet, false);
      } catch (IOException e) {
        Log.e(TAG, e.getMessage(), e);
        return SendResult.IO_ERROR;
      } catch (AuthException e) {
        Log.i(TAG, &quot;Invalid authorization.&quot;);
        return SendResult.AUTH_ERROR;
      } catch (JSONException e) {
        Log.w(TAG, &quot;Could not parse JSON after sending update.&quot;);
        return SendResult.IO_ERROR;
      } catch (ApiException e) {
        Log.e(TAG, e.getMessage(), e);
        return SendResult.IO_ERROR;
      }

      return SendResult.OK;
    }

    @Override
    public void onPostExecute(SendResult result) {
      if (isCancelled()) {
        // Canceled doesn't really mean &quot;canceled&quot; in this task.
        // We want the request to complete, but don't want to update the
        // activity (it's probably dead).
        return;
      }

      if (result == SendResult.AUTH_ERROR) {
        logout();
      } else if (result == SendResult.OK) {
        onSendSuccess();
      } else if (result == SendResult.IO_ERROR) {
        onSendFailure();
      }
    }
  }

  private void onSendBegin() {
    disableEntry();
    updateProgress(&quot;Updating status...&quot;);
  }

  private void onSendSuccess() {
    mTweetEdit.setText(&quot;&quot;);
    updateProgress(&quot;&quot;);
    enableEntry();
    draw();
    goTop();
  }

  private void onSendFailure() {
    updateProgress(&quot;Unable to update status&quot;);
    enableEntry();
  }

  private void doRetrieve() {
    Log.i(TAG, &quot;Attempting retrieve.&quot;);

    if (mRetrieveTask != null
        &amp;&amp; mRetrieveTask.getStatus() == UserTask.Status.RUNNING) {
      Log.w(TAG, &quot;Already retrieving.&quot;);
    } else {
      mRetrieveTask = new RetrieveTask().execute();
    }
  }

  private void onRetrieveBegin() {
    updateProgress(&quot;Refreshing...&quot;);
  }

  private enum RetrieveResult {
    OK, IO_ERROR, AUTH_ERROR, CANCELLED
  }

  private class RetrieveTask extends UserTask&lt;Void, Void, RetrieveResult&gt; {
    @Override
    public void onPreExecute() {
      onRetrieveBegin();
    }

    @Override
    public void onProgressUpdate(Void... progress) {
      draw();
    }

    @Override
    public RetrieveResult doInBackground(Void... params) {
      JSONArray jsonArray;

      long maxId = getDb().fetchMaxId();

      try {
        jsonArray = getApi().getTimelineSinceId(maxId);
      } catch (IOException e) {
        Log.e(TAG, e.getMessage(), e);
        return RetrieveResult.IO_ERROR;
      } catch (AuthException e) {
        Log.i(TAG, &quot;Invalid authorization.&quot;);
        return RetrieveResult.AUTH_ERROR;
      } catch (ApiException e) {
        Log.e(TAG, e.getMessage(), e);
        return RetrieveResult.IO_ERROR;
      }

      ArrayList&lt;Tweet&gt; tweets = new ArrayList&lt;Tweet&gt;();
      HashSet&lt;String&gt; imageUrls = new HashSet&lt;String&gt;();

      for (int i = 0; i &lt; jsonArray.length(); ++i) {
        if (isCancelled()) {
          return RetrieveResult.CANCELLED;
        }

        Tweet tweet;

        try {
          JSONObject jsonObject = jsonArray.getJSONObject(i);
          tweet = Tweet.create(jsonObject);
          tweets.add(tweet);
        } catch (JSONException e) {
          Log.e(TAG, e.getMessage(), e);
          return RetrieveResult.IO_ERROR;
        }

        imageUrls.add(tweet.profileImageUrl);

        if (isCancelled()) {
          return RetrieveResult.CANCELLED;
        }
      }

      getDb().addTweets(tweets, false);

      if (isCancelled()) {
        return RetrieveResult.CANCELLED;
      }

      publishProgress();

      for (String imageUrl : imageUrls) {
        if (!Utils.isEmpty(imageUrl)) {
          // Fetch image to cache.
          try {
            getImageManager().put(imageUrl);
          } catch (IOException e) {
            Log.e(TAG, e.getMessage(), e);
          }
        }

        if (isCancelled()) {
          return RetrieveResult.CANCELLED;
        }
      }

      return RetrieveResult.OK;
    }

    @Override
    public void onPostExecute(RetrieveResult result) {
      if (result == RetrieveResult.AUTH_ERROR) {
        logout();
      } else if (result == RetrieveResult.OK) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putLong(Preferences.LAST_TWEET_REFRESH_KEY, Utils.getNowTime());
        editor.commit();
        draw();
        goTop();
      } else {
        // Do nothing.
      }

      updateProgress(&quot;&quot;);
    }
  }

  private class FollowersTask extends UserTask&lt;Void, Void, RetrieveResult&gt; {
    @Override
    public RetrieveResult doInBackground(Void... params) {
      try {
        ArrayList&lt;Long&gt; followers = getApi().getFollowersIds();
        getDb().syncFollowers(followers);
      } catch (IOException e) {
        Log.e(TAG, e.getMessage(), e);
        return RetrieveResult.IO_ERROR;
      } catch (AuthException e) {
        Log.i(TAG, &quot;Invalid authorization.&quot;);
        return RetrieveResult.AUTH_ERROR;
      } catch (ApiException e) {
        Log.e(TAG, e.getMessage(), e);
        return RetrieveResult.IO_ERROR;
      }

      return RetrieveResult.OK;
    }

    @Override
    public void onPostExecute(RetrieveResult result) {
      if (result == RetrieveResult.OK) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putLong(Preferences.LAST_FOLLOWERS_REFRESH_KEY, Utils
            .getNowTime());
        editor.commit();
      } else {
        // Do nothing.
      }
    }
  }

  // Menu.

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuItem item = menu.add(0, OPTIONS_MENU_ID_REFRESH, 0, R.string.refresh);
    item.setIcon(R.drawable.refresh);

    item = menu.add(0, OPTIONS_MENU_ID_DM, 0, R.string.dm);
    item.setIcon(android.R.drawable.ic_menu_send);

    /*
    item = menu.add(0, OPTIONS_MENU_ID_TOGGLE_REPLIES, 0,
        R.string.show_at_replies);
    item.setIcon(android.R.drawable.ic_menu_zoom);
    */

    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    /*
    MenuItem item = menu.findItem(OPTIONS_MENU_ID_TOGGLE_REPLIES);

    if (isReplies()) {
      item.setIcon(R.drawable.ic_menu_zoom_out);
      item.setTitle(R.string.show_all);
    } else {
      item.setIcon(android.R.drawable.ic_menu_zoom);
      item.setTitle(R.string.show_at_replies);
    }
    */

    return super.onPrepareOptionsMenu(menu);
  }

  public void toggleShowReplies() {
    mState = mState == STATE_REPLIES ? STATE_ALL : STATE_REPLIES;

    SharedPreferences.Editor editor = mPreferences.edit();
    editor.putInt(Preferences.TWITTER_ACTIVITY_STATE_KEY, mState);
    editor.commit();

    setupState();
  }

  private static final String INTENT_MODE = &quot;mode&quot;;
  private static final int MODE_REPLIES = 1;

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case OPTIONS_MENU_ID_REFRESH:
      doRetrieve();
      return true;
    case OPTIONS_MENU_ID_REPLIES:
      Intent repliesIntent = new Intent(this, TwitterActivity.class);
      repliesIntent.putExtra(INTENT_MODE, MODE_REPLIES);
      startActivity(repliesIntent);
      return true;
    case OPTIONS_MENU_ID_DM:
      launchActivity(DmActivity.createIntent());
      return true;
    case OPTIONS_MENU_ID_TOGGLE_REPLIES:
      toggleShowReplies();
      return true;
    }

    return super.onOptionsItemSelected(item);
  }

  // Various handlers.

  private View.OnKeyListener tweetEnterHandler = new View.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_ENTER
          || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
        if (event.getAction() == KeyEvent.ACTION_UP) {
          doSend();
        }
        return true;
      }
      return false;
    }
  };

	@Override
	public void onInit(int arg0) {
		ttsReady = true;
	}
}
</pre>
<p>Below is the Speak class which simply takes in a string of text and utilizing the Text-to-Speech synthesizes it.</p>
<pre class="brush: plain; title: ; notranslate">
package com.dart.android.twitter;

import com.google.tts.TTS;

public class Speak {

	public void speak(boolean ttsReady, TTS myTTS, String textToSpeak){
		if (ttsReady) {
			// This param does only work on pre-recorded voice and has no
			// effect on this speak.
			String[] params = { &quot;VOICE_FEMALE&quot; };
			// Speaks the text
			myTTS.speak(textToSpeak, 1, params);
		} 

		else {
			// Notifys the user if the TTS service is not ready or installed
//			Toast.makeText(this, &quot;TTS is not ready or  installed&quot;,
//					Toast.LENGTH_LONG).show();
		}
	}

	public void stop(boolean ttsReady, TTS myTTS){
		myTTS.stop();
	}

}
</pre>
<p>If you want to try the working copy you can download it by clicking the link below.</p>
<p><a href="/school_content/bin/TwitterActivity.apk"><img src="/images/download_now.png"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/10/10/talking-twitter/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Powers of base 2 between 2 values using array in MIPS</title>
		<link>http://www.hdelossantos.com/2009/03/15/powers-of-base-2-between-2-values-using-array-in-mips/</link>
		<comments>http://www.hdelossantos.com/2009/03/15/powers-of-base-2-between-2-values-using-array-in-mips/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 04:46:11 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[code assignment]]></category>
		<category><![CDATA[hanly de los santos]]></category>
		<category><![CDATA[hdelossantos]]></category>
		<category><![CDATA[hdelossantos.com]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[mips]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[register]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=349</guid>
		<description><![CDATA[Program requests and reads in exactly one character, which represents an exponent. If the value is acceptable, then the program reads in another value. The program calculates the base 2 power between the user input values, and then stores the calculated values in an array. It then prints the values in the array.]]></description>
			<content:encoded><![CDATA[<p>Program requests and reads in exactly one character, which represents an exponent. If the value is acceptable, then the program reads in another value. The program calculates the base 2 power between the user input values, and then stores the calculated values in an array. It then prints the values in the array.</p>
<p></p>
<pre class="brush: plain; title: ; notranslate">
# Assignment 3: Powers of 2 Assembly utilizing Array
# by Hanly De Los Santos
# Copyright ©2009, Hanly De Los Santos. All Rights Reserved.
# http://www.hdelossantos.com
#
# Program requests and reads in exactly one character,
# which represents an exponent. If the value is acceptable, then the
# program reads in another value. The program calculates
# the base 2 power between the user input values, and then
# stores the calculated values in an array. It then prints the
# values in the array.
#
		.text
		.globl __start 

# Load acceptable ascii decimal value for number ranges
# since input is read in as a character.
__start: 	li	$8, 48		# This is the decimal equivalent of 0
		li	$9, 57		# This is the decimal equivalent of 9

# Prompt the user for input.
		la	$11, prompt
		puts	$11

# Grab user input and store value in register 10
		getc	$10
		la	$11, newline	# Create new line
		lb	$17, ($11)
		putc	$17
		add	$15, $10, 0	# Make copy of contents of r10 in r15.
		sub	$15, $15, 48	# Convert char from first input to int.

# Test to determine whether or not the user input value is acceptable.
# If user input is less than 48 and greater than 57, branches to
# exit_donothing, where the user is told the input is wrong.
		bgt	$10, $9, exit_donothing
		blt	$10, $8, exit_donothing
		sub	$10, $10, 48	# After check, convert char to int.

# Prompt user for additional input
		la	$11, prompt2
		puts	$11

# Grab user input and store in r12
		getc	$12
		la	$11, newline	# Create new line
		lb	$17, ($11)
		putc	$17
		add	$18, $10, 0	# Make copy of contents of r12 in r18.
		sub	$18, $18, 48	# Convert char to int.

# Test to determine whether or not the user input value is acceptable.
# If user input is less than 48 and greater than 57, branches to
# exit_donothing, where the user is told the input is wrong.
		bgt	$12, $9, exit_donothing
		blt	$12, $8, exit_donothing
		sub	$12, $12, 48	# After check, convert char to int.

# Determine if the difference between the two user input values is 0
		bnez	$10, neqz
		beqz	$12, special_zero

# Determine difference between 2 values
neqz:		sub	$21, $12, $10	#Store diff of the two values in r21
		bltz	$21, exit_printgtr
		add	$21, $21, 1

# If the value was acceptable, proceed to calculate the power.
		li	$11, 2		# Load multiplier value into $11.
		li	$17, 2		# Initialize 17 to multiplier value

# Check to see if the second usr input is &gt; 1, if it is modify r10 so that
# the calculations can be made properly. This sets r10 = 2. If the second
# input is == 1, then print the results. Must also load 2 into 2nd array
# location here in case the seond input is 1.
		la	$16, powers
		li	$22, 1
		mult	$11, $22
		mflo	$11
		sw	$11, 4($16)
		li	$23, 1
		beq	$23, $12, print_result
		bgt	$10, $23, cont_gtn
		li	$10, 2

# Multiplication loop. While $10 != 0 keep multiplying $17 by 2, and
# decrement $10 by 1 every time this is done. Once $10 == 0, store
# the result.
cont_gtn:	sub	$10, $10, 1	# Since 2^1 has been taken care of
		add	$14, $10, 0
		add	$24, $10, 0
		add	$24, $24, 1

multiply_for:	mult	$17, $11	# Loop to determine the power val
		mflo	$17
		sub	$10, $10, 1
		bnez	$10, multiply_for

# The result is stored in the location of the user input * 4, which would
# give the matching address location on the array. This loops to
# multiply_for while the $10 is != $12.
nextval:	add	$10, $14, 0	# Restores r10 from copy
		mul	$14, $24, 4	# Calculation to determine the
		add	$23, $16, $14	#  location in which to place the
		sw	$17, ($23)	#  resulting power in the array.
		add	$10, $10, 1	# Increment the counters for next
		add	$24, $24, 1	#  iteration.
		add	$14, $10, 0
		li	$17, 2		# restore the multiplier value
		blt	$10, $12, multiply_for
		beq	$10, $12, print_result

# Display the value of the exponential function. This loops through the
# values in the array starting at the first user input until the
# difference between the first and last user input is 0.
print_result:	la	$14, str3
		puts	$14		# Print out &quot;2^&quot;
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		la	$20, powers	# Calculation to determine the
		mul	$19, $15, 4	#  location of the power value.
		add	$23, $20, $19
		lw	$17, ($23)
		move	$a0, $17
		syscall			# Print out result.
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		sub	$21, $21, 1
		add	$15, $15, 1
		bnez	$21, print_result
		b	endofline

# Print out the result for 2 to the power of 0 if teh two user
# inputs are 0 (special case).
special_zero:	la	$14, str3
		puts	$14		# Print out &quot;2^&quot;
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		la	$20, powers
		lw	$17, ($20)	# Print first value of array.
		move	$a0, $17
		syscall
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		b	endofline

# If second input is less than or not equal to first input, print mbgtrthan.
exit_printgtr:	la	$13, mbgtrthan
		puts	$13

# If the input is not appropriate, print str2 and exit.
exit_donothing:	la	$13, str2
		puts	$13
		b	endofline

# This is the exit statement.
endofline:	done		# END OF PROGRAM

# Define strings which will be used throughout program
		.data
prompt:		.asciiz &quot;Enter a digit '0'-'9': &quot;
prompt2:	.asciiz &quot;Enter another digit '0'-'9': &quot;
mbgtrthan:	.asciiz &quot;Second digit must be greater than or equal to the first digit.\n&quot;
str2:		.asciiz &quot;Bad user input.  Quitting.\n&quot;
str3:		.asciiz &quot;2^&quot;
str4:		.asciiz &quot; = &quot;
newline:  	.byte  '\n'
		.align 4
powers:		.word	1:10		# Create a 10-element int array.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/03/15/powers-of-base-2-between-2-values-using-array-in-mips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powers of base 2 in MIPS</title>
		<link>http://www.hdelossantos.com/2009/03/01/powers-of-base-2-in-mips/</link>
		<comments>http://www.hdelossantos.com/2009/03/01/powers-of-base-2-in-mips/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 04:36:25 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[code assignment]]></category>
		<category><![CDATA[hanly de los santos]]></category>
		<category><![CDATA[hdelossantos]]></category>
		<category><![CDATA[hdelossantos.com]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[mips]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[register]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=341</guid>
		<description><![CDATA[Program requests and reads in exactly one character, which represents an exponent. The program calculates the base 2 power, and then prints the calculated value.]]></description>
			<content:encoded><![CDATA[<p>Program requests and reads in exactly one character, which represents an exponent. The program calculates the base 2 power, and then prints the calculated value.</p>
<p></p>
<pre class="brush: plain; title: ; notranslate">
# Assignment 2: Powers of 2 Assembly
# by Hanly De Los Santos
# Copyright ©2009, Hanly De Los Santos. All Rights Reserved.
# http://www.hdelossantos.com
#
# Program requests and reads in exactly one character,
# which represents an exponent. The program calculates
# the base 2 power, and then prints the calculated value.
#
		.text
		.globl __start 

# Load acceptable ascii decimal value for number ranges
# since input is read in as a character.
__start: 	li	$8, 48		# This is the decimal equivalent of 0
		li	$9, 57		# This is the decimal equivalent of 9

# Prompt the user for input.
		la	$11, prompt
		puts	$11

# Grab user input and store value in register 10
		getc	$10
		la	$11, newline	# Create new line
		lb	$17, ($11)
		putc	$17
		add	$15, $10, 0	# Make copy of contents of r10 in r15.
		sub	$15, $15, 48	# Convert char to int.

# Test to determine whether or not the user input value is acceptable.
# If user input is less than 48 and greater than 57, branches to
# exit_donothing, where the user is told the input is wrong.
		bgt	$10, $9, exit_donothing
		blt	$10, $8, exit_donothing
		sub	$10, $10, 48	# After check, convert char to int.

# If the value was acceptable, proceed to calculate the power.
# Checks to determine if $10 is 0 or 1 since they are special cases.
# If value is 0 or 1, branches to their respective prints.
		li	$11, 2		# Load multiplier value into $11.
		beqz	$10, result_zero
		li	$17, 1
		beq	$10, $17, result1
		li	$17, 2		# Initialize 17 to multiplier value
		sub	$10, $10, 1	# Since 2^1 has been taken care of

# Multiplication loop. While $10 != 0 keep multiplying $17 by 2, and
# decrement $10 by 1 every time this is done. Once $10 == 0, print_result.
multiply_for:	mult	$17, $11
		mflo	$17
		sub	$10, $10, 1
		bnez	$10, multiply_for
		beqz	$10, print_result

# Display the value of the exponential function.
print_result:	la	$14, str3
		puts	$14		# Print out &quot;2^&quot;
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		move	$a0, $17
		syscall			# Print out result.
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		b	endofline

# Print out the result for 2 to the power of 0 (special case).
result_zero:	la	$14, str3
		puts	$14		# Print out &quot;2^&quot;
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		li	$a0, 1
		syscall
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		b	endofline

# Print the result for 2 to the power of 1 (special case).
result1:	la	$14, str3
		puts	$14		# Print out &quot;2^&quot;
		li	$v0, 1
		move	$a0, $15
		syscall			# Print out value of user input.
		la	$16, str4
		puts	$16		# Print out '='
		li	$v0, 1
		li	$a0, 2
		syscall
		la	$13, newline	# Create new line
		lb	$12, ($13)
		putc	$12
		b	endofline

# If the input is not appropriate, print str2 and exit.
exit_donothing:	la	$13, str2
		puts	$13
		b	endofline

# This is the exit statement.
endofline:	done		# END OF PROGRAM

# Define strings which will be used throughout program
		.data
prompt:		.asciiz &quot;Enter a digit '0'-'9': &quot;
str2:		.asciiz &quot;Bad user input.  Quitting.\n&quot;
str3:		.asciiz &quot;2^&quot;
str4:		.asciiz &quot; = &quot;
newline:  	.byte  '\n'
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/03/01/powers-of-base-2-in-mips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powers of base 2 in C</title>
		<link>http://www.hdelossantos.com/2009/02/21/powers-of-base-2-in-c/</link>
		<comments>http://www.hdelossantos.com/2009/02/21/powers-of-base-2-in-c/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 04:26:33 +0000</pubDate>
		<dc:creator>Hanly</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[c language]]></category>
		<category><![CDATA[code assignment]]></category>
		<category><![CDATA[hanly de los santos]]></category>
		<category><![CDATA[hdelossantos]]></category>
		<category><![CDATA[hdelossantos.com]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[mips]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tea]]></category>

		<guid isPermaLink="false">http://www.hdelossantos.com/?p=334</guid>
		<description><![CDATA[This program takes a user input from 1 through 512 (inclusive), and calculates all powers of two that are less than or equal to the value. The program prints out all of these values. NOTE: Due to my usage of the math library&#8217;s log function, it is necessary to compile using -lm under Unix systems [...]]]></description>
			<content:encoded><![CDATA[<p>This program takes a user input from 1 through 512 (inclusive), and calculates all powers of two that are less than or equal to the value. The program prints out all of these values. </p>
<p><span style="color: #ff0000;">NOTE: Due to my usage of the math library&#8217;s log function, it is necessary to compile using -lm under Unix systems for the linker to properly define the log function. Information referenced from: <a href="http://c-faq.com/fp/libm.html">http://c-faq.com/fp/libm.html</a></span></p>
<p></p>
<pre class="brush: cpp; title: ; notranslate">
/* Assignment1: Powers of 2
 * by Hanly De Los Santos
 * Copyright ©2009, Hanly De Los Santos. All Rights Reserved.
 * http://www.hdelossantos.com
 *
 * This program takes a user input from 1
 * through 512 (inclusive), and calculates all powers of
 * two that are less than or equal to the value. The
 * program prints out all of these values.
 *
 * NOTE: Due to my usage of the math library's log function,
 * it is necessary to compile using -lm under Unix systems
 * for the linker to properly define the log function.
 * Information referenced from: http://c-faq.com/fp/libm.html
 */

/* Load standard I/O library */
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;math.h&amp;gt;

/* Define macro */
#define ARRAYSIZE 10

/* Declare function prototypes to define the output of the
 * following functions.
 */
void printPowers(int ar[], int firstindex, int lastindex);
void setPowers(int userinteger, int ar[], int lastindex);

main(int argc, char *argv[]){
	int powers[ARRAYSIZE];

	/* This determines whether there are 2 arguments in the command
	 * line input. If there are less than 2 arguments, then a message
	 * is printed prompting the user to enter a positive integer value.
	 */
	if( argc &amp;lt; 2)
		printf(&amp;quot;Invalid command line. Positive integer value required.\n&amp;quot;);

	/* If there are 2 variables, then the second variable is tested
	 * for the required integer values.
	 */
	else{
		int usrval = atoi(argv[1]);

		/* If the user input value is within the accepted range
		 * 1-512, then the operation is done with the user value.
		 */
		if( usrval &amp;gt;= 1 &amp;amp;&amp;amp; usrval &amp;lt;= 512 ){
			int maxexp = ((log(usrval))/log(2));
			setPowers( usrval, powers, maxexp);
			printf(&amp;quot;Powers of 2 that are less than or equal to %d are:\n&amp;quot;, usrval);
			printPowers(powers, 0, maxexp);
		}

		/* If the value is greater than 512, the operation is done with the
		 * maximum value of 512
		 */
		else if ( usrval &amp;gt; 512 ){
			printf(&amp;quot;Powers of 2 that are less than or equal to 512 are:\n&amp;quot;, usrval);
			setPowers( 512, powers, 9);
			printPowers(powers, 0, 9);
			printf(&amp;quot;argc is equal to: %d&amp;quot;, argc);
		}

		/* If a character/negative number is entered instead of an integer, the user is
		 * prompted that a positive integer is required to complete the
		 * operation.
		 */
		else if ( !isdigit(usrval) || usrval &amp;lt;= 0 ){
			printf(&amp;quot;Invalid command line. Positive integer value required.\n&amp;quot;);
			printf(&amp;quot;argc is equal to: %d&amp;quot;, argc);
		}
	}

	return 0;
}

/* This function sets the array's values; only the array elements
 * whose values are less than or equal to the userinteger are set.
 * It calls function power() for each value.
 */
void setPowers(int userinteger, int ar[], int lastindex){
	int i;
	for( i = 0; i &amp;lt;= lastindex; i++)
		ar[i] = power( 2, i );
}

/*This function calculates and returns baseexponent utilizing the
 * math library function 'pow'.
 */
int power(int base, int exponent){
	int e;

	e = pow(base, exponent);
	return e;
}

/* This function prints the program's output. For each array
 * element in the range of integers defined by firstindex and
 * lastindex, the function prints one line of the output.
 */
void printPowers(int ar[], int firstindex, int lastindex){
	int p;
	for( p = 0; p &amp;lt;= lastindex; p++)
		printf(&amp;quot;2^%d = %d\n&amp;quot;, p, ar[p] );
}
</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hdelossantos.com/2009/02/21/powers-of-base-2-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.767 seconds -->

