simple statistics with PHP - php

I have a bunch of JSON objects stored in my database with user input,
i.e.
{ "items": [
{question_id: 5, answer_id: 4, is_correct: 1},
{question_id, 45, answer_id: 233, is_correct: 0},
...]
}
and I'd like to build statistics about which answer_id for which question_id is answered most, etc.
I have tried PHP associative arrays like so:
<?php
$stats = array();
foreach($jsonObject->items as $item)
{
$stats[$item->question_id][$item->answer_id]++;
}
?>
I'm using PHP much like I'd use AWK, and it works, but the problem is that I get a lot of warnings like this one
Undefined offset: 23026
Where 23026 is the id of the question or the answer.
How do I debug / ensure the accuracy of the statistics? Is there a better way of doing this?

The notices occurs, because you try to increase a not existing value for the first occurrence of the question or answer id. If you want to run your script without warning you simply have to check if it was already set or not.
Some sample code which should work:
<?php
$stats = array();
foreach ($jsonObject->items as $item) {
if (isset($stats[$item->question_id][$item->answer_id])) {
$stats[$item->question_id][$item->answer_id]++;
} else {
// Set to 1 if not exist
$stats[$item->question_id][$item->answer_id] = 1;
}
}
?>

Related

How do you set up an array to hold '0's for empty locations so graphs(Highcharts) can format them correctly?

I'm trying to get my Highcharts graph to work. The Reason I'm having so much trouble with it this time is because I have to keep the program adaptable for future changes when it comes to my columns(named issues1 through 12).
The Goal is pretty simple, I just need to grab the issues between hours 1-12 during a certain time period, then create a graph.
My idea Is that I should create a view that organizes the desired information because there is a lot more to that table that I left out, and then create an SQL to organize the data from there. Which I realize might be overkill, but I'm an intern and my supervisor probably did it to help make it simple for me.
There are 4 different places I need to use SQL to make the Table work.
X-Axis
Day shift numbers
Swing shift numbers
Night shift numbers
So for my code The X-Axis, It works fine for just calling in the names.
xAxis: {
categories: [
<?php
foreach ($xAxisresult as $Xrow) {
echo "'" . $Xrow['IssueName'] . "'" . ',';
}
?>
]
I believe the Day/Swing/Grave SQL statements should all be similar so I'm just going to focus on one. But this is where the problem starts with how I have it set up. I tried to run an If statement were I compare the two arrays I have set up and try to match the IssueName Columns.
name: 'Day',
data: [
<?php
foreach ($Dresult as $Drow) {
if ($Xrow['IssueName'] == $Drow['IssueName']){
echo $Drow['Issues'] . ',';
}
else{
echo $Drow['Issues'] . ',';
}
}
You guys can most likely see a lot of whats wrong here. But I need to make a loop or array that will find out that if there is an empty spot in the array and output a 0 so the data stays correct.
Sorry for the wall of Text, I just wanted to give you guys as much information as possible.
To answer your question how to create an array that holds zero values and merge with the data array (I assume).
You can use array_fill to create the array with zeros, and use array_replace to replace with the data array.
$arr = array_fill(0, 10, 0); //[0,0,0,0,0,0,0,0,0,0]
$data = [2 => 15, 5 =>10, 7 => 16]; // your data
$new = array_replace($arr, $data);
var_dump($new); // [0,0,15,0,0,10,0,16,0,0]

PHP array limit? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
friends i am new in php. I am playing with array. So i am unable to solve one login using array. In this program i want to show array limit. I have number of data it's come form Database. But i want to show limit data like ( 10 posts only ). I know the MYSQL query to show limit data. But i am trying with array. So please help to solve this logic thanks.
here is the code.
$reverse = array_reverse($showpost, true);
foreach ($reverse as $key=>$postvalue) {
$latestpost = explode(',', $postvalue['postcategory']);
if (in_array("3", $latestpost)) {
// result here...
}
}
I have save the category this format (1,2,3,4,5,6). That's why I have used explode() function.
My DataBase fields name are ( post_id, postname, postcategory, postdisc,).
Not sure if I've understood the problem correctly but I think it maybe related to this link
$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"
You can use array_chunk() function
CODE:
<?php
$reverse = array_reverse($showpost, true);
foreach($reverse as $key=>$postvalue){
$latestpost = explode(',', $postvalue['postcategory']);
$chunks = array_chunk($latestpost, 3);
print_r($chunks);
}
?>
If you're only wanting to show 10 rows, and result here... is where each post is show, then something like this may work:
$postsShown = 0;
$reverse = array_reverse($showpost, true);
foreach ($reverse as $key => $postvalue) {
if ($postsShown >= 10) {
break;
}
$latestpost = explode(',', $postvalue['postcategory']);
if (in_array("3", $latestpost)) {
// result here...
$postsShown++;
}
}
All this does is count how many posts are shown using the $postsShown variable, and increments it when a new post is shown. When this variable reaches 10 (IE, 10 posts are shown), the loop will be terminated using the break command.
maybe you can use a session variable to save few attempts the user used to log, and you validate it in the server.
with this code you can create a session variable:
session_start();
$_SESSION['name_of_my_variable'] = 'value of my session variable';
and for example each time the user tries to log you can increase the value of your counter in the session variable:
the first time you needs create the session variable:
session_start();
$_SESSION['log_counter'] = 1;
and the next attempts you increment the counter like this:
session_start();
$log_counter = $_SESSION['log_counter'];
$log_counter++;
$_SESSION['log_counter'] = $log_counter;
check if the user already reached the limit:
session_start();
if ($_SESSION['log_counter'] == 10)
{
echo "Limit reached";
}
This is the final code:
// init session variables
session_start();
// Check if exist the session variable
if (isset($_SESSION['log_counter']))
{
// Enter here if the session variable exist
// check if the log_counter is equals to the limit
if ($_SESSION['log_counter'] == 10)
{
echo "Limit reached";
}else
{
// increase the counter
$log_counter = $_SESSION['log_counter'];
// this increate 1 more to the log_counter session variable
$log_counter++;
// here we save the new log_counter value
$_SESSION['log_counter'] = $log_counter;
}
}else
{
// Enter here if not exist the session variable
// this create the log_counter session variable
$_SESSION['log_counter'] = 1;
}

PHP variable variables in a foreach loop aren't working

This is a brilliant little trick if I can get it to work - I have hundreds data columns from dozens of tables spread across a dozen data forms (they are HTML print forms) and they are all html with embedded php variables. Very normal. However the customer had a requirement to know what field went in where - a very good question.
So what did I do? I worked on a solution that allows the key'd arrays from the database to give up their column names. a brilliant move! except I need to do it via variable variables, and guess what, they DON'T work in a foreach loop.
here is the code
if ($_REQUEST['data']=="false"){
$supera = array("RowService", "RowSite", "RowCustomer", "RowEngineer"); //there can be many of these they are key'd arrays $RowService['column_name_1']; is the format
foreach($supera as $super){
foreach(${$super} as $key=>$value){
if (!is_numeric($key)){
${$super}[$key] = "<span style=\"color:pink;\">".$key."</span>";
}
}
}
}
as you can see I want a kill switch easy mechanism to cut and paste the key'd arrays that aren't to show real data any more rather they are to show (in pink) the column name, and (perhaps) the table name too. There is a lot of code already in place and this would be a brilliant option if it can be made to work
EDIT: this is the PHP error:
Warning: Invalid argument supplied for foreach()
EDIT: THE CODE ACTUALLY ALREADY WORKS: FIX IS TO test for is_array()
if(is_array(${$super})) foreach(${$super} as $key=>$value){
will work, as opposed to just
foreach(${$super} as $key=>$value){
I'm not sure what you are trying to achieve but your code (simplified) works just fine:
$a = array("asd", "qwe");
$asd = array("a" => 1, "b" => 2, "c" => 3);
$qwe = array("d" => 4, "e" => 5, "f" => 6);
foreach ($a as $item)
{
foreach ($$item as $key => $value)
{
echo $key . ": " . $value . "<br />";
}
}
Output:
a: 1
b: 2
c: 3
d: 4
e: 5
f: 6
Most likely one of your variables is empty (not an array) and that's why you receive that warning.
Personally, I find variable variables to be a really bad idea. There are a few ways around it.
For example:
$process = array(&$RowService,&$RowSite,&$RowCustomer,&$RowEngineer);
foreach($process as $p) {
foreach($p as $k=>$v) {
$p[$k] = "<span style=\"color:pink\">".$v."</span>";
}
}
Using references means you can affect the original variables.
If the above doesn't work (I'm not that great with references XD), try this:
$process = array($RowService,$RowSite,$RowCustomer,$RowEngineer);
foreach($process as $p) {
foreach($p as $k=>$v) {
$p[$k] = "<span style=\"color:pink\">".$v."</span>";
}
}
list($RowService,$RowSite,$RowCustomer,$RowEngineer) = $process;
As per my understanding of your requirement.
If you want to get table name with pink color then you just need to use below code
$supera = array("RowService", "RowSite", "RowCustomer", "RowEngineer"); //there can be many of these they are key'd arrays $RowService['column_name_1']; is the format
$super = array();
foreach($supera as $key=>$value){
if (!is_numeric($value)){
$super[$value] = "<span style=\"color:pink;\">".$value."</span>";
}
}
print_r($super);

Error using array_push

I am trying to use array_push but I am recieving error messages like:
Warning: array_push() expects parameter 1 to be array, string given in C:\Users\DMR\Google Drive\android\maquetas\show.php on line 50
in two linews where I am using array_push, I don't understand why, could you help me please? the code is the next:
...
$etiquetes = array("N.I.F.", "Direcció");
$tipus = array("varchar", "varchar");
$columnes = array("CIF_NIF", "DIRECCION");
$llongituds = array(30, 30);
...
$i=0;
foreach ($etiquetes as $etiqueta) {
$control = array_push($etiqueta, $columnes[$i], $tipus[$i], $llongituds[$i]); <==== IT GIVE ME ERROR (ATTACHED AT THE END)
$controls[$i % 2] = array_push($control); <==== IT GIVE ME ERROR (ATTACHED AT THE END)
$i++;
}
$etiqueta is not an array thus
array_push($etiqueta, ...
is wrong. You might be looking for:
array_push($etiquetes, ...
Also, from array_push() docs:
Returns the new number of elements in the array.
Which means $control will have an int value. So you second line
array_push($control);
Is ofcourse invalid, I would suggest you look at the docs and try to figure out what are you planning to do.
Here it is better to answer because it will be more clear for all of you (I hope)
I will explain here my solution, I have two DIV left and right and I have n controls in the array, what I am trying to do is when I loopp in the array I set the impair in the left and the pais in the right, for this reason I used the bucle:
foreach ($etiquetes as $etiqueta) {
$control = array(array(), array(), array(), array());
array_push($control, $etiqueta, $columnes[$i], $tipus[$i], $llongituds[$i]);
array_push($controls[$i % 2], $control);
$i++;
}
Now I have it it will be easy to set in the html code. The code I set before $columnes will be the fields of the table in the database and $etiquetes will be the label.
then I will need to put the length, type for the input fields, etc...
then the screen will be wllformed.
I hope it can be more clear for you. Now code I wrote here it is working just I have to put performance.

Improving algorithm using MySQL

The code below is written mainly using PHP, but I am hoping to speed up the process, and parsing strings in PHP is slow.
Assume the following where I get a string from the database, and converted it into an array.
$data['options_list'] = array(
"Colours" => array('red','blue','green','purple'),
"Length" => array('3','4','5','6'),
"Voltage" => array('6v','12v','15v'),
);
These subarrays will each be a dropdown Select list, an the end user can select exactly 1 from each of the select lists.
When the user hits submit, I will want to match the submitted values against a "price table" pre-defined by the admins. Potentially "red" and "6v" would cost $5, but "red" and "5"(length) and "6v" would cost $6.
The question is, how to do so?
Currently the approach I have taken is such:
Upon submission of the form (of the 3 select lists), I get the relevant price rules set by the admin from the database. I've made an example of results.
$data['price_table'] =
array(
'red;4'=>'2',
'red;5'=>'3',
'red;6'=>'4',
'blue;3'=>'5',
'blue;4'=>'6',
'blue;5'=>'7',
'blue;6'=>'8',
'green;3'=>'9',
'green;4'=>'10',
'green;5'=>'11',
'green;6'=>'12',
'purple;3'=>'13',
'purple;4'=>'14',
'purple;5'=>'15',
'purple;6'=>'16',
'red;3'=>'1',
'red;3;12v'=>'17',
'blue;6;15v'=>'18',
);
Note : The order of the above example can be of any order, and the algorithm should work.
I then explode each of the above elements into an array, and gets the result that matches the best score.
$option_choices = $this->input->post('select');
$score = 0;
foreach($data['price_table'] as $key=>$value)
{
$temp = 0;
$keys = explode(';',$key);
foreach($keys as $k)
{
if(in_array($k, $option_choices))
{
$temp++;
}else{
$temp--;
}
}
if($temp > $score)
{
$score = $temp;
$result = $value;
}
}
echo "Result : ".$result;
Examples of expected results:
Selected options: "red","5"
Result: 3
Selected Options: "3", "red"
Result: 1
Selected Options: "red", "3", "12v"
Result: 17
The current method works as expected. However, handling these using PHP is slow. I've thought of using JSON, but that would mean that I would be giving the users my whole price table, which isn't really what I am looking for. I have also thought of using another language, (e.g python) but it wouldn't particularly be practical considering the costs. That leaves me with MySQL.
If someone can suggest a cheap and cost-efficient way to do this, please provide and example. Better still if you could provide an even better PHP solution to this which works fast.
Thank you!
It looks like you did work to make the results read faster but you're still parsing and testing every array part against the full list? This would probably run faster moving the search to MySQL and having extra columns there.
Since you can control the array (or test string) perhaps try fixed length strings:
$results = explode("\n", "
1 Red v1
22 Blue v2
333 Green v3");
$i = 0;
while($i < count($results)) {
$a = substr($results[$i], 0, 10);
$b = substr($results[$i], 10, 20);
$c = substr($results[$i], strpos(' ', strrev($results[$i]))-1);
if(stripos($userInput, $a . $b . $c) !== false) {
// parse more...
Supposedly JavaScript is good at this with memoizaion:
http://addyosmani.com/blog/faster-javascript-memoization/

Categories