Need XML Response in descending order and total count - php

<?php
$xml = simplexml_load_string( $response->ApiCallDeatilDataFeedResult );
foreach ( $xml->call_data as $data )
{
?>
<tr>
<td class="sss"><?php
echo $data->call_time;?></td>
<td class="sss"><?php
$init = $data->call_duration;
$hours = floor($init / 3600);
$minutes = floor(($init / 60) % 60);
$seconds = $init % 60;
echo "$minutes Min : $seconds Sec";
?></td>
<td class="sss"><?php echo $data->call_status;?></td>
<td class="sss"><?php echo $data->caller_number;?></td>
<td class="sss"><?php echo $data->caller_name;?></td>
<td class="sss"><?php echo $data->caller_city;?></td>
<td class="sss"><?php echo $data->caller_state;?></td>
<td class="sss"><?php echo $data->caller_zip;?></td>
</tr>
<?php
}
?>
</table>
While request the xml i reciveing xml response which is give result in ascending order. I need XML response in descending order and need no of rows in total.

Use krsort for the sorting. And yeah use count() to count the array.

Simplexml is offering an iterator for the foreach, if you want to reverse it, you could convert it to an array, reverse the array and then foreach over the array:
$datas = $xml->call_data;
$datas = iterator_to_array($datas, 0);
$datas = array_reverse($datas);
foreach($datas as $data)
{
...
}
$count = count($datas);

The answer of #Yogesh Suthar is correct (despite calling count on $xml directly instead of $xml->call_data) , but I think the indices are wrong since an array index starts from zero and ends at length-1.
EDIT:
As #hakra stated in the comments, call_data is not an array, but an iterable SimpleXMLElement.
But for the sake of argument, let us say that it is. So, I think it should be:
for($i = count($xml->call_data) - 1 ;$i >= 0 ; $i--)
Or, if you want to avoid the trouble of using indices, try using array_reverse if call_data is indeed an array
foreach ( array_reverse($xml->call_data) as $data )

use count for number of rows and use for loop in reverse for descending order like this example
for($i = count($xml) ;$i >0 ; $i--)
{
// your code
}

Related

Get index of Shuffle Range on 2D Array php

I want to random 80*13 digits for genetic algorithm where 80 is popsize and 13 is dna size. And I trying to get index of range value on 2d array. To make a random int from 1 - 13 without duplicate where i mean 2d for 80 rows and 13 column. like this
$arr = [0][0]; //this is output will be same with the table value in row1 col1
$arr = [0][1]; //this is output will be same with the table value in row1 col2
...
$arr = [0][12]; //this is output will be same with the table value in row2 col1
$arr = [1][1]; //this is output will be same with the table value in row2 col2
..
i have a code like this.
<?php
function randomGen($min, $max) {
$numbers = range($min, $max);
shuffle($numbers);
return array_slice($numbers, 0);
}
?>
<table>
<tr>
<th rowspan="2">Kromosom ke-</th>
<th colspan="13">Stasiun Kerja</th>
</tr>
<tr>
<?php
for ($i=1; $i <= 13; $i++) {
?>
<th>
<?php echo $i;?>
</th>
<?php
}
?>
</tr>
<tr>
<?php
for($i = 0; $i < 80; $i++) {
$no = 1;
echo "<td> v".$no."</td>";
$arr[$i] = randomGen(1,13);
for ($j=0; $j <= 12; $j++) {
$arr[$j] = randomGen(1,13);
echo "<td>";
echo $arr[$i][$j];
echo "</td>";
}
echo "</td><tr>";
$no++;
}
// print_r($arr[0][0].' '); // for see the value is same or not
?>
when i try to printout $arr[0][0], thats value is not same with the table in row1 col1.
Any ideas?
UPDATE!
great solution for this problem is answer from Rainmx93 , thats work for me. Thankyou very very much
In first for loop you already generating multidimensional array, but now in second loop you override all array elements on each iteration, you need to remove that second function call.
Your code should look like this:
for($i = 0; $i < 80; $i++) {
$no = 1;
echo "<td> v".$no."</td>";
$arr[$i] = randomGen(1,13);
for ($j=0; $j <= 12; $j++) {
echo "<td>";
echo $arr[$i][$j];
echo "</td>";
}
echo "</td><tr>";
$no++;
}

Calculate mean of a range of XML Elements in PHP

I'm trying to calculate the mean of a range of XML elements in PHP, but haven't found any solution yet.
Here are the XML elements.
<root>
<quoteDay>
<date>2018-02-26</date>
<close>1586,96</close>
</quoteDay>
<quoteDay>
<date>2018-02-23</date>
<close>1577,11</close>
</quoteDay>
<quoteDay>
<date>2018-02-22</date>
<close>1565,5</close>
</quoteDay>
</root>
Here is the PHP code:
<?php
$xml = simplexml_load_file("file.xml") or die("Error: Cannot create object");
$id = -1;
$total[] = 0;
foreach ($xml->root as $root) {
foreach ($root->quoteDay as $quoteDay) {
$id ++;
$total[] += $root->quoteDay[$id]->close;
$close = number_format(round($quoteDay->close,0));
echo $quoteDay->date; echo $close; echo $total[$id+1];
}
}
?>
So, for each quoteDay, I would like to return the date, close and a moving average.
Date 2018-02-26 would return the mean of "close" for 2018-02-26 and 2018-02-23 = (1586,96+1577,11)/2.
Mean for 2018-02-23 would return (1577,11+1565,5)/2.
I've, as you can see, tried to sum a cumulative total sum for each element, but for some reason I can't understand it won't work.
How can I accomplish calculating a moving average for the elements?
In order to achieve your result you need to do a couple of things:
simplexml_load_file() already gives you the root, so there's no need for your first loop
The $total array is not necessary
Your XML has , as decimal separators, but PHP uses ., so you need to replace them in order to do math and not lose the decimals (here I cast to float which can make you lose precision, look into bcmath to avoid that)
I assume that for the first day, when there's no previous, the moving average is the day's value
So, your code would look like this:
<?php
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$current = (float) str_replace(",", ".", $quoteDay->close);
$previous = $xml->quoteDay[$id + 1]
? (float) str_replace(",", ".", $xml->quoteDay[$id + 1]->close)
: $current;
$movingMean = ($current + $previous) / 2;
echo $movingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
Demo
Result
Moving average for 2018-02-26:
1582.035
Moving average for 2018-02-23:
1571.305
Moving average for 2018-02-22:
1565.5
To generalize it to $daysInMovingMean days, use a for loop to get the days up to the days needed, stopping earlier if necessary (i.e. no more days left):
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
$daysInMovingMean = 3;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$sum = 0;
for ($days = 0; $days < $daysInMovingMean; $days++) {
if (!$xml->quoteDay[$id + $days]) break;
$sum += (float) str_replace(",", ".", $xml->quoteDay[$id + $days]->close);
}
$sumovingMean = $sum / $days;
echo $sumovingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
Notice that in this example you get the same results as before if you set $daysInMovingMean = 2;
Demo

How to sum amount from mysql query

I wrote this code to sum only amount but is not working.Everything works perfectly except the sum. Can some one help me out?
Here is the code:
<tr >
<td > Total </td>
<td >
<?php $sum2=0; foreach($contributions_ as $val){
$sum = $sum2 + $contributions_[$val];
}echo array_sum($contributions_);
?>
</td>
</tr>
Here is the php:
<?php
$tempArray = array(
$rowRes['amount'],
$rowRes['remarks'],
$rowRes['ID']
);
$contributions_[] = $tempArray;
?>
I want to sum only amount(s) whiles the condition is true
This is my query which worked perfectly but cannot sum amount after displaying the various members contributions .
<?php $selectQuery = "select a.*,b.* ID, monthname(date) as month,month(date) as mnth, year(date) as yr, type,amount, recipient_initials,remarks, in_kind_items,other_type,other_payment_name,date from member_payments a inner join member b on a.memberID = b.ID";
?>
Why can't I sum amount here like SUM(amount)
<tr >
<td> Total </td>
<td>
<?php
$sum = 0;
foreach($contributions_ as $val){
$sum = $sum + $val['amount'];
}
echo $sum;
?>
</td>
</tr>
<?php
$tempArray = array(
$rowRes['amount'],
$rowRes['remarks'],
$rowRes['ID']
);
$contributions_[] = $tempArray;
$sum += $rowRes['amount'];
?>
Got it now after echoing sum
You used $sum and $sum2 in this line:
$sum = $sum2 + $contributions_[$val];
If I'm reading your code right, it should be more like this:
<?php $sum2=0; foreach($contributions_ as $val){
$sum2 = $sum2 + $contributions_[$val];
}echo $sum2;
?>
Sorry, I don't know what you mean by "I want to sum only amount(s) whiles the condition is true".

How to print a 2nd variable within a loop using PHP. Nested loop maybe?

I'm having a little problem figuring out 'how' to print a 2nd variable within a loop. Basically, I'm trying to create a table that shows 'how many years' someone will save for retirement AND 'what their total savings' would be each year. I've never used a 'nested loop' before and I think this may be what I need to use.
I have the following code. It works by echoing the years saved as a loop, but I don't know what to do to echo the 'total savings' correctly. You'll notice that the first part of the number in "total savings" column is correct, but the variable is adding the previous value to the end of the number.
Thank you for your help!
The CODE I'm using is
<?php
//variables
$savings = $_POST["savings"];
$invested = $_POST["invested"];
$networth = $_POST["networth"];
$salary = $_POST["salary"];
$save_rate = $_POST["save_rate"];
$military = $_POST["military"];
$donate = $_POST["donate"];
$goods = $_POST["goods"];
$years_save = $_POST["years_save"];
//savings calculator
$annual_savings = $salary*$save_rate;
$total_savings = $savings + ($annual_savings*$years_save);
?>
</head>
<body>
<h1>Test Handler</h1><hr />
<table width="800" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="150">Years</td>
<td width="450">Yearly Savings</td>
<td width="200">Total Savings </td>
</tr>
<?php
for ( $i=1; $i<=$years_save; $i++ ) {
echo "<tr>
<td>$i</td>
<td>$annual_savings</td>
<td>" . $totalsavings = $i*$annual_savings . "$totalsavings</td>
</tr>";
}
?>
</table>
Output is
Years Yearly Savings Total Savings
1 13500 13500
2 13500 2700013500
3 13500 405002700013500
4 13500 54000405002700013500
5 13500 6750054000405002700013500
6 13500 810006750054000405002700013500
7 13500 94500810006750054000405002700013500
8 13500 10800094500810006750054000405002700013500
9 13500 12150010800094500810006750054000405002700013500
10 13500 13500012150010800094500810006750054000405002700013500
11 13500 14850013500012150010800094500810006750054000405002700013500
12 13500 16200014850013500012150010800094500810006750054000405002700013500
Try to make it like this:
<?php
for ( $i=1; $i<=$years_save; $i++ ) {
$totalsavings = $i*$annual_savings;
echo "<tr>
<td>$i</td>
<td>$annual_savings</td>
<td>$totalsavings</td>
</tr>";
}
?>
Here's a very basic loop; it doesn't use all of your form values, but it's simplified and should help you implement what you're looking for. You could also do some additional math inside the loop:
$rate = 0.6;
$salary = 50000;
$years = 12;
$savings = 13500;
$base = $salary;
echo "<table>";
for ($i = 0; $i < $years; $i++)
{
// do some basic math; calculate this however you like
// += will add the math result to $base, leaving $salary available for additional calculations
$base += $savings * $rate;
echo "<tr><td>Years: $i</td><td>Savings: $base</td></tr>";
}
echo "</table>";

Print one table, two-column PHP associative array as three side-by-side, two-column tables

I use the following to print a 15-row, two-column table from an associative arrray in PHP:
<table id="freq-table" class="table-list" cellspacing="0" cellpadding="10">
<tbody>
<?
$rowCount = 0;
foreach($word_frequency as $word => $frequency) if ($rowCount++ < 15) {?>
<tr>
<td><? echo $word; ?></td>
<td<? echo $frequency; ?></td>
</tr>
<?}?>
</tbody>
</table>
It works fine but takes up too much vertical space on the page. How can I format this into three side-by-side tables of five rows and two columns each with the first group having array items 1-5, the second group 6-10, and the last group 11-15? (refer to following illustration):
key1 value1 | key6 value6 | key11 value11
key2 value2 | key7 value7 | key12 value12
...
...
key5 value5 | key10 value10 | key15 value15
I've tried various table, div, container, and multiple loop experiments with very mixed (and unsuitable) results. Thank you in advance.
Since you can also use multiple columns to achieve this visual effect, you're going to probably want to format the data ahead of time to make the code of generating the table a little cleaner.
<?php
// Format the array data so each row contains all of the columns needed
$rows = array();
$max_per_column = 5;
$max_words = 15;
$rows = array_pad($rows, $max_per_column, array());
$count = 0;
foreach ($word_frequency as $word => $frequency) {
if ($count >= $max_words) {
break;
}
array_push($rows[$count % $max_per_column], $word, $frequency);
$count++;
}
?>
<table id="freq-table" class="table-list" cellspacing="0" cellpadding="10">
<tbody>
<?php
foreach ($rows as $cols) {
echo '<tr><td>' . implode('</td><td>', $cols) . '</td></tr>';
}
?>
</tbody>
</table>
Try some thing like that.
<table width="100%">
<tr>
<?php
$rowCount = 0;
foreach($word_frequency as $word => $frequency) if ($rowCount < 15) { ?>
<?php if($rowCount % 5 == 0) { ?>
<td><table border=1>
<?php } ?>
<tr>
<td><?php echo $word; ?></td>
<td><?php echo $frequency; ?></td>
</tr>
<?php if($rowCount % 5 == 4) { ?>
</table></td>
<?php } ?>
<?php $rowCount++; } ?>
</tr>
</table>
The only way to do this is to use a numeric key. For example
$word_frequency[0] = array();
$word_frequency[0]['word'] = "some word";
$word_frequency[0]['frequency'] = 10;
...
$word_frequency[15] = array();
$word_frequency[15]['word'] = "some other word";
$word_frequency[15]['frequency'] = 14;
Once you have your array, you could repeat the loop as follows
<table id="freq-table" class="table-list" cellspacing="0" cellpadding="10">
<tbody>
<?
$rowCount = 0;
for($i = 0; $i <= 5; $i++) {
$word[0] = $word_frequency[$i]["word"];
$frequency[0] = $word_frequency[$i]["frequency"];
$word[1] = $word_frequency[$i + 5]["word"];
$frequency[1] = $word_frequency[$i + 5]["frequency"];
$word[2] = $word_frequency[$i + 10]["word"];
$frequency[2] = $word_frequency[$i + 10]["frequency"];
?>
<tr>
<?
for($x = 0; $x <= 2; $x++ ){
?>
<td><? echo $word[$x]; ?></td>
<td<? echo $frequency[$x]; ?></td>
<?
}
?>
</tr>
<?
}
?>
</tbody>
</table>
Every $i loop creates the row, while the $x loop creates the columns. This assumes, of course, that you have at least 15 items, that you're going to create only 5 rows and three columns of key/value pairs.
Well, if I were doing it, I'd probably use a ul with a css columns :D
http://davidwalsh.name/css-columns
However, that's not a very "programmerly" thing to do.
It might help that you don't have to go through the array in order.
If you look at what you have, there is a pattern to the indices:
i + 0x, i + 1x, i + 2x, ...
Where x is your number of items divided by the number of columns.
and you stop iterating when i = total / x
Sorry to be too tired to code this for you but the gist is this:
$myarray = [1 ... 15];
$columns = 3;
$arrayKeys = array_keys($myarray);
$total = count($array);
$x = floor $total / $column;
for ($i = 0; $i > $x; $i += $x + 1 ){
echo $arrayKeys[$i] . " - " . $myarray($arrayKeys[$i]);
echo $arrayKeys[$i + $x] . " - " . $myarray($arrayKeys[$i + $x]);
echo $arrayKeys[$i + ($x * 2) ] . " - " . $myarray($arrayKeys[$i + ($x * 2)]);
}
Or something like that... that's off the top of my head and I think it has some issues, but you should be able to beat that into something that works.

Categories