Click to See Complete Forum and Search --> : Working PHP Scripts


Mr Initial Man
01-27-2007, 02:02 AM
I hereby propose a sticky: Scripts you want to show off.

A few rules for this thread:


They must be usable as an included text file.
You must explain either in the post or in the comments how this script works, and how to use it.
The script must have been tested and made to work properly.
The script should be as efficient as possible.


Allow me to start this off. I have created this script, tested it, and made sure it works.


<?php

#############################################################################
# WHOLE NUMBERS TO ROMAN NUMERALS #
#===========================================================================#
# A script in which a whole number is converted to a Roman Numeral #
# Coded by Lynx Kraaikamp #
# This script is provided free of charge and copyright #
# Others may freely copy, use, modify, swear by, swear at, enjoy, and hate. #
#############################################################################

# EXPLANATION OF HOW THIS WORKS.
# The value of Roman Numerals are: M=1000, D=500, C=100, L=50, X=10, V=5, and I=1.
# In modern Roman Numerals, CM=900, CD=400, XC=90, XL=40, IX=9, and IV=4.
# M, C, and I can all occur up to 3 times in a row. Therefore, they are placed in loops.
# CM, D, CD, XC, L, XL, IX, V, and IV all occur once and once only. Therefore they are placed in if statements.
# The "while" loops run as long as the number to be converted is above the triggering number for the loop.
# Each time the number goes through the loop, the proper amount is subtracted from the number, and the corresponding letter is added to the string.
# For example, if 201 goes through the "C" loop, 100 is subtracted the first time, and a C is added to the string, so the number is now 101, and the string reads "C". The number is still above 100, so it goes through a second time. Another 100 is subtracted, leaving the number and string 1 and CC, respectively. The number will continue down until it hit the "I" loop. 1 will be subtracted, leaving the number as 0, and the string as CCI.
# However, the number was smaller than 1000, 900, 500, and 400, so the while loop and if statements were skipped. The resulting number from the "C" loop was smaller than 90, 50, 40, 10, and 5, so those were skipped as well.
#The best way to set the starting variable is to put the following in your parent PHP file: $OriginalNumber=$[YourVariable]; You may then use the variable $RomanNumeral in your parent file.

# $OriginalNumber is used to test to see if the number is greater than 0.


if ($OriginalNumber>=1)
{
$ConvertNumber=$OriginalNumber;
}
else
{
die('Your number needs to be greater than 0');
}

# $RomanNumeral='' is VERY IMPORTANT in loops. It "resets" the variable to an empty string. Otherwise, it will be a serious mess if you use it in a loop.

$RomanNumeral='';

while($ConvertNumber>=1000)
{
$ConvertNumber=$ConvertNumber-1000;
$RomanNumeral=$RomanNumeral.'M';
}

if($ConvertNumber>=900)
{
$ConvertNumber=$ConvertNumber-900;
$RomanNumeral=$RomanNumeral.'CM';
}

if($ConvertNumber>=500)
{
$ConvertNumber=$ConvertNumber-500;
$RomanNumeral=$RomanNumeral.'D';
}
if($ConvertNumber>=400)
{
$ConvertNumber=$ConvertNumber-400;
$RomanNumeral=$RomanNumeral.'CD';
}
while($ConvertNumber>=100){
$ConvertNumber=$ConvertNumber-100;
$RomanNumeral=$RomanNumeral.'C';
}
if($ConvertNumber>=90)
{
$ConvertNumber=$ConvertNumber-90;
$RomanNumeral=$RomanNumeral.'XC';
}
if($ConvertNumber>=50)
{
$ConvertNumber=$ConvertNumber-50;
$RomanNumeral=$RomanNumeral.'L';
}
if($ConvertNumber>=40)
{
$ConvertNumber=$ConvertNumber-40;
$RomanNumeral=$RomanNumeral.'XL';
}
while($ConvertNumber>=10)
{
$ConvertNumber=$ConvertNumber-10;
$RomanNumeral=$RomanNumeral.'X';
}
if($ConvertNumber>=9)
{
$ConvertNumber=$ConvertNumber-9;
$RomanNumeral=$RomanNumeral.'IX';
}
if($ConvertNumber>=5)
{
$ConvertNumber=$ConvertNumber-5;
$RomanNumeral=$RomanNumeral.'V';
}
if($ConvertNumber>=4)
{
$ConvertNumber=$ConvertNumber-4;
$RomanNumeral=$RomanNumeral.'IV';
}
while($ConvertNumber>=1)
{
$ConvertNumber=$ConvertNumber-1;
$RomanNumeral=$RomanNumeral.'I';
}
?>

NightShift58
01-27-2007, 03:45 AM
After seeing all the loops, I thought it to be an ideal case for a somewhat recursive function. Here's what I came up with:<?php
echo MakeRoman($_GET['num']);

function MakeRoman($ConvertNumber, $UnitLtr='M', $UnitSub='C', $UnitNum=1000, $tenth='100') {
if ($ConvertNumber < 1) {
return;
}
static $RomanNumeral;
$count = intval($ConvertNumber / $UnitNum);
if ($count > 0) {
$RomanNumeral .= str_repeat($UnitLtr, $count);
$ConvertNumber -= $count * $UnitNum;
if ($ConvertNumber >= ($UnitNum - $tenth)) {
$RomanNumeral .= $UnitSub . $UnitLtr;
$ConvertNumber -= ($UnitNum - $tenth);
}
}
if ($UnitNum == 1000) :
MakeRoman($ConvertNumber, "D", "C", 500, 100);
elseif ($UnitNum == 500) :
MakeRoman($ConvertNumber, "C", "X", 100,10);
elseif ($UnitNum == 100) :
MakeRoman($ConvertNumber, "L", "X", 50, 10);
elseif ($UnitNum == 50) :
MakeRoman($ConvertNumber, "X", "I", 10,1);
elseif ($UnitNum == 10) :
MakeRoman($ConvertNumber, "V", "I", 5, 1);
elseif ($UnitNum == 5) :
MakeRoman($ConvertNumber, "I", "", 1,0);
endif;
return $RomanNumeral;
}
?>I use a GET to input numbers for testing purposes. If you find this version suitable, we could document it. Otherwise, I think it meets all the other cirteria you set forth.

Mr Initial Man
01-27-2007, 04:06 AM
I've never used that method. Mostly because I don't have the knowledge to do it that way.

LiLcRaZyFuZzY
01-27-2007, 04:16 AM
Definately better for reuse

Say NightShift, any reason you didn't use a switch-case?

NightShift58
01-27-2007, 04:18 AM
I almost never use them because - lame excuse - I always forget to use "break" and it's cost me years of my life...

LiLcRaZyFuZzY
01-27-2007, 04:21 AM
Well that would seem like a good case to use them ;)

NightShift58
01-27-2007, 04:25 AM
It's 4:24 a.m. and you want me to switch/case... At your risk and peril...<?php
echo MakeRoman($_GET['num']);

function MakeRoman($ConvertNumber, $UnitLtr='M', $UnitSub='C', $UnitNum=1000, $tenth='100') {
if ($ConvertNumber < 1) {
return;
}
static $RomanNumeral;
$count = intval($ConvertNumber / $UnitNum);
if ($count > 0) {
$RomanNumeral .= str_repeat($UnitLtr, $count);
$ConvertNumber -= $count * $UnitNum;
if ($ConvertNumber >= ($UnitNum - $tenth)) {
$RomanNumeral .= $UnitSub . $UnitLtr;
$ConvertNumber -= ($UnitNum - $tenth);
}
}

switch ($UnitNum ) {
case 1000 :
MakeRoman($ConvertNumber, "D", "C", 500, 100);
break;
case 500 :
MakeRoman($ConvertNumber, "C", "X", 100,10);
break;
case 100 :
MakeRoman($ConvertNumber, "L", "X", 50, 10);
break;
case 50 :
MakeRoman($ConvertNumber, "X", "I", 10,1);
break;
case 10 :
MakeRoman($ConvertNumber, "V", "I", 5, 1);
break;
case 5 :
MakeRoman($ConvertNumber, "I", "", 1,0);
break;
}
return $RomanNumeral;
}
?>

LiLcRaZyFuZzY
01-27-2007, 04:30 AM
hehe! good now go back to bed!

NightShift58
01-27-2007, 04:35 AM
I still a couple of coffees to wear off...

Mr Initial Man
01-27-2007, 04:11 PM
I tried it, and well, my script is good because it can be used in a loop (each time the loop is run, the script file is called). Yours can't be in a loop.

Here's where my script is being used:

for ($loop=1;$loop<=$partstotal;$loop++)
{
$OriginalNumber=$part;

#My script called here:
include("../PHP_Scripts/Roman.php");

if (($part%8)==1)
{
$partclass="part clear";
}
else
{
$partclass="part";
}

echo('
<li class="'.$partclass.'">Part '.$RomanNumeral.':<br>'.$partnames[$part].'<br><em>('.$addlimit[$part].' Chapters)</em>
<ul>
');
$toplimit=$toplimit + $addlimit[$part];
for ($chapter; $chapter<=$toplimit;$chapter++)
{
echo(' <li><a tabindex="'.$tab++.'" href="./Fighter/fighter.php?chapter='.$chapter.'">Chapter '.$chapter.'</a></li>'.$nl);
}
$part++;
echo(' </ul>
</li>');
}

NightShift58
01-27-2007, 04:17 PM
I wrote it as function. You should be able to call that function within a loop, just the same. For example:<?php
FOR ($x=999; $x < 3333; $x++) :
echo MakeRoman($x);
ENDFOR;
?>

P.S. I just modified the "structure" of the script. The "logic" - how to convert and when - is yours.

Mr Initial Man
01-27-2007, 05:02 PM
But you're running into the problem I ran into when I put it through a loop without "resetting" $RomanNumeral. Remember that a roman numeral is NOT a number, it is a string, and the string is built via concatenation. Thus, every time you run the function, you have to reset $RomanNumeral to an empty string, or it will carry it's previous value into the new iteration of the function, and the results will be rather bizarre.

For example, here's what I'm getting for the numbers 1-7: I, III, IIIIII, IIIIIIIIII, IIIIIIIIIIV, IIIIIIIIIIVVI, IIIIIIIIIIVVIVII. It SHOULD be instead (using this function) I, II, III, IIII, V, VI, VII.

Your script also lacks the mechanisms to deal with 900 (CM), 400 (CD), 90 (XC), 40 (XL), 9 (IX) and 4 (IV), which are taken into account in my script. DCCCC, CCCC, LXXXX, XXXX, VIIII, and IIII are acceptable, but are seldom used, since they're archaic.

bokeh
01-27-2007, 05:32 PM
any reason you didn't use a switch-case?One reason not to use switch statements is because they only allow an equality (loose) comparison between the return value of the common expression and the return value of each case expression.

Mr Initial Man
01-27-2007, 05:57 PM
Also, your script comes up with a mistake every time you use a 9, 90, or 900:

Arabic Your Script Archaic Modern
----------------------------------------------
900 DCD DCCCC CM
90 LXL LXXXX XC
9 VIV VIIII IX

DCD, LXL, and VIV are never used when writing Roman Numerals.

Not only that, but when you use 4, 40, or 400, the result is IIII, XXXX, or CCCC, respectively, so it's inconsistent to boot.

I use a GET to input numbers for testing purposes. If you find this version suitable, we could document it. Otherwise, I think it meets all the other cirteria you set forth.

1. They must be usable as an included text file.
Check. I tested it it, and it will work that way.
2. You must explain either in the post or in the comments how this script works, and how to use it.
Bit lacking in the description, such as how it actually works. Once PHP coders know how it actually works, we can modify it to suit our own needs.
3. The script must have been tested and made to work properly.
This is the most important one. I'm sorry, yours does not deal with the contatenation properly, nor the conversion process. Remember, this was designed for a series of numbers being converted as part of a LOOP.
4. The script should be as efficient as possible.
It's smaller than mine, but who knows? If you get it working properly, it might not be quite so slim.

Basically, it fulfills 1 and 4 nicely, is okay on 2, but flops on 3. Your script needs a bit more work, methinks. :o

BTW, Bokeh, what do you think of mine?

NightShift58
01-27-2007, 07:14 PM
One reason not to use switch statements is because they only allow an equality (loose) comparison between the return value of the common expression and the return value of each case expression.
Here was my statement when asked to switch/case it:It's 4:24 a.m. and you want me to switch/case... At your risk and peril...I haven't - purposely - used switch/case in over 3 years. I don't see what others see in it nor what functions it fulfills that if/elseif/else will not...

NightShift58
01-27-2007, 08:29 PM
DCD, LXL, and VIV are never used when writing Roman Numerals.Hoping to improve efficiency, I had made a last minute - post-test - change by adding the statement:if ($count > 0) {thinking it would skip over a few unnecessary lines of code if the condition were true. As the saying goes, if it ain't broke, don't fix it... I shortened the script by this and its respective closing bracket and the results are now back in line with your original script - as far as I can tell.

I did fix the static problem with $RomanNumeral by adding these lines: if ($UnitLtr=="M") {
$RomanNumeral = "";
}I changed the structure slightly to give the function a single point of entry and single point of exit, as functions used to be...

Here it is again, minus switch...function MakeRoman($ConvertNumber, $UnitLtr='M', $UnitSub='C', $UnitNum=1000, $tenth='100') {
static $RomanNumeral;
if ($UnitLtr=="M") {
$RomanNumeral = "";
}
if ($ConvertNumber > 0) {
$count = intval($ConvertNumber / $UnitNum);
$RomanNumeral .= str_repeat($UnitLtr, $count);
$ConvertNumber -= $count * $UnitNum;
if ($ConvertNumber >= ($UnitNum - $tenth)) {
$RomanNumeral .= $UnitSub . $UnitLtr;
$ConvertNumber -= ($UnitNum - $tenth);
}
if ($UnitNum == 1000) :
MakeRoman($ConvertNumber, "D", "C", 500, 100);
elseif ($UnitNum == 500) :
MakeRoman($ConvertNumber, "C", "X", 100,10);
elseif ($UnitNum == 100) :
MakeRoman($ConvertNumber, "L", "X", 50, 10);
elseif ($UnitNum == 50) :
MakeRoman($ConvertNumber, "X", "I", 10,1);
elseif ($UnitNum == 10) :
MakeRoman($ConvertNumber, "V", "I", 5, 1);
elseif ($UnitNum == 5) :
MakeRoman($ConvertNumber, "I", "", 1,0);
endif;
}
return $RomanNumeral;
}To make testing easier, I put up a script with both methods running side by side. It should make it easier to verify results (1. is my function and 2. yours). See: http://www.nightshift58.com/webdev/test_Roman.php

Mr Initial Man
01-27-2007, 11:52 PM
I ran it through a loop that went from 1-1000. It works excellently.

NightShift58
01-27-2007, 11:58 PM
Thank you, sir...

Mr Initial Man
01-28-2007, 12:21 AM
And here it is, slimmed down even further with a switch/case:

<?php
function MakeRoman($ConvertNumber,$UnitLtr='M',$UnitSub='C',$UnitNum=1000,$tenth='100')
{
static $RomanNumeral;
if ($UnitLtr=="M")
{
$RomanNumeral="";
}
if ($ConvertNumber > 0)
{
$count=intval($ConvertNumber/$UnitNum);
$RomanNumeral.=str_repeat($UnitLtr,$count);
$ConvertNumber-=$count*$UnitNum;
if ($ConvertNumber>=($UnitNum-$tenth))
{
$RomanNumeral.=$UnitSub.$UnitLtr;
$ConvertNumber-=($UnitNum-$tenth);
}
switch($UnitNum)
{
case 1000:
MakeRoman($ConvertNumber,"D","C",500,100);
break;
case 500:
MakeRoman($ConvertNumber,"C","X",100,10);
break;
case 100:
MakeRoman($ConvertNumber,"L","X",50,10);
break;
case 50:
MakeRoman($ConvertNumber,"X","I",10,1);
break;
case 10:
MakeRoman($ConvertNumber,"V","I",5,1);
break;
case 5:
MakeRoman($ConvertNumber,"I","",1,0);
break;
}
}
return $RomanNumeral;
}
?>

One reason not to use switch statements is because they only allow an equality (loose) comparison between the return value of the common expression and the return value of each case expression.
But if you are using a series of elseif(x==y) statements, you might as use switch statements, as == is much the same as case.

NightShift58
01-28-2007, 12:34 AM
My problem is that I always forget to code the "break" in there.

With if/elseif, I drive safer...

But, with case you're not limited to strict == checking, it works (almost) just like an if/elseif, except that the break; must be there:<?
$a = 11;
$b = 99;

switch (true) :
case ($a == 9) :
print "hello 9";
break;
case ($b == 10) :
print "hello 10";
break;
case ($a == 11) :
print "hello 11";
break;
case ($b == 12) :
print "hello 12";
break;
endswitch;
?>Internally, it all boils down to if/else, because machine language doesn't have any other options.

Mr Initial Man
01-28-2007, 12:54 AM
I prefer to use case, though. It makes things a bit cleaner.

One thing I /would/ like to figure out is how your script works. I've never used functions before.

NightShift58
01-28-2007, 01:09 AM
Here's an example of a function you'll be able to relate to "intimately":<?php

if ($OriginalNumber>=1)
{
echo MakeRoman($OriginalNumber);
echo MakeRoman($OriginalNumber+1);
echo MakeRoman($OriginalNumber+2);
echo MakeRoman($OriginalNumber+3);
echo MakeRoman($OriginalNumber+4);
}
else
{
die('Your number needs to be greater than 0');
}

//-------------------------------------------------------------
function MakeRoman($ConvertedNumber) {
$RomanNumeral='';

while($ConvertNumber>=1000)
{
$ConvertNumber=$ConvertNumber-1000;
$RomanNumeral=$RomanNumeral.'M';
}

if($ConvertNumber>=900)
{
$ConvertNumber=$ConvertNumber-900;
$RomanNumeral=$RomanNumeral.'CM';
}

if($ConvertNumber>=500)
{
$ConvertNumber=$ConvertNumber-500;
$RomanNumeral=$RomanNumeral.'D';
}
if($ConvertNumber>=400)
{
$ConvertNumber=$ConvertNumber-400;
$RomanNumeral=$RomanNumeral.'CD';
}
while($ConvertNumber>=100){
$ConvertNumber=$ConvertNumber-100;
$RomanNumeral=$RomanNumeral.'C';
}
if($ConvertNumber>=90)
{
$ConvertNumber=$ConvertNumber-90;
$RomanNumeral=$RomanNumeral.'XC';
}
if($ConvertNumber>=50)
{
$ConvertNumber=$ConvertNumber-50;
$RomanNumeral=$RomanNumeral.'L';
}
if($ConvertNumber>=40)
{
$ConvertNumber=$ConvertNumber-40;
$RomanNumeral=$RomanNumeral.'XL';
}
while($ConvertNumber>=10)
{
$ConvertNumber=$ConvertNumber-10;
$RomanNumeral=$RomanNumeral.'X';
}
if($ConvertNumber>=9)
{
$ConvertNumber=$ConvertNumber-9;
$RomanNumeral=$RomanNumeral.'IX';
}
if($ConvertNumber>=5)
{
$ConvertNumber=$ConvertNumber-5;
$RomanNumeral=$RomanNumeral.'V';
}
if($ConvertNumber>=4)
{
$ConvertNumber=$ConvertNumber-4;
$RomanNumeral=$RomanNumeral.'IV';
}
while($ConvertNumber>=1)
{
$ConvertNumber=$ConvertNumber-1;
$RomanNumeral=$RomanNumeral.'I';
}
return $RomanNumeral;
}
?>It's as easy as that. Take some code that is going to be used often - or that is so messy that you don't don't want cluttering your main code - and you've got a function in the making. The bit about recursion simply means that the function, while processing your data, is able to call itself and then return to the exact spot it "left" and remember everything as it was... By definition a function always returns a value upon completion - whether you make any use of it is another story. In the case of your script, it returns the Roman numeral.

Mr Initial Man
01-28-2007, 01:48 AM
Okay. I see what you're saying. intval and str_repeat are new to me, though.

bokeh
01-28-2007, 09:59 AM
I don't see what others see in it nor what functions it fulfills that if/elseif/else will not...Nor do I!

Mr Initial Man
01-28-2007, 02:30 PM
First of all, it allows guys like me to use methods that make guys like Bokeh and NightShift wonder what the heck I'm on. I just find it slimmer than if/elseif/else

NightShift58
01-28-2007, 03:07 PM
First of all, it allows guys like me to use methods that make guys like Bokeh and NightShift wonder what the heck I'm on. I just find it slimmer than if/elseif/elseA lot of people on this and other forums share your views on switch/case.

I think it's more of a "chic" trend - because it looks very "C-ish" and there are really no convincing arguments for a syntax which requires multiple exit points just to get it right.

In fact, it used to be considered bad programming style to have a function with more than one exit point. Quality control wouldn't even accept any code where the programmer couldn't justify it (act of God or similar causes...)

Nowadays, just about every function you see floating around has multiple returns - and poor structure, which often goes hand in hand. The same goes for scripts with myriads of exit points - exit(), header()... It seems that these exit points are there to solve poor structure. And I don't like switch/case make it looks acceptable - almost encourages that kind of thinking - because it requires it the exits points in most cases.

When to use switch/case? I can see a switch/case block being used to "filter" top-down but not as a replacement for the slimmer AND more efficient if/else.

Example:<?
$a = 100;
SWITCH ($a) :
case 100:
$a = $a / 2;
case 75:
$a = $a * 2;
case 50:
$a = $a * 5;
case 25:
$a = $a *
ENDSWITCH;
?>Sadly, to do the above, most people would use if/else in place of switch/case. A perversion of sorts...

But... whatever makes one happy... it's a big world... :)

Mr Initial Man
01-28-2007, 03:16 PM
*Sighs and watches as the original purpose of the thread gets completely lost.*

NightShift58
01-28-2007, 03:49 PM
But if you are using a series of elseif(x==y) statements, you might as use switch statements, as == is much the same as case.What Bokeh is saying - I think - is this:<?
$a = strpos("abc", "a");
switch ($a) {
case (true) :
// found it
break;
case (false):
// didn't find it
}
?>which would lead you to think - wrongly - that it wasn't found. Granted, it's solvable but it does start looking really strange... And if I have to make excuses for bending syntax over backwards...

Mr Initial Man
01-28-2007, 03:58 PM
I really didn't want this to turn into an argument between Switch and Case. What I really wanted this thread to be was a showcase of scripts we'd come up with on our own, and got to work.

Sorry that it turned into a snapping contest.

bokeh
01-28-2007, 04:23 PM
$a = strpos("abc", "a");[/php]Well that is a very common novice error. It is not exactly what I meant but it does prove the point.
switch ('LiLcRaZyFuZzY!')
{
case '0':
echo 'Confused!<br>';
case 0:
echo 'More confused!<br>';
}How many people know what that is going to output without running it.

LiLcRaZyFuZzY
01-28-2007, 04:30 PM
Erm..I'm confused :p

Mr Initial Man
01-28-2007, 04:35 PM
"More confused", I do believe. 'LiLcRaZyFuZzY' would be a null value, as it's not a variable, and nulls are false. 0 is also false, but '0' is true, since that is a string. Am I correct?

bokeh
01-28-2007, 04:41 PM
I really didn't want this to turn into an argument between Switch and Case. What I really wanted this thread to be was a showcase of scripts we'd come up with on our own, and got to work.Don't worry! If one of the mods think that's what's happened I'm sure they will split the thread.

bokeh
01-28-2007, 04:45 PM
"More confused", I do believe. 'LiLcRaZyFuZzY' would be a null value, as it's not a variableActually it's a string.

NightShift58
01-28-2007, 05:23 PM
-> "More confused" I think... 0, as opposed to '0' evaluates to false, same as the switch variable... Or am I really confused?

Mr Initial Man
01-28-2007, 05:39 PM
Would a moderator be so kind as to seperate out the Switch/IfElse discussion into a different thread?

bokeh
01-28-2007, 05:47 PM
-> "More confused" I think... 0, as opposed to '0' evaluates to false, same as the switch variable... Or am I really confused?Well that's really my point. Someone as experienced as you can still be baffled by this.var_dump( 0 == '0' ); #true
var_dump( 0 == false); #true
var_dump('0' == false); #true

In the case of var_dump('0' == 'LiLcRaZyFuZzY'); #falseIt is a string to string comparision so it is obvious that the result will be false.

In the case of var_dump(0 == 'LiLcRaZyFuZzY'); #true this is an integer to string comparison. The string is first converted to an integer. If the string is non-numeric its value is considered zero for numeric comparison purposes.

NightShift58
01-28-2007, 06:00 PM
Someone as experienced as you...As always, it depends on the context...

If you mean I've coded made my shares of errors, then you are absolutely right. In fact, as is often obvious in this forum, I am still "gaining" experience...:)

But, yes, or better, no, switch/case makes no sense as a general purpose control structure. Besides, even if I would get everything else right, I always forget to code in the breaks. So it' s really hopeless - and useless - for me.

Mr Initial Man
01-28-2007, 06:23 PM
*Looks sadly at all the switch/cases he's used.*

NightShift58
01-28-2007, 06:27 PM
I think that Bokeh has very eloquently made a case for switching.

I certainly learned a lot from it and I'm glad you started this thread as it has been extremely informative.

Good job, Mr. Initial Man!

LiLcRaZyFuZzY
01-29-2007, 02:31 AM
For me too ;)

Mr Initial Man
01-29-2007, 07:23 PM
Back to the original topic, this is the idea, stripped down to its bare essentials. It's less than half the size of the original, too.


<?php
function ConvertToRoman($Convert){
$Roman = array( 'M' => 1000,
'CM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'XC' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1
);
foreach($Roman as $RomNum => $Value){
while($Convert >= $Value){
$Convert -= $Value;
$RomanNumeral .= $RomNum;
}
}
return $RomanNumeral;
}
?>

Think this is fit for showcasing?

NightShift58
01-29-2007, 07:25 PM
Yes, but do initialize $RomanNumeral, as discussed in my reply on the other thread.

Mr Initial Man
01-29-2007, 07:29 PM
And done.


<?php
function ConvertToRoman($Convert){
$RomanNumeral='';
$Roman = array( 'M' => 1000,
'CM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'XC' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1
);
foreach($Roman as $RomNum => $Value){
while($Convert >= $Value){
$Convert -= $Value;
$RomanNumeral .= $RomNum;
}
}
return $RomanNumeral;
}
?>

NightShift58
01-29-2007, 07:35 PM
I like it!

Mr Initial Man
01-29-2007, 08:34 PM
For something even tighter, the old Roman Numerals.
<?php
function ConvertToOldRoman($Convert){
$RomanNumeral='';
$Roman = array( 'M' => 1000,
'D' => 500,
'C' => 100,
'L' => 50,
'X' => 10,
'V' => 5,
'I' => 1
);
foreach($Roman as $RomNum => $Value){
while($Convert >= $Value){
$Convert -= $Value;
$RomanNumeral .= $RomNum;
}
}
return $RomanNumeral;
}
?>

NightShift58
01-30-2007, 01:46 AM
This example combines both of your functions into a single one:<?php

echo ConvertToRoman(1955);
echo ConvertToRoman(1955, true);


function ConvertToRoman($Convert, $OldRoman=false){
$Roman = array();
$Roman[] = array('M' => 1000);
if (!$OldRoman) { $Roman[] = array('CM' => 900); }
$Roman[] = array('D' => 500);
if (!$OldRoman) { $Roman[] = array('CD' => 400); }
$Roman[] = array('C' => 100);
if (!$OldRoman) { $Roman[] = array('XC' => 90); }
$Roman[] = array('L' => 50);
if (!$OldRoman) { $Roman[] = array('XL' => 40); }
$Roman[] = array('X' => 10);
if (!$OldRoman) { $Roman[] = array('IX' => 9); }
$Roman[] = array('V' => 5);
if (!$OldRoman) { $Roman[] = array('IV' => 4); }
$Roman[] = array('I' => 1);

$RomanNumeral = '';
foreach($Roman as $RomNum => $Value) {
while($Convert >= $Value) {
$Convert -= $Value;
$RomanNumeral .= $RomNum;
}
}
return $RomanNumeral;
}
?>By simply ading a parameter when calling the function, you get the same function to convert to either the modern or old format. It's not as "tight" but "packs" a little more.

Mr Initial Man
01-30-2007, 02:46 AM
It's definately tighter than having both functions seperately. :) Unfortunately, it's not quite working. I'll have to fiddle around with it, to see if I can make it work.

Mr Initial Man
02-04-2007, 10:38 PM
I have a solution, that will offer both styles in one function:

function MakeRoman($Convert, $Style='Modern'){
$RomanNumeral='';
$RomNum = array('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I');
$Value = array(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1);
if ($Style=='Old'){
$step=2;
} else {
$step=1;
}
for($i=0; $i<=12; $i+=$step){
while($Convert >= $Value[$i]){
$Convert -= $Value[$i];
$RomanNumeral .= $RomNum[$i];
}
}
return $RomanNumeral;
}

The reason I can get away with a for loop is there are only 13 basic values when it comes to modern Roman Numerals, and only 7 when it comes to the old style. I checked, and it works. *Goes and updates his PHP Script Showcase Index (http://www.webdeveloper.com/forum/showthread.php?t=136555)*