using PHP to find exact value in a string - php

the current tasks at hand is using PHP to check if data exists
to make things short the problem is:
i am trying to search some of the available sizes in a unorganized string.
sizes are
SM/M M/L L/XL XS S M L XL XXL 28 30 31 32 33 34 35 36 28 X 30 28 X 32
currently most of the issues are solved by utilizing whitespaces to disgtinush unique variable, but when it comes to (number X number) as a phrase it becomes very difficult.
when I search for "28" it also detect as found when seeing "28 X 30"
or when I search for unique number " 30 " with the whitespaces included, it still detects the 28 X "30"
Is there any method to tackle this issue?

What you could do is make the string easier to deal with by first transforming the nnn X nnn strings and removing spaces from them:
//BEFORE: SM/M M/L L/XL XS S M L XL XXL 28 30 31 32 33 34 35 36 28 X 30 28 X 32
//AFTER: SM/M M/L L/XL XS S M L XL XXL 28 30 31 32 33 34 35 36 28X30 28X32
$sizes=preg_replace('/(\d+) X (\d+)/', '$1X$2', $sizes);
Now you can explode the string on spaces
$sizeArray=explode(' ', $sizes);
With all the distinct sizes in an array, you can use in_array to look for a specific size code.
//we want to find this
$searchFor='28 X 30';
//our codes no longer have spaces...
$searchFor=str_replace(' ', '', $searchFor);
if (in_array($searchFor, $sizeArray)) {
//great!
}

Related

Multiple elements in the array having the same value, will get a different percentile

I am calculating the number that falls into a specific percentile. However, the problem with my equation is that if multiple elements in the array having the same value, this code will assign a different percentile number to each of those elements.
$percentile_50 = $array[round((50/100) * $count_array -.5)];
For example, first column is the percentile, and second is the score. You can see that same second gets different percentile, but in fact it should be the same.
How can I avoid this?
5-1
10-1
15-1
20-1
25-2
30-2
35-3
40-4
45-4
50-5
55-6
60-7
65-9
70-11
75-14
80-17
85-23
90-32
95-53
To calculate the kth percentile, you should :
Order all the values in the data set from smallest to largest.
Multiply k percent by the total number of values, n.
This number is called the index.
If the index obtained in Step 2 is not a whole number, round it up to the nearest whole number and go to Step 4. If the index obtained in Step 2 is a whole number, go to Step 5.
Count the values in your data set from left to right (from the smallest to the largest value) until you reach the number indicated by Step 3.
The corresponding value in your data set is the kth percentile
Count the values in your data set from left to right until you reach the number indicated by Step 2.
The kth percentile is the average of that corresponding value in your data set and the value that directly follows it.
( from here)
Translated to PHP:
$sData = sort($data);
$percentile = 50/100;
$index = ceil($percentile * count($sData));
$value = $sData[$index-1];
Or shorter:
$sData = sort($data);
$value = $sData[ceil((50/100) * count($sData)) - 1]
However, in a small dataset, sometimes the percentiles end up the same. For example, the following code produces the following output.
Code
$data = array(74, 15, 25, 62, 45, 9, 16, 63, 60, 76, 7, 20, 67, 30, 12);
sort($data);
for($i=5;$i<100;$i+=5){
echo $i . " - " . $data[ceil(($i/100) * count($data)) - 1];
echo PHP_EOL;
}
Output
5 - 7
10 - 9
15 - 12
20 - 12 //same as aboce
25 - 15
30 - 16
35 - 20
40 - 20 //same as above
45 - 25
50 - 30
55 - 45
60 - 45 //same as above
65 - 60
70 - 62
75 - 63
80 - 63 //same as above
85 - 67
90 - 74
95 - 76

How to parse this xml in required format if the xml has no child parent structure

I have an xml given below.How should i parse this so that i can store in the array to display it in the structure like the below.
need to dispaly spec group first and then title and value for each group..
For example
group title Specidentifier Specvalue
Audi specifications Power 5w x 2
Maximum SPL –90 dB
.......... ......
General Specifications Battery type 11.1 V, 2500 mAh Lithium
Power Max 54 M Maximum
Below is the xml. I have tried by converting this into array.But it becomes difficult for me as this tags(product_spec_identifier1) are repeating under each group.
<product_published_start>31-07-2013</product_published_start>
<product_published_end>31-07-2013</product_published_end>
<product_spec_group1>Audio Specifications</product_spec_group1>
<product_spec_identifier1>Power</product_spec_identifier1>
<product_spec_value1>65W x 2</product_spec_value1>
<product_spec_value1_language>en</product_spec_value1_language>
<product_spec_identifier2>Maximum SPL</product_spec_identifier2>
<product_spec_value2>–90 dB</product_spec_value2>
<product_spec_value2_language>en</product_spec_value2_language>
<product_spec_identifier3>Slew rate</product_spec_identifier3>
<product_spec_value3>40V/μsec</product_spec_value3>
<product_spec_value3_language>en</product_spec_value3_language>
<product_spec_identifier4>Sensitivity/impendance</product_spec_identifier4>
<product_spec_value4>250mV/46k ohms</product_spec_value4>
<product_spec_value4_language>en</product_spec_value4_language>
<product_spec_identifier5>Dynamic Range adjustment</product_spec_identifier5>
<product_spec_value5>90dB</product_spec_value5>
<product_spec_value5_language>en</product_spec_value5_language>
<product_spec_identifier6>Type</product_spec_identifier6>
<product_spec_value6>Multimedia Speakers</product_spec_value6>
<product_spec_value6_language>en</product_spec_value6_language>
<product_spec_identifier7>Frequency Response</product_spec_identifier7>
<product_spec_value7>60 Hz – 20 kHz</product_spec_value7>
<product_spec_value7_language>en</product_spec_value7_language>
<product_spec_identifier8>Signal-to-Noise Ratio</product_spec_identifier8>
<product_spec_value8>dB</product_spec_value8>
<product_spec_value8_language>en</product_spec_value8_language>
<product_spec_group2>General Specifications</product_spec_group2>
<product_spec_identifier1>Battery type</product_spec_identifier1>
<product_spec_value1>11.1 V, 2500 mAh Lithium</product_spec_value1>
<product_spec_value1_language>en</product_spec_value1_language>
<product_spec_identifier2>Power Max</product_spec_identifier2>
<product_spec_value2>54 M Maximum</product_spec_value2>
<product_spec_value2_language>en</product_spec_value2_language>
<product_spec_identifier3>Power requirement</product_spec_identifier3>
<product_spec_value3>100 – 240V AC, 50/60Hz</product_spec_value3>
<product_spec_value3_language>en</product_spec_value3_language>
<product_spec_identifier4>Dimensions (H x W x D)</product_spec_identifier4>
<product_spec_value4>300 mm X 164 mm x 275 mm</product_spec_value4>
<product_spec_value4_language>en</product_spec_value4_language>
<product_spec_identifier5>Weight</product_spec_identifier5>
<product_spec_value5>2,7 Kg</product_spec_value5>
<product_spec_value5_language>en</product_spec_value5_language>
<product_spec_identifier6>Dimensions: Subwoofer (H x W x D – Metric/English)</product_spec_identifier6>
<product_spec_value6>345 mm x 222 mm x 325 mm</product_spec_value6>
<product_spec_value6_language>en</product_spec_value6_language>
<product_spec_identifier7>Colour</product_spec_identifier7>
<product_spec_value7>Black</product_spec_value7>
<product_spec_value7_language>en</product_spec_value7_language>
Use an xslt to do this check w3 schools for xslt examples

PHP str_replace bug

I'm running simple PHP code
$myVariable = 1;
$myVariable2 = str_replace(array(1, 2, 3), array('do 25 lat', 'od 26 do 35 lat', 'pow. 35 r.z.'), $myVariable);
echo $myVariable2;
And result is:
do od 26 do pow. 35 r.z.5 lat5 lat
I checked on different PHP versions. Any ideas?
You're falling victim to the gotcha specified in the documentation - look under "notes" on the str_replace documentation
Replacement order gotcha
Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. See also the examples in this document.
Essentially what's happening is the sequential replacements, as you passed an array as the second parameter:
1 is replaced with do 25 lat
In that string, 2 is replaced with od 26 do 35 lat, giving you do od 26 do 35 lat5 lat
In that string, 3 is replaced with pow. 35 r.z. giving you the final result you're seeing.
This is because str_replace array pairs are applied one after the other.
Try strtr:
$myVariable = 1;
$replacePairs = array(
1 => "do 25 lat",
2 => "od 26 do 35 lat",
3 => "pow. 35 r.z."
);
$myVariable2 = strtr($myVariable,$replacePairs);
echo $myVariable2;
It's not a bug, this is the normal behavior of str_replace. What happens is the function iterates through your search array and each time it finds an occurrence, it replaces it with relevant replace.
Thus:
(search and match 1) 1 -> "do 25 lat"
(search and match 2) "do 25 lat" -> "do od 26 do 35 lat5 lat"
(search and match 3) "do od 26 do 35 lat5 lat" -> "do od 26 do pow. 35 r.z.5 lat5 lat"

Fetch value from text file using preg_match PHP

I have a text file in following format.
Wed Aug 27 20:24:53.536 IST
address ref clock st when poll reach delay offset disp
*~172.16.18.163 .GPS. 1 657 1024 377 13.99 1.801 19.630
~127.127.1.1 .LOCL. 3 15 64 377 0.00 0.000 1.920
* sys_peer, # selected, + candidate, - outlayer, x falseticker, ~ configured
file has been generated dynamically I need to fetch value of 'st' (1) value next to '.GPS.' . text '.GPS.' is going to be same in every file.
Check my following code:
$f1_content = file_get_contents('filename.txt');
if(preg_match("/\b(.*)\s(.*)\s[0-9]\s\b/i", $f1_content, $match))
{
print_r($match); die();
}
not getting any match. Any idea how it can be done?
You can follow this:
#\.GPS\.\s+\K(\d+)#is
PHP:
preg_match("#\.GPS\.\s+\K(\d+)#is", $f1_content, $match)
If you may have more than of occurrences of that, you should use preg_match_all
Live demo
(?=.*?\.GPS\.).*?GPS\.\s*(\d+)
Try this.This works.
See demo.
http://regex101.com/r/pP3pN1/12

Mapping Values to 14 categories (Math and permutations stuff)

My app has people put 24 groups of 4 statements in order. In each group of 4 one is the "D" statement, one is the "I" statement, one is the "S" statement, and one is the "C" statement.
So the end result looks something like ['ISCD','CISD','DISC',CISD,'CISD','ISCD'...] because the are essentially rearranging the 4 letters
In the end, they get a "score" for each letter using the following algorithm.
For each of I,S,C and D
Find the number of times that letter is first and multiply by 3
Find the number of times that letter is second and multiply by 2
Find the number of times that letter is third and muliply by 1
Total it up, and that is the score for that letter
The end result is that each letter (I,S,D,C) gets a score from 0 to 72, and there are always 144 total points given out:
I want to map the results to 14 reports:
D
I
S
C
DI
IS
SC
CD
DS
IC
DIS
ISC
SCD
CDI
The idea is that if S is dominant, we choose the S report. If Both D and I are dominant, we choose the DI report. If none is particularly dominant, we choose the top 3. (there is no difference between DI and ID meaning which one is most dominant is irrelevant if they are both high)
So if the scores are D=50, I=48, S=20,C=26 then I want it to choose "DI" since D and I are dominant. There are 24^(4!) possible responses from the user, that I need to map to 14 reports
I understand that I will have to set the thresholds for what "dominant" means, but for starters, I want to assume all possible responses are equally likely, and to map all possible responses to the 14 reports to where each of the 14 reports is equally likely, given random input.
I expect it's 1 to 5 lines of code. It'll be in php but any language including math or pseudo code should be fine.
UPDATE:
I figured out a way to do it in one line of code, but it's not evenly distributed. here's the php (no dependencies)
<?php
$totals=array();
$lets=array('D','I','S','C');
for($j=0;$j<100000;$j++)
{
$vals=array('D'=>0,'I'=>0,'S'=>0,'C'=>0);
for($i=0;$i<24;$i++)
{
shuffle($lets);
$vals[$lets[0]]+=3;
$vals[$lets[1]]+=2;
$vals[$lets[2]]+=1;
}
$D=$vals['D'];$I=$vals['I'];$S=$vals['S'];$C=$vals['C'];
//calculate which report
$reportKey=($D>36?'D':'').($I>36?'I':'').($S>36?'S':'').($C>36?'C':'');
if(!$reportKey)
$reportKey="DIS";
if(isset($totals[$reportKey]))
$totals[$reportKey]+=1;
else
$totals[$reportKey]=1;
echo $reportKey." $D $I $S $C <br>";
}
echo "<br>";
foreach ($totals as $k=>$v)
echo "$k: $v<br>";
The magic line is
$reportKey=($D>36?'D':'').($I>36?'I':'').($S>36?'S':'').($C>36?'C':'');
That line says if any value is over 36, include that letter. the output of the script is like this:
SC 35 33 38 38
IC 33 42 32 37
DI 44 39 29 32
...
...
DC 46 21 35 42
DIS 38 37 40 29
IC 36 39 28 41
DS 41 36 42 25
C 36 34 29 45
IS 29 41 38 36
IS 28 46 41 29
DS 38 33 40 33
DS 41 33 40 30
DS: 1444
D: 889
IS: 1466
S: 910
C: 874
SC: 1442
IC: 1467
DI: 1569
ISC: 407
DSC: 386
DIS: 388
DC: 1487
DIC: 396
I: 875
As you can see, it automatically split it into 14 categories, but the distribution varies with the 2 letter ones being way more likely.
You can do this recursively using Haskell e.g. as follows:
combinationsOf _ 0 = [[]]
combinationsOf [] _ = []
combinationsOf (x:xs) k = map (x:) (combinationsOf xs (k-1) ) ++ combinationsOf xs k
The results from GHCI:
*Main> concatMap (combinationsOf "DISC") [1,2,3]
["D","I","S","C","DI","DS","DC","IS","IC","SC","DIS","DIC","DSC","ISC"]

Categories