Flash pelejä

13 October 2008 - 2 kk 24 pv sitten.

Se on taas maanantai, mutta mitään järkevää ei ole tullut saatua aikaiseksi. Oikeastaan koko päivä on mennyt webissä surffatessa ja pelatessa flash pelejä. Oma top 3:

Google - 10 vuotta

4 October 2008 - 3 kk 3 pv sitten.

Google täytti 10 vuotta, pari päivää sitten. Pyöreän juhlan kunniaksi julkaistiin historiallinen google versio vuodelta 2001. Voi hetken aikaa miettiä retro meininkiä ja googlettaa vaikka omia vanhoja webbi sivujaan.

Voisi väittää että webin luonne on kaupunkilaistunut. Keskustelu on muuttunut pienestä kylä yhteisöstä kaupinkimaiseksi omassa piireissä oleviin sosiaalisiin yhteisöihin. Ulkoasu on parantunut ja tarjontaa on tullut lisää.

Death Dice Overdose

30 September 2008 - 3 kk 7 pv sitten.

Tuntuuko että paikka lataamossa on lähellä? Rauhoitu ja vähennä stressiä pelaamalla jotain rauhoittavaa flash peliä.

Death Dice Overdose:ssa väistellään kohtalon heittelemiä noppia! Suuret taivaalta putoilevat nopat aiheuttavat ymmärrettävästi paniikkia sankarissamme, joten kerää lääkkeitä pysyäksesi järjissäsi. Kun popsit tarpeeksi pillereitä niin pääset overdose tilaan jossa rauhallisimmatkin epilepsikot saavat oireita. Tämä kaikki höystettynä tracker musiikin kanssa on oman laatuinen kokemus.

Päivitystä

17 September 2008 - 3 kk 20 pv sitten.

Rauha maassa ja tietokone pari viikkoa pois käytästä. Ensimmäinen käynnistys ja päivitys rulianssi alkaa. Haluatko päivittää ilmoitus x kertaa ja sähköpostilaatikko tupaten täynnä. Hiljainen palaaminen takaisin arkeen ei oikein tunnu onnistuvan.

C# merkkijono suorituskyky testi

13 August 2008 - 4 kk 26 pv sitten.

Tässä on pieni suorituskyky testi C#:llä, joka vertailee merkkijonojenen merkkien käsittelyä eri toimintatavoilla.

Testin tulokset:

28218,75 ns per operation (RegEx)
765,63 ns per operation (StringBuilder)
687,50 ns per operation (char taulukot)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Testi1
{
    class Program
    {
        static void Main(string[] args)
        {
            int loopCount = 1000000;
            long startTime, endTime;
            double nanoseconds;
 
            startTime = DateTime.Now.Ticks * 100;
            for (int x = 0; x < loopCount; x++)
            {
                ExtractNumbers1("Its is only 4 numbers but must be 1337");
            }
            endTime = DateTime.Now.Ticks * 100;
            nanoseconds = ((double)(endTime - startTime)) / ((double)loopCount);
            Console.WriteLine(nanoseconds.ToString("F") + " ns per operation");
 
            startTime = DateTime.Now.Ticks * 100;
            for (int x = 0; x < loopCount; x++)
            {
                ExtractNumbers2("Its is only 4 numbers but must be 1337");
            }
            endTime = DateTime.Now.Ticks * 100;
            nanoseconds = ((double)(endTime - startTime)) / ((double)loopCount);
            Console.WriteLine(nanoseconds.ToString("F") + " ns per operation");
 
            startTime = DateTime.Now.Ticks * 100;
            for (int x = 0; x < loopCount; x++)
            {
                ExtractNumbers3("Its is only 4 numbers but must be 1337");
            }
            endTime = DateTime.Now.Ticks * 100;
            nanoseconds = ((double)(endTime - startTime)) / ((double)loopCount);
            Console.WriteLine(nanoseconds.ToString("F") + " ns per operation");
 
            Console.Read();
        }
 
        static string ExtractNumbers1(string expr)
        {
            return string.Join(null, System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));
        }
 
        static string ExtractNumbers2(string expr)
        {
            StringBuilder sb = new StringBuilder(expr.Length);
 
            foreach (char ch in expr)
            {
                if (Char.IsDigit(ch))
                    sb.Append(ch);
            }
 
            return sb.ToString();
        }
 
        static string ExtractNumbers3(string expr)
        {
            char[] nums = new char[expr.Length];
            int pos = 0;
 
            foreach (char ch in expr)
            {
                if( Char.IsDigit( ch ))
                    nums[pos++] = ch;
            }
 
            return new string ( nums, 0, pos );
        }
    }
}

Rinnakkaislaskentaa

4 August 2008 - 5 kk 4 pv sitten.

Intel suosittelee algoritmien suunnittelemisen rinnakkaislaskentaan soveltuvaksi ja AMD työpöydällä on 12 ytiminen prosessori. Siinä missä prosessori valmistajat lisäävät ytimiä prosessoriin niin tavallisen koodaajan päänsärky vain kasvaa.

Tavallisten algoritmien muuttaminen rinnakkaisalgoritmaiksi ei varmaan ole mitään herkkua. Jotta moniydin arkkitehtuurista saataisiin käytännön laskentatehoa irti pitäisi sovelluskirjastot suunnitella uudestaan.

Olen aistivinani tässä ohjelmistokehityksen tulevan virstanpylvään.

C# Laajennetut luokat

24 July 2008 - 5 kk 15 pv sitten.

Tuli luettua C# kielioppia. Mukavana ominaisuutena huomasin että nykyään pystytään (versiosta 3.0 lähtien) laajentamaan valmiita kirjastoluokkia. Tämä avaa mukavia mahdollisuuksia poistaa itseään häiritseviä piirteitä.

Laajennuksen tekeminen onnistuu lisäämällä this sana metodin parametrin määrittelyyn. Alla esimerkki string luokan laajennuksesta.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Text.RegularExpressions;
 
namespace StringExtensions
{
    public static class StringExtensions
    {
        /// <summary>
        /// Remove any non-numeric characters and then return the resultant string.
        /// Useful for parsing phone numbers.
        /// </summary>
        /// <param name="s">The text that is to be evaluated.</param>
        /// <returns>New string</returns>                 
        public static string RemoveNonNumeric(this string s)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
                if (Char.IsNumber(s[i]))
                    sb.Append(s[i]);
            return sb.ToString();
        }
 
        /// <summary>
        /// Returns the substring of the first argument string that follows the first occurrence 
        /// of the second argument string in the first argument string, or the empty 
        /// string if the first argument string does not contain the second argument string.
        /// </summary>
        /// <param name="source">The text that is to be evaluated.</param>
        /// <param name="value">String to search.</param>
        /// <returns>New string</returns>
        public static string SubstringAfter(this string source, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return source;
            }
            CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
            int index = compareInfo.IndexOf(source, value, CompareOptions.Ordinal);
            if (index < 0)
            {
                //No such substring
                return string.Empty;
            }
            return source.Substring(index + value.Length);
        }
 
        /// <summary>
        /// Returns the substring of the first argument string that precedes the first occurrence of 
        /// the second argument string in the first argument string, or the empty string if 
        /// the first argument string does not contain the second argument string.
        /// </summary>
        /// <param name="source">The text that is to be evaluated.</param>
        /// <param name="value">String to search.</param>
        /// <returns>New string</returns>
        public static string SubstringBefore(this string source, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }
            CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
            int index = compareInfo.IndexOf(source, value, CompareOptions.Ordinal);
            if (index < 0)
            {
                //No such substring
                return string.Empty;
            }
            return source.Substring(0, index);
        }
 
        /// <summary>
        /// Truncate string using dots...
        /// Useful for displaying long filename paths.
        /// </summary>
        /// <param name="s">String to be truncated.</param>
        /// <param name="maxLength">Maximum string size</param>
        /// <returns>New string</returns>
        public static string Truncate(this string s, int maxLength)
        {
            if (string.IsNullOrEmpty(s) || maxLength <= 0)
                return string.Empty;
            else if (s.Length > maxLength)
                return s.Substring(0, maxLength) + "...";
            else
                return s;
        }
 
        /// <summary>
        /// Reverse string.
        /// </summary>
        /// <param name="s">String to be reversed.</param>
        /// <returns>Reversed string.</returns>
        public static string Reverse(this string s)
        {
            char[] c = s.ToCharArray();
            Array.Reverse(c);
            return new string(c);
        }
 
        /// <summary>
        /// Test if string contains only numbers.        
        /// </summary>
        /// <param name="text">The text that is to be evaluated.</param>
        /// <returns>True if text included only letters.</returns>
        public static bool IsAlpha(this string text)  
        {            
            foreach (char c in text.ToLower())  
            {  
                if (!char.IsLetter(c))
                    return false;  
            }  
            return true;  
        }
 
        /// <summary>
        /// Check is string is valid email address.
        /// </summary>
        /// <param name="email">Email to be checked.</param>
        /// <returns>True if email address was ok.</returns>        
        public static bool IsValidEmailAddress(this string email)
         {             
             const string REGEX_VALID_EMAIL =
                 @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|" +
                 @"(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
             bool valid = Regex.IsMatch(email, REGEX_VALID_EMAIL);
             return valid;
         }
 
        /// <summary>
        /// Convert string to integer.
        /// </summary>
        /// <param name="s">String to be processed.</param>
        /// <returns>Integer</returns>
        public static int ToInteger(this string s)
        {
            int integerValue = 0;
            int.TryParse(s, out integerValue);
            return integerValue;
        }
 
        /// <summary>
        /// Compare two strings, ignore case.
        /// </summary>
        /// <param name="s1">String 1</param>
        /// <param name="s2">String 2</param>
        /// <returns>If equal return true.</returns>
        public static bool Comparei(this string s1, string s2)
        {
            CompareInfo Compare = CultureInfo.InvariantCulture.CompareInfo;
            int i = Compare.IndexOf(s1, s2, CompareOptions.IgnoreCase);
            if (i != 0 )
                return true;
            else
                return false;
        }
    }
}

Hakukone äänestämistä

20 July 2008 - 5 kk 19 pv sitten.

Tietoviikko uutisoi että googleen on tulossa äänestystoiminto. Ainakin siellä päin tunnetaan uskovan äänestyksen tulevaisuuteen. Hakukone äänestäminen voisi avata yhden uuden mahdollisuuden jossa ennen ollaan epäonnistuttu. Nimittäin maakohtaiset hakukoneet.

Onhan tätä suomessakin koitettu pariin kertaan ja kukaan ei oikeastaan ole käyttänyt kotimaista alku innostuksen jälkeen. Ongelmana on ollut hakutulosten epäloogisuus, jotta joku palvelua käyttäisi niin sen täytyisi olla parempi kuin Google.

Herätyskello

19 July 2008 - 5 kk 20 pv sitten.

Joskus se pyörä vaan kannattaa keksiä uudestaan. Tämmöinen tapaus tuli eteen kun koitin etsiä sopivaa herätyskello ohjelmaa. No mitäs ongelmaa tässä voi olla eikun surffailua www.download.com:iin ja alarm hakusanaksi. Ongelmaksi muodostui 739 osumaa. Eri ohjelmien vertailu vie ikuisuuden.

Herätyskello on ohjelmoinnin kannalta helppo tehtävä. Tuntuu että jokainen harrastelija on väsännyt oman ohjelman jossa on miljoona eri ominaisuutta ja minä olisin kaivannut vain jotain pientä ja yksinkertaista.

Eli mahdollisimman minimalistinen toteutus. Formi on mahdollisimman pieni ettei se vie ruudulta tilaa. Eli luodaan pieni työkaluikkuna. Erilaisia formin asetuksia:

  • BackColor 233;233;233
  • FormBorderStyle FixedToolWindow
  • MaximizeBox False
  • MaximumSize 156;70
  • Opacity 80%
  • ShowInTaskBar False

Kuten kuvasta näkyy on käytössä on kaksi lapsi ikkunaa. DateTimePicker ja CheckBox. DateTimePickerin asetuksia on yksinkertaistettu, tiputin sekunnit ja kalenteri mahdollisuuden pois.

  • CustomFormat HH:mm
  • Format Custom
  • ShowUpDown True

Valintalaatikko joka näyttää napilta on valittu Appearance: button kohdasta. Näin saadaan aika minimalistinen ulkomuoto. Yleensä herätyskellot pitää jonkinlaista ääntä mutta itse pidän enemmän visuaalisista tehosteista. Ikkuna pomppaa eteen hälyyttäessä ja värisee (Windows live messangerin tapaan).

// Simple alarm clock.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Alarm
{
    public partial class Alarm : Form
    {
        private DateTime AlarmTime;
        private bool AlarmState = false;
 
        public Alarm()
        {
            InitializeComponent();
        }
 
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            // If alarm is running then change it to back to normal.
            if (AlarmState == true)
            {
                AlarmState = false;
                checkBox1.Text = "Set alarm";
                TopMost = false;
                Timer.Interval = 60000;
                Timer.Stop();
                return;
            }
 
            if (checkBox1.Checked == false)
            {
                Timer.Stop();
                dateTimePicker1.Enabled = true;
                return;
            }
 
            AlarmTime = dateTimePicker1.Value;
            RolloverTime();
 
            Timer.Start();
            dateTimePicker1.Enabled = false;
        }
 
        private void RolloverTime()
        {
            // If the user selects a time already passed, it must be for tomorrow
            if (DateTime.Now.TimeOfDay.CompareTo(AlarmTime.TimeOfDay) &gt; 0)
            {
                AlarmTime = new DateTime(DateTime.Now.Year,
                    DateTime.Now.Month, DateTime.Now.Day + 1,
                    AlarmTime.Hour, AlarmTime.Minute, AlarmTime.Second);
            }
            // Otherwise, set it for today
            else
            {
                AlarmTime = new DateTime(DateTime.Now.Year,
                    DateTime.Now.Month, DateTime.Now.Day,
                    AlarmTime.Hour, AlarmTime.Minute, DateTime.Now.Second);
            }
        }
 
        private void AlarmTimer_Tick(object sender, EventArgs e)
        {
            AlarmState = true;
            checkBox1.Text = "Turn off";
            TopMost = true;
 
            NudgeMe(this);
            Timer.Interval = 5000;
            Timer.Start();
 
        }
 
        private void Alarm_Load(object sender, EventArgs e)
        {
            dateTimePicker1.Value = dateTimePicker1.Value.AddMinutes(10);
        }
 
        static void NudgeMe(Form TargetForm)
        {
            // Store the original location of the form.
 
            int xCoord = TargetForm.Left;
            int yCoord = TargetForm.Top;
 
            // An integer for storing the random number each time
 
            int rnd = 0;
 
            // Instantiate the random generation mechanism
 
            Random RandomClass = new Random();
 
            for (int i = 0; i &lt;= 500; i++)
            {
                rnd = RandomClass.Next(xCoord + 1, xCoord + 15);
                TargetForm.Left = rnd;
                rnd = RandomClass.Next(yCoord + 1, yCoord + 15);
                TargetForm.Top = rnd;
            }
 
            // Restore the original location of the form
            TargetForm.Left = xCoord;
            TargetForm.Top = yCoord;
        }
    }
}

Facebook-sukupolvi on vaarallinen

3 July 2008 - 6 kk 6 pv sitten.

Iltalehti otsikoi että Facebook-sukupolvi on vaarallinen.

Tyagin mukaan ihmiset, jotka tottuvat netin nopeaan tahtiin, voivat pian kokea sen ulkopuolisen maailman tylsänä ja epästimuloivana, mikä voi johtaa äärimmäiseen käytökseen.

Ei mielestäni ole kovin ihmeellinen päätelmä. Eiköhän jokainen aktiivinen tietotekniikan harrastaja tai ammattilainen joka puuhailee tietokoneella intohimoisesti näe jotain mielenkiintoista siinä tietokoneen ruudulla. Tästähän on syntynyt tämmöinen nörtti käsitekkin.

Ulkopuolinen maailma alkaa tuntua hitaalta. Sen huomaa ensimmäiseksi uutisista, sen että lukee lehteä ja tuntee suurimman osan uutisotsikoista. Seurauksena erilaisista nopeista uutispalveluista kuten Ampparit.com.

Aiheuttaako tietotekniikka sitten äärimmäistä käyttäytymistä? Voi sanoa että yllättävän helposti. Käytännön esimerkki heti tulee mieleen pitkät peli sessiot. Mene kysymään tietotekniikan opiskelijalta että mitä teit lauantaina niin vastauksena on että pelasin xxx 12 tuntia. Eikä vastausta pidetä mitenkään kummallisena.

Tuntuu että nuorempi sukupolvi elää paljon nopeampaa elämää. Nopeus tuskin tulee pelkästään tietotekniikasta, vaikkaisin että suurin osa tulee populaarikulttuurista. Mitäs sitten kun nopeuteen tottunut sukupolvi vanhenee? Tulee pika ihmmisteita ja pika organisaatio uudistuksia jne.

Noh jos vaikka hallituskin ryhtyisi pikaisiin toimenpiteisiin tulevaisuudessa.