This little snippet gets all the days in a month, and groups them by week.
<?php
error_reporting(E_ALL);
// Return an array of all the days in a month grouped by week number
// (Sunday is considered to be the first day of the week)
function weeksInMonth($month, $year)
{
$firstDay = mktime(0, 0, 0, $month, 1, $year);
$daysInMonth = date('t', $firstDay);
$week = 1;
$breakdown = array();
for($i = 1; $i <= $daysInMonth; $i++)
{
$date = mktime(0, 0, 0, $month, $i, $year);
$day = date('l', $date);
// Sunday triggers the start of a new week, except if it's
// also the first day of the month.
if(($day == 'Sunday') && ($i != 1))
{
$week++;
}
$breakdown[$week][] = $date;
}
return $breakdown;
}
$results = monthToWeek(6, 2008);
printf("There are %d weeks in June 2008\n\n", count($results));
foreach($results as $weekNumber => $days)
{
printf("Week %d\n", $weekNumber);
foreach($days as $day)
{
printf("%10s %s\n", date("l", $day), date("Y-m-d", $day));
}
printf("\n");
}
/*
There are 5 weeks in June 2008
Week 1
Sunday 2008-06-01
Monday 2008-06-02
Tuesday 2008-06-03
Wednesday 2008-06-04
Thursday 2008-06-05
Friday 2008-06-06
Saturday 2008-06-07
Week 2
Sunday 2008-06-08
Monday 2008-06-09
Tuesday 2008-06-10
Wednesday 2008-06-11
Thursday 2008-06-12
Friday 2008-06-13
Saturday 2008-06-14
Week 3
Sunday 2008-06-15
Monday 2008-06-16
Tuesday 2008-06-17
Wednesday 2008-06-18
Thursday 2008-06-19
Friday 2008-06-20
Saturday 2008-06-21
Week 4
Sunday 2008-06-22
Monday 2008-06-23
Tuesday 2008-06-24
Wednesday 2008-06-25
Thursday 2008-06-26
Friday 2008-06-27
Saturday 2008-06-28
Week 5
Sunday 2008-06-29
Monday 2008-06-30
*/
?>
Just added a couple of quick photos to the k100d gallery. Really wish I could have speant longer watching the surfers near The Spit
Camera is Pentax K100D 6MP with a Sigma 70-300 / Sigma 28-70 F2.8
Below are the top 50 login names when trying to gain access to this web server over the last 4 weeks
| Name |
Attempts |
| root |
3273 |
| admin |
119 |
| test |
110 |
| mysql |
44 |
| guest |
41 |
| user |
37 |
| oracle |
37 |
| temp |
25 |
| sales |
24 |
| info |
21 |
| webmaster |
21 |
| postgres |
21 |
| dan |
18 |
| robert |
18 |
| student |
17 |
| ftpuser |
17 |
| ftp |
17 |
| richard |
16 |
| apache |
16 |
| web |
15 |
| adm |
15 |
| webadmin |
15 |
| john |
15 |
| paul |
15 |
| office |
15 |
| tony |
14 |
| james |
14 |
| postfix |
13 |
| michael |
13 |
| alex |
13 |
| david |
13 |
| amanda |
13 |
| adam |
12 |
| mike |
12 |
| staff |
12 |
| steven |
12 |
| recruit |
12 |
| jeff |
12 |
| pgsql |
12 |
| library |
12 |
| username |
12 |
| frank |
12 |
| susan |
11 |
| cyrus |
11 |
| dave |
11 |
| gast |
10 |
| postmaster |
10 |
| nagios |
10 |
| martin |
10 |
| admins |
10 |
Note: No external connections are allowed to log in as root (of course)
Note2: After 5 failed login attempt, the IP address is temporary banned (fail2ban)
A console based implementation of Conway’s Game of Life in Python.
As fascinating as it is useless.
#!/usr/bin/python
import sys
import random
import time
import os
import copy
WIDTH = 32
HEIGHT = 16
class Grid:
def __init__(self, width, height):
self.width = width
self.height = height
self.create_blank_grid()
def create_blank_grid(self):
self.grid = []
for x in range(0, self.width):
self.grid.append([0 for y in range(0, self.height)])
def seed(self, chance = 0.4):
for x in range(0, self.width):
for y in range(0, self.height):
if random.random() < chance:
self.grid[x][y] = 1
else:
self.grid[x][y] = 0
def add_glider(self):
self.grid[1][0] = 1
self.grid[2][1] = 1
self.grid[0][2] = 1
self.grid[1][2] = 1
self.grid[2][2] = 1
def __str__(self):
buffer = ''
for y in range(0, self.height):
for x in range(0, self.width):
str = ' '
if self.grid[x][y] == 1:
str = '#'
buffer += str
buffer += '\n';
buffer += '\n';
return buffer
def get_number_neighbours(self, x, y):
def get_value(i,j):
try:
return self.grid[i][j]
except:
return 0
number_neighbours = get_value(x-1, y-1) + get_value(x, y-1) + get_value(x+1, y-1) + \
get_value(x-1, y) + get_value(x+1, y) + \
get_value(x-1, y+1) + get_value(x, y+1) + get_value(x+1, y+1)
return number_neighbours
def tick(self):
new_grid = copy.deepcopy(self.grid)
for x in range(0, self.width):
for y in range(0, self.height):
number_neighbours = self.get_number_neighbours(x,y)
if self.grid[x][y] == 1:
if number_neighbours < 2:
new_grid[x][y] = 0
elif number_neighbours > 3:
new_grid[x][y] = 0
else:
if number_neighbours == 3:
new_grid[x][y] = 1
self.grid = new_grid
if __name__ == "__main__":
grid = Grid(WIDTH, HEIGHT)
# chance for a cell to be 'alive'
grid.seed(0.2)
# grid.add_glider()
# 100 generations
for x in range(0, 100):
os.system('clear')
print grid
grid.tick()
time.sleep(1)
<?php
// Perhaps the simplest practical use of a fold?
//
// (While this is fairly consise (even in PHP) it calculates the length of a
// string 2n-2 times [which is n-2 times more than needed])
function getLongestWord($words)
{
$fun = create_function('$a,$b', 'return (strlen($a) > strlen($b)) ? $a : $b;');
return array_reduce($words, $fun);
}
// This looks a little better, but it loses a lot of the simplicity of the above
function getLongestWord_2($words)
{
$map = create_function('$a', 'return array($a, strlen($a));');
$fold = create_function('$a,$b', 'return ($a[1] > $b[1]) ? $a : $b;');
$word = array_reduce(array_map($map, $words), $fold);
return $word[0];
}
$words = array('a', 'bb', 'ccc', 'dd', 'eeee', 'fff', 'gg');
var_dump(getLongestWord($words));
// string(4) "eeee"
var_dump(getLongestWord_2($words));
// string(4) "eeee"
?>
Is there an even simpler way to find the longest string in an array?
Many months ago there was a PHP competition to make the smallest script to extract all the links from a document. I’ve lost a link to the actual site, but the rules and conditions were set up expecting everyone to solve the problem with regular expressions. In my opinion relying on regular expressions to parse HTML would be a terrible idea (and may actually be impossible to do with a normal engine), so I tried a slightly different approach:
Program listing. 162 Bytes.
<?php foreach(@DOMDocument::loadHTMLFile($argv[1])->getElementsByTagName('a') as $t)@$u[$t->getAttribute('href')]=0;foreach($u as $k=>$v)echo $k!=''?"$k\n":'';?>
Expanded program listing with comments
<?php
// Using PHP DOMDocument class, we load in a HTML file from the
// command line and extract all the 'a' tags. The '@' is used to
// suppress any parse errors
foreach(@DOMDocument::loadHTMLFile($argv[1])->getElementsByTagName('a') as $t)
{
// We get the value of the href attribute and store is as a
// key in $u. This is so each URL only appears once without
// having to call array_unique(). '@' is used to suppress the
// error when we add the first element to a non-existent array
// $u (which PHP then kindly creates for us)
@$u[$t->getAttribute('href')]=0;
}
// Finally we iterate over the array of URLS ($u) and if the key
// (which is the actual URL) is empty don't do anything, else print
// the url followed by a new line.
foreach($u as $k=>$v)
{
echo $k != '' ? "$k\n" : '';
}
?>
<?php
error_reporting(E_ALL | E_STRICT);
/*
Manual optional type checking for PHP functions
Basic example:
function log_error($line_number, $filename, $desc)
{
CheckFunctionArgs('integer', 'string', 'string');
[snip]
}
Object example:
class LogObject {}
function register_object($obj)
{
// Check for an object
CheckFunctionArgs('object');
// When an object is passed, you can optionally check for the class name
CheckFunctionArgs('LogObject');
[snip]
}
Wildcard example:
function log_anything($line, $thing)
{
// '*' really means anything, included true/false/null or an empty string
// however it doesn't mean the argument in optional
CheckFunctionArgs('integer', '*');
}
Notes:
Throws an exception on error
No support for functions that take a variable number of arguments
Must define the types of all arguments
The type '*' acts as a wild card, matching anything (including null)
Works with public and private methods in classes
*/
function CheckFunctionArgs()
{
$types = func_get_args();
$stack = debug_backtrace();
// Make sure there is some stack information
// Stack[1] contains the details about the function that called this function
if(!isset($stack[1]))
{
throw new Exception("No function stack present. Make sure CheckFunctionArgs() isn't called from the global scope");
}
// The arguments that were passed to the function we are checking
$arguments = $stack[1]['args'];
// Get the name of the class/function/file
$functionClass = (isset($stack[1]['class'])) ? $stack[1]['class'] . "::" : '';
$functionFile = (isset($stack[1]['file'])) ? basename($stack[1]['file']) . ':' . $stack[1]['line'] : '[No file information]';
$functionName = "{$functionClass}{$stack[1]['function']}()";
// Basic check, make sure the correct numbers of arguments were passed
if(count($arguments) != count($types))
{
$passed = count($arguments);
$expected = count($types);
throw new Exception("Incorrect number of argumemts passed to {$functionName} in {$functionFile}. Expected {$expected} got {$passed}");
}
// Now try and check each argument
for($i = 0; $i < count($arguments); $i++)
{
// Allow a check to be skiped, if the type equals '*'
if($types[$i] == '*')
{
continue;
}
$argumentType = gettype($arguments[$i]);
// Check basic types like integer/object ect
if($argumentType == $types[$i])
{
continue;
}
// Check to see if the type matches the classname of an object
if(($argumentType == 'object') && (get_class($arguments[$i]) == $types[$i]))
{
continue;
}
throw new Exception("Incorrect argument passed to {$functionName} in {$functionFile}. Argument {$i} was type {$argumentType} expected {$types[$i]}");
}
return true;
}
// Some really basic tests
function assertException($fun, $args)
{
try
{
call_user_func_array($fun, $args);
throw new Exception(sprintf("Error: No exception thrown in function %s\n", $fun));
}
catch(Exception $e)
{
}
}
function assertNoException($fun, $args)
{
try
{
call_user_func_array($fun, $args);
}
catch(Exception $e)
{
throw new Exception(sprintf("Error: Exception thrown in function %s\n", $fun));
}
}
function test_string($a)
{
CheckFunctionArgs('string');
}
assertNoException('test_string', array('abc'));
assertNoException('test_string', array(''));
assertNoException('test_string', array('123'));
@assertException('test_string', array());
assertException('test_string', array(123));
assertException('test_string', array(null));
function test_integer($a)
{
CheckFunctionArgs('integer');
}
assertNoException('test_integer', array(0));
assertNoException('test_integer', array(123));
@assertException('test_integer', array());
assertException('test_integer', array(null));
assertException('test_integer', array(''));
assertException('test_integer', array('a'));
assertException('test_integer', array(1.0));
assertException('test_integer', array(1.2));
function test_wildcard($a)
{
CheckFunctionArgs('*');
}
assertNoException('test_wildcard', array('a'));
assertNoException('test_wildcard', array(1233));
assertNoException('test_wildcard', array(null));
@assertException('test_wildcard', array());
class Foobar {}
$foobar = new Foobar();
function test_classname($a)
{
CheckFunctionArgs('Foobar');
CheckFunctionArgs('object');
}
assertNoException('test_classname', array($foobar));
assertException('test_classname', array('Foobar'));
?>
Pankaj Kumar has a slightly disturbing look at memory usage in PHP.
Each element requires a value structure (zval) which takes 16 bytes.
Also requires a hash bucket - which takes 36 bytes. That gives 52 bytes
per value. Memory allocation headers take another 8 bytes*2 - which
gives 68 bytes. Pretty close to what you have.
<?php
define('WORD_LIST_FILENAME', '/usr/share/dict/words');
class AnagramLookup
{
private $lookup;
// Loads a file with one word per line
private function load_word_list($filename)
{
$lines = file($filename); // One word per line
$lines = array_map('trim', $lines); // Strip any excess whitespace
$lines = array_filter($lines, 'ctype_alpha'); // Words been to match [a-zA-Z]
$lines = array_map('strtolower', $lines); // Set all the words to lowercase
$lines = array_unique($lines); // Remove any duplicate words
$lines = array_diff($lines, array('')); // Remove any empty lines
return $lines;
}
// Sort the individual letters in a string
// i.e. tale => aelt
private function sort_letters($word)
{
$letters = str_split($word);
sort($letters);
$sorted_word = implode('', $letters);
return $sorted_word;
}
// Generate our lookup table. This takes ~1.5second for 70,000 words
// $lookup ends up looking like:
//
// $lookup[4] = array
// (
// 'aelt' => array('late', 'tale', 'leta', 'teal'),
// 'belu' => array('blue', 'lube'),
// [etc...]
// )
// $lookup[5] = array
// (
// 'allms' => array('small', 'malls'),
// [etc...]
// )
//
// 4 and 5 are the word lengths, while 'aelt', 'belu' and 'allms' contains
// an array of all the words that can be spelt using these letters
public function __construct($filename)
{
$word_list = $this->load_word_list($filename);
$lookup = array();
foreach($word_list as $word)
{
$length = strlen($word);
if(!isset($lookup[$length]))
{
$lookup[$length] = array();
}
$sorted_word = $this->sort_letters($word);
if(!isset($lookup[$length][$sorted_word]))
{
$lookup[$length][$sorted_word] = array();
}
$lookup[$length][$sorted_word][] = $word;
}
$this->lookup = $lookup;
}
// Return all the anagrams of the passed word
public function lookup_word($word)
{
$word_length = strlen($word);
$sorted_word = $this->sort_letters($word);
if(isset($this->lookup[$word_length][$sorted_word]))
{
return $this->lookup[$word_length][$sorted_word];
}
return array();
}
// Return an array of all the sets of anagrams with a specific length
//
// Example result for a word length of 14:
//
// array
// (
// [0] => array('certifications','rectifications'),
// [1] => array('impressiveness','permissiveness'),
// [2] => array('tablespoonfuls','tablespoonsful'),
// )
public function all_of_length($word_length)
{
if(!isset($this->lookup[$word_length]))
{
return array();
}
$results = array();
foreach($this->lookup[$word_length] as $words)
{
if(count($words) > 1)
{
$results[] = $words;
}
}
return $results;
}
}
$anagram = new AnagramLookup(WORD_LIST_FILENAME);
printf("Anagrams of 'blue': %s\n", implode(', ', $anagram->lookup_word('blue')));
printf("Anagrams of 'late': %s\n", implode(', ', $anagram->lookup_word('late')));
printf("Anagrams of 'slow': %s\n", implode(', ', $anagram->lookup_word('slow')));
printf("Anagrams of 'seven': %s\n", implode(', ', $anagram->lookup_word('seven')));
printf("Anagrams of 'anagram': %s\n", implode(', ', $anagram->lookup_word('anagram')));
printf("All anagrams of word length 14\n");
foreach($anagram->all_of_length(7) as $words)
{
printf(" * %s\n", implode(', ', $words));
}
?>
Javascript is both infuriating and awesome at the same time. I don’t think I’ve ever speant so much time tracking down annoying bugs (even compared to PHP), yet at the same time it makes functions like the one below very simple to write.
For reference, the below code returns a `getter` method that we use to instantiate objects via a cache system.
var buildSimpleObjectGetter = function(cacheRef, objectRef)
{
var f = "buildSimpleObjectGetter()";
UTILS.checkArgs(f, arguments, [ObjectCache, Function]);
return function(idRecord, idArg)
{
return cacheRef.get('' + idArg, function()
{
return new objectRef(idRecord, idArg);
});
}
}
Update 20080327:
On the topic of stupid Javascript bugs, who thought auto terminating lines was a good default!
function getWords()
{
return
[
'Hello',
'World!'
];
}
console.info(getWords());
// Ouput
// >>> undefined