I'm doing a little php script and i have a form that saves several things on a txt.
I need to read all the lines and take the last value of each and put them all inside an array
I was thinking that i could do that with the explode function but i don't know how to implement it several times to sum all the values and get the average.
$nombre=$_POST['nombre'];
$edad=$_POST['edad'];
$email=$_POST['email'];
$importe=$_POST['importe'];
$nombre=$_POST['nombre'];
//this part writes each value of the form to a txt file separated by an " | "
// this is where I need help. I have to show the sum of all the $importe values in all of the lines in the txt
//
$miarchivo=fopen("resultados.txt","a");
if(!($miarchivo))
{
print("Imposible abrir archivo");
exit;
}
fputs($miarchivo," $nombre | $edad | $email | $importe \n" .PHP_EOL);
fclose($miarchivo);
//echo "<script>location.href='forma.php'</script>";
//This part only shows the values of the txt after the script ends
$miarchivo=fopen("resultados.txt","r");
if
(! ($miarchivo))
{
print("no hay resultados");
exit;
}
while(!feof($miarchivo)){
$linea=fgets($miarchivo,255);
print"$linea<BR>";
}
fclose($miarchivo);
I expect to get an array like:
tab [0] $importe //from line 0
tab [1] $importe //from line 2
tab [2] $importe //from line 3
tab [3] $importe //from line 4
So i can sum all of them and get the average in other variable
Export to array then take last value and store in array. Finally add the array and get the average result. Here is your code
while(!feof($miarchivo)){
$linea=fgets($miarchivo,255);
$quantityArray[] = end(explode('|',$linea));
}
$averageResult = array_sum($quantityArray)/count($quantityArray);
You need to make $linea[] an array by adding brackets like this.
while(!feof($miarchivo)){
$linea[]=fgets($miarchivo,255);
}
Then you can access each line like this...
$linea[0] = "line 1"
$linea[1] = "line 2"
if you need to print the current line, like you do in your while loop, you can add another temporary variable and print that like this...
$linea[] = $currentLine = fgets($miarchivo,255);
print($currentLine);
You don't need to store the values in an array to get an average. Unless you need to do something else with that array, it's just a waste of memory. You can sum and count the $importe values as you read the lines, and then calculate the average from those values at the end.
$count = $sum = 0;
while (($linea = fgetcsv($miarchivo, 0, '|')) !== false) {
$importe = trim($linea[3]);
$count++;
$sum += $importe;
}
if ($count) { // check count to prevent division by zero
$average = $sum / $count;
}
Related
There is a csv file with data about the weather. I am making something which calculates the mean of a column per station from that csv file. That column is passed in the parameters of the function.
First of all I have this list of id's from the weatherstation. The values I add to the list are arrays which contains the sum and count of a datatype.
$station_id = array("960350", "960870", "961090", "961790", "962210", "962370", "962950", "963230",
"965810", "966330", "966850", "967430", "967470", "967490", "967810",
"968050", "968810", "969330", "969350", "969870", "970140", "970480",
"970720", "971200", "971260", "971460", "971800", "971925", "972300",
"972400", "972600", "973000", "973400", "974280", "974300", "975600",
"977240", "977900", "978100", "979000");
//Every item in the array becomes a key, with an array as a value.
//StationID => [sum, count]
$station_id = array_fill_keys($station_id, []);
The function down here reads the lines of the csv file, adds the value if it is there, adds one to the counter, calculates the mean and prints it per station. Finally it clears the values of the array station_id.
function calc_average($to_be_calc){
global $station_id; //array with station_id's as keys. The value is the sum and the count. (0=sum , 1+count)
global $file; //The csv file.
while (($line = fgetcsv($file)) !== FALSE) {
list($STN, $DATE, $TIME, $TEMP, $DEWP, $STP, $SLP, $VISIB, $WDSP, $PRCP, $SNDP, $FRSHTT, $CLDC, $WNDDIR) = $line;
if (is_numeric($STN)) {
$station_id[$STN][0] += $$to_be_calc; //Sums the values of for example temp
$station_id[$STN][1] += 1; //Adds one to the counter of the station.
}
}
foreach ($station_id as $key => $value) {
if ($value[1] > 0) {
//Calculate average
$average = number_format($value[0] / $value[1], 1, ',', ' ');
//print average per station
echo "Average of station $key: $average</br>";
}
}
foreach ($station_id as $key => $value){
unset($key);
}
}
The problem I have now is that when I call it like this:
calc_average("TEMP");
echo "<br>";
calc_average("CLDC");
It prints the averages of the temperature per station twice. Instead of first TEMP, then CLDC. Like this. If I first call calc_average with CLDC as parameter it only does with CLDC.
I have no idea how this is possible. Therefore, my question is how to fix this.
SOLUTION
I didn't rewind the pointer at the end of my function. All I had to do was add rewind($file); to my function. I works great now. Thanks
Placing my answer from the comments in an actual answer:
I am assuming $file is a file pointer obtained using something like fopen(). If so, are you resetting the pointer back to the beginning of the file? If not, $line = fgetcsv($file) will always return false at the start of the second calc_average() call.
I am trying to create an array that holds the count of each course we offer based on location and then instructor. Here is sample code
$courseCnt = array();
foreach($courseList as $course){
$courseCnt[$course['location']][$course['instructor']] += 1
}
This code creates the array properly and displays well but I get a bunch of warnings like:
Unidentified index "Orlando" for locations, Unidentified index "John
Smith" for instructor
I have found that if I just make it = 1 instead of += 1 the warnings go away but of course this makes every course for location/instructor 1 which is not good.
My next though was checking if it exists, if it doesn't, make it 1 and if it does += 1. Here is an example
if(isset($courseCnt[$course['location']][$course['instructor']]){
$courseCnt[$course['location']][$course['instructor']] += 1
}else{
$courseCnt[$course['location']][$course['instructor']] = 1
}
This results in the fatal error:
Cannot use string offset as an array
$course array structure is just a 2 dimensional array pulled from sql
Sample:
courseID location instructor
1 Orlando John Smith
2 Detroit Bill Murray
You are not checking if the location exists before checking for the instructor in your first line of the new version of the code. You need to check if it exists and create it in your $courseCnt array if it doesn't (as an empty array). After that, you can check for the instructor:
// Initialise the empty array
$courseCnt = array();
// Create location if not in array
if( ! isset($courseCnt[$course['location']])) {
$courseCnt[$course['location']] = array();
}
// Either increment the instructor or create with initial value of 1
if ( isset($courseCnt[$course['location']][$courseCnt[$course['instructor']]]) ) {
$courseCnt[$course['location']][$courseCnt[$course['instructor']]] += 1;
}
else
{
$courseCnt[$course['location']][$courseCnt[$course['instructor']]] = 1;
}
You've got a lot of square brackets going on in there, so you might find it easier to read if you use PHP's array_key_exists (documentation) instead of isset:
// Initialise the empty array
$courseCnt = array();
// Create location if not in array
if( ! array_key_exists($course['location'], $courseCnt)) {
$courseCnt[$course['location']] = array();
}
// Either increment the instructor or create with initial value of 1
if ( array_key_exists($course['instructor'], $courseCnt[$course['location']]) ) {
$courseCnt[$course['location']][$courseCnt[$course['instructor']]] += 1;
}
else
{
$courseCnt[$course['location']][$courseCnt[$course['instructor']]] = 1;
}
I used this but my array show blank.
foreach($page_data->result() as $text){ $i++;
echo $name="text".$i; //this line print ok.
$$name=array();
echo $$name['content']=$text->$content; //this line print ok.
print_r($text1);
} print_r($text1);
here i am tying to name the array dynamically as text1,text2,text3.......
but when i print $text1 it shows me a blank array.
can any one help me out with this.
It's simply a syntax ambiguity. $$name['content'] is understood as:
${$name['content']}
I.e. the name of the variable is supposed to be the value of $name['content'], which obviously doesn't exist, which actually leads to an error if you'd enable error reporting. You can solve this with:
${$name}['content'] = $text->$content;
However, you really should solve this by using an array instead of variable variables:
$texts[] = array('content' => $text->$content);
You're incrementing the index before you echo the contents of the variable, so if you only have 1 result, it will try and access an undefined index, you are also re initialising the name array every time you pass through the loop, you should not do this
Results
------------------
Num Content
0 I am a text post
If these were the results returned and you wanted to point to index i, then when your loop goes through this would happen:
i = 0;
i = 1;
assign values to name array
As there is only one result this would then happen
Results
------------------
Num Content
0 I am a text post
- - <----- i = 1 (null pointer exception?)
This would be why no values are showing in your array, try change your code to this:
// Declare i to point at the 0 index
$i = 0;
$name=array();
foreach($page_data->result() as $text){
$name[i]['content']=$text;
$i++;
}
Your name array will no add the text content to a new index with each pass of the loop, i.e. if you had 2 results
$name[0]['content'] = "This is a text post";
$name[1]['content'] = "Here is another post";
Hope this helps.
I am trying to redeem a value from the array. For example I have 20 Points and I am going to redeem from the list of earned points.
Here is my array structure which will shown as follows
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'0'),
array('earnedpoints'=>'25','usedpoints'=>'0'),
);
which has n number of data's(array).
I am trying to reduce the values from the earned points
Points to redeem : 20. In a foreach statement i am just
$remainingpoints=20; // Redeeming Points is named as in variable of $remainingpoints
foreach ($newstructure as $keys => $newone) {
if ($remainingpoints > $newone['earnedpoint']) {
$remainingpoints = $remainingpoints - $newone['earnedpoint'];
} else {
$remainingpoints = $newone['earnedpoint'] - $remainingpoints;
}
}
For the Point Redeeming for the first iteration of foreach earned point is 10, remaining point is 10 (based on above code) and used point is 10
For the second iteration the earned point is 25 but i want to redeem only 10 so i want to stop the loop once the redeeming values are finished (Previous Iteration 10 and Current Iteration 10)
I trying to get the result as (Redeem Point 20)
First Iteration Used Points 10 and Remaining Points is 10.
Second Iteration Used Points 10 and Remaining Points is 0.
Also I am trying to store the information as in the form of array too.
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'10','remainingpoints'=>'10'),
array('earnedpoints'=>'25','usedpoints'=>'10','remainingpoints'=>'0'),
);
Can anyone point me a right direction inorder to get this desired result?
First thing, in one place you use earnedpoints as your table key, and in loop you use earnedpoint.
This code should work for you:
<?php
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'0'),
array('earnedpoints'=>'25','usedpoints'=>'0'),
);
$remainingpoints=25; // Redeeming Points is named as in variable of $remainingpoints
foreach ($newstructure as $keys => $newone) {
if ($remainingpoints > $newone['earnedpoints']) {
$toRedeem = $newone['earnedpoints'];
}
else {
$toRedeem = $remainingpoints;
}
$remainingpoints -= $toRedeem;
$newstructure[$keys]['usedpoints'] = $toRedeem;
$newstructure[$keys]['remainingpoints'] = $remainingpoints;
/*
if ( $remainingpoints == 0 ) {
break;
}
*/
}
var_dump($newstructure);
In comment I put code where you could break your loop but when you break it, you won't have set used_points and remainingpoints for the following array values
I've checked a lot of solutions regarding about looping still, can't apply to my problem.
Still confused about looping though. I want to generate random number then check if the generated number is equal to the content of the table column if it's the same it would generate again until it does not have the same value.
Hope you guys help me, so here we go.
I have a table in database which called "list" it has a structure of id and img
it contains value of
list table:
id | img
1 | 1
2 | 2
3 | 3
4 | 4
number.php
$new_array = array();
$query = "SELECT img FROM list";
$query = mysql_query($query);
while ($query_get = mysql_fetch_array($query)) {
$new_array[] = $query_get[0]; //Store img values into an array
}
$rand = rand(1,5); //Generates random number 1 to 5
$search_r = array_search($rand, $new_array); //Checks if the random number has the same value to the array
while($search == "") { //Until random number gets number 5 it would stop looping
$rand = rand(1,5);
}
echo $rand; //and echo the number 5 here.
Still the result is non-stop loading screen at my browser
Well I have this piece of code to determine if the random number and the array has the same value. But it's only good at one loop.
if (array_search($rand,$new_array)) {
echo "random number has the same value inside the array" . $rand;
} else {
echo "random number does not have the same value inside an array" . $rand;
}
To cut the story short, the values in my table img is 1,2,3, and 4 and I'm generating numbers 1 to 5. Until the generated numbers output 5 it would echo. If the generated numbers get 1 to 4 it would generate again until it gets 5.
Use a do...while loop:
do {
$rand = rand(1, 5);
} while (in_array($rand, $new_array));
Although I'm not sure why you need to generate a random number like this. Why do you need this number?
A recursive function maybe useful in this scenario.
inside function create a random string
Check it in database
If exists then move call recursive function again
else return string