How to calculate numbers in string from DB in PHP - php

I echo some numbers from the database and show only those numbers with a foreach. I now want to calculate the total of these numbers.
$test = str_replace('\\', '', $orderDetails['jsonData']);
$bonbonOrders = unserialize($test);
foreach($bonbonOrders as $bonbonOrder){
foreach($bonbonOrder as $bonbons){
echo $bonbons['gewicht'];
}
}
I tried several things but I really don't know how I can calculate them.
the output for a example can be:
18 15 16 12 11
Thanks!

This depends how you are getting those numbers from your database. However, since you are deserializing something I will assume that it cannot be done in a simple SQL query.
The following code should echo out the total of all of the numbers.
$test = str_replace('\\', '', $orderDetails['jsonData']);
$bonbonOrders = unserialize($test);
$nums = array();
foreach($bonbonOrders as $bonbonOrder){
foreach($bonbonOrder as $bonbons){
$nums[] =$bonbons['gewicht'];
}
}
$total = array_sum($nums);
echo $total;
Achieved by adding all of the numbers to an array, and calling array_sum on the final array.
Another alternative would have been to create $total = 0 before the foreach and to simply increment it as you get access to each number.

Simply addup each $bonbons['gewicht'] value in a variable and echo it
$test = str_replace('\\', '', $orderDetails['jsonData']);
$bonbonOrders = unserialize($test);
$sum =0;
foreach($bonbonOrders as $bonbonOrder){
foreach($bonbonOrder as $bonbons){
echo $bonbons['gewicht'];
$sum += $bonbons['gewicht'];
}
}
echo $sum;

Related

Remove the 0 from for results

Currently, I'm messing around with SoundCloud's API and it's returning something that looks like this.
0. HotBox Michael da Vinci Prod Free P.mp3
https://api.soundcloud.com/tracks/373337717/stream?client_id=OURID
1. LSSR Chris P Prod Jake Knight.mp3
https://api.soundcloud.com/tracks/373336760/stream?client_id=OURID
Which is working properly as how the code appears, here it is how I'm printing out the results (very messy but I'm just messing around)
for ($i = 0; isset($house[$i]); $i++) {
$b1 = $house[$i]['title'];
$b2 = $house[$i]['stream_url'];
print '<br>'; print '<br>';
$title = preg_replace('/[^a-zA-Z0-9\s]/', '', strip_tags($b1));
print ''.$i.'. '.$title.'.mp3';
print '<br>';
print $stream = ''.$b2.'?client_id=OURID';
}
Now what I'm wondering is how under every circumstance can we make the 0. return as a 1. and continue counting upwards until reaching the end of the for loop, not removing the 0. data but only changing the number.
I recommend a foreach loop with the $i counter declared in the loop and just increment it as you go.
Untested code:
foreach ($house as $i=>$row){
echo '<br><br>',++$i,'. ',preg_replace ('/[^a-z\d\s]+/i','',strip_tags ($row ['title'])),".mp3<br>{$row ['stream_url']}?client_id=OURID";
}
p.s. I've improved the regex pattern and eliminated all single-use variable declarations. You can break this up over many lines if you prefer.
If you want to avoid the first iteration's double break tags...
foreach ($house as $i=>$row){
if($i) echo '<br><br>'; // if $i is not 0
echo ++$i,'. ';
echo preg_replace ('/[^a-z\d\s]+/i','',strip_tags ($row ['title']));
echo ".mp3<br>{$row ['stream_url']}?client_id=OURID";
}
Based on the comments and your description of what you are trying to do, it sounds like you just need to add another iteration variable:
# Add another variable
$a = 1;
for ($i = 0; isset($house[$i]); $i++) {
$b1 = $house[$i]['title'];
$b2 = $house[$i]['stream_url'];
$title = preg_replace('/[^a-zA-Z0-9\s]/', '', strip_tags($b1));
echo '<br><br>';
# Here you have the $a show up starting at 1
echo ''.$a.'. '.$title.'.mp3<br>';
echo $stream = ''.$b2.'?client_id=OURID';
# Auto increment here
$a++;
}

Random generator returning endless duplicates

I am trying to create a random string which will be used as a short reference number. I have spent the last couple of days trying to get this to work but it seems to get to around 32766 records and then it continues with endless duplicates. I need at minimum 200,000 variations.
The code below is a very simple mockup to explain what happens. The code should be syntaxed according to 1a-x1y2z (example) which should give a lot more results than 32k
I have a feeling it may be related to memory but not sure. Any ideas?
<?php
function createReference() {
$num = rand(1, 9);
$alpha = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, 1);
$char = '0123456789abcdefghijklmnopqrstuvwxyz';
$charLength = strlen($char);
$rand = '';
for ($i = 0; $i < 6; $i++) {
$rand .= $char[rand(0, $charLength - 1)];
}
return $num . $alpha . "-" . $rand;
}
$codes = [];
for ($i = 1; $i <= 200000; $i++) {
$code = createReference();
while (in_array($code, $codes) == true) {
echo 'Duplicate: ' . $code . '<br />';
$code = createReference();
}
$codes[] = $code;
echo $i . ": " . $code . "<br />";
}
exit;
?>
UPDATE
So I am beginning to wonder if this is not something with our WAMP setup (Bitnami) as our local machine gets to exactly 1024 records before it starts duplicating. By removing 1 character from the string above (instead of 6 in the for loop I make it 5) it gets to exactly 32768 records.
I uploaded the script to our centos server and had no duplicates.
What in our enviroment could cause such a behaviour?
The code looks overly complex to me. Let's assume for the moment you really want to create n unique strings each based on a single random value (rand/mt_rand/something between INT_MIN,INT_MAX).
You can start by decoupling the generation of the random values from the encoding (there seems to be nothing in the code that makes a string dependant on any previous state - excpt for the uniqueness). Comparing integers is quite a bit faster than comparing arbitrary strings.
mt_rand() returns anything between INT_MIN and INT_MAX, using 32bit integers (could be 64bit as well, depends on how php has been compiled) that gives ~232 elements. You want to pick 200k, let's make it 400k, that's ~ a 1/10000 of the value range. It's therefore reasonable to assume everything goes well with the uniqueness...and then check at a later time. and add more values if a collision occured. Again much faster than checking in_array in each iteration of the loop.
Once you have enough values, you can encode/convert them to a format you wish. I don't know whether the <digit><character>-<something> format is mandatory but assume it is not -> base_convert()
<?php
function unqiueRandomValues($n) {
$values = array();
while( count($values) < $n ) {
for($i=count($values);$i<$n; $i++) {
$values[] = mt_rand();
}
$values = array_unique($values);
}
return $values;
}
function createReferences($n) {
return array_map(
function($e) {
return base_convert($e, 10, 36);
},
unqiueRandomValues($n)
);
}
$start = microtime(true);
$references = createReferences(400000);
$end = microtime(true);
echo count($references), ' ', count(array_unique($references)), ' ', $end-$start, ' ', $references[0];
prints e.g. 400000 400000 3.3981630802155 f3plox on my i7-4770. (The $end-$start part is constantly between 3.2 and 3.4)
Using base_convert() there can be strings like li10, which can be quite annoying to decipher if you have to manually type the string.

php loop with letters without using an array of letters

I have an php code that writes an excel file with a variable number of columns. Each 4 rows, on the 5th I want to put the total of the four rows above, per column.
My issue is on how to write the formula in terms of columns.
My code is this one:
$col_index=20;
$i=20;
for($anno = $annoMin; $anno<=$annoMax; $anno++){
for($mese = 1; $mese <= 12; $mese++){
$string = "=$i$v+$i$q-$i$z-$i$t";
$ews->setCellValueByColumnAndRow($col_index,$k,$string);
$col_index=$col_index+1;
$i=$i+1;
}
}
In $string I need to put the column letter instead of $i. $v,$q,$z and $t are the reference to the rows and are ok. In other words $string should be evaluated to:
$string = "=U5+U3-U2-U4";
during the first for loop,
$string = "=V5+V3-V2-V4";
in the second and so on.
I know I can build an array of columns letter and use that $i reference to get my goal but I'm sure there is a better approach. I am using php 5.5 btw
The other option is to write the formula with the R1C1 notation but I'm pretty sure I cannot have the standard and the R1C1 notation in an excel sheet at the same time
You can increment a string variable. I think this is the most efficient way to do what you need (if I understood it right).
$ch = "a";
++$ch;
echo $ch; //prints "b"
Knowing this you can build a loop to update the value as you need.
This works very good for Excel because:
$ch = "z";
++$ch;
echo $ch; //prints aa
I'm just concentrating on the column letter as that seems to be what you're asking. Use the ASCII code of the letter and increment it, then convert it to the character:
$col_index = 20;
$i = ord('U'); // 85
for($anno = $annoMin; $anno<=$annoMax; $anno++){
for($mese = 1; $mese <= 12; $mese++){
$c = chr($i);
$string = "=$c$v+$c$q-$c$z-$c$t"; // $i will be U then V etc...
$ews->setCellValueByColumnAndRow($col_index,$k,$string);
$col_index = $col_index+1;
$i++;
}
}
If you need to keep $i starting at 20 and incrementing then just add 65:
$col_index = 20;
$i = 20;
for($anno = $annoMin; $anno<=$annoMax; $anno++){
for($mese = 1; $mese <= 12; $mese++){
$c = chr($i + 65);
$string = "=$c$v+$c$q-$c$z-$c$t"; // $i will be U then V etc...
$ews->setCellValueByColumnAndRow($col_index,$k,$string);
$col_index = $col_index+1;
$i++;
}
}

Adding data from an array to a new array

I have created an array of data, from which I can loop through specific fields and echo these values out, but what I need to do is add these values to a new array, ultimately allowing me to find the average of the values in the new array. As i've said, I can echo out the data, and I think I've figured how to get the average, if only I can create the new array! Any help would be greatly appreciated as I just can't find the answer anywhere, and I'm running low on talent!
My table contains approx 25 fields, im pulling out a number of rows based on a session variable. In the instance im working on, I need to take just the values from 1 column in the table, and add these to an array. The code below will loop through the values, and echo them out, 1 at a time:-
while ($cdarray=mysql_fetch_array($calldata)) {
echo $cdarray['score_total'];
}
This gives me 25555 which are the 4 values I would expect 25, 5, 5, 5
I've tried
while ($cdarray=mysql_fetch_array($calldata)) {
$cdts = $cdarray['score_total'];
$cdtsar = array($cdts);
}
Which results in $cdts being assigned a value of 5,
Any help greatly appreciated!!
This will get your data from the array, place it into a new one and calculates the average.
$cdtsar = array();
while ($cdarray=mysql_fetch_array($calldata)) {
$cdtsar[] = $cdarray['score_total'];
}
$average = array_sum($cdtsar) / count($cdtsar);
It actually prints 25 and 5 and 5 and 5, but there are no spaces in between so it looks like "25555". To verify this yourself:
while ($cdarray=mysql_fetch_array($calldata)) {
echo $cdarray['score_total'];
echo " / ";
}
To get the average, you can either use
$sum = $count = 0;
$average = null;
while ($cdarray=mysql_fetch_array($calldata)) {
$sum += $cdarray['score_total'];
++$count;
}
// Make sure to guard against divide by zero
if ($count) {
$average = $sum / $count;
}
or you might have the database calculate the average for you, if changing the query is an option.
If you want to assign the elements to the new array use like this
$cdtsar = array();
while ($cdarray=mysql_fetch_array($calldata)) {
array_push($cdtsar,$cdarray['score_total']);
}
To find the average of the array
$sum = array_sum($cdtsar);
$num = sizeof($cdtsar);
$avg = $sum/$num;
echo $avg;

Adding up total of mysql_num_rows in a while loop

For example I have a mysql_num_rows results of 4,8,15,16,23,42 in a query that is inside a while loop of another query. My question is how can I total all the results inside that while loop? (Total of 133) Thanks.
EDIT:
How about if I want to get the percentage per each result of mysql_num_rows inside my while loop? Example: 4,8,15,16,23,42. Total is 108. $sum = 108. Percentage of 4 = 4/$sum = 3.7%, 8 = 8/$sum = 7.4% and so on..
Try something like this:
$Sum = 0;
while ($SomeInvariant)
{
mysql_query($SomeQuery);
$Sum += mysql_num_rows();
}
echo 'The sum is: ' . $Sum;
However, this approach is not very efficient (what if $SomeInvariant is true for many iterations, and your app has even more concurrent users?). To account for this, I would recommend restructuring your approach so the addition is done in SQL. This way, your query could look something like this: SELECT SUM(ColumnName) FROM ....
UPDATE: Addressing follow-up question in the comments
If you don't already have the sum available from the query, then you'll have to loop over the dataset twice. On the first pass, you'll calculate the sum. On the second pass, you'll calculate the ratio of each value to the sum.
For example:
$Sum = 0;
$Rows = array();
while ($SomeInvariant)
{
mysql_query($SomeQuery);
$Value = mysql_num_rows();
$Rows[] = $Value; // Push the value onto the row array
$Sum += $Value; // Add the value to the cumulative sum
}
echo 'The sum is: ' . $Sum;
foreach ($Rows as $Row)
{
echo $Row . '/' . $Sum . ' = ' . number_format($Row / $Sum) . '%';
}

Categories