Kategorie: web development

Alles was mit Web Development zu tun hat gehört zu dieser Kategorie.

  • Loops for Beginners

    This is a shallow tutorial about loops for programming beginners (as my wife). It should get you kick-started but please don’t stop here. There’s a lot more to explore.
    I chose JavaScript since you can run it right here in your browser’s dev tools (CTRL+SHIFT+i in most browsers, then choose console).

    There might be some things in the code examples that don’t make sense to you yet. Just note them down and don’t fall into the rabbit just yet. I provide some extra hints and rabbit holes. Try to sweep over this once without following the white rabbit to focus on the topic.

    Prerequisites:

    • you want to learn this stuff – at least at a practical level
    • you’ve seen JavaScript (JS) before
    • you’ve read the term iteration before
    • you have at least an idea what some of these mean: collection, set, list, vector, array, iterable
    • you know basic data types such as Booleans

    Aight, let’s start with a problem. Let’s say you program a little game for a set of players. There’s Tom, Anne and Jane. You want to greet them before explaining the rules. That’s easy:

    console.log('Hi Tom, Anne and Jane.')

    Fair enough. Now think you have twenty players. Things start to get a little tedious but that’s still managable. Alright.
    Now think you want to open this up to an unknown set of players. At the time you write your program you don’t know how many players there will be nor their names. Now how do you solve this problem?

    Take a moment to figure something out.

    .
    .
    .

    Right, how could the answer not have been „loops“?

    There’s pretty much two and a half types of loops in almost all languages and they come in some differen flavours.

    A loop consists of some condition or control structure and a body. The body gets executed over and over again as long as the condition holds. In C-style languages the basic form is some keyword(s) (condition in parantheses) {body in curly braces}.

    First there is the while loop. It keeps executing it’s body as long as a given expression stays true (and you do not break out of it).

    As long as there’s dirty dishes:
    ____do the dishes

    or:

    While there are dirty dishes:
    ____wash
    ____rinse

    Let’s see how it can solve our problem:

    alert("Who's playing? Type in player names one after another. Type 'done' when you're done.")
    let players = []
    let isDone = false
    
    while (!isDone) {
        let player = prompt('Who are you?')
        if (player === 'done')
            isDone = true
        else
            players.push(player)
    }
    alert('Hello ' + players.join(', '))

    What happens here? As long as we are not done (isDone is false), we will keep asking for player names. If the user types in done we will set isDone to false and the next time the loop’s condition is checked it will evaluate to false and the program flow will continue past the loop’s body. In JS and many other languages the form is „while (condition) { stuff to do as long as condition holds }„.

    Hint: For one-lines you can omit the curly braces.
    Hint: There’s often also do-while of the form „do { stuff } while (condition)“ or do-until where the first iteration of the loop is executed before the condition is checked. Can be handy but you won’t see it often.
    Rabbit Hole: In sane languages, code outside the loop’s body has no access to things declared inside of it.

    Great! Now try to output the collected player names with a while loop.

    Let’s continue with the classic for loop. It is the same as the while loop but with some handy extras. It also keeps executing it’s body as long as a condition holds. But it allows you to declare and initialize a variable and to provide a statement to be executed after each iteration. The common form is „for (initializer; condition; post-loop-statement) { stuff to be repeated }“.

    A speed date:
    For: pour in one glass of wine; not more than ten in total; refill after each round:
    ____have a conversation
    ____drink wine
    ____move to next table


    Let’s see it in action:

    players = []
    let numPlayers = prompt('How many players are there?')
    alert("Who's playing? Type in player names one after another.")
    
    for (let i = 0; i < numPlayers; i++) {
        players.push(prompt('Who are you?'))
    }
    alert('Hello ' + players.join(', '))

    Rabbit Hole: See JS‘ variable declaration to understand what let does here.

    What’s going on here? We first ask for the number of players. Then, we execute the loop’s body this many times. We declare a variable i and initialize it to zero. This is only done once, before the loop’s body executes. The next thing that happens is that the loop’s condition gets checked. If you entered five, for example, 0 < 5 holds and the body gets executed. After that, the post-iteration statement gets executed (i++ in this case is the same as i = i + 1) and i will be incremented by one. It is now 1 (0 + 1). The condition still holds so we go for another round and so on until 5 < 5 evaluates to false. What values does i take one after another?

    0, 1, 2, 3, 4.
    You could as well have started at 1 and chosen i <= 5 as your condition. Or i < 6. You could have chosen 5 as initial value for i and counted down: for (let i = 5; i > 0; i--);. Or you could have counted until 10 with two-step increments. In our case the value of i only matters for the condition and we want to run the body five times.

    But this loop style comes in handy when you have a reason to know that it’s currently the nth iteration of the loop. Let’s change our example a little with emphasis on the first and last players:

    players = []
    numPlayers = prompt('How many players are there?')
    alert("Who's playing? Type in player names one after another.")
    
    for (let i = 0; i < numPlayers; i++) {
        if (i == 0)
            players.push(prompt("Who's first?"))
        else if (i == numPlayers - 1)
            players.push(prompt("And finally:"))
        else
            players.push(prompt("Who else?"))
    }
    alert('Hello ' + players.join(', '))

    The first and last player now get a special prompt.

    Try to output the player names by using a for loop.

    But what if you don’t care about if it’s the first, second, or one millionths iteration? Do you always have to jump through all the calculation hoops? Of course not. There’s another flavor of the for loop, often called foreach, for-in, or for-of. It (usually) iterates over something you (the computer) knows the size of. Let’s use it to output the player’s names:

    players = []
    numPlayers = prompt('How many players are there?')
    alert("Who's playing? Type in player names one after another.")
    
    for (let i = 0; i < numPlayers; i++) {
        players.push(prompt("Who is it?"))
    }
    
    for (let player of players) {
        alert('Hello ' + player)
    }

    This is way less to type and to think about. You can read it as „for each x of some collection y do z“ where x is substituted with one value of y after another within your loop’s body z.

    Can you do the name-prompting loop with this type of loop? Don’t worry if you can’t but give it a try.

    If you failed to do it there’s a reason for it. There’s a reason we have different types of loops – because they are useful in different situations. But still, they are (usually) equivalent. You can do the same things with them.

    for (let x of Array(5)) 
        players.push(prompt("Who is it?"))

    Here’s another one for the classic for loop:

    numPlayers = prompt('How many players are there?')
    players = []
    alert("Who's playing? Type in player names one after another.")
    
    for (let i = 0; i < numPlayers; i++) {
        players[i] = (prompt("Who is it?"))
    }
    alert('Hello ' + players.join(', '))

    We set the ith element of the array to to current value.

    When to choose which?
    Use while for unknown sizes or non-countable cases.
    Use classic for when the current index matters.
    Use foreach for limited collections, when only the values matter – or if your language supports it for key-value cases, too.

    In reality you will probably most often iterate over some known set (maybe unbounded) and a foreach loop is usually most concise.

    Bonus: break and continue
    You can either break out of the loop’s body at any time via the break keyword or skip one iteration via the continue keyword.

    alert("Who's playing? Type in player names one after another. Type 'done' when you're done. Note that no Bobs are allowed to play. Sorry Bob.")
    let players = []
    
    while (true) {
        let player = prompt('Who are you?')
        if (player === 'done')
            break
        else if (player.toLowerCase() === 'bob') {
            alert('I said NO BOBS!')
            continue
        }
        else
            players.push(player)
    }
    alert('Hello ' + players.join(', ') + ' ... and no Bob')

    Bonus: You don’t need the initializer and post-iteration clause for the classic for loop. Actually not even the condition, it’s implicitly true. for (;;) break is perfectly fine. Or for (;;); – but you shouldn’t run it. What would happen if you did?

    There’s more to it but these building blocks should make you „Turing complete“ already. You can nest loops, mostly do whatever you want inside their bodies or compute all the prime numbers … if you have some spare time. As a final task, do compute the prime numbers between 1 and a given number. It doesn’t have to be efficient, just make it work.

    let upperLimit = prompt('Upper limit, > 1')
    let primes = [1]
    for (let i = 2; i <= upperLimit; ++i) {
        let halfI = i / 2
        let isPrime = i % 2 != 0
    
        if (isPrime)
            for (let j = 2; j <= halfI; ++j) {
                if (i % j == 0) {
                    isPrime = false
                    break
                } 
            }
        if (isPrime)
            primes.push(i)
    }
    console.log(primes)

    Rabbit Hole: Look into FRP, things like map, filter, reduce, folding, streams.

  • cached redirect

    cached redirect

    If you wonder why your browser redirects you from your local development URL to your live URL – it’s probably because you had your local apache redirect to your live URL (since you forgot to strip the lines from your dev .htaccess or whatsoever) and your browser has cached that redirect. So if you removed your .htacces already and still get redirected and are almost up to smashing your motherfrickin machine then try flushing your browser cache (somethin‘ like options->advanced->clear now). Totally worked for me.

    Y’ain’t stupid; or at least, we both are.

  • Zu faul zum bloggen

    Bin wohl kein geborener Blogger; wozu auch?

    ConsoleInvaders liegt vorerst auch Eis und auch für myXMLsql2 fehlt momentan die Zeit. Zeit die verfügbar ist wird in Android Entwicklung investiert werden und vielleicht ein wenig ins Studium.

    Heute geht’s erstmal zu IAMX ins Astra. Bin sehr gespannt; hab verschiedenes über ihre Live-Performances gehört.
    Cheerio

  • Paper Stack 1.2.2 released

    I’ve just released Paper Stack v.1.2.2 featuring some minor upgrades from previous version and a brand new built-in „check for updates“-function!
    Check it out at SourceForge.net!

    Cheers!

  • Paper Stack 1.0 released

    Paper Stack 1.0 has just been released on SourceForge.net.

    See changeslog.txt for further information.

  • Paper Stack update

    Paper Stack verfügt jetzt über eine Kommentar-Funktion, also gebt fleißig euren Senf wenn ihr wollt.

    Außerdem hat die Suche jetzt ein text-highlighting *hooray* und das layout wurde ein wenig gefixt.

    Cheers

  • scheduled features for myXMLsql 1.3.1

    myXMLsql 1.3.1 will feature:

    • improved select-syntax (SELECT field1, field2, fieldx FROM table – will lead to an error with 1.3 and earlier versions)
    • improved performance (especially functions that are used more often will be handled first in loops)
    • overall improved SQL syntax support (common SQL syntax should at least not lead to errors)
    • INSERT INTO will treat integer as integer (e.g. INSERT INTO table (field) VALUES (1) will work)

    later versions will feature:

    • implementation of LIMIT BY
    • implementation of REPLACE
    • myxmlsql_connect() with password feature
    • manual enable/disable of built-in error reporting
  • scheduled features for myXMLsql 1.2.4

    * new function myxmlsql_set_auto_increment($val, $table)
    # requires myxmlsql_connect()
    # allows to manually set the table’s global auto_increment value

    * new function myxmlsql_affected_rows($result)
    # as you know it from MySql

    * new syntax included: ORDER BY
    # ORDER BY xy ASC/DESC has been added and will work as expected

    * syntax improvement
    # WHERE 1 is now optional
    # if there’s no WHERE x=y or WHERE 1 the script will automatically interpret WHERE 1

    plus some further performance and syntax improvements

    // UPDATE: progress 75%
    // UPDATE 31.1.10: progress 90%
  • Weihnachts VLC Player

    Der VLC Player wünscht allen frohe Weihnachten (siehe unten).

    Kleine Dinge sind’s doch die vieles ausmachen, nicht?

    vlc xmas
    vlc xmas

  • myXMLsql 1.2.3 released

    So, alle bekannten Bugs sind mit Version 1.2.3 von myXMLsql behoben.

    myXMLsql
    myXMLsql

    Nun sollten auch Umlaute und Sonderzeichen problemlos verwendet werden können. Ich empfehle Seiten mit UTF-8 zu kodieren; bin mir nicht sicher ob es mit ISO 8859-1 auch problemlos läuft.

    Die neue Version findet ihr wie immer auf http://sourceforge.net/projects/myxmlsql/.

    Cheers!