Originally posted by dalecosp
I decided I wanted to be known as a "guru hacker', as described in the classic tale here (and indeed, all over the web)....
Why do I get the feeling that "Master Programmer" was bowdlerised from "Microsoft Programmer"?
Originally posted by dalecosp
I decided I wanted to be known as a "guru hacker', as described in the classic tale here (and indeed, all over the web)....
Why do I get the feeling that "Master Programmer" was bowdlerised from "Microsoft Programmer"?
Originally posted by Weedpacket
Why do I get the feeling that "Master Programmer" was bowdlerised from "Microsoft Programmer"?
That was my impression, too; look at the symptoms; code bloat, overstructured, complex dependencies, etc. etc.
That why I wanted to be a "Guru Hacker". Type your command, and it Does The Right Thing (TM). Seemed like the best of the best in the tradition
Essentially:
$code = file_get_contents('file_to_test.php');
$code = str_replace("'", "'\"'\"'",$code);
$check = `echo '$code' | php -l`;
echo $check;
I knocked this up ages ago when I was still on dial up but still use it now.
It caches pages from On The Box and localises all the links and pictures so I can have a look at the telly listings really quick. If you get pages for future days it'll still show you that page when it arrives.
Useful if you live in Britain, and I'm sure it can be tacked onto somewhere else really easily.
Originally posted by drawmack
for($j=1;$j<count($calc);$j++)
Instead of using this as the statement for for loop using:
$sqrt_of_n = sqrt($n);
for($j=1;$j<count($calc)&&$calc[$j]<$sqrt_of_n;$j++)
we only need to check with all primes less than the square root of the number to confirm whether the number is prime or not.
Hmm, I'd never even looked at drawmack's "primes" post. Probably 'cuz he'd put the "validator" one down so quickly after it, and I found the validator more interesting/pertinent at the time...
Anyway, one of the coding contests we had $n months ago was on this subject, and there is plenty of discussion there. It was interesting --- for the limited subset of numbers we were using (3 second execution limit IIRC), it was actually quicker to do a rather simple loop of trial division than to use a more complex (read caching, for one) algorithm...IIRC, Weedpacket won that one (big surprise, that )
There might be no readily-accessible and/or portable method for determining which timezone the server running the script is located.
Things like "EST" are useless (a human with enough background knowledge might guess that that is Eastern Standard Time - but how many would guess it referred to eastern Australia? Sure, you may know where the server physically is, but it might not, and you don't want to be fiddling with your scripts every time they're installed in a different part of the world).
What you want is the actual current offset with respect to "Coordinated Universal Time" - or UTC (That's GMT to most people; but strictly speaking "Greenwich Mean Time" is ambiguous. Okay, the difference in the two definitions (the other one is known as UT1) is never more than 0.9 seconds - but hey, in GPS that makes a difference!) No, that parenthetical remark is really only there so that this post will contain a few extra search strings.
More, you want Daylight Saving to be automatically accounted for. New Zealand Standard Time is UTC+12 hours, and New Zealand Daylight Time is UTC+13 hours. British Standard Time is equivalent to UTC, and British Summer Time is UTC+1.
So here's a couple of lines that calculate that offset in hours; note that there are a few timezones that are offset from UTC by some odd multiple of half an hour. You'll know if yours is.
Obviously, your server's OS needs to be configured with the correct time zone - though, oddly, having the clock set to the correct time is not so critical!
list($y,$m,$d,$h,$i,$s) = explode('|', date('Y|m|d|H|i|s'));
echo (gmmktime($h,$i,$s,$m,$d,$y) - mktime($h,$i,$s,$m,$d,$y))/3600;
Here's a nifty way of calculating the mean of an array of numbers that works
even in cases where there are a LOT of large numbers (i.e., in situations where
adding all the numbers together and then dividing can result in a loss of
precision because the intermediate sum got too big).
function mean($array)
{
$mean = 0;
for($i=0,$c=count($array); $i<$c; $i++)
$mean += ($array[$i]-$mean)/($i+1);
return $mean;
}
Originally posted by benkillin
I think it's time for me to share some code again:
Coin flip simulator:
just some optimizations ideas, nothing major
<?php
$tf = array('T','H');
$results = array(); //T = dubTails H=dubHeads and E=oneEach
for($i=0; $i<100; $i++){// i seem to recall that <= is more intensive
$curFlip1 = $tf[rand(0,1)];
$curFlip2 = $tf[rand(0,1)];
if($curFlip1 == $curFlip2) //why check twice?
$results[$curFlip1]++; //take advantage of the increment operators and flip values to indice the results array
else
$results['E']++; //1 each
}
echo 'Double Tails: '.$results['T'].'<br /> \r\n Heads and Tails: '.$results['E'].'<br /> \r\n Double Heads: '.$results['H'];
?>
just something I noticed could be improved a bit
and to join in the contribution
a function that would mimic the 'short story' function on blogs... but instead of always being degradative (is that a word?) and always removing words to meet or beat the limit imposed by $len, it will check the length of the next word and add it, if it will bring it closer to $len then dropping the previous word.
this is based on len-current strlen < current strlen+nextwordlen-len = current result is closer
ie.
len=5
'abc e f' would return 'abc e...'
len=5
'ab cdefghi' would return 'ab...' but (5-2=3,9-5=4)
len=6 woule return 'ab cdefghi...' (6-2=4,9-6=3)
The user that requested help with a function like this tested it on a fairly large DB he said and it wasnt slow at all, but I'm always open to suggestions that I've overlooked in speeding it up
<?php
function limit_char($str,$len)
{
//this will always return the first word at minimum
$arr = explode(' ', $str);
$cnt = count($arr);
$return = '';
if ($len > strlen($str)) //if len is longer then str return full str
return(trim($str));
if (substr($str,$len,1) == ' ' || substr($str,$len+1,1) == ' ') //simple check to see if len is at or just before a space
return(trim(substr($str,0,$len+1)) . '...');
//we dont do the opposite check for just after a space due to short words following the break
for($i=0;$i<$cnt;$i++)
{
if ($i > 0)
{
$wlen = strlen($arr[$i]); //current word len
$rlen = strlen($return); //current return string length + 1 space
if (($wlen+$rlen) > $len) //next word puts us over the limit
if ($len - $rlen < $rlen+$wlen-$len) //if current return closer to len then return+ next word..
return(trim($return) . '...');
else //adding next word will be closer to len then the current return value
return($return . $arr[$i] . '...');
else
$return .= $arr[$i] . ' '; //next word still under len, add it
next;
}
else
{
$return .= $arr[$i] . ' ';
}
if (strlen($return) == $len || strlen($return) > $len) //see if first word puts us at or above the limit
return(trim($return) . '...');
}
}
echo 'strlen=32<br />';
for($j=0;$j<32;$j++)
echo "len=$j " . limit_char('abc def ghi jklmno pqr stu vwxyz',$j) . '<br />';
?>
PHP doesn't have static initialisers for classes the way - for example - Java does. In fact, you can't even use a constant expression (not even 5+4) as a static initialiser [Edit: You can as of PHP 5.6, with limitations]. Literals and arrays of literals, that's pretty much your lot.
But that's okay. PHP doesn't need them.
class foo
{
private static $one, $two, $three;
public static function static__construct()
{
static $constructed = false;
if($constructed) return;
$constructed = true;
self::$one = time();
self::$two = self::precompute_some_sort_of_table();
self::$three = self::$two[self::$one%42];
}
public function __construct()
{
//....etc.
}
//......Yadayadayada.......
} // End of class. Unless you're on detention.
foo::static__construct();
(On a parenthetical note, I just realised today that "self" can be used within a class anywhere the class's name is used - it's not just for static method calls any more.
static function splunge(self $beetroot)
{
$turnip = new self;
$turnip->mash_with($beetroot);
$vegie = self::dig_something_up();
if($vegie instanceof self)
echo 'Get all smug.';
else
throw new wobbly("An Unexpected Error occurred.");
return $vegie->mash_with($turnip);
}
This probably comes as no surprise to anyone, but frankly I blinked when I found it doing so eminently sensible. This can be evidence by my not doing it in my intervals class.)
The algorithm smells like Knuth to me. Anyway, roman_numeral(1997) returns mcmxcvii.
function roman_numeral($n)
{
settype($n, 'integer');
$ret = '';
$j = 0;
$str='mdclxvi';
$v = 1000;
for(;;)
{
while($n>=$v)
{
$ret.=$str{$j};
$n -= $v;
}
if($n<=0) return $ret;
$u = intval($v/((($k=$j)&1)?5:2));
if(!($k&1))
{
$u = intval($u/(((++$k)&1)?5:2));
}
if($n+$u>=$v)
{
$ret .= $str{$k+1};
$n += $u;
}
else
{
$v = intval($v/(((++$j)&1)?2:5));
}
}
}
Here is something that might be helpful to someone and it's dirt simple to implement. Often you want to do a report of "missing numbers" in a sequence, like missing checks. I'm not going to explain too much on this because the coding is very obvious once you see the trick involved, which is a LEFT JOIN of the table to itself on either the next greatest check number (provides a maximum if the join is null) or the next lesser check number (provides minimum if join is null). the SQL table creation and data is as follows:
CREATE TABLE `_breaks` (
`ID` int(9) unsigned NOT NULL auto_increment,
`checknumber` int(9) unsigned NOT NULL default '0',
PRIMARY KEY (`ID`)
) TYPE=MyISAM AUTO_INCREMENT=12 ;
#
# Dumping data for table `_breaks`
#
INSERT INTO `_breaks` VALUES (1, 1000);
INSERT INTO `_breaks` VALUES (2, 1001);
INSERT INTO `_breaks` VALUES (3, 1007);
INSERT INTO `_breaks` VALUES (4, 1008);
INSERT INTO `_breaks` VALUES (5, 1009);
INSERT INTO `_breaks` VALUES (6, 1010);
INSERT INTO `_breaks` VALUES (7, 1011);
INSERT INTO `_breaks` VALUES (8, 1012);
INSERT INTO `_breaks` VALUES (9, 1014);
INSERT INTO `_breaks` VALUES (10, 1020);
INSERT INTO `_breaks` VALUES (11, 1021);
Be sure and index your checknumber field!!!!
Next we query the table twice as follows:
/** Range Minimums **/
SELECT a.checknumber
FROM _breaks a
LEFT JOIN _breaks b ON
a.checknumber = b.checknumber +1
WHERE b.checknumber IS NULL
/** Range Maximums **/
SELECT a.checknumber
FROM _breaks a
LEFT JOIN _breaks b ON
a.checknumber = b.checknumber -1
WHERE b.checknumber IS NULL
I'll skip the php-mysql scripting to contact the table, you can figure that out, but you'll need to get the minimums and maximums as two arrays as follows:
$minimums= array(1000,1007,1014,1020);
$maximums= array(1001,1012,1014,1021);
Now here's the simple code to put the contiguous sequences into an array, and an example of its use:
foreach($minimums as $v){
$i++;
$ranges[$i]['min']=$v;
do{
//nothing needed here
}while( (list(,$w)=each($maximums))<$v);
$ranges[$i]['max']=$w;
}
echo 'Contiguous Sequences:<br>';
foreach($ranges as $n=>$v){
echo ($v['min']==$v['max']) ? 'Check '.$v['min'] : 'Checks '.$v['min'].'-'.$v['max'];
echo '<br>';
}
The end result:
Contiguous Sequences:
Checks 1000-1001
Checks 1007-1012
Check 1014
Checks 1020-1021
That's it! So if your client ever wants a report on a range of contiguous numbers like a missing check report, this will be helpful.
Samuel
Okay, so num2name() converts the decimal representation of a natural number into its English representation. But there are two types of natural numbers. There are the cardinals (which are used for counting how many there are of something), and there are the ordinals (which are used for ordering). The fact is that English distinguishes between the two.
The cardinals run "zero", "one", "two", "three", and so forth. The ordinals are called (in order!) "first", "second", "third", "forth", etc. Note that in conventional English there is no ordinal corresponding to "zero". I need only mention zero-indexed arrays and you'll recognise some of the issues this difference can cause. There is a need for "zeroth" and so this function supplies it. (Plus, it's the obvious return value when 0 is passed in.
For convenience this function takes the same input as num2name().
num2ordinal($number)
{
$cardinal = num2name($number);
$replacements = array(
'one'=>'first',
'two'=>'second',
'three'=>'third',
'five'=>'fifth',
'nine'=>'ninth',
'twelve'=>'twelfth',
'y'=>'ieth');
foreach($replacements as $card=>$ord)
{
$len=-strlen($card);
if(substr($cardinal,$len)==$card)
return substr($cardinal,0,$len).$ord;
}
return $cardinal.'th';
}
I am putting together a website that is supposed to have a large collection of free PHP scripts. If you want to, you can post any scripts you want there along with any copyright or contact information you want to go with it. I would greatly appreciate it. The website is here:
http://phpshift.fireproductions.co.uk
It gets a good amount of traffic, so if you want people to see your codes, it's a good place to put it.
Hey, I've not seen this thread in ages. I've just been taking a look back through and saw my rather ropey PHP4 static property implementation. PHP4 does not have static class properties but it does have static function properties so we can use that instead, and the best bit is, it's painfully simple. The majority of the code is just a convaluted test.
<?php
class MyTest {
var
$dynamic,
$static;
function MyTest() {
static $static;
$this->static =& $static;
}
}
$obj1 = new MyTest;
$obj2 = new MyTest;
$obj1->static = 'Blah';
$obj1->dynamic= 'Blah';
echo <<<END_TEXT
\$obj1->static: {$obj1->static}
\$obj1->dynamic: {$obj1->dynamic}
\$obj2->static: {$obj2->static}
\$obj2->dynamic: {$obj2->dynamic}
END_TEXT;
$obj2->static = 'Whoa!';
$obj2->dynamic= 'Whoa!';
echo <<<END_TEXT
\$obj1->static: {$obj1->static}
\$obj1->dynamic: {$obj1->dynamic}
\$obj2->static: {$obj2->static}
\$obj2->dynamic: {$obj2->dynamic}
END_TEXT;
phpshift wrote:It gets a good amount of traffic, so if you want people to see your codes, it's a good place to put it.
Why not post it here? This site gets a good amount of traffic, too. Or was this just an excuse to pimp your site again?
Weedpacket wrote:Why not post it here? This site gets a good amount of traffic, too. Or was this just an excuse to pimp your site again?
Well, I'm sure these forum posts are eventually deleted. If you put it on my site, it'll be there permanently.
No, you will be remembered forever here now. But, what's with the design on your site...ouch.
A lot of the people here need to cool down a bit....