I am to import a file, say june.txt that would have data such as the following data:
Sandy,820,384,133,18,408
Wanda,120,437,128,807,595
Jane,631,415,142,687,600
Andrea,179,339,349,594,986
Wanda,803,191,6,807,322
Jane,741,975,34,15,832
Jane,239,714,250,94,497
Andrea,219,188,411,584,713
And then the PHP would parse it into 2 difference ways:
The first way being all the names bundled together with totals, such as:
Sandy 820 384 133 18 408
Total 820 384 133 18 408
Jane 631 415 142 687 600
Jane 741 975 34 15 832
Jane 239 714 250 94 497
Total 1611 2104 426 796 497
Andrea 179 339 349 594 986
Andrea 219 188 411 584 713
Total 398 527 760 1178 1699
Wanda 120 437 128 807 595
Wanda 803 191 6 807 322
Total 923 628 134 1614 917
The second way would total and add the names together in a big list, such as
Sandy 820 384 133 18 408
Jane 1611 2104 426 796 497
Andrea 398 527 760 1178 1699
Wanda 923 628 134 1614 917
Any logic or suggestions would be helpful, I am new to PHP and not sure how this could even be done. My plan is to eventually display the results in HTML tables and have them sortable, but I can tackle that at a later date, Unless someone feels obligated to just add the and such for me in the parsing.
I think something useful for you would be the explode function.
As far as creating these views I'd start by loading all this data into an associative array of arrays based on the name, then iterate as necessary:
$datafile = file("filename.txt");
// reads lines into an associative array (key is the name) of arrays
// where each sub-array is a list of the records for each name
$arr = array();
foreach($datafile as $line){
$temp = explode(',', $line);
$arr[$temp[0]][] = $temp;
}
// iterate over each person
foreach($arr as $person_set){
// create an array to hold the sum of each column
// (and the name in the first column)
$totals = array();
$totals[0] = $person_set[0][0];
for($i = 1; $i < length($record); $i++){
$totals[$i] = 0;
}
// now iterate over each record for this person
foreach($person_set as $record){
// print a particular record
echo implode(' ', $record) . '<br>';
// add each column (1..end) to the totals array
for($i = 1; $i < length($record); $i++){
$totals[$i] += $record[$i];
}
}
// print out the totals line
echo implode(' ', $totals) . '<br><br>';
}
I'll leave formatting this data into a table as an exercise.
Well, to start, I'd real a file like that with PHP's fgetcsv(). Docs.
You could try a script like this:
<?php
echo "<table>";
$data = file("june.txt");
foreach($data as $month) {
$line = explode(',', $data);
echo '<tr><td>', implode('</td><td>', $line), '</td></tr>';
}
echo "</table>";
Edit:
My bad, didn't notice that you were sorting/grouping/totaling. This should set you on the right track, though. The key is to use $line as your source of information. Just compile it into an array and output later (instead of right in the loop).
Related
I run a query, the result is good, but while putting into PHP result, the resuts are duplicated per row, here is the code:
$selectSi = 'SELECT * FROM series LEFT JOIN series_join on series.ids = series_join.id_sil GROUP BY series.ids';
$querySi = $connexion->query($selectSi);
$resultSi = $querySi->fetchAll();
$displaying = 5;
// building table here
foreach($resultSi as $siK=>$siV)
{
$ids = $siV['ids'];
$silsila_en = $siV['silsila_en'];
$id_shks = $siV['id_shks'];
// get singer
$sSel = 'SELECT shk_fname, shk_lname, shk_tran FROM shk_tbl WHERE id_shk = "'.$id_shks.'"';
$sReq = $connexion->query($sSel);
$sRes = $sReq->fetchAll();
$listShk = '';
foreach($sRes as $vS)
{
$shk_fname = $vS['shk_fname'];
$shk_lname = $vS['shk_lname'];
$shkFullName = $shk_fname.' '.$shk_lname;
$shkFullNameLink = '<a href="">';
$shkFullNameLink .= $shkFullName;
$shkFullNameLink .= '</a> - ';
$listShk .= $shkFullNameLink;
$listSheikhs = substr($listShk, 0,-2).'<br />';
}
// putting result into a table
echo '<tr class="multiColor">';
echo '<td>'.$silsila_en.'</td>';
echo '<td>'.$listSheikhs.'<br /></td>';
echo '</tr>';
}
echo '</table>';
and the tables are like this
PS: Instead of numbers result, it is singers name
I am looking for a result like:
Conciseness of speech: 114 - 136
The eternal journey: 325 - 326 - 327
Night Mare: 303 - 332 - 331 - 330 - 329 - 328 - 282 - 306 - 281 - 126 - 120
but I am getting something like:
Conciseness of speech: 114 - 136
The eternal journey: 114 - 136 - 325 - 326 - 327
Night Mare: 114 - 136 - 325 - 326 - 327 - 303 - 332 - 331 - 330 - 329 - 328 - 282 - 306 - 281 - 126 - 120
so the first row is duplicated to second, and second is duplicated to third
Thanks in advance
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"]
i'm trying to put input (below) into multiple arrays (or maybe its simpler into one array) to finally export it into mysql table, input data goes like:
0 98
77 09
0 12
0 98234
32 0
0 1
0 0
345 32
34 9
6437 34
789 0
0 0
.
.
34 0
my simple code ($run_txt_filter1 is input):
if ( $counted == 64)
{
echo "line's number: ".$counted;
//echo $run_txt_filter1;
for ($modi = 0; $modi <= 15; $modi++)
{
for ($simhi = 1; $simhi <= 4 ; $simhi++)
{
$exploded=explode(" ", $run_txt_filter1);
var_dump($exploded)." \n";
}
}
}
Why var_dump keeps saying the id from 0-64 ? (there always should be 64 input lines).
What a really want to achieve is:
array0=(0, 77, 0, 0)
array1=(98, 09, 12, 98234)
array2=(32, 0, 0, 345)
.
.
array30=(0, 12, 0, 34)
array31=(0, 0, 0, 0)
thanks in advance
try to separate your explode for the next line and explode for the white space. cause on your code above it's reading the whole string as one causing your program to store it on a single array. so it would be a nested loop by then. :)
Considering this input:
$in = <<<IN
0 98
77 09
0 12
0 98234
32 0
0 1
0 0
345 32
34 9
6437 34
789 0
0 0
IN;
This algorithm solves your problem i think:
$final_array = array();
$offset = 0;
foreach(preg_split("/(\r?\n){2,}/",$in) as $block){
foreach(preg_split("/(\r?\n)/",$block) as $line){
foreach(preg_split("/\s+/",$line) as $column => $value){
if($value=='') continue;
if(!isset($final_array[$offset+$column]))
$final_array[$offset+$column] = array();
$final_array[$offset+$column][]=$value;
}
}
$offset = count($final_array);
}
print_r($final_array);
try something similar to this one I'm not sure if this would work:
inputs:
$inputs = "0 98
77 09
0 12
0 98234
32 0
0 1
0 0
345 32
34 9
6437 34
789 0
0 0
.
.
34 0";
code:
$run_txt_filter1 = explode("\n", $inputs);
if(count($run_txt_filter1) == 64)
{
foreach($run_txt_filter1 as $input)
{
$exploded = explode(' ', $input);
print_r($exploded);
}
}
The "\n" is the next line for windows but it's different on linux its "\r" I'm not sure if it would work you may also try the combination as
explode("\r\n", $inputs);
but just a try if the next line won't work I think you could use some other way to separate each set of values either user other type of characters like ',',';',':' etc. :)
i am creating a student management system and i want to be able to generate a pdf report that will contain every students data in its own page i.e . studentId, Math, English, Science, Class, totals, Rank, myClass and myTotals.for example, in the table below i would expect the pdf to have 6 pages. each containing only details of a particular student. how do i go about doing this?
Thank you in advance
studentId Math English Science Class totals Rank myClass myTotals
2 75 83 84 3p1 242 1 3p1 242
5 88 77 77 3p1 242 1 3p1 242
1 80 66 85 3p1 231 2 3p1 231
6 92 97 96 5p2 285 1 5p2 285
3 70 88 90 5p2 248 2 5p2 248
4 50 82 50 5p2 182 3 5p2 182
loop through the rows and create a new page for every row. How to do that exactly depends on with what you create the pdf.
You could output the information to a LaTeX file (assuming the machine has it installed). I assume you get all your student details from a database into an array of arrays called students. If you are using mySQL or similar to store the data, this should be simple enough.
This should generate a report.tex file and then execute pdflatex to generate report.pdf file.
<?
$f = fopen('report.tex','w');
$out = '\documentclass{article}
\usepackage{a4wide}
\begin{document}
';
fwrite($f,$out);
//Example array
$students = array(array('studentId'=> 1, 'Math'=> 1, 'English'=> 5 , 'Science' => 5, 'Class' =>6, 'totals'=>6 , 'Rank'=>7 , 'myClass' =>7, 'myTotals'=>9));
foreach($students as $x){
$out = '\begin{table}[htbp]'."\n".' \centering'."\n";
$out .= '\begin{tabular}{|r|r|r|r|r|r|r|r|r|}'."\n";
$out .= '\hline'."\n";
$out .= 'studentId & Math & English & Science & Class & totals & Rank & myClass & myTotals \\\\ '."\n \\hline \n";
$out .= "{$x['studentId']} & {$x['Math']} & {$x['English']} & {$x['Science']} & {$x['Class']} & {$x['totals']} & {$x['Rank']} & {$x['myClass']} & {$x['myTotals']} ";
$out .= '\\\\'."\n \\hline";
$out .= '\end{tabular} '."\n".' \end{table}'."\n".'\newpage' ."\n";
fwrite($f,$out);
}
fwrite($f,"\n".'\end{document}');
fclose($f);
echo (exec('pdflatex report.tex'));
echo "\ndone";
?>
The script works properly now, that produces a correct file. Having the server send the pdf to you shouldn't be too difficult.
<?php
$file = 'file.dat';
$file_contents = file_get_contents($file);
for ($i = 0x000481; $i <= 0x00048B; $i++) {
print $i;
}
?>
I am creating an online file analyzer but I have a small problem. It outputs (which is the actual position the hex is in)
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
when it should be
44 72 48 79 64 72 61 6C 69 73 6B
which his hex for DrHydralisk (me). Can anyone help me output the latter or just have it strait output ASCII (but hex is fine, I can just convert it)?
edit
Here is an image of what I am trying to do that I think will help.
http://imgur.com/nwenA.png
Here is the file I am trying to read, its a Starcraft replay (file.SC2Replay). Just search for DrHydralisk in a hex editor and that is where I am trying to read from.
http://www.mediafire.com/?6w8wi35q3o6ix8q
It should be (if clear text is in the file):
for( $i=0x481; $i<0x48D; $i++ ) {
printf("%X ", ord($file_contents[$i]));
}
Note the loop boundaries: 0x481 .. 0x48D
Result:
44 72 20 48 79 64 72 61 6C 69 73 6B
If the file contains hexadecimal numbers, this would be impossible because you need two bytes per hex char for the ascii character value range. So what is really in the file?
Edit
After reading your file, i did:
...
$file = 'file.SC2Replay';
$file_contents = file_get_contents($file);
for( $i=0x438; $i<0x443; $i++) {
printf("%X ", ord($file_contents[$i]));
}
for( $i=0x438; $i<0x443; $i++) {
printf("%s ", $file_contents[$i]);
}
...
And it says:
72 48 79 64 72 61 6C 69 73 6B
and
D r H y d r a l i s k
You messed up the file position ;-)
Regards
rbo
EDIT:
Thanks for providing the file, helped a lot! Beleive I got it working too:
//Do binary safe file read
$filename = 'file.SC2Replay';
$file = fopen($filename, "rb");
$contents = fread($file, filesize($filename));
fclose($file);
//position 1080 - 1091
for ($i = 0x438; $i < 0x443; $i++)
echo $contents[$i];
The reasons you were probably having problems is that first of all, a binary safe file read in php automatically replaces the bytes with the correct ASCII characters, so that threw off what position you actually needed to start reading from. Intead of 1153, it starts at 1080.
Could you explain how you are using the file you read in? Because the hex equivalent of:
11531154115511561157115811591160116111621163
is:
481 482 483 484 485 486 487 488 489 48a 48b
Also, there are two php functions you may find helpful
chr(int): returns the ascii character associated with the integer provided - http://php.net/manual/en/function.chr.php
dechex(int): returns the hex value of the integer provided - http://php.net/manual/en/function.dechex.php