Thursday 28 March 2013

C Programming - converting a number to hexidecimal and other bases larger then 10

I'm in the middle of writing a program which converts normal base 10 numbers into any base. When you convert to a base larger then 10 it gets a little confusing how to represent those numbers larger than 10. In hexidecimal the numbers 10 through to 15 are represented as A through to F. Here's a function I have written which converts a number in this way, representing larger then 10 numbers into letters up to Z.


//prints a number in a base using symbols for numbers greater than 10
//similar to hexidecimal. Max base is 36
void printInBaseWithUniqueSymbols (int number, int base){
assert(base > 1);
//find out how many units is needed to make the number
//int numberOfUnits = 1;
int units = base;
while (units <= number) {
//numberOfUnits ++;
units = units * base;
}
    //make an array which contains symbols to use from 1 to base
//using a to z for numbers 10 to 36
    char numberArray [base];
for (int i=0; i
if (i<10) {
numberArray[i]=(48+i);
else {
numberArray[i]= (65 + (i-10));
}

}
//printf("%c", numberArray[1]);
//work out which how many of each unit
    //int i = 0;
    
int result = number;
while (units > 1) {
units = units / base;
int numberOfUnits = result / units;
//printf("%c", numberOfUnits);
char character = numberArray[numberOfUnits];
printf("%c", character);
result = result % units;
        //i++;
}

}

Results:

Type a starting number: Running…
1
Type an end number: 100
Type a base to count in: 16
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 7
8 = 8
9 = 9
10 = A
11 = B
12 = C
13 = D
14 = E
15 = F
16 = 10
17 = 11
18 = 12
19 = 13
20 = 14
21 = 15
22 = 16
23 = 17
24 = 18
25 = 19
26 = 1A
27 = 1B
28 = 1C
29 = 1D
30 = 1E
31 = 1F
32 = 20
33 = 21
34 = 22
35 = 23
36 = 24
37 = 25
38 = 26
39 = 27
40 = 28
41 = 29
42 = 2A
43 = 2B
44 = 2C
45 = 2D
46 = 2E
47 = 2F
48 = 30
49 = 31
50 = 32
51 = 33
52 = 34
53 = 35
54 = 36
55 = 37
56 = 38
57 = 39
58 = 3A
59 = 3B
60 = 3C
61 = 3D
62 = 3E
63 = 3F
64 = 40
65 = 41
66 = 42
67 = 43
68 = 44
69 = 45
70 = 46
71 = 47
72 = 48
73 = 49
74 = 4A
75 = 4B
76 = 4C
77 = 4D
78 = 4E
79 = 4F
80 = 50
81 = 51
82 = 52
83 = 53
84 = 54
85 = 55
86 = 56
87 = 57
88 = 58
89 = 59
90 = 5A
91 = 5B
92 = 5C
93 = 5D
94 = 5E
95 = 5F
96 = 60
97 = 61
98 = 62
99 = 63
100 = 64

Tuesday 26 March 2013

installing Octave on Mac OS X 10.6 and 10.7

So, just read the wiki here. As it's open source, they havent yet made a pkg installer for it. Apparently, the best thing to do is to use a Package Manager to install it for you.

I've just tried Fink but the website isn't working. Looks like they've moved their website to http://fink.thetis.ig42.org/. Apperantly there's no pkg installer for this either! Here's the download for the binary.

I gave up here and found that MacPorts have an installer.

Installed MacPorts alright, but when I tried to run the command:

sudo port install octave-devel +atlas+docs
It came up with the error not knowing what the command "port" was. I had to type in:
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
One prerequisite is to have xcode installed.


Having done all this, still came up with an error:
Error: Port octave-devel not found

I think it's because we have a proxy server which looks like complicated to add to MacPorts!

Oh well, might just try Matlab! (student version £55!)


....... a little time later......

So I'm now trying at home on OS X 10.7.5

Installed MacPorts
trying to install octave but comes up with:
Error: Port octave not found
Turns out you have to selfupdate MacPort in order for it to sync something or other. Type:
sudo port -v selfupdate
This then came up with the error:
rsync: failed to connect to rsync.macports.org: Connection refused (61)
rsync error: error in socket IO (code 10) at /SourceCache/rsync/rsync-42/rsync/clientserver.c(105) [receiver=2.6.9]
Command failed: /usr/bin/rsync -rtzv --delete-after rsync://rsync.macports.org/release/tarballs/base.tar /opt/local/var/macports/sources/rsync.macports.org/release/tarballs
Exit code: 10
Error: /opt/local/bin/port: port selfupdate failed: Error synchronizing MacPorts sources: command execution failed
Doh! Just did a search and found this. Turns out I have PeerGuardian running. Turned it off and ran selfupdate again which worked fine. So, next I tried installing octave again:
sudo port install octave
--->  Computing dependencies for octave
Error: Dependency 'atlas' not found.
Doh! I read this article which tells how other people are having the same trouble. Looks like one of the sync files on a server must be wrong. selfupdating port at some point will fix it;
sudo port -v selfupdate
sudo port install octave +accelerate +gcc45
What do you know? It worked!!

HP Scanjet 4370 browse devices not found

I have a computer suite with 5 x HP Scanjet 4370's. One of them can't be found on the attached computer. I have moved it from machine to machine and no machines seem to find it. The other scanners work fine. So it is clearly something wrong with this one.

On plugging it in to the power it makes the usual noises. Also when you reboot the machine and it is connected to the USB port it works.

When you load up HP Scan and click browse it just says 0 Devices found:
When you load up HP Scan and click browse it just says 0 Devices found:
The only real obvious thing to suspect is the USB port. After opening the scanner up, I found no evidence of loose connections or shorted circuits.

Looks like this ones a gonna.

Friday 22 March 2013

Screen Recording Project - timelapsed

So, I would like to record a whole working week, or maybe more, of work at my computer, but how?

Well, first off I think I want it to be time-lapsed. I think I would like 1 working day compressed into 1 minute:

1 working day = 8.5 x 60 = 510 minutes = 30600 seconds
1 minute = 60 seconds = 60 x 24fps = 1440 frames
30600 / 1440 = 21.25 seconds between each frame

Well, Quicktime does come with screen recording capabilities, but these are a bit hefty on the old processor/ram/disk space.

What I will probably do is make an Automator workflow which takes a screenshot every 21 seconds. Here it is:
Automator workflow which takes a screenshot every 22 seconds
By default "Take a screenshot" saves a file in a location but calls it something. For the next screenshot it overwrites the first. I had to use variables to change this.

Firstly I got a location variable and this contained the folder to save it to. I then got the time variable. I then made a text variable and dragged both of these other variables in, with a "/" in between. I dragged this variable into  the "Save to:" box. It then saves it to the location folder, with the name of the time it was taken.

I think you also need the "Get Value of Variable" before so it updates the variable "time".

Each screenshot is about 1.7MB:

1.7MB x 1440 = 2448MB per day.

I converted this into a quicktime movie using MPEGStreamClip  and it made a 17MB file! (15fps). Sorted!

To anonymise reducing it by 1/3rd (600 x 400 px) seems to render the text unreadable!


After a while of running this I got slightly annoyed at the screencapture noise. To run it silently I figured changing the preferences for it would work. Nope. Next I found the plist file:
com.apple.screencapture

But firstly it didn't exist, and next I couldn't find full documentation of it! Just the simple stuff like file format and location.

The command line for it is:

screencapture -x filelocation/filename.png

So I modified the automator workflow to use this command line instead of the screencapture object. It took 5 mins to work out how to access the variables in Run Shell Script but here's how I did it:
Screencapture workflow with automator using command line argument and passing variable
To access variables I think the only way is to pass them into the run shell script. I found this helpful page on it

The main points were:

  1. Make sure you ignore the inputs unless you really need them.
    1. i.e. I only really needed the full path name and filename combined so this was only passed into the "Run Shell Script"
  2. To use the passed variable you type:
    1. "$@"
      1. I don't think you need the speech marks but I needed them in the shell script
Now I'm thinking about it I don't think I need the workflow at all, could just run it using a simple shell script. But I think Automator is a nice way of introducing people to programming.

Tuesday 19 March 2013

Set Automatic Proxy Configuration through Command line in OS X 10.7

It took me a while to find it, but to set the Automatic Proxy Configuration url and tick the box through command line I found this helpful post which describes a script on how to do it.

First you need to find which network interface you want to change:

networksetup -listallnetworkservices
Ethernet

Use this in the command:
networksetup -setautoproxyurl Ethernet http://wpad.your.path.here/wpad.dat
By adding a url it automatically switches it on. To check:
networksetup -getautoproxyurl Ethernet
Simples. Don't know why it took me so long to find it. Don't think it's in the man page for networksetup for some reason!

Monday 18 March 2013

C Programming - convert number to any base

Just to continue with my programming practice I decided to write a function which takes a number and a base and converts that number to that base.

Here's the function:

//takes a number and a base to work to. It converts (just prints) this number to said base
//base has to be greater then 1
void printInBase(int number, int base) {
    
    assert(base > 1);
    
//find out how many units is needed to make the number
//int numberOfUnits = 1;
int units = base;
while (units <= number) {
//numberOfUnits ++;
units = units * base;
}
    //make an array which will be printed out in the end
    //int numberArray [numberOfUnits];
//work out which how many of each unit
    //int i = 0;
    
int result = number;
while (units > 1) {
units = units / base;
printf("%d", result / units);
result = result % units;
        //i++;
}
 
//prints out array
    //for (int c = 0; c <= numberOfUnits ; c++) {
    //    printf("%d", numberArray[c]);
    //}
}
 Output:
Type a starting number: 1
Type an end number: 30
Type a base to count in: 7
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 10
8 = 11
9 = 12
10 = 13
11 = 14
12 = 15
13 = 16
14 = 20
15 = 21
16 = 22
17 = 23
18 = 24
19 = 25
20 = 26
21 = 30
22 = 31
23 = 32
24 = 33
25 = 34
26 = 35
27 = 36
28 = 40
29 = 41
30 = 42
The function fails at counting base 1, but it hurts my brain too much to think about it! Also, to count in a base larger then 10, it's best to put a comma between digits. e.g:

Type a starting number: 1
Type an end number: 30
Type a base to count in: 15
1 = 1,
2 = 2,
3 = 3,
4 = 4,
5 = 5,
6 = 6,
7 = 7,
8 = 8,
9 = 9,
10 = 10,
11 = 11,
12 = 12,
13 = 13,
14 = 14,
15 = 1,0,
16 = 1,1,
17 = 1,2,
18 = 1,3,
19 = 1,4,
20 = 1,5,
21 = 1,6,
22 = 1,7,
23 = 1,8,
24 = 1,9,
25 = 1,10,
26 = 1,11,
27 = 1,12,
28 = 1,13,
29 = 1,14,
30 = 2,0,
This way you can distinguish between the 10's and 20's etc. Might be worth putting this in the function. But also, I could make it convert to hexadecimal? Might require more brain hurt.

Monday 11 March 2013

converting numbers/primes into binary

I want to compare some different number systems together with respect to primes. Wanted to know how to convert to binary. Thought this would be in-built to the computers/language, as all numbers are already stored as binary?

Anyway, found this forum with lots of different answers. Smallest answer was:
#include
int main(void) {
  int i, target;
  printf("Enter a number: ");
  scanf("%d", &target);
  for(i = 32; i--;) {
    if(target & (1 << i))
      putc('1', stdout);
    else
      putc('0', stdout);
  }
  return 0;
}

although they suggest altering part of it to


for(i=(j-1);i >= 0; i--)
/* or 'for(i=j;i--; )' would also work but is a bit too cryptic for me to get my head round */
{
  if(target & (1 << i))
    putc('1', stdout);
  else
    putc('0', stdout);
}

I shall try this out.

I ended up doing it my own way, mostly so that I could practice programming. I used the divide by 2 way, and if there is remainers then print 1, else print 0:

#define BINARYARRAYSIZE 1000

//converts a number into Binary and prints with greatest bit first
void convertAndPrintBinary (int number) {
    //printf("converting to binary\n");
    
    
    int binaryArray [BINARYARRAYSIZE] = {0};
    int i = 0;
    for (int result = number; result > 0; result = result/2) {
        
        if (result % 2 == 0 ) {
            binaryArray[i]=0;
            //printf("0");
        else {
            binaryArray[i]=1;
            //printf("1");
        }
        
        i++;
    }
    
    //printf("%d\n", i );
    
    //prints out array in reverse
    for (int c = i-1; c >=0 ; c--) {
        printf("%d", binaryArray[c]);
    }
    
}

Worked really well in the end:

Type a starting number: 1
Type an end numbers: 20
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
9 = 1001
10 = 1010
11 = 1011
12 = 1100
13 = 1101
14 = 1110
15 = 1111
16 = 10000
17 = 10001
18 = 10010
19 = 10011
20 = 10100

I used BINARYARRAYSIZE because I didn't want to run the first for loop twice; once to measure how big the array needed to be, and the second to fill it. When I didn't give the array a size to begin with, it kept erroring. But 1000 digits for binary is a large number!