Option Explicit
Public Sub splitCSV(targetCell As range)
Dim row As Integer
row = targetCell.row
Dim col As Integer
col = targetCell.Column
Dim source As String
source = targetCell.Text
Dim count As Integer
count = 0
Dim startPos As Integer
startPos = 1
Dim nextCommaPos As Integer
Dim exitLoop As Boolean
exitLoop = False
While (exitLoop = False)
Dim commaPos As Integer
commaPos = InStr(startPos, source, ",")
Dim token As String
If (commaPos = 0) Then
exitLoop = True
Else
If (startPos = 1) Then
commaPos = 0
End If
nextCommaPos = InStr(commaPos + 1, source, ",")
If (nextCommaPos = 0) Then
nextCommaPos = Len(source) + 1
End If
token = Mid(source, commaPos + 1, nextCommaPos - commaPos - 1)
count = count + 1
Cells(row, col + count).Value = token
If (startPos <> 1) Then
startPos = commaPos + 1
Else
startPos = 2
End If
End If
Wend
End Sub
Public Sub SplitSelection()
Application.ScreenUpdating = False
Dim sel As range
Set sel = Selection
Dim row As Integer
For row = sel.row To (sel.row + sel.Rows.count - 1)
Dim targetCell As range
Set targetCell = Cells(row, sel.Column)
Call splitCSV(targetCell)
Next row
Application.ScreenUpdating = True
End Sub
Monday, November 30, 2009
VBA Macro - Split/Parse CSV Strings
Thursday, November 26, 2009
Sunday, November 1, 2009
Saturday, October 31, 2009
Tuesday, October 27, 2009
Mielie Bread Recipe
2 cups flour
3 teaspoons baking powder
1 tin creamed sweetcorn
2 eggs
1 tablespoon sugar
½ teaspoon salt
3 Tablespoons melted butter
½ cup milk
Sift flour, salt, baking powder. Add sugar. Beat eggs, add milk, sweetcorn and (cool) melted butter and mix. Gradually add liquid mixture to dry ingredients, stirring to ensure smoothness.
Bake at 1800 C for approx. 35 minutes, reduce temperature to 1400 and cook for a further 15-25 minutes until set.
3 teaspoons baking powder
1 tin creamed sweetcorn
2 eggs
1 tablespoon sugar
½ teaspoon salt
3 Tablespoons melted butter
½ cup milk
Sift flour, salt, baking powder. Add sugar. Beat eggs, add milk, sweetcorn and (cool) melted butter and mix. Gradually add liquid mixture to dry ingredients, stirring to ensure smoothness.
Bake at 1800 C for approx. 35 minutes, reduce temperature to 1400 and cook for a further 15-25 minutes until set.
Crumpet Recipe
1 egg
2 Tablespoons sugar
pinch salt
1 cup flour
3 teaspoons baking powder
¾ cup milk
2 Tablespoons oil
Beat egg and sugar till light and fluffy. Add milk. Sift salt, flour and baking powder. Gradually add egg and milk mixture, stirring to keep batter smooth. Lastly, gently stir in oil. Do not beat as this will destroy baking powder action. Cook in lightly greased pre-heated pan on a medium-high temperature.
2 Tablespoons sugar
pinch salt
1 cup flour
3 teaspoons baking powder
¾ cup milk
2 Tablespoons oil
Beat egg and sugar till light and fluffy. Add milk. Sift salt, flour and baking powder. Gradually add egg and milk mixture, stirring to keep batter smooth. Lastly, gently stir in oil. Do not beat as this will destroy baking powder action. Cook in lightly greased pre-heated pan on a medium-high temperature.
Marie Biscuit Fudge Recipe
Ingredients
1 pkt. crushed Marie biscuits
250g butter
1 egg
1 pkt. icing sugar
3 level Tablespoons of cocoa
large, shallow dish
Method
1. crush biscuits
2. beat egg
3. melt butter
4. add cocoa and beaten egg to molten butter
5. mix in icing sugar and crushed biscuits
6. stir well - until icing sugar is melted and biscuits are evenly mixed
7. grease a large shallow dish with butter, until there is a thin layer across the whole interior surface
8. pour the fudge mixture into the greased dish
9. refrigerate - for 6 to 8 hours
10. during cooling, when the fudge has started to set, but still not yet rock hard, cut into squares
1 pkt. crushed Marie biscuits
250g butter
1 egg
1 pkt. icing sugar
3 level Tablespoons of cocoa
large, shallow dish
Method
1. crush biscuits
2. beat egg
3. melt butter
4. add cocoa and beaten egg to molten butter
5. mix in icing sugar and crushed biscuits
6. stir well - until icing sugar is melted and biscuits are evenly mixed
7. grease a large shallow dish with butter, until there is a thin layer across the whole interior surface
8. pour the fudge mixture into the greased dish
9. refrigerate - for 6 to 8 hours
10. during cooling, when the fudge has started to set, but still not yet rock hard, cut into squares
Peanut Butter Biscuit Recipe
125 grams butter 1 ½ cups flour
½ cup brown sugar ¾ teaspoon bicarb.
½ cup white sugar ¼ teaspoon salt
1 egg (beaten) ½ cup peanut butter
½ teaspoon vanilla
Heat oven to 2000 C . Grease baking sheet. Cream butter and sugar, add egg and essence and beat well. Sift dry ingredients and add to cream mixture. Mix well. Add peanut butter to form a soft dough. Roll out and flatten on floured surface. Cut biscuits into desired shapes. Bake for 5-20 minutes. Cool.
½ cup brown sugar ¾ teaspoon bicarb.
½ cup white sugar ¼ teaspoon salt
1 egg (beaten) ½ cup peanut butter
½ teaspoon vanilla
Heat oven to 2000 C . Grease baking sheet. Cream butter and sugar, add egg and essence and beat well. Sift dry ingredients and add to cream mixture. Mix well. Add peanut butter to form a soft dough. Roll out and flatten on floured surface. Cut biscuits into desired shapes. Bake for 5-20 minutes. Cool.
Date Loaf Recipe
1 cup chopped dates
¼ teaspoon salt
½ cup sugar
1 rounded teaspoon butter
1 ½ cups flour
1 cup boiling water
1 teaspoon bicarbonate of soda
½ cup chopped nuts/raising/mixed fruit
1 egg
Pour boiling water over bicarb. Pour over chopped dates while fizzy. Mix well to soften dates. Add butter, sugar, nuts/raising and beaten egg, stirring well with each addition. Separately, sift flour and salt. Add to date mixture when cool. Bake in loaf pan at 1800 C for 45-60 minutes.
¼ teaspoon salt
½ cup sugar
1 rounded teaspoon butter
1 ½ cups flour
1 cup boiling water
1 teaspoon bicarbonate of soda
½ cup chopped nuts/raising/mixed fruit
1 egg
Pour boiling water over bicarb. Pour over chopped dates while fizzy. Mix well to soften dates. Add butter, sugar, nuts/raising and beaten egg, stirring well with each addition. Separately, sift flour and salt. Add to date mixture when cool. Bake in loaf pan at 1800 C for 45-60 minutes.
Banana Loaf Recipe
2 eggs
1 ½ cups sugar
¼ lb. butter or 3 tablespoons cooking oil
3 cups flour
4 ripe bananas, mashed with a little lemon juice
1 cup milk
2 teaspoons bakiing powder
½ teaspoon bicarb. of soda
½ teaspoon salt
Cream butter and sugar i.e. mix and beat till creamy. Add eggs, beat well. Then add bananas, mashed with a fork. Dissolve bicarb in 1 tablespoon hot water. Add enough milk to fill one cup. Sift dry ingredients together. Add alternately with milk to egg mixture. Bake in greased tin/2 tins at 180o C for 1 hr. or until done. Makes one big or two smaller loaves.
1 ½ cups sugar
¼ lb. butter or 3 tablespoons cooking oil
3 cups flour
4 ripe bananas, mashed with a little lemon juice
1 cup milk
2 teaspoons bakiing powder
½ teaspoon bicarb. of soda
½ teaspoon salt
Cream butter and sugar i.e. mix and beat till creamy. Add eggs, beat well. Then add bananas, mashed with a fork. Dissolve bicarb in 1 tablespoon hot water. Add enough milk to fill one cup. Sift dry ingredients together. Add alternately with milk to egg mixture. Bake in greased tin/2 tins at 180o C for 1 hr. or until done. Makes one big or two smaller loaves.
Pasta Recipe
Home made pasta
250 g (= 2¼ cups) bread (durum wheat) flour
1 teaspoon salt
3 small eggs (beaten)
1 tablespoon olive oil
sift flour and salt into
add egss and oil
knead and roll (with pin) to a homogeneous paste
wrap paste in cling film
age for 30 minutes
roll & cut pasta to size
dry pieces by laying on an adsorbent surface (e.g. paper towl) for 30 minutes
cook in boiling salted water for 3-5 minutes
250 g (= 2¼ cups) bread (durum wheat) flour
1 teaspoon salt
3 small eggs (beaten)
1 tablespoon olive oil
sift flour and salt into
add egss and oil
knead and roll (with pin) to a homogeneous paste
wrap paste in cling film
age for 30 minutes
roll & cut pasta to size
dry pieces by laying on an adsorbent surface (e.g. paper towl) for 30 minutes
cook in boiling salted water for 3-5 minutes
Basil Pesto Recipe
How to Make Pesto like an Italian Grandmother
One key to perfect pesto is chopping all the ingredients by hand, preferably with a sharp mezzaluna or knife. I gave my double-bladed mezzaluna to a friend last year because it was collecting dust (I also didn't like how ingredients would get stuck between the blades), but have a large half-moon shaped pizza cutter that works like a dream. Francesca's mom even approved and said it cut her chopping time in half. This pesto will keep a bit in the refrigerator, but it really hits its peak when served soon after it is made.
The technique here is: chop a bit, add some ingredients, chop some more. I think part of the reason she does it this way (instead of chopping everything all at once) is because some things get chopped into oblivion, while some not as much - it encourages specturm of cut sizes throughout the pesto contributing to the overall texture. All told, the chopping took me a leisurely twenty to thirty minutes, I wasn't in any particular rush.
You'll notice this recipe doesn't have any added salt (just the saltiness from the cheese), make sure your pasta water is well salted if you are going to use this pesto on pasta or the overall flavor profile will fall flat. Also, be sure to adjust for seasoning before serving. With food this simple, you need to get the seasoning right.
1 large bunch of basil, leaves only, washed and dried
3 medium cloves of garlic
one small handful of raw pine nuts
roughly 3/4 cup Parmesan, loosely packed and FRESHLY GRATED
A few tablespoons of extra-virgin olive oil
Special equipment: large mezzaluna for chopping
Start chopping the garlic along with about 1/3 of the basil leaves. Once this is loosely chopped add more basil, chop some more, add the rest of the basil, chop some more. I scrape and chop, gather and chop. At this point the basil and garlic should be a very fine mince. Add about half the pine nuts, chop. Add the rest of the pine nuts, chop. Add half of the Parmesan, chop. Add the rest of the Parmesan, and chop. In the end you want a chop so fine that you can press all the ingredients into a basil "cake" - see the photo up above. Transfer the pesto "cake" to a small bowl (not much bigger than the cake). Cover with a bit of olive oil, it doesn't take much, just a few tablespoons.
You can set this aside or place it in the refrigerator until you are ready to use it. Just before serving give the pesto a quick stir to incorporate some of the oil into the basil. She occasionally thins the pesto with a splash of pasta water for more coverage, but for our gnocchi this wasn't necessary.
Makes about 1 cup.
One key to perfect pesto is chopping all the ingredients by hand, preferably with a sharp mezzaluna or knife. I gave my double-bladed mezzaluna to a friend last year because it was collecting dust (I also didn't like how ingredients would get stuck between the blades), but have a large half-moon shaped pizza cutter that works like a dream. Francesca's mom even approved and said it cut her chopping time in half. This pesto will keep a bit in the refrigerator, but it really hits its peak when served soon after it is made.
The technique here is: chop a bit, add some ingredients, chop some more. I think part of the reason she does it this way (instead of chopping everything all at once) is because some things get chopped into oblivion, while some not as much - it encourages specturm of cut sizes throughout the pesto contributing to the overall texture. All told, the chopping took me a leisurely twenty to thirty minutes, I wasn't in any particular rush.
You'll notice this recipe doesn't have any added salt (just the saltiness from the cheese), make sure your pasta water is well salted if you are going to use this pesto on pasta or the overall flavor profile will fall flat. Also, be sure to adjust for seasoning before serving. With food this simple, you need to get the seasoning right.
1 large bunch of basil, leaves only, washed and dried
3 medium cloves of garlic
one small handful of raw pine nuts
roughly 3/4 cup Parmesan, loosely packed and FRESHLY GRATED
A few tablespoons of extra-virgin olive oil
Special equipment: large mezzaluna for chopping
Start chopping the garlic along with about 1/3 of the basil leaves. Once this is loosely chopped add more basil, chop some more, add the rest of the basil, chop some more. I scrape and chop, gather and chop. At this point the basil and garlic should be a very fine mince. Add about half the pine nuts, chop. Add the rest of the pine nuts, chop. Add half of the Parmesan, chop. Add the rest of the Parmesan, and chop. In the end you want a chop so fine that you can press all the ingredients into a basil "cake" - see the photo up above. Transfer the pesto "cake" to a small bowl (not much bigger than the cake). Cover with a bit of olive oil, it doesn't take much, just a few tablespoons.
You can set this aside or place it in the refrigerator until you are ready to use it. Just before serving give the pesto a quick stir to incorporate some of the oil into the basil. She occasionally thins the pesto with a splash of pasta water for more coverage, but for our gnocchi this wasn't necessary.
Makes about 1 cup.
Wednesday, October 21, 2009
log4net - Force New (Specified) Log File
private static readonly ILog alog = LogManager.GetLogger("AlgoLogger");
public void SwitchToNewUniqueAlgoLogFile(long scheduleID)
{
ILoggerRepository logRepos = LogManager.GetRepository();
IAppender[] logAppenders = logRepos.GetAppenders();
string targetAppenderName = "myAppender"
// first find the logger we are actually looking for
for (int i = 0; i < logAppenders.Length; i++)
{
IAppender appender = logAppenders[i];
if (appender.Name == targetAppenderName )
{
// cast generic appender to our type
RollingFileAppender rfa = appender as RollingFileAppender;
// get full name of current log file
string oldFName = rfa.File;
// extract path
int indexOfLastSlash = oldFName.LastIndexOf(@"\");
string path = oldFName.Substring(0, indexOfLastSlash + 1);
// generate new log file name
string newLogFileName = "newLog.txt"
string newFullFileName = path + newLogFileName;
// set new file name
rfa.File = newFullFileName;
// indicate to change
rfa.ActivateOptions();
break;
}
}
}
Switching Log-Files During Logging
private static readonly ILog alog = LogManager.GetLogger("AlgoLogger");
public void SwitchToNewUniqueAlgoLogFile(long scheduleID)
{
ILoggerRepository logRepos = LogManager.GetRepository();
IAppender[] logAppenders = logRepos.GetAppenders();
string targetAppenderName = "myAppender"
// first find the logger we are actually looking for
for (int i = 0; i < logAppenders.Length; i++)
{
IAppender appender = logAppenders[i];
if (appender.Name == targetAppenderName )
{
// cast generic appender to our type
RollingFileAppender rfa = appender as RollingFileAppender;
string oldFName = rfa.File;
int indexOfLastSlash = oldFName.LastIndexOf(@"\");
string path = oldFName.Substring(0, indexOfLastSlash + 1);
// generate new log file name
string scheduleName = SQLHandler.GetScheduleName(scheduleID);
string newLogFileName = "newLog.txt"
string newFullFileName = path + newLogFileName ;
rfa.File = newFullFileName;
rfa.ActivateOptions();
break;
}
}
}
Thursday, October 1, 2009
Debugging Python
The standard python includes includes a debug module : PDB
Python Docs Entry @ doc.python.org
Cheat Sheet
reqd to use the debugger
= import pdb
define breakpoint
= pdb.set_trace()
halts program execution, and drops you into the debugger console
commands available within debugger console
n = execute next line of code, making entire method call
s = execute next line, stepping into any method calls
c = continue to next break point
q = quit
!xxxxx = execute python instruction xxxxx
Tutorials
- Ayman Hourieh Blog Post
- Steve Ferg Blog Post
- SonTek / John Anderson Blog Post
Python Docs Entry @ doc.python.org
Cheat Sheet
reqd to use the debugger
= import pdb
define breakpoint
= pdb.set_trace()
halts program execution, and drops you into the debugger console
commands available within debugger console
n = execute next line of code, making entire method call
s = execute next line, stepping into any method calls
c = continue to next break point
q = quit
!xxxxx = execute python instruction xxxxx
Tutorials
- Ayman Hourieh Blog Post
- Steve Ferg Blog Post
- SonTek / John Anderson Blog Post
C# Object.CompareTo(otherOb)
big.CompareTo(small) = 1
self.CompareTo(self) = 0
small.CompareTo(big) = -1
self.CompareTo(self) = 0
small.CompareTo(big) = -1
Sunday, September 27, 2009
UNIX Time Standard
WikiPedia
"Unix time, or POSIX time, is a system for describing points in time, defined as the number of seconds elapsed since midnight proleptic Coordinated Universal Time (UTC) of January 1, 1970, not counting leap seconds."
"Unix time, or POSIX time, is a system for describing points in time, defined as the number of seconds elapsed since midnight proleptic Coordinated Universal Time (UTC) of January 1, 1970, not counting leap seconds."
Convert FLV to MP3 - uBuntu
sudo apt-get install ffmpeg
ffmpeg -i /suorcefile_path/sourcefile.flv -ab 128k /path/file.mp3
Source
may need to get ffmpeg from non-os repos because of non-os nature of format
ffmpeg -i /suorcefile_path/sourcefile.flv -ab 128k /path/file.mp3
Source
may need to get ffmpeg from non-os repos because of non-os nature of format
Saturday, September 26, 2009
Evolution - GMail POP
http://tuxicity.wordpress.com/2007/03/08/howto-set-up-gmail-in-evolution-gnomes-mail-client-and-organizer/
http://cviorel.easyblog.ro/2008/11/05/nokia-n73-synchronization-with-opensync-under-ubuntu-804/
http://sidrit.wordpress.com/2008/07/03/nokia-e61i-sync-with-evolution-on-ubuntu-804/
http://discussions.europe.nokia.com/discussions/board/message?board.id=smartphones&message.id=94045
http://cviorel.easyblog.ro/2008/11/05/nokia-n73-synchronization-with-opensync-under-ubuntu-804/
http://sidrit.wordpress.com/2008/07/03/nokia-e61i-sync-with-evolution-on-ubuntu-804/
http://discussions.europe.nokia.com/discussions/board/message?board.id=smartphones&message.id=94045
Tuesday, September 22, 2009
Set GRUB Default Boot Option
config file = /boot/grub/menu.lst
edit line
## default num
...
default 0
change default number (generally to 4 for std ubuntu/win dual boot)
for karmic koala (9-10), the config file is /etc/default/grub
and change GRUB_DEFAULT=4
in either case, follow up with
update-grub
Source = HowToGeek
edit line
## default num
...
default 0
change default number (generally to 4 for std ubuntu/win dual boot)
for karmic koala (9-10), the config file is /etc/default/grub
and change GRUB_DEFAULT=4
in either case, follow up with
update-grub
Source = HowToGeek
Saturday, September 19, 2009
mySQL - Python
Official mySQL Site on Integration
MySQLdb is an interface for connecting to a MySQL database server from Python. It implements the Python Database API v2.0, and is built on top of the MySQL C API.
Writing MySQL Scripts with Python DB-API
SourceForge mySQL-Python Home
PEP 249 : Python Database API Specification v2.0
DOWNLOAD
MySQL for Python [SourceForge]
MySQLdb is an interface for connecting to a MySQL database server from Python. It implements the Python Database API v2.0, and is built on top of the MySQL C API.
Writing MySQL Scripts with Python DB-API
SourceForge mySQL-Python Home
PEP 249 : Python Database API Specification v2.0
DOWNLOAD
MySQL for Python [SourceForge]
Installing & Configuring MySQL
excellent BASIC MYSQL CONFIGURATION
(typical) LOCATION OF mySQL CONFIG FILE [=my.cnf]
= /etc/mysql/my.cnf
LOG ON TO MYSQL CONSOLE
> mysql - u user -p
drop database syntax
How to change the mysql database location
LIST DATABASES
> mysqlshow -u root -p
CREATE DATABASE
1
2
3
SHUTDOWN SERVER
mysqladmin -u root -p shutdown
---
Information Schema Tables [official mysql ref]
The schema 'information_schema' contains the meta-data for the db server
TO QUERY ALL TABLES CONTAINED IN DB test
> select *
> from information_schema.tables
> where table_schema = 'test';
(typical) LOCATION OF mySQL CONFIG FILE [=my.cnf]
= /etc/mysql/my.cnf
LOG ON TO MYSQL CONSOLE
> mysql - u user -p
drop database syntax
How to change the mysql database location
LIST DATABASES
> mysqlshow -u root -p
CREATE DATABASE
1
2
3
SHUTDOWN SERVER
mysqladmin -u root -p shutdown
---
Information Schema Tables [official mysql ref]
The schema 'information_schema' contains the meta-data for the db server
TO QUERY ALL TABLES CONTAINED IN DB test
> select *
> from information_schema.tables
> where table_schema = 'test';
Thursday, September 17, 2009
Thai Green Curry Recipe
THAI GREEN CURRY
Ingredients
1 tbsp vegetable oil
2 tbsp green curry paste (according to taste)
1 tbsp soft dark brown sugar
1-2 thick stalks lemongrass, fat ends bashed with a rolling pin (optional)
750g skinless, boneless chicken, cut into chunks (use breast and/or leg meat)
6-8 lime leaves, torn into pieces (if unavailable, use the grated zest of 1 lime)
400ml coconut milk
good shake Thai fish sauce or light soy sauce
small handful coriander, roughly chopped
1 lime, juice only
Method
1. Heat the oil in a wok or large frying pan. Add the green curry paste and sugar and cook over a fairly high heat for about a minute, stirring with the lemongrass, if using. Reduce the heat slightly and stir in the chicken pieces and lime leaves or zest until coated in the paste. Add the coconut milk, fish sauce or soy sauce and bring to a simmer, cooking for 25-30 minutes until thickened slightly. Stir in the coriander and lime juice. Check for seasoning, adding more fish sauce or soy sauce if needed.
2. The curry is now best left to sit for a few minutes so the sauce becomes creamier. You will also taste the true flavours of the curry paste ingredients when it's slightly cooler. Serve with lots of fragrant Thai jasmine rice.
THAI GREEN CURRY PASTE
Ingredients
4-6 medium green chillies, de-seeded and roughly chopped
2 shallots, roughly chopped
5cm/2in piece of fresh ginger, peeled and grated
2 garlic cloves, crushed
small bunch of fresh coriander, stalks and roots attached if possible
2 lemongrass stalks, chopped (if unavailable, use 2 tbsp dried)
1 lime, grated zest and juice
8 kaffir lime leaves, torn into pieces (if unavailable, use the grated zest of
1 extra lime)
2.5cm/1in piece galangal, peeled and chopped (if available)
1 tbsp coriander seeds, crushed
1 tsp ground cumin
1 tsp black peppercorns, crushed
2 tsp Thai fish sauce or light soy sauce
3 tbsp olive oil
Method
1. Place all of the ingredients in a food processor and blitz to a paste. Use straight away or store in a jar in the fridge for up to 3 weeks. This quantity is enough for a curry for 8 people.
Tip:
When your curry is cooked, if you think it is too spicy, add some more sugar; if it isn't spicy enough, fry a little more curry paste in some oil for a minute or two and add to the sauce.
Ingredients
1 tbsp vegetable oil
2 tbsp green curry paste (according to taste)
1 tbsp soft dark brown sugar
1-2 thick stalks lemongrass, fat ends bashed with a rolling pin (optional)
750g skinless, boneless chicken, cut into chunks (use breast and/or leg meat)
6-8 lime leaves, torn into pieces (if unavailable, use the grated zest of 1 lime)
400ml coconut milk
good shake Thai fish sauce or light soy sauce
small handful coriander, roughly chopped
1 lime, juice only
Method
1. Heat the oil in a wok or large frying pan. Add the green curry paste and sugar and cook over a fairly high heat for about a minute, stirring with the lemongrass, if using. Reduce the heat slightly and stir in the chicken pieces and lime leaves or zest until coated in the paste. Add the coconut milk, fish sauce or soy sauce and bring to a simmer, cooking for 25-30 minutes until thickened slightly. Stir in the coriander and lime juice. Check for seasoning, adding more fish sauce or soy sauce if needed.
2. The curry is now best left to sit for a few minutes so the sauce becomes creamier. You will also taste the true flavours of the curry paste ingredients when it's slightly cooler. Serve with lots of fragrant Thai jasmine rice.
THAI GREEN CURRY PASTE
Ingredients
4-6 medium green chillies, de-seeded and roughly chopped
2 shallots, roughly chopped
5cm/2in piece of fresh ginger, peeled and grated
2 garlic cloves, crushed
small bunch of fresh coriander, stalks and roots attached if possible
2 lemongrass stalks, chopped (if unavailable, use 2 tbsp dried)
1 lime, grated zest and juice
8 kaffir lime leaves, torn into pieces (if unavailable, use the grated zest of
1 extra lime)
2.5cm/1in piece galangal, peeled and chopped (if available)
1 tbsp coriander seeds, crushed
1 tsp ground cumin
1 tsp black peppercorns, crushed
2 tsp Thai fish sauce or light soy sauce
3 tbsp olive oil
Method
1. Place all of the ingredients in a food processor and blitz to a paste. Use straight away or store in a jar in the fridge for up to 3 weeks. This quantity is enough for a curry for 8 people.
Tip:
When your curry is cooked, if you think it is too spicy, add some more sugar; if it isn't spicy enough, fry a little more curry paste in some oil for a minute or two and add to the sauce.
Sunday, September 13, 2009
Re-Using .DEB Packages
[select saving of downloaded packages]
Downloaded packages saved to /var/cache
http://www.go2linux.org/debian-ubuntu-package-proxy-server
Downloaded packages saved to /var/cache
http://www.go2linux.org/debian-ubuntu-package-proxy-server
Friday, September 11, 2009
Log4Net - load config from file and demo basic log
public class Program
{
private static readonly log4net.ILog alog = LogManager.GetLogger("AlgoLogger");
public static void Main(string[] args)
{
FileInfo fInfo = new FileInfo(@"C:\this\that\log4net.config");
log4net.Config.XmlConfigurator.Configure(fInfo);
Klass klass = new Klass();
klass.LogStuff();
}
}
public class Klass
{
private static readonly log4net.ILog alog = LogManager.GetLogger("AlgoLogger");
public void LogStuff()
{
string logStr = "log info";
alog.Debug(logStr);
}
}
log4net.config XML file
[?xml version="1.0" encoding="utf-8" ?]
[log4net]
[appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" ]
[layout type="log4net.Layout.PatternLayout"]
[conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" /]
[/layout]
[/appender]
[appender name="RollingFile" type="log4net.Appender.RollingFileAppender"]
[file value="log-file.txt" /]
[appendToFile value="true" /]
[maximumFileSize value="1024KB" /]
[maxSizeRollBackups value="10" /]
[rollingStyle value="Size" /]
[layout type="log4net.Layout.PatternLayout"]
[conversionPattern value="%date %level %thread %logger - %message%newline" /]
[/layout]
[/appender]
[!--
[root]
[level value="ALL" /]
[appender-ref ref="RollingFile" /]
[/root]
--]
[logger name="AlgoLogger"]
[level value="ALL" /]
[appender-ref ref="AlgoAppender" /]
[/logger]
[/log4net]
Sunday, September 6, 2009
Retaining WhiteSpace When Posting Python Code
To post python code in a blog (html) and retain the line whitespace that is required in order for the code to remain unambiguous, simply enclose your code within pre html tag block.
The 'pre' tag yields a fixed-width (monospace) font, and preserves spaces and line-breaks.
<pre>
</pre>
The 'pre' tag yields a fixed-width (monospace) font, and preserves spaces and line-breaks.
<pre>
def doStuff(i):
print()
for z in range(i):
print(z)
c = 4
for z in range(c):
doStuff(z)
</pre>
Tuesday, August 25, 2009
IT Business Analyst Knowledge Areas
Database - Normal forms
xml schema, Domain Model
PIM vs PSM
Zachmann FrameWork
IDEF1X
UML 2.0
Solution Documentation
1. User Story (The main stories the application will implement, stories start higher level and then drill down into details “I want to add blocks”)
2. Use Cases (The use cases are driven from the user stories, each use case must tie up to a user story. Use cases describe the various different ways the user can for example “Add blocks at top”, “Add blocks at bottom”, “Add blocks at specific position in existing list”)
3. Functional Requirements (Validation rules, formatting rules, business rules not fitting into use cases, and then rules coming from use cases, each functional requirement should be tied to a use case and user story)
4. Activity Diagrams (Only include these if a use case or functional requirement requires complicated logic flow – complicated is anything where you have a if/else or loop type logic)
5. Test plan (This is a list of all tests you would perform to check that all the functional requirements are matched. Each functional requirement must have an associated test)
The above makes up the functional specification for an application.
You could also include user interface screen mock ups, with examples of data. We find these really helpful aswell.
xml schema, Domain Model
PIM vs PSM
Zachmann FrameWork
IDEF1X
UML 2.0
Solution Documentation
1. User Story (The main stories the application will implement, stories start higher level and then drill down into details “I want to add blocks”)
2. Use Cases (The use cases are driven from the user stories, each use case must tie up to a user story. Use cases describe the various different ways the user can for example “Add blocks at top”, “Add blocks at bottom”, “Add blocks at specific position in existing list”)
3. Functional Requirements (Validation rules, formatting rules, business rules not fitting into use cases, and then rules coming from use cases, each functional requirement should be tied to a use case and user story)
4. Activity Diagrams (Only include these if a use case or functional requirement requires complicated logic flow – complicated is anything where you have a if/else or loop type logic)
5. Test plan (This is a list of all tests you would perform to check that all the functional requirements are matched. Each functional requirement must have an associated test)
The above makes up the functional specification for an application.
You could also include user interface screen mock ups, with examples of data. We find these really helpful aswell.
Saturday, August 15, 2009
Linux Python BlueTooth Dev
The official Linux BlueTooth protocol stack.
BlueZ
ubuntu pkg = bluez
A cross-platform Python Bluetooth API.
Light Blue
ubuntu pkg = python-lightblue
Python wrappers for bluetooth system resources.
Google PyBluez
ubuntu pkg = python-bluez
Open source implementation of the Object Exchange (OBEX) Protocol
Open OBEX
ubuntu pkg = openobex-apps
---
bug with my broadcom bluetooth usb dongle
https://bugs.launchpad.net/ubuntu/+source/gnome-bluetooth/+bug/133690
BlueZ
ubuntu pkg = bluez
A cross-platform Python Bluetooth API.
Light Blue
ubuntu pkg = python-lightblue
Python wrappers for bluetooth system resources.
Google PyBluez
ubuntu pkg = python-bluez
Open source implementation of the Object Exchange (OBEX) Protocol
Open OBEX
ubuntu pkg = openobex-apps
---
bug with my broadcom bluetooth usb dongle
https://bugs.launchpad.net/ubuntu/+source/gnome-bluetooth/+bug/133690
Wednesday, July 29, 2009
(almost) Everything you wanted to know about linux and the net, but were afraid to ask
Eric Raymond's (esr@thyrsus.com) document "describes the working basics of PC-class computers, Unix-like operating systems, and the Internet in non-technical language."
Greg 'o Keefe's (gcokeefe@postoffice.utas.edu.au) brief "description of what happens in a Linux system, from the time that you turn on the power, to the time that you log in and get a bash prompt."
Greg 'o Keefe's (gcokeefe@postoffice.utas.edu.au) brief "description of what happens in a Linux system, from the time that you turn on the power, to the time that you log in and get a bash prompt."
Renewal of Driver's Licences @ Selected SA Postal Offices
GARDEN VIEW
BEDFORD GARDENS
BEDFORD SHOPPING CENTRE, CNR SMITH & BRADFORD ST, GARDENVIEW
WITS CENTRAL
BEDFORDVIEW
BRIXTON
BRIXTON
121 HIGH ST
WITS CENTRAL
JOHANNESBURG
TSHIAWELO
CHAWELO
989 SIBASA ST
SOUTHWEST RAND
SOWETO
DIEPKLOOF
DIEPKLOOF
7451 EBEN CUYLER DR
SOUTHWEST RAND
SOWETO
DUBE
DUBE
2224 MAHALEFELE ST
SOUTHWEST RAND
SOWETO
ELDORADOPARK
ELDORADOPARK
CIRCLE ROAD
SOUTHWEST RAND
SOWETO
ZOLA
EMDENI NORTH
DOPSONPOINT CENTRE MOHAJANE STREET DOBSONVILLE EXT 3
SOUTHWEST RAND
SOWETO
RANDBURG
FERNDALE
SANLAM CENTRE, LOWER LEVEL,
NORTHWEST RAND
RANDBURG
JOUBERTPARK
JOUBERT PARK
THE BRIDGE CENTRE CNR BLOCK NOORD, WANDERERS KING GEORGE & KOCH STR
WITS CENTRAL
JOUBERT PARK
KLIPTOWN
KLIPTOWN
WALTER SISULU MALL SHOP 5 VALLEY ROAD
SOUTHWEST RAND
SOWETO
KIASHA PARK
LENASIA SOUTH
CNR GOLDEN HIGHWAY & WIMBELDON
SOUTHWEST RAND
LENASIA
MARAISBURG
MARAISBURG
CNR 7TH AVE & 10TH ST
NORTHWEST RAND
ROODEPOORT
MEADOWLANDS
MEADOWLANDS
HACK RD, CIRCLE
SOUTHWEST RAND
SOWETO
ORLANDO
ORLANDO
6515 MOOKI ST
SOUTHWEST RAND
SOWETO
CRESTA
RANDBURG
CRESTA CENTRE BEYERS NAUDE DRIVE CRESTA
NORTHWEST RAND
RANDBURG
SOUTH GATE
SOUTH GATE
SOUTHGATE MALL CNR COLUMBINE AVE & RIFLE RANGE RD MONDEOR JHB
WITS CENTRAL
JOHANNESBURG
PROTEA GLEN
PROTEA GLEN
PROTEA GLEN NEIGHBOURHOOD CENTRE WILD CHESTNUT STR PROTEA GLEN SOWETO
SOUTHWEST RAND
JOHANNESBURG
SUNNINGHILL WEST
SUNNINGHILL
SHOP NO LL14SUNNINGHILL SHOPPING CENTRE EDISON CRESCENT SUNNINGHILL ERF 96/97
NORTHWEST RAND
RIVONIA
HALFWAYHOUSE
MIDRAND
SHOP 111 BOULDERS SHOPPING CENTRE OLD PRETORIA ROAD
NORTHWEST RAND
HALFWAY HOUSE
MARSHALLTOWN
JOHANNESBURG
C/O FOX AND SAUER STREET
BRYANSTON
BRYANSTON
THE POSTHOUSE C/R MAIN AND BRUTON DRIVE
SOUTHWEST RAND
ROODEPORT
VAN WYK ST 24 ROODEPOORT 1724
BEDFORD GARDENS
BEDFORD SHOPPING CENTRE, CNR SMITH & BRADFORD ST, GARDENVIEW
WITS CENTRAL
BEDFORDVIEW
BRIXTON
BRIXTON
121 HIGH ST
WITS CENTRAL
JOHANNESBURG
TSHIAWELO
CHAWELO
989 SIBASA ST
SOUTHWEST RAND
SOWETO
DIEPKLOOF
DIEPKLOOF
7451 EBEN CUYLER DR
SOUTHWEST RAND
SOWETO
DUBE
DUBE
2224 MAHALEFELE ST
SOUTHWEST RAND
SOWETO
ELDORADOPARK
ELDORADOPARK
CIRCLE ROAD
SOUTHWEST RAND
SOWETO
ZOLA
EMDENI NORTH
DOPSONPOINT CENTRE MOHAJANE STREET DOBSONVILLE EXT 3
SOUTHWEST RAND
SOWETO
RANDBURG
FERNDALE
SANLAM CENTRE, LOWER LEVEL,
NORTHWEST RAND
RANDBURG
JOUBERTPARK
JOUBERT PARK
THE BRIDGE CENTRE CNR BLOCK NOORD, WANDERERS KING GEORGE & KOCH STR
WITS CENTRAL
JOUBERT PARK
KLIPTOWN
KLIPTOWN
WALTER SISULU MALL SHOP 5 VALLEY ROAD
SOUTHWEST RAND
SOWETO
KIASHA PARK
LENASIA SOUTH
CNR GOLDEN HIGHWAY & WIMBELDON
SOUTHWEST RAND
LENASIA
MARAISBURG
MARAISBURG
CNR 7TH AVE & 10TH ST
NORTHWEST RAND
ROODEPOORT
MEADOWLANDS
MEADOWLANDS
HACK RD, CIRCLE
SOUTHWEST RAND
SOWETO
ORLANDO
ORLANDO
6515 MOOKI ST
SOUTHWEST RAND
SOWETO
CRESTA
RANDBURG
CRESTA CENTRE BEYERS NAUDE DRIVE CRESTA
NORTHWEST RAND
RANDBURG
SOUTH GATE
SOUTH GATE
SOUTHGATE MALL CNR COLUMBINE AVE & RIFLE RANGE RD MONDEOR JHB
WITS CENTRAL
JOHANNESBURG
PROTEA GLEN
PROTEA GLEN
PROTEA GLEN NEIGHBOURHOOD CENTRE WILD CHESTNUT STR PROTEA GLEN SOWETO
SOUTHWEST RAND
JOHANNESBURG
SUNNINGHILL WEST
SUNNINGHILL
SHOP NO LL14SUNNINGHILL SHOPPING CENTRE EDISON CRESCENT SUNNINGHILL ERF 96/97
NORTHWEST RAND
RIVONIA
HALFWAYHOUSE
MIDRAND
SHOP 111 BOULDERS SHOPPING CENTRE OLD PRETORIA ROAD
NORTHWEST RAND
HALFWAY HOUSE
MARSHALLTOWN
JOHANNESBURG
C/O FOX AND SAUER STREET
BRYANSTON
BRYANSTON
THE POSTHOUSE C/R MAIN AND BRUTON DRIVE
SOUTHWEST RAND
ROODEPORT
VAN WYK ST 24 ROODEPOORT 1724
Wednesday, July 15, 2009
Reverting the Head Revision to a Previous Revision with Tortoise SVN
CodeRenaissance
To roll back a file, start by right clicking on it and selecting Show Log.
Once you have the log open, right click on the desired version of your file.
Upon selecting this Tortoise SVN will notify you that it is doing a reverse merge into your working copy; click yes.
Commit the file (or make changes and commit) and you're done.
On committing the revision,the previous revision will become the head, effectively rolling-back, and chopping off the 'branch' at the desired point. (Although of course the 'branch' is there).
To roll back a file, start by right clicking on it and selecting Show Log.
Once you have the log open, right click on the desired version of your file.
Upon selecting this Tortoise SVN will notify you that it is doing a reverse merge into your working copy; click yes.
Commit the file (or make changes and commit) and you're done.
On committing the revision,the previous revision will become the head, effectively rolling-back, and chopping off the 'branch' at the desired point. (Although of course the 'branch' is there).
Sunday, June 28, 2009
simple python closure example
Original taken without permission from ScratchPad.
1>>> def counter(start=0, step=1):
2 ... x = [start]
3 ... def _inc():
4 ... x[0] += step
5 ... return x[0]
6 ... return _inc
7 ...
8 >>> c = counter()
9 >>> c()
10 1
11 >>> c()
12 2
13 >>> c()
14 3
Monday, June 22, 2009
changing ubuntu splash screens
1. http://ubuntuforums.org/archive/index.php/t-210268.html
2. http://ubuntuforums.org/showthread.php?t=89916&highlight=grub+splash+screen
2. http://ubuntuforums.org/showthread.php?t=89916&highlight=grub+splash+screen
Saturday, June 20, 2009
general linux commands
~/.bashrc is used to initialise each new shell instance
to set an environment variable, include a line analagous to
export PYTHONPATH=$PYTHONPATH:/home/david/Desktop/gdata-1.3.3/src
to set an environment variable, include a line analagous to
export PYTHONPATH=$PYTHONPATH:/home/david/Desktop/gdata-1.3.3/src
Setting up a mySQL DataBase on uBuntu
http://www.debuntu.org/how-to-create-a-mysql-database-and-set-privileges-to-a-user
'import MySQLdb' failed
http://davidmichaelthompson.com/?p=12
duh, need to install package 'python-mysqldb', 'A Python interface to mySQL'.
'import MySQLdb' failed
http://davidmichaelthompson.com/?p=12
duh, need to install package 'python-mysqldb', 'A Python interface to mySQL'.
Wednesday, June 17, 2009
Stationary Traffic Waves
Almost everyone in Jozi has experienced it:
You're driving along the ring-road, when suddenly you drive into the back of a traffic jam. 30 blood-boiling minutes later, you emerge out the other side, never the wiser for the cause of your delay.
Well, some mathematicians have modelled the process, which appears to involve information waves: Wired Magazine Article: Phantom Jams.
You're driving along the ring-road, when suddenly you drive into the back of a traffic jam. 30 blood-boiling minutes later, you emerge out the other side, never the wiser for the cause of your delay.
Well, some mathematicians have modelled the process, which appears to involve information waves: Wired Magazine Article: Phantom Jams.
Tuesday, June 16, 2009
plot f, f', f'' from csv with python & matplotlib
class rawDataObj:
pointCount = 0
colCount = 0
columns = []
colLabels = []
title = ""
# ===========================================
class Series:
def __init__(self):
self.x = []
self.y = []
#~ def __init__(self, xIn, yIn):
#~ if (len(xIn) != len(yIn)):
#~ raise lengthInequalityError, "length inequality"
#~ for zidx in range(len(xIn)):
#~ self.x.append(xIn[zidx])
#~ self.y.append(yIn[zidx])
# ================================
def DbyDX(self, xIn, yIn):
if (len(xIn) != len(yIn)):
raise setSizeInequalityError, 'set size inequality'
else:
for zidx in range(len(xIn) - 1):
xVal = (xIn[zidx + 1] + xIn[zidx]) / 2.0
self.x.append(xVal)
yVal = (yIn[zidx + 1] - yIn[zidx]) / (xIn[zidx + 1] - xIn[zidx])
self.y.append(yVal)
# ===========================================
import re
def loadrawDataObjFromFile(filePathAndName="/home/david/Desktop/ptpdrh.csv", hasHeader=False):
try:
f = open(filePathAndName, 'r')
one = []
two = []
eof = False
retDataObj = rawDataObj()
lineNum = 0
headerLineCount = 2
while (eof == False):
line = f.readline()
eof = (line == "")
if (line != ""):
lineNum = lineNum + 1
elements = re.split(',', line)
# strip newline (\n escape sequence) from last field of line
elements[len(elements) - 1] = elements[len(elements) - 1].rstrip("\n")
# validate column count
if (lineNum > headerLineCount):
if (len(elements) != retDataObj.colCount):
raise inconsistentColumnCountError, ('column count inconsistent at data line ' + (retDataOb.pointCount + 1))
if (lineNum <= headerLineCount):
if (lineNum == 1):
retDataObj.title = line
elif (lineNum == 2):
retDataObj.colCount = len(elements)
for num in range(retDataObj.colCount):
retDataObj.columns.append([])
for label in elements:
retDataObj.colLabels.append(label)
else: # if (lineNum > headerLineCount)
string = ""
for zidx in range(retDataObj.colCount):
string = elements[zidx]
if (len(string) == 0):
retDataObj.columns[zidx].append(None)
else:
retDataObj.columns[zidx].append(float(string))
retDataObj.pointCount = retDataObj.pointCount + 1
f.close()
except IOError:
print "io exception while attempting to load raw data"
print "from file:"
print filePathAndName
return retDataObj
# ===========================================
# ===========================================
from pylab import *
filePath = "/home/david/Desktop/FinData/"
fileName = "RSA_CPI_1981-2008.csv"
filePathAndName = filePath + fileName
dataObj = loadrawDataObjFromFile(filePathAndName, True)
#for y in range(dataObj.colCount - 1):
# plot(dataObj.columns[0], dataObj.columns[y + 1], label=str(dataObj.colLabels[y + 1]))
fig = figure()
fig.canvas.set_window_title(dataObj.title)
# BASE SERIES
axBase = subplot(311)
baseLabel = label=str(dataObj.colLabels[dataObj.colCount - 1])
plot(dataObj.columns[0], dataObj.columns[dataObj.colCount - 1], label="base")
legend(numpoints=1, loc="upper left")
# FIRST DERIVATIVE
d1 = Series()
d1.DbyDX(dataObj.columns[0], dataObj.columns[dataObj.colCount - 1])
axD1 = subplot(312, sharex=axBase)
plot(d1.x, d1.y, label="d/dt")
legend(numpoints=1, loc="upper left")
#SECOND DERIVATIVE
d2 = Series()
d2.DbyDX(d1.x, d1.y)
axD2 = subplot(313, sharex=axBase)
plot(d2.x, d2.y, label="d2/dt2")
legend(numpoints=1, loc="upper left")
#xlabel(dataObj.colLabels[0])
show()
Monday, June 15, 2009
Import & Display CSV Scatter with Python & MatPlotLib
class dataObject:
pointCount = 0
colCount = 0
columns = []
colLabels = []
# ===========================================
import re
def loadDataObjectFromFile():
filePath = "/home/david/Desktop/"
fileName = "ptpdrh.csv"
filePathAndName = filePath + fileName
firstLineIsLabels = True
try:
f = open(filePathAndName, 'r')
one = []
two = []
eof = False
retDataObj = dataObject()
isFirstLine = True
while (eof == False):
line = f.readline()
eof = (line == "")
if (line != ""):
elements = re.split(',', line)
elements[len(elements) - 1] = elements[len(elements) - 1].rstrip("\n")
if (isFirstLine == False):
if (len(elements) != retDataObj.colCount):
raise inconsistentColumnCountError, ('column count inconsistent at data line ' + (retDataOb.pointCount + 1))
if (isFirstLine == True):
isFirstLine = False
retDataObj.colCount = len(elements)
for num in range(retDataObj.colCount):
retDataObj.columns.append([])
if (firstLineIsLabels == True):
for label in elements:
retDataObj.colLabels.append(label)
else:
string = ""
for zidx in range(retDataObj.colCount):
string = elements[zidx]
if (len(string) == 0):
retDataObj.columns[zidx].append(None)
else:
retDataObj.columns[zidx].append(float(string))
retDataObj.pointCount = retDataObj.pointCount + 1
f.close()
except IOError:
print "io exception while attempting to load raw data"
print "from file:"
print filePathAndName
return retDataObj
# ===========================================
from pylab import *
dataObj = loadDataObjectFromFile()
titleText = "title"
for y in range(dataObj.colCount - 1):
plot(dataObj.columns[0], dataObj.columns[y + 1], label=str(dataObj.colLabels[y + 1]))
legend(numpoints=1)
xlabel(dataObj.colLabels[0])
ylabel("")
title(titleText)
show()
Howzit my China ?
For some very interesting reading on China, check out Wired News material on China.
Reading this has helped ease any misgivings I may have had about the ANC's pragmatic but possibly sub-optimal approach to foreign relations with the People's Republic of China.
I think there's plenty of room for improvement in terms of maximizing our side of the bargain, but the Chinese are definitely people you want to be involved in dialogue with at all times.
Reading this has helped ease any misgivings I may have had about the ANC's pragmatic but possibly sub-optimal approach to foreign relations with the People's Republic of China.
I think there's plenty of room for improvement in terms of maximizing our side of the bargain, but the Chinese are definitely people you want to be involved in dialogue with at all times.
Friday, June 12, 2009
small business rules
- allocate a generous leave allowance. enforce it's all being consumed within a window period.
Thursday, June 11, 2009
Durban Style Curry
1. Put oil
2. Put more oil [more oil than you would think.]
3. Fry the 'seeds' until they pop
here 'seeds' refers to
- jiru
- mustard seed
- cumin
- cardamom
- coriander
- cloves
- cinnamon
- star anise
- fennel seed
- some or other Indian herb
4. Add 'spices' and fry until they brown
here 'spices' refers to
- hot masala
- bay leaves
- chilli
- fresh ginger (finely chopped)
- ...
5. Add onions and garlic, and fry
6. Add tomatoes, other quicker cooking vegetables, potatoes and meat
in South Africa, use only 'up-to-date' brand potatoes
7. Cook on a low heat for a long time (essentially until potatoes are done)
8. Serve on a paper plate with a polysterene cup of brandy and coke
2. Put more oil [more oil than you would think.]
3. Fry the 'seeds' until they pop
here 'seeds' refers to
- jiru
- mustard seed
- cumin
- cardamom
- coriander
- cloves
- cinnamon
- star anise
- fennel seed
- some or other Indian herb
4. Add 'spices' and fry until they brown
here 'spices' refers to
- hot masala
- bay leaves
- chilli
- fresh ginger (finely chopped)
- ...
5. Add onions and garlic, and fry
6. Add tomatoes, other quicker cooking vegetables, potatoes and meat
in South Africa, use only 'up-to-date' brand potatoes
7. Cook on a low heat for a long time (essentially until potatoes are done)
8. Serve on a paper plate with a polysterene cup of brandy and coke
Un-Installing that unsolicited MS.NET FireFox Add-On
In order to un-install the unsolicited MS .NET Mozilla FireFox Add-On that appears after installing the 3.5 framework, follow Brad Abrahms directions:
http://blogs.msdn.com/brada/archive/2009/02/27/uninstalling-the-clickonce-support-for-firefox.aspx
http://blogs.msdn.com/brada/archive/2009/02/27/uninstalling-the-clickonce-support-for-firefox.aspx
Wednesday, June 10, 2009
Member Field Serialisation for Config Storage
using System;
using System.Reflection;
using System.IO;
using System.Collections;
namespace ConfigTester
{
public class CFG
{
public int pi = 3;
public string word = "tetragrammatron";
public TimeSpan time = new TimeSpan(1,6,6,6);
public string homeDir = @"/home/david/Desktop/";
public string configFName = "config.cfg";
public CFG()
{
}
// ===== ----- ===== ----- =====
public string FieldToSerial(string fieldName, int fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue.ToString());
}
public string FieldToSerial(string fieldName, string fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue);
}
public string FieldToSerial(string fieldName, TimeSpan fieldValue)
{
return string.Format("{0},{1},{2},{3},{4}", fieldName, fieldValue.Days, fieldValue.Hours, fieldValue.Minutes, fieldValue.Seconds);
}
// ===== ----- ===== ----- =====
public string[] FieldsToSerial()
{
ArrayList lines = new ArrayList();
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;
if (fieldInfo.FieldType == typeof(string))
{
string val = (string)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
if (fieldInfo.FieldType == typeof(int))
{
int val = (int)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = (TimeSpan)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
}
int fieldCount = lines.Count;
string[] fields = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
fields[fieldNum - 1] = (string)(lines[fieldNum - 1]);
return fields;
}
// ===== ----- ===== ----- =====
public void ListFieldInfo()
{
Console.WriteLine();
Console.WriteLine("FIELD INFO");
Console.WriteLine();
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Console.WriteLine("name: {0}", name);
Type fieldType = fieldInfo.FieldType;
Console.WriteLine("type: {0}", fieldType);
object obj = fieldInfo.GetValue(this);
Console.WriteLine("value: {0}", obj.ToString());
Console.WriteLine();
}
Console.WriteLine("{0} fields", fieldInfos.Length);
}
// ===== ----- ===== ----- =====
public void SerializeFields()
{
string fullFName = this.homeDir + this.configFName;
try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Create);
StreamWriter streamWriter = new StreamWriter(fileStream);
this.SerializeFields(streamWriter);
streamWriter.Close();
}
catch (Exception exc)
{
throw new Exception("ConfigSaveException");
}
}
// ===== ----- ===== ----- =====
public void SerializeFields(TextWriter tw)
{
string[] lines = this.FieldsToSerial();
foreach (string line in lines)
tw.WriteLine(line);
}
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
public void LoadSerialised()
{
string fullFName = this.homeDir + this.configFName;
ArrayList lines = new ArrayList();
try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Open);
StreamReader streamReader = new StreamReader(fileStream);
string line;
while ((line = streamReader.ReadLine()) != null)
lines.Add(line);
streamReader.Close();
int fieldCount = lines.Count;
string[] serials = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
serials[fieldNum - 1] = (string)(lines[fieldNum - 1]);
this.FieldsFromSerials(serials);
}
catch (Exception exc)
{
throw new Exception("ConfigLoadException");
}
}
// ===== ----- ===== ----- =====
public string StringFromSerial(string serial)
{
return serial;
}
// ===== ----- ===== ----- =====
public int IntFromSerial(string serial)
{
return Convert.ToInt32(serial);
}
// ===== ----- ===== ----- =====
public TimeSpan TimeSpanFromSerial(string serial)
{
string[] vals = serial.Split(',');
if (vals.Length != 4)
throw new Exception("timespan serial has incorrect number of variables");
int days = Convert.ToInt32(vals[0]);
int hrs = Convert.ToInt32(vals[1]);
int mins = Convert.ToInt32(vals[2]);
int secs = Convert.ToInt32(vals[3]);
return new TimeSpan(days, hrs, mins, secs);
}
// ===== ----- ===== ----- =====
public string MatchKey(string key, string[] keys, string[] values)
{
if (keys.Length != values.Length)
throw new Exception("key count must match value count, but does not");
for (int num = 1; num <= keys.Length; num++)
if (key == keys[num - 1])
return values[num - 1];
return null;
}
// ===== ----- ===== ----- =====
public void FieldsFromSerials(string[] serials)
{
// separate names & serialised form of fields retrieved from storage
int fieldCount = serials.Length;
string[] names = new string[fieldCount];
string[] forms = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
{
int splitMarker = serials[fieldNum - 1].IndexOf(',');
string name = serials[fieldNum - 1].Substring(0, splitMarker);
string form = serials[fieldNum - 1].Substring(splitMarker + 1);
names[fieldNum - 1] = name;
forms[fieldNum - 1] = form;
}
// scan through this instantiated object
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;
string serialString = this.MatchKey(name, names, forms);
if (fieldInfo.FieldType == typeof(string))
{
string val = this.StringFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
if (fieldInfo.FieldType == typeof(int))
{
int val = this.IntFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = this.TimeSpanFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
}
}
// ===== ----- ===== ----- =====
} // class
} // namespace
using System.Reflection;
using System.IO;
using System.Collections;
namespace ConfigTester
{
public class CFG
{
public int pi = 3;
public string word = "tetragrammatron";
public TimeSpan time = new TimeSpan(1,6,6,6);
public string homeDir = @"/home/david/Desktop/";
public string configFName = "config.cfg";
public CFG()
{
}
// ===== ----- ===== ----- =====
public string FieldToSerial(string fieldName, int fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue.ToString());
}
public string FieldToSerial(string fieldName, string fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue);
}
public string FieldToSerial(string fieldName, TimeSpan fieldValue)
{
return string.Format("{0},{1},{2},{3},{4}", fieldName, fieldValue.Days, fieldValue.Hours, fieldValue.Minutes, fieldValue.Seconds);
}
// ===== ----- ===== ----- =====
public string[] FieldsToSerial()
{
ArrayList lines = new ArrayList();
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;
if (fieldInfo.FieldType == typeof(string))
{
string val = (string)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
if (fieldInfo.FieldType == typeof(int))
{
int val = (int)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = (TimeSpan)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
}
int fieldCount = lines.Count;
string[] fields = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
fields[fieldNum - 1] = (string)(lines[fieldNum - 1]);
return fields;
}
// ===== ----- ===== ----- =====
public void ListFieldInfo()
{
Console.WriteLine();
Console.WriteLine("FIELD INFO");
Console.WriteLine();
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Console.WriteLine("name: {0}", name);
Type fieldType = fieldInfo.FieldType;
Console.WriteLine("type: {0}", fieldType);
object obj = fieldInfo.GetValue(this);
Console.WriteLine("value: {0}", obj.ToString());
Console.WriteLine();
}
Console.WriteLine("{0} fields", fieldInfos.Length);
}
// ===== ----- ===== ----- =====
public void SerializeFields()
{
string fullFName = this.homeDir + this.configFName;
try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Create);
StreamWriter streamWriter = new StreamWriter(fileStream);
this.SerializeFields(streamWriter);
streamWriter.Close();
}
catch (Exception exc)
{
throw new Exception("ConfigSaveException");
}
}
// ===== ----- ===== ----- =====
public void SerializeFields(TextWriter tw)
{
string[] lines = this.FieldsToSerial();
foreach (string line in lines)
tw.WriteLine(line);
}
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
public void LoadSerialised()
{
string fullFName = this.homeDir + this.configFName;
ArrayList lines = new ArrayList();
try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Open);
StreamReader streamReader = new StreamReader(fileStream);
string line;
while ((line = streamReader.ReadLine()) != null)
lines.Add(line);
streamReader.Close();
int fieldCount = lines.Count;
string[] serials = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
serials[fieldNum - 1] = (string)(lines[fieldNum - 1]);
this.FieldsFromSerials(serials);
}
catch (Exception exc)
{
throw new Exception("ConfigLoadException");
}
}
// ===== ----- ===== ----- =====
public string StringFromSerial(string serial)
{
return serial;
}
// ===== ----- ===== ----- =====
public int IntFromSerial(string serial)
{
return Convert.ToInt32(serial);
}
// ===== ----- ===== ----- =====
public TimeSpan TimeSpanFromSerial(string serial)
{
string[] vals = serial.Split(',');
if (vals.Length != 4)
throw new Exception("timespan serial has incorrect number of variables");
int days = Convert.ToInt32(vals[0]);
int hrs = Convert.ToInt32(vals[1]);
int mins = Convert.ToInt32(vals[2]);
int secs = Convert.ToInt32(vals[3]);
return new TimeSpan(days, hrs, mins, secs);
}
// ===== ----- ===== ----- =====
public string MatchKey(string key, string[] keys, string[] values)
{
if (keys.Length != values.Length)
throw new Exception("key count must match value count, but does not");
for (int num = 1; num <= keys.Length; num++)
if (key == keys[num - 1])
return values[num - 1];
return null;
}
// ===== ----- ===== ----- =====
public void FieldsFromSerials(string[] serials)
{
// separate names & serialised form of fields retrieved from storage
int fieldCount = serials.Length;
string[] names = new string[fieldCount];
string[] forms = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
{
int splitMarker = serials[fieldNum - 1].IndexOf(',');
string name = serials[fieldNum - 1].Substring(0, splitMarker);
string form = serials[fieldNum - 1].Substring(splitMarker + 1);
names[fieldNum - 1] = name;
forms[fieldNum - 1] = form;
}
// scan through this instantiated object
Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;
string serialString = this.MatchKey(name, names, forms);
if (fieldInfo.FieldType == typeof(string))
{
string val = this.StringFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
if (fieldInfo.FieldType == typeof(int))
{
int val = this.IntFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = this.TimeSpanFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
}
}
// ===== ----- ===== ----- =====
} // class
} // namespace
Wednesday, May 27, 2009
GTK-Sharp: Scrollable (Window) Label Example
using System;
using System.Collections;
using Gtk;
namespace gtkTest
{
public class SWinLabel
{
private Window topWin;
private static int defWidth = 400;
private static double phi = 1.6180339887;
private static int defHeight = (int)( ((double)(defWidth)) / phi);
private ScrolledWindow sWin;
private Label label;
private string labelText;
private string winTitleText;
// ==========================================================
public SWinLabel(string pWinTitleText, string rawLabelText)
{
winTitleText = pWinTitleText;
topWin = new Window(winTitleText);
topWin.SetDefaultSize(defWidth, defHeight);
topWin.SetPosition(WindowPosition.Center); // TODO
sWin = new ScrolledWindow();
sWin.SetPolicy(Gtk.PolicyType.Always, Gtk.PolicyType.Always);
topWin.Add(sWin);
sWin.Show();
labelText = rawLabelText;
label = new Label(rawLabelText);
sWin.AddWithViewport(label);
label.Show();
topWin.Show();
}
// ==========================================================
}
}
Tuesday, May 26, 2009
Terrorism & Self Worth
I was chatting with an intelligent young lady on Saturday, and over time became rather alarmed.
She was convinced of the following points:
1. The world economy is in a state of collapse.
2. Total ecological holocaust is imminent.
3. Her and her peers, raised to believe that great things were within their reach, should accept their inevitable mediocrity.
On the topic of potential and achievement, I felt that this attitude and the crisis of identity crisis it speaks of, seems to be a direct result from having a top-down / one-to-many media distribution system and the related one-to-many mass production of consumable and semi-durable goods.
This girl felt that she had to do something great, I can only think in order to acquire status or a sense of worth, in order to _justify_ her existence.
As a result of the top-down nature of society this girl does not receive animal satisfaction through co-operative interaction with members of her community, and cannot derive an immediate sense of self-worth as result of the clear and obvious benefit the ramifications of her existence, specifically the fruits of her labour, render to others whom _she_ values.
Unfortunately the likelihood of her successfully emerging from the herd to a position of rarity is made all the more unlikely by the top-down winner-takes-all nature of the current social model.
Thus, she effectively exhibits what I, knowing nothing of Marx, would guess to be classical workers alienation.
She was convinced of the following points:
1. The world economy is in a state of collapse.
2. Total ecological holocaust is imminent.
3. Her and her peers, raised to believe that great things were within their reach, should accept their inevitable mediocrity.
On the topic of potential and achievement, I felt that this attitude and the crisis of identity crisis it speaks of, seems to be a direct result from having a top-down / one-to-many media distribution system and the related one-to-many mass production of consumable and semi-durable goods.
This girl felt that she had to do something great, I can only think in order to acquire status or a sense of worth, in order to _justify_ her existence.
As a result of the top-down nature of society this girl does not receive animal satisfaction through co-operative interaction with members of her community, and cannot derive an immediate sense of self-worth as result of the clear and obvious benefit the ramifications of her existence, specifically the fruits of her labour, render to others whom _she_ values.
Unfortunately the likelihood of her successfully emerging from the herd to a position of rarity is made all the more unlikely by the top-down winner-takes-all nature of the current social model.
Thus, she effectively exhibits what I, knowing nothing of Marx, would guess to be classical workers alienation.
Using Gtk-Sharp in VS2008 - .DLL Path & Assembly Reference Issues
Get the .msi windows installer from the Mono project page:
http://www.mono-project.com/Gtk-Sharp_Installer_for_.NET_Framework
After running the installer, I found that it incorrectly appended the system Path variable, forgetting to add a trailing '\', resulting in VS2008 failing to find .dll's, and throwing a DllNotFoundException [Unable to load DLL 'libglib-2.0-0.dll'].
After fixing this, you're good to go.
Just remember to add references to the following assemblies
glib-sharp
atk-sharp
gtk-sharp
in your project.
Some useful links on the subject:
http://www.ondotnet.com/pub/a/dotnet/2004/08/09/gtk_mono.htm?page=last&x-order=date
http://www.mono-project.com/Gtk-Sharp_Installer_for_.NET_Framework
After running the installer, I found that it incorrectly appended the system Path variable, forgetting to add a trailing '\', resulting in VS2008 failing to find .dll's, and throwing a DllNotFoundException [Unable to load DLL 'libglib-2.0-0.dll'].
After fixing this, you're good to go.
Just remember to add references to the following assemblies
glib-sharp
atk-sharp
gtk-sharp
in your project.
Some useful links on the subject:
http://www.ondotnet.com/pub/a/dotnet/2004/08/09/gtk_mono.htm?page=last&x-order=date
Monday, May 25, 2009
GTK-Sharp: Scrollable (Window) Table Example
using System;
using Gtk;
namespace gtkTest
{
public class WinTable
{
private Gtk.ScrolledWindow sWinRef;
private Table table;
private uint rowCount, colCount, rowSpacing, colSpacing;
// ==========================================================
public WinTable(uint pRowCount, uint pColCount, uint pRowSpacing, uint pColSpacing, Gtk.ScrolledWindow pSWinRef)
{
sWinRef = pSWinRef;
rowCount = pRowCount;
colCount = pColCount;
rowSpacing = pRowSpacing;
colSpacing = pColSpacing;
bool homogeneous = true;
table = new Table (rowCount, colCount, homogeneous);
for (uint rowNum = 1; rowNum <= rowCount; rowNum++)
table.SetRowSpacing(rowNum - 1, rowSpacing);
for (uint colNum = 1; colNum <= colCount; colNum++)
table.SetColSpacing(colNum - 1, colSpacing);
sWinRef.AddWithViewport(table);
}
// ==========================================================
/* for e.g. = 2 x 2 table, say (horiz,vert), then
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
*/
public void PackWidgetAtXY(Widget widget, uint x, uint y)
{
uint leftAttach = x - 1;
uint rightAttach = x;
uint topAttach = y - 1;
uint bottomAttach = y;
//Gtk.AttachOptions xOptions = new Gtk.AttachOptions(); // fill, shrink, expand
table.Attach(widget, leftAttach, rightAttach, topAttach, bottomAttach);
widget.Show();
}
// ==========================================================
public void Demo()
{
for (uint rowNum = 1; rowNum <= rowCount; rowNum++)
for (uint colNum = 1; colNum <= colCount; colNum++)
{
string text = "one\ntwo\nthree\nfour";
Label label = new Label(text);
this.PackWidgetAtXY(label, rowNum, colNum);
}
this.table.Show();
}
// ==========================================================
}
//####################################################
public partial class MainWindow: Gtk.Window
{
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
}
//####################################################
class MainClass
{
public static void Main (string[] args)
{
Application.Init ();
MainWindow mainWin = new MainWindow ();
uint rowCount = 8, colCount = 7;
uint rowSpacing = 80, colSpacing = 200;
mainWin.ShowAll();
Window priWin = new Window("Primary Window");
priWin.SetDefaultSize(250, 200);
priWin.SetPosition(WindowPosition.Center);
Gtk.ScrolledWindow sWin = new Gtk.ScrolledWindow();
sWin.SetPolicy(Gtk.PolicyType.Always, Gtk.PolicyType.Always);
priWin.Add(sWin);
sWin.Show();
WinTable winTable = new WinTable(rowCount, colCount, rowSpacing, colSpacing, sWin);
winTable.Demo();
priWin.Show();
Application.Run ();
}
}
}
Sunday, May 24, 2009
ubuntu 9.04 audio fiddling
On having trouble getting sound to work under rhythmbox after installing uBuntu 9.04 on my old Fujitsu-Siemens, I found the following directions very useful:
http://www.ubuntugeek.com/sound-solutions-for-ubuntu-904-jaunty-users.html
http://www.ubuntugeek.com/sound-solutions-for-ubuntu-904-jaunty-users.html
ubuntu 9.04 audio codecs
sudo apt-get install non-free-codecs libxine1-ffmpeg gxine mencoder mpeg2dec
to fix skype 'problem with audio playback' in ubuntu 9.04
- killall pulseaudio
- sudo apt-get remove pulseaudio
- sudo apt-get install esound
- sudo rm /etc/X11/Xsession.d/70pulseaudio
Subscribe to:
Posts (Atom)