I have a rating system on my Wordpress that came with the theme. The maximum rating possible is 10, so I wanted to edit this and make a 100 possible rating.
So I edited this part:
public static function max_rating( $listing_id = null ) {
$default = 100;
So now it understands that the max possible rating is 100.
But under the rating array, there were these lines:
$rating_options = array(
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'10' => 10,
Which understand that the maximum possible rating is 10. Now I want to make a maximum rating of 100, but adding '11' => 11, '12' => 12, '13' => 13 etc takes a lot of time and it consumes a lot of space in my file. Is there a possiblity to shorten this or do I really have to enter every rating up to 100?
The accepted answer points you in the right direction.
Additional I would advice using array_combine like so:
$range = range(1,100);
$rating_options = array_combine($range, $range);
// array(1=>1, 2=>2, ...)
This way, your keys will be the same as the values.
you can use PHP's range function:
$ratings = range(0, 100);
reference: https://secure.php.net/manual/en/function.range.php
Related
I want to calculate and store the dense rank and gapped rank for all entries in an array using PHP.
I want to do this in PHP (not MySQL because I am dealing with dynamic combinations 100,000 to 900 combinations per week, that’s why I cannot use MySQL to make that many tables.
My code to find the dense ranks is working, but the gapped ranks are not correct.
PHP code
$members = [
['num' => 2, 'rank' => 0, 'dense_rank' => 0],
['num' => 2, 'rank' => 0, 'dense_rank' => 0],
['num' => 3, 'rank' => 0, 'dense_rank' => 0],
['num' => 3, 'rank' => 0, 'dense_rank' => 0],
['num' => 3, 'rank' => 0, 'dense_rank' => 0],
['num' => 3, 'rank' => 0, 'dense_rank' => 0],
['num' => 3, 'rank' => 0, 'dense_rank' => 0],
['num' => 5, 'rank' => 0, 'dense_rank' => 0],
['num' => 9, 'rank' => 0, 'dense_rank' => 0],
['num' => 9, 'rank' => 0, 'dense_rank' => 0],
['num' => 9, 'rank' => 0, 'dense_rank' => 0]
];
$rank=0;
$previous_rank=0;
$dense_rank=0;
$previous_dense_rank=0;
foreach($members as &$var){
//star of rank
if($var['num']==$previous_rank){
$var['rank']=$rank;
}else{
$var['rank']=++$rank;
$previous_rank=$var['num'];
}//end of rank
//star of rank_dense
if($var['num']===$previous_dense_rank){
$var['dense_rank']=$dense_rank;
++$dense_rank;
}else{
$var['dense_rank']=++$dense_rank;
$previous_dense_rank=$var['num'];
}
//end of rank_dense
echo $var['num'].' - '.$var['rank'].' - '.$var['dense_rank'].'<br>';
}
?>
My flawed output is:
num
rank
dynamic rank
2
1
1
2
1
1
3
2
3
3
2
3
3
2
4
3
2
5
3
2
6
5
3
8
9
4
9
9
4
9
9
4
10
Notice when the error happens and there is a higher number in the number column it corrects the error in that row. See that when the number goes from 3 to 5.
Given that your results are already sorted in an ascending fashion...
For dense ranking, you need to only increment your counter when a new score is encountered.
For gapped ranking, you need to unconditionally increment your counter and use the counter value for all members with the same score.
??= is the "null coalescing assignment" operator (a breed of "combined operator"). It only allows the right side operand to be executed/used if the left side operand is not declared or is null. This is a technique of performing conditional assignments without needing to write a classic if condition.
Code: (Demo)
$denseRank = 0;
$gappedRank = 0;
foreach ($members as &$row) {
$denseRanks[$row['num']] ??= ++$denseRank;
$row['dense_rank'] = $denseRanks[$row['num']];
++$gappedRank;
$gappedRanks[$row['num']] ??= $gappedRank;
$row['rank'] = $gappedRanks[$row['num']];
// for better presentation:
echo json_encode($row) . "\n";
}
Output:
{"num":2,"rank":1,"dense_rank":1}
{"num":2,"rank":1,"dense_rank":1}
{"num":3,"rank":3,"dense_rank":2}
{"num":3,"rank":3,"dense_rank":2}
{"num":3,"rank":3,"dense_rank":2}
{"num":3,"rank":3,"dense_rank":2}
{"num":3,"rank":3,"dense_rank":2}
{"num":5,"rank":8,"dense_rank":3}
{"num":9,"rank":9,"dense_rank":4}
{"num":9,"rank":9,"dense_rank":4}
{"num":9,"rank":9,"dense_rank":4}
For the record, if you are dealing with huge volumes of data, I would be using SQL instead of PHP for this task.
It seems like you want the dynamic rank to be sequential?
Your sample data appears to be sorted, if this remains true for your real data then you can remove the conditional and just increment the variable as you assign it:
//start of rank_dense
$var['dense_rank']=++$dense_rank;
//end of rank_dense
It sounds like you're saying you won't be implementing a database.
Databases like MySQL can easily handle the workload numbers you outlined and they can sort your data as well. You may want to reconsider.
it's possible overwrite the values of each star?
i need define step = 3.75, min = 0 and max = 15, and prevent from selecting half a star.
the values I want are:
star 1 => 0; star 2 => 3.75; star 3 => 7.5; star 4 => 11,25; star 5
=> 15.
form.php
echo $form->field($model, 'rating')->widget(StarRating::classname(), [
'pluginOptions' => [
'stars' => 5,
'step' => 3.75,
'min' => 0,
'max' => 15,
]
]);
but when i make this, the selection of each star not display correctly, half of star is selected.
I thought you only want to display the client side (with manual numbers). And you will not get numbers from DB
the correct way is to overwrite the star-rating file. Which should be referred to the Kartik forum.
You must overwrite that the first star has a zero score (highlight first star = 0)
However, you can use the following code in your model.
public function beforeSave($insert)
{
// if ($insert) { // only for Save (No Update)
if (!empty($this->Your_field)) {
$this->setAttribute('Your_field', $this->Your_field-3.75);
}
// }
return parent::beforeSave($insert);
}
Instead of your_field, enter your field name (field of the rate).
You have made the settings incorrectly.
Refer the plugin documentation and demos for details.
quotation krajee:
The logic for highlighting stars depends on the stars, min, max, and
step configurations. The percentage of each star to be highlighted for
each step, will be evaluated using the following expression:
STAR_HIGHLIGHT_PERCENT = (max - min) * step * 100 / stars
For example:
If min = 0, max = 5, step = 0.5, and stars = 5, then
STAR_HIGHLIGHT_PERCENT will evaluate to 50% of each star for each
step.
If min = 1, max = 5, step = 0.5, and stars = 5, then
STAR_HIGHLIGHT_PERCENT will evaluate to 40% of each star for each
step.
So, for example 2 above, the stars will not be completely highlighted
as desired. It is therefore important you set the configuration of
stars, min, max, and step correctly.
Refer the plugin documentation and demos for details.
for You:
'stars' => 4,
'step' => 3.75,
'min' => 0,
'max' => 15,
or
echo StarRating::widget(['name' => 'rating',
'pluginOptions' => [
'stars' => 5,
'step' => 3.75,
'min' => 0,
'max' => 18.75,
'starCaptions' => new JsExpression("function(val){return val-3.75 + ' hearts';}")
]
]);
1
If your field values are integers 1 to 5
To display half stars and full stars, You must use round numbers.
After putting the numbers in the following formula:
(max - min) * step * 100 / stars
Equal to: 50% or 100%
And to display only a full star, Equal to: 100%
2
However, it is better that the rate and step are equal.
For example, if step is 2, is better than max equal to 10 (5 Stars)
3
All of this varies according to the value of your field:
for example:
values: .5, 1, 1.5 , ... 5
Default (stars=5,max=5,step=0.5)
values: 1, 2, 3 , ... 5
(stars=5,max=5,step=1)
values: 1, 2, 3 , ... 12
(stars=6,max=12,step=1) => Half star = one point
values: 2, 4, 6 , ... 12
(stars=6,max=12,step=1) => one star = 2 point
I'm building an Insert query using Faker and I wonder whether it is possible to use a value to-be-inserted in another value.
Here is an example, not accurate for my situation but explains well:
DB::table('debts')->insert([
'name' => $faker->company,
'debt' => $faker->randomFloat($nbMaxDecimals = 2, $min = 20000, $max = 10000000),
'debt_paid' => 'debt' / rand ( 2 , 8 ),
'notes' => $faker->paragraph($nbSentences = 3, $variableNbSentences = true),
]);
As you can see, in the row of debt_paid I want to access the value of 'debt' that was randomly defined a row above. This is because debt_paid needs to be logical and without the value of debt it might be non-sense.
I know that defining 'debt' as a variable before the insert would solve it, but I wonder whether there's a more elegant solution.
So do that outside the insert
$dbt = $faker->randomFloat($nbMaxDecimals = 2, $min = 20000, $max = 10000000);
DB::table('debts')->insert([
'name' => $faker->company,
'debt' => $dbt,
'debt_paid' => $dbt / rand ( 2 , 8 ),
'notes' => $faker->paragraph($nbSentences = 3, $variableNbSentences = true),
]);
Hey all i am new at classes and arrays in php but need to find out how to go about getting the correct value from this class function array
class theCart {
public static $DISTANCE = array(
'0' => '0 - 75',
'10' => '76 - 125',
'20' => '126 - 175',
'30' => '176 - 225',
'40' => '226 - 275',
'50' => '276 - 325'
);
}
My output i am trying to match looks like this: 76 - 125
Do i just call it like
$distanceNum = '76 - 125';
$tmpDistanceTotal = $DISTANCE($distanceNum);
Should $tmpDistanceTotal then have a value of 10? I'm thinking that the array only has the values 0,10,20,30,40,50 in it?
I have another array:
public static $STEPS = array(
'0' => 0,
'1' => 0,
'2' => 0,
'3' => 25,
'4' => 50,
'5' => 75,
'6' => 100,
'7' => 125
);
My output i am trying to match with that above is 3 I'm not sure if its looking for a string or not?
This should clear the point:
foreach (theCart::$DISTANCE as $k => $v) {
if ($v == '76 - 125') {
echo $k;
break;
}
}
For $tmpDistanceTotal to get the value 10, you could do the following:
$tmpDistanceTotal = array_search($distanceNum, theCart::DISTANCE);
or you may wish to end up with something like this:
class theCart {
public static $DISTANCE = array(
'0' => '0 - 75',
'10' => '76 - 125',
'20' => '126 - 175',
'30' => '176 - 225',
'40' => '226 - 275',
'50' => '276 - 325'
);
public function getTotalDistance($distanceNum)
{
return array_search($distanceNum, self::DISTANCE);
}
}
Your question is actually just about arrays, and you should remove the classes from here to make things easier to understand:
$DISTANCE = array(
'0' => '0 - 75',
'10' => '76 - 125',
'20' => '126 - 175',
'30' => '176 - 225',
'40' => '226 - 275',
'50' => '276 - 325'
);
$variable = $DISTANCE[10];
In the above example Variable will be equal to 76-125. You're working with Associative Arrays, so you need to go read up on them a little bit as your questions shows you don't really understand how arrays work. Once you have that down, go ahead and move into a class context like you mentioned above.
You can check out the PHP Manual here: http://php.net/manual/en/language.types.array.php
For a short and quick answer you can use
$tempVar = 10;
$tmpDistance = $this->DISTANCE[$tempVar];
Not sure what you are trying to do, but you could use array_search:
$distanceNum = '76 - 125';
$key = array_search($distanceNum, theCart::$DISTANCE);
$key is now 10.
I ran into an issue with a data feed I need to import where for some reason the feed producer has decided to provide data that should clearly be either INT or FLOAT as strings-- like this:
$CASES_SOLD = "THREE";
$CASES_STOCKED = "FOUR";
Is there a way in PHP to interpret the text string as the actual integer?
EDIT: I should be more clear-- I need to have the $cases_sold etc. as an integer-- so I can then manipulate them as digits, store in database as INT, etc.
Use an associative array, for example:
$map = array("ONE" => 1, "TWO" => 2, "THREE" => 3, "FOUR" => 4);
$CASES_SOLD = $map["THREE"]; // 3
If you are only interested by "converting" one to nine, you may use the following code:
$convert = array('one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9
);
echo $convert[strtolower($CASES_SOLD)]; // will display 3
If you only need the base 10 numerals, just make a map
$numberMap = array(
'ONE' => 1
, 'TWO' => 2
, 'THREE' => 3
// etc..
);
$number = $numberMap[$CASES_SOLD];
// $number == 3'
If you need something more complex, like interpreting Four Thousand Two Hundred Fifty Eight into 4258 then you'll need to roll up your sleeves and look at this related question.
Impress your fellow programmers by handling this in a totally obtuse way:
<?php
$text = 'four';
if(ereg("[[.$text.]]", "0123456789", $m)) {
$value = (int) $m[0];
echo $value;
}
?>
You need a list of numbers in english and then replace to string, but, you should play with 'thousand' and 'million' clause where must check if after string 'thousend-three' and remove integer from string.
You should play with this function and try change if-else and add some functionality for good conversion:
I'm writing now a simple code for basic, but you know others what should change, play!
Look at million, thousand and string AND, it should be change if no in string like '1345'. Than replace with str_replace each of them separaterly and join them to integer.
function conv($string)
{
$conv = array(
'ONE' => 1,
'TWO' => 2,
'THREE' => 3,
'FOUR' => 4,
'FIVE' => 5,
'SIX' => 6,
'SEVEN' => 7,
'EIGHT' => 8,
'NINE' => 9,
'TEN' => 10,
'ELEVEN' => 11,
'TWELVE' => 12,
'THIRTEEN' => 13,
'FOURTEEN' => 14,
'FIFTEEN' => 15,
'SIXTEEN' => 16,
'SEVENTEEN' => 17,
'EIGHTEEN' => 18,
'NINETEEN' => 19,
'TWENTY' => 20,
'THIRTY' => 30,
'FORTY' => 40,
'FIFTY' => 50,
'SIXTY' => 60,
'SEVENTY' => 70,
'EIGTHY' => 80,
'NINETY' => 90,
'HUNDRED' => 00,
'AND' => '',
'THOUSAND' => 000
'MILLION' => 000000,
);
if (stristr('-', $string))
{
$val = explode('-', $string);
#hardcode some programming logic for checkers if thousands, should if trim zero or not, check if another values
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
else
{
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
}
Basically what you want is to write a parser for the formal grammar that represents written numbers (up to some finite upper bound). Depending on how high you need to go, the parser could be as trivial as
$numbers = ('zero', 'one', 'two', 'three');
$input = 'TWO';
$result = array_search(strtolower($input), $numbers);
...or as involved as a full-blown parser generated by a tool as ANTLR. Since you probably only need to process relatively small numbers, the most practical solution might be to manually hand-code a small parser. You can take a look here for the ready-made grammar and implement it in PHP.
This is similar to Converting words to numbers in PHP
PHP doesn't have built in conversion functionality. You'd have to build your own logic based on switch statements or otherwise.
Or use an existing library like:
http://www.phpclasses.org/package/7082-PHP-Convert-a-string-of-English-words-to-numbers.html