Wednesday, August 21, 2013

Euler #1 and #2

This is a simple solution to the first Euler problem
http://projecteuler.net/problem=1


import sys
import time
sum=0
for a in range (3,10):
    if ((a%3==0) or (a%5==0)):
        sum+=a



This is a simple script that should be simple to understand.
import is python's means of accessing functions in external files.

The for loop structure in python is a bit different compared to Basic or C/Java. Range(0,n) makes a list of numbers from 0 to n-1. i.e. n is not included.
For a in <list> will iterate through the list, and the variable "a" will represent each element in that iteration.

Here's my solution to Euler 2:
http://projecteuler.net/problem=2



#By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
import sys
import time

num1=1
num2=2
sum=0

while num1<4000000:
    if (not num1%2) and num1 < 4000000:
        sum+=num1
    if (not num2%2) and num2 < 4000000:
        sum+=num2
    num1+=num2
    num2+=num1
print sum


This is another fairly basic algorithm. No need to worry about memory and fairly simple checks. Fibonacci explodes fairly quickly so the number of iterations here is low - under 20.

That's all for now. Both quite simple. Problem 3 gets much more interesting.

Project Euler

Project Euler is a collection of mathematical problems that generally require writing a program to solve. It's probably not the best way to learn a language, but it's a very good way to exercise your mental capability for coming up with algorithms heavily grounded in logic.

I've been toying around here using Python as my language and it's quite satisfying so far. What nice about python for doing this:


  • Strings and integers are easily changed back and forth.
    e.g.
    if a=12345, and I want the 4th digit as an integer:
    String way: a4=int(str(a)[3])
    i.e. convert a to string, grab index 3 (0 is first), and convert back to int.
    Of course there's an integer method too which can render this specific argument moot (a4=(a//10)%10) but it is still useful for other examples.
  • Integers have no size limit. So no need to rely on outside modules for "big" numbers - i.e. numbers that are actually long strings.
  • Python list ('array' sort of...) manipulation is very very simple. Reading in data and organizing strings is incredibly easy. Growing a list is a basic operation. If this were C, we'd have to use another class, such as vector.
  • List elements can be anything. String, integers, more lists etc.
One of the major weaknesses I've seen would be OS specific functions. In some cases, it's fine. But say you want to pull of PID information on a process in windows, or have a script run only once, and not run again to prevent duplicates. Differences in Windows and Linux/Unix implementations prevent this from being truly portable. In some cases - like pexpect - it ends up really only working properly in Linux, and while I guess it's possible to get working in windows, running it in a virtual machine is less of a hoop to jump through.

I'll try posting a few Euler solutions in subsequent posts as it's actually somewhat relaxing.


http://projecteuler.net/

Wednesday, August 7, 2013

The HTML/Javascript makeup of the animated Bubble Sort

Below is the HTML and Javascript source for the animated bubble-sort animation.


Animation in Javascript is a bit annoying.


Let's say I want to show an object moving from point ax,ay to point bx,by in 100 steps.


I'd normally expect something like this:


For (c=0;c<=100;c++){
   cx=ax+(c/100)*(bx-ax)
   cy=ay+(c/100)*(by-ay)
   object.move(cx,cy)
   delay(frametime)
}


Instead javascript needs something more like:


function moveobject_ani(ax,ay,bx,by,c){
   cx=ax+(c/100)*(bx-ax)
   cy=ay+(c/100)*(by-ay)
   object.move(cx,cy)
   if c<100 {
      setTimeout('moveobject_ani(ax,ay,bx,by,c+1)',delay)
   }
}

NB: About the equation - cx=ax+(c/100)*(ax-bx)
When c=0, the red portion of cx=ax+(c/100)*(bx-ax) is 0. therefore, cx starts at ax.
When c=100, it becomes cx=ax+(100/100)*(bx-ax). The equation becomes cx=ax+(bx-ax). i.e. cx=bx.

C:\Documents and Settings\ryan.cipriani\My Documents\scripts\bubblesort.html.html
<html>
  <head>
    <title>
      BubbleSort
    </title>
    <style>
      #resetit {
        font-size:1.2em;
        padding:4px;
        background-color:#cdcdcd;
        width:500px;
        box-sizing:border-box;
        -moz-box-sizing:border-box;
        -webkit-box-sizing:border-box;
        position:relative;
        cursor:pointer;
        font-family:"Courier", "Terminal", Monospace;
      }
      #scratchboard {
        font-size:0.8em;
        padding:4px;
        background-color:#dfefdf;
        color:#002200;
        width:500px;
        height:450px;
        box-sizing:border-box;
        -moz-box-sizing:border-box;
        -webkit-box-sizing:border-box;
        position:relative;
        cursor:pointer;
        font-family:"Courier", "Terminal", Monospace;
      }
      .typ1{
        font-size:1.2em;
        color:#007700;
        padding:4px;
        border-color:#222222;
        border-style:solid;
        border-width:1px;
        font-weight:bold;
        position:absolute;
        width:180;
        font-family:"Courier", "Terminal", Monospace;
      }
      #smallest{
        font-size:1.2em;
        color:#bb0000;
        padding:4px;
        font-weight:bold;
        position:absolute;
        width:55px;
        Left:50px;
        Top:20px;
        font-family:"Courier", "Terminal", Monospace;
      }
      #curcompare{
        font-size:1.2em;
        color:#0000bb;
        padding:4px;
        font-weight:bold;
        position:absolute;
        width:55px;
        Left:360px;
        Top:20px;
        font-family:"Courier", "Terminal", Monospace;
      }
    </style>

    <script language="Javascript">
      function $(id){return document.getElementById(id);}

      var elements=["watermelon", "orange", "pear", "kumquat", "apricot", "banana", "apple", "squash", "cantalope"]
      function make_number_list(){
        current=""
        $('scratchboard').innerHTML="Click to sort...<div id='smallest'>Smallest=&gt;</div><div id='curcompare'>&lt;=Checking</div>"
        for (i=0;i<elements.length;i++)
        {
          numpackage="<div class='typ1' id='fele_"+i+"'>"+elements[i]+"</div>"
          current=$('scratchboard').innerHTML;
          $('scratchboard').innerHTML=current+numpackage
          $('fele_'+i).style.top = 20+i * 40;
          $('fele_'+i).style.left = '160px';
        }
      }
      function resetalpha(){
        elements=["watermelon", "orange", "pear", "kumquat", "apricot", "banana", "apple", "squash", "cantalope"];
        make_number_list();
      }

      funk=""
      function moveboxes(box1, b1top, mainx, box2, b2top, mainx,iter,idx1,idx2) {
        totaliter = 30
        turnrad=Math.round((b2top-b1top)*Math.sin((Math.PI*iter*0.5)/totaliter ));
        box1newtop=b1top+turnrad;
        box2newtop=b2top-turnrad;
        $(box1).style.top=box1newtop+'px';
        $(box2).style.top=box2newtop+'px';
        s=Math.round((b2top-b1top)*Math.sin( (Math.PI*iter)/totaliter ));
        $(box1).style.left=Math.round(mainx+(s*0.4))+'px';
        $(box2).style.left=Math.round(mainx-(s*0.3))+'px';
        if (iter < totaliter) {
          setTimeout('moveboxes(box1, b1top, mainx, box2, b2top, mainx,'+(iter+1)+','+idx1+','+idx2+')',(1000/120));
        } else {
          swaptmp=elements[idx1]
          elements[idx1]=elements[idx2]
          elements[idx2]=swaptmp
          make_number_list()
          $('smallest').style.top = (20+idx1 * 40)+'px';
          $('curcompare').style.top = (20+idx2 * 40)+'px';
          setTimeout(funk,50);
        }
      }
      function swap(ia,ib){
        box1='fele_'+ia
        box2='fele_'+ib
        b1top=parseInt(($(box1).style.top).replace('px', ''));
        b2top=parseInt(($(box2).style.top).replace('px', ''));
        mainx=parseInt(($(box2).style.left).replace('px', ''));
        moveboxes(box1, b1top, mainx, box2, b2top, mainx,0,ia,ib)
      }

      function bubblestate(min, max, aidx, bidx){
        funk='bubblestate('+min+', '+max+', '+aidx+', '+bidx+')'
        $('smallest').style.top = (20+aidx * 40)+'px';
        $('curcompare').style.top = (20+bidx * 40)+'px';
        if (elements[aidx] > elements[bidx]) {
          swap(aidx, bidx)
          return
        } else {
          if (bidx == max) {
            aidx=aidx+1
            bidx=aidx+1
          } else {
            bidx +=1
          }
          if (aidx<max) {
            setTimeout('bubblestate('+min+', '+max+', '+aidx+', '+bidx+')',0);
          }
        }
      }

      function sortitall(){
        $('scratchboard').innerHTML=""
        make_number_list();
        bubblestate(0,elements.length-1,0,1)
      }
    </script>

  </head>
  <body onload="make_number_list()">
    <div id="resetit" onclick="resetalpha()">
      Reset Order...
    </div>
    <div id="scratchboard" onclick="sortitall()">
    </div>
  </body>
</html>

Tuesday, August 6, 2013

Bubble Sort

I was chatting with a friend about out kids, and he mentioned that his daughter was just getting introduced to scripting.

Basic scripting/programming is a great hobby for a kid. It costs nothing, can be done at any time, becomes a marketable skill and can greatly improve their understanding and capabilities with a computer.


When I was 13, I saw my brother starting to learn to code in QBasic. There were also a few games written in it. What struck me immediately was that the game he had brought home, because it was written in a non-compiled language, presented all the logic clearly visible, just waiting to be understood.


I took it upon my self to start modifying it bit by bit. I turned the sun into a moon. The day became night, and the buildings into neon gaudy things, I'd cringe at today. I figured out the pixel and line drawing next, and the moon was given sunglasses...


After that I started toying with my own little scripts. When  I discovered loops, animations follows. without use of an offscreen buffer, my animations were all "twinkle". i.e. redraw black over the screen, then redraw whatever. Horribly inefficient, but even my lowly 40MHz DX2 was fast enough for little vector based animations such that it wouldn't be obvious.


I kept tinkering - especially with graphics. Visual shiny fun stuff was interesting. Text was and mostly still is boring.

I started playing with Pascal and eventually, inline assembly (GOGO MODE 13H!!!), and frame buffers. With the tinkering, it expanded my understanding of logic, and math. Deriving your own 3d algorithms for animation takes a lot of thought, but eventually, I was using trigonometric functions easily, and simple physics equations for acceleration/distance/time.


While on the phone with network engineers that saw to it their hold button gets a workout, I whipped up the below demo of a bubble sort. It's the most basic of sorts, and algorithms. While it in itself is boring, it employs fundamental principles that anyone with decent scripting capabilities should be able to reproduce. This one is for our future programmers and scripters.
Reset...

Thursday, August 1, 2013

What we should have in a WIFI capable camera

WIFI cameras appear to be a trend. The problem is that manufacturers think of people as stupid, so they decide to make rather specific applications for specific devices and operating systems that complicates use of WIFI.

WIFI on a camera shouldn't be used as a means of uploading pictures to facebook, flicker, <insert random social clutter here>.

This is what WIFI should look like:
  • Touchscreen entry for connecting to a wifi network to upload pictures as they are selected, or taken via FTP, CIFS and HTML.
  • If no touchscreen, then the camera should make an easily readable text file template. Something you can easily select from a menu on the camera. Config files can be kept in a folder like the usual "DCIM". If there's no file, or if the user wants, he should be able to create a template for the protocol of choice. Something looking like:
    • Protocol=FTP
    • ServerIP=xxx.xxx.xxx.xxx
    • ServerPort=21(default)
    • ServerLogin=username
    • ServerPassword=password
    •  Active/Passive=active(default)
  •  While I'm not a huge fan of Java, it does have it's place. A simple file receive app written in Java that received files from the camera and puts it in a folder of choice would work pretty much anywhere.
  • Run a simple web server on the camera. Seriously I can't believe this isn't done yet. File server should facilitate browsing, and downloading RAW/JPG. Ftp also nice and easy.
Take all of the above a step further and you should be able to download and upload camera configuration settings.

Just my 2 cents on how I envision it. FTP is easier to setup these days than samba - at least a samba solution that doesn't jerk people around. Microsoft is continually making life harder with their updates. Nowadays I run a virtual machine - Linux Mint - to share files without all the problems I get sharing Windows 7 folders to a range of operating systems.