PHP crosstab formatting from array - php

Hi I have a PHP array like this
$table=array();
$subject_names=array();
$subject_names[118]="English";
$subject_names[108]="Software Engeneering";
$table['Josh'][118]['int'] =55;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['int'] =45;
$table['Josh'][108]['ext'] = 12;
$table['Matt'][118]['int'] =45;
$table['Matt'][118]['ext'] = 12;
$table['Matt'][108]['int'] =50;
$table['Matt'][108]['ext'] = 15;
Here 118 and 108 are subject_id I am trying to format it like this
student | English | Software Engeneering |
| int. mark | ext. mark | int. mark | ext. mark |
___________________________________________________________
Josh | 55 | 10 | 45 | 12
Matt | 45 | 12 | 50 | 15
I tried
echo "Student Name\t";
foreach($subject_names as $sub_name)
{
echo "$sub_name\t";
}
echo "<br>";
foreach($table as $sname => $subjects){
echo "$sname\t";
foreach($subjects as $subject_name => $types)
{
foreach($types as $marks)
{
echo "$marks\t";
}
}
echo "<br>";
}
It working fine but if I change the position of array item of table like
$table['Josh'][118]['int'] =55;
$table['Josh'][108]['int'] =45;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['ext'] = 12;
It won't give a correct result. Is there anyway to assure that the result are always correct.
Thank you for your any help and suggestions

Here's a solution I wrote for your request, picking the scores using the $subject_names as control rather than the students' scoresheet (I hope you get what I mean after going through the codes)...
$table=array();
$subject_names=array();
// notice that I switched subject order, just to show that subjects control the marks displayed thereby ensuring consistent score mapping
$subject_names[108]="Software Engeneering";
$subject_names[118]="English";
// and I'm using the rearranged scores (the sample use-case you specified in the question that distorts your output)
$table['Josh'][118]['int'] =55;
$table['Josh'][108]['int'] =45;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['ext'] = 12;
$table['Matt'][118]['int'] =45;
$table['Matt'][118]['ext'] = 12;
$table['Matt'][108]['int'] =50;
$table['Matt'][108]['ext'] = 15;
echo "Student Name\t";
foreach($subject_names as $sub_name)
{
echo "$sub_name\t";
}
echo "\n";
// proposed solution:
foreach($table as $sname => $subjects){
echo "$sname\t";
foreach ($subject_names as $subject_id => $name) {
foreach ($subjects[$subject_id] as $mark) {
echo "$mark\t";
}
}
echo "\n";
}
Here's the output of the script above...
Student Name Software Engeneering English
Josh 45 12 55 10
Matt 50 15 45 12
Running the same data through the script provided in the question, here's the output (distorted)...
Student Name Software Engeneering English
Josh 55 10 45 12
Matt 45 12 50 15
P.S: 'Engeneering' should be 'Engineering'
I hope I've been helpful.
Cheers!

Related

how to add number into table array php saprfc [duplicate]

This question already has answers here:
Zero-pad digits in string
(5 answers)
Closed 4 years ago.
my table sap rfc
how can I add number in front of ID? if ID contain 3 digits it will add 000 in front of ID, if ID contain 4 digits it will add 00 in front of ID, if ID contain 5 digits it will add 0 in front of ID. For an example
ID | FEE | NAME | PERIOD
000711 | 204000 | YUDI MANDALA | 201807
000790 | 84000 | AGUS WAHYUDI | 201807
001171 | 151500 | SARJANA | 201807
my code:
if ($FI_HPs!=0)
{
$array = [];
for ($i=1;$i<=$FI_HPs;$i++)
{
$FI_HP = saprfc_table_read ($fce,"FI_HP",$i);
$id = $FI_HP['ID'];
if(isset($array[$id]))
{
$array[$id]['FEE'] += $FI_HP['FEE'];
}
else
{
$array[$id] = $FI_HP;
}
}
foreach($array as $item)
{
echo '<tr>
<td>'.$item['ID'].'</td>
<td>'.($item['FEE']*100).'</td>
<td>'.$item['NAME'].'</td>
<td>'.$item['PERIOD'].'</td>
</tr>';
}
}
you could use str_pad
foreach($array as $item)
{
echo '<tr>
<td>'.str_pad($item['ID'], 6, "0", STR_PAD_LEFT) .'</td>
<td>'.($item['FEE']*100).'</td>
<td>'.$item['NAME'].'</td>
<td>'.$item['PERIOD'].'</td>
</tr>';
}
$base = 100000 ;
'. substr($base+$item['ID'],1) .'

for loop return string 1-30 on the 5th count and 13count from mysql database that matches numbers using php

I've created a for loop to count 1-30 and want to match mysql number columns 1 - 30 with its attach string data column name and display string inside for loop.
Mysql structure:
|-------------|-------------|--------------|
| id | Number | Name |
|-------------|-------------|--------------|
| 90 | 3 | Test Data |
|-------------|-------------|--------------|
tried simular attempts such as:
foreach($db->results() as $result) {
$count = $result->Number;
$results = $result->Name;
}
for($i=1;$i<=30;$i++) {
if($count == $i) {
echo $results;
}else{
echo '';
}
}
Needing help! Thank you!!!
================================================================================================================================================================
Ok here is what I am trying to accomplish... It works with assigning to the correct number when matching (Thanks for the suggestion). Here is what I have:
$name = array();
$number = array();
foreach($forDB->results() as $for){
$name = $for->firstname;
$number = $for->number;
for($i=1;$i<=30;$i++) {
if($i<=5){
if($number == $i) {
echo $i.' = '.$name;
}
} //then the rest of remanding numbers to 30
}
}
this echos:
2 = name1
4 = name4
But what I would like to do is also echo the numbers of $i between the numbers and values as:
1
2 = name1
3
4 = name4
5
So I try this but it appends to each value:
$name = array();
$number = array();
foreach($forDB->results() as $for){
$name = $for->firstname;
$number = $for->number;
for($i=1;$i<=30;$i++) {
if($i<=5){
if($number == $i) {
echo $i.' = '.$name.'<br><br>';
} else {
echo $i.'<br>';
}
} else {
echo $i;
}
}
}
Results:
2
3
4
5
6
7
1
2 = name2
3
4
5
6
7
1
2
3
4 = Jeff
1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7
I think you should initialize your count and name variables before the foreach loop as an array then in the foreach loop fill it up with the results, then iterate through it in the for loop.

Consecutive dateranges in PHP

This is a follow-up question for my earlier question here:
Some help "syncing" two loops in PHP
I want to take a list of dates and show them as ranges if their date is the same or max 1 day apart.
This is the output of my database:
+-----+------------+
| uid | date |
+-----+------------+
| 39 | 2014-09-17 |
| 46 | 2014-09-18 |
| 40 | 2014-09-19 |
| 48 | 2014-09-19 |
| 45 | 2014-09-20 |
| 47 | 2014-12-05 |
+-----+------------+
This is the HTML I want to generate:
Contract from 17/09/2014 to 20/09/2014
UIDS: 39-46-40-48-45
Contract from 05/12/2014
UIDS: 47
This is my sourcecode
<?php
$output = '';
$list = array();
$lastitem = $lastdate = null;
$query = 'SELECT * FROM project_dates';
$sth = $dbh->prepare($query);
$sth->execute();
if($sth->rowCount() > 0) {
$i = 0;
while($row = $sth->fetch()) {
// CURRENT DATE
$date = new DateTime($row['date']);
// STORAGE
$item = array(
'date' => array(),
'var' => $row['uid'], // A '-' delimited variable of all the uids in the range (40-41-...)
'uids' => array() // An array of all the uids in the range
);
// IF THE DATE DIFF IS LESS THAN OR EQUAL TO ONE DAY
if ($item['date'] === $lastitem['date'] && $date->diff($lastdate)->days <= 1) {
// Problem here: looking for last date in set!
$list[$i-1]['date']['end'] = $date;
//Add current uid to the '-' delimited variable of uids of this range
$list[$i-1]['uid'] = $list[$i-1]['uid'].'-'.$item['uid'];
// Add current uid to the array of uids of this range
array_push($list[$i-1]['uids'],$item['uid']);
} else {
// Next range
$list[$i] = $item;
$list[$i]['date']['start'] = $date;
$lastitem = $item;
$lastdate = $date;
array_push($list[$i]['uids'],$item['uid']);
$i++;
}
}
}
if(count($list)){
// Show text with first date and last date of the range
$output .= 'Contract from '.$item['date']['start']->format('d/m/Y');
$output .= isset($item['date']['end']) ? ' to ' . $item['date']['end']->format('d/m/Y') : '';
$output .= '<br />Uids: '.$item['var'];
}
foreach ($list AS $item) {
// Loop over the dates in this range
$output .= $item['date'].'<br />';
}
if(count($list)) {
// Line under this range
$output .= '<hr />';
}
echo $output;
?>
For some reason, my code returns 4 ranges instead of 2. I've been trying to figure out for hours why. Can someone help me? This is the faulty HTML:
Contract from 17/09/2014 to 18/09/2014
UIDS: 39-46
Contract from 19/09/2014
UIDS: 40
Contract from 19/09/2014 tot 20/09/2014
UIDS: 48-45
Contract van 05/12/2014
UIDS: 47
Can anyone be of assistance?

Search results group by 10 in each page

I have stacked on finding a way to code a php search script which will group results e.g of 10 per page.
e.g page
______________________________
| ________ |
| search: |________| submit |
| |
| |
| ________________________ |
| | <-|---|------------<div id=results></div>
| |________________________| | |
|______________________________| |
v
div which shows the results grouped
by 10
For example: Suppose that I search images by tag, and for the tag 'love' there are 20 images. How could I show the first 10 results on one page and the last 10 results on another page. (the first page has a link to the second page and visa versa).
A hint is that the modulo operator is really handy for pagination. It checks the remainder of a division operation, which corresponds to zero for new pages when using it for pagination.
Here's a quick and dirty example of pagination:
<?php
$arr = array();
for ( $x = 0; $x < 100; $x += 1 ) {
$arr[] = $x;
};
$page = 7;
$per_page = 7;
$current_page = 1;
for ( $z = 0; $z < count( $arr ); $z += 1 ) {
if ( 0 === ( $z % $per_page ) ) {
$current_page += 1;
}
if ( $current_page === $page ) {
echo "value $z on page $page\n";
}
}
?>
~$ php pagination.php
value 35 on page 7
value 36 on page 7
value 37 on page 7
value 38 on page 7
value 39 on page 7
value 40 on page 7
value 41 on page 7

converting from base 10 to base 31 (working only with select characters)

I'd like to convert base 10 numbers to base 31
I would like to use only these characters: 23456789abcdefghjkmnpqrstuvwxyz
As you can see, 5 characters are excluded (i don't need these): 1 0 o l i
The function I have now is below but of course it doesn't work. When 2 is input it outputs 4. The output for tenTo31(2) should be 2
function tenTo31($num)
{
$out = "";
$alpha = "23456789abcdefghjkmnpqrstuvwxyz";
while($num > 30)
{
$r = $num % 31;
$num = floor($num / 31) - 1;
$out = $alpha[$r] . $out;
}
return $alpha[$num] . $out;
}
Any ideas on how to make this work?
This is a blind guess at what you want:
$alpha = "yz23456789abcdefghjkmnpqrstuvwx";
There's a built-in function for converting from one base to another, base_convert(). The alphabet is fixed, but you can use strtr() to replace those digits with your own.
"The output for tenTo31(2) should be 2": One possibility is to make '2' the third symbol again.
function tenTo31($num) {
static $from = "0123456789abcdefghijklmnopqrstu";
static $to = "yz23456789abcdefghjkmnpqrstuvwx";
return strtr(base_convert($num, 10, 31), $from, $to);
}
for($i=0; $i<31; $i++) {
echo $i, '=', tenTo31($i), ' | ';
if ( 9===$i%10 ) echo "\n";
}
prints
0=y | 1=z | 2=2 | 3=3 | 4=4 | 5=5 | 6=6 | 7=7 | 8=8 | 9=9 |
10=a | 11=b | 12=c | 13=d | 14=e | 15=f | 16=g | 17=h | 18=j | 19=k |
20=m | 21=n | 22=p | 23=q | 24=r | 25=s | 26=t | 27=u | 28=v | 29=w |
30=x |
edit:
To convert the base(31) number back to decimal you first have to reverse the translation (strtr) and then call base_convert(.., 31, 10). You can combine the conversion from and to base(31) in a single function.
function convert_ten_31($num, $numIsDecimal) {
static $default = "0123456789abcdefghijklmnopqrstu";
static $symbols = "yz23456789abcdefghjkmnpqrstuvwx";
if ( $numIsDecimal ) {
return strtr(base_convert($num, 10, 31), $default, $symbols);
}
else {
return base_convert(strtr($num, $symbols, $default), 31, 10);
}
}
// testing
for($i=0; $i<10000; $i++) {
$x = convert_ten_31($i, true);
$x = convert_ten_31($x, false);
if ( $i!==(int)$x ) {
var_dump($i, $x);
die;
}
}
echo 'done.';
It's also easily possible to write a function like base_convert() yourself that take the symbols as parameter and thus having one flexible function instead of tenTo30(), tenTo31(), tenTo32(), ....
You aren't using the 1 and 0 characters, the first digit in your numbering system is 2 meaning 2 is the equivalent of 0 in base 10. 3 is equivalent to 1 in base 10 and 4 is equivalent to 2 in base 10.
Why are you taking modules by 32? You should use %31 and /31. In base 10 we are using modules by 10, so should be in base 31. But if we forget about this, I think your logic is correct. I can't understand why 2 in base 10 is equal to 4 in base 31 using your "modified digits".
While I'd encourage you to continue along with your algorithm for the learning exercise, consider using base_convert if you just need to get the job done.
The mapping according to http://www.crockford.com/wrmg/base32.html appears to be:
function symbolToEncode ($num) {
$out = "";
static $alpha = "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U";
while ($num >= 37) {
$r = $num % 37;
$num = floor ($num / 37);
$out = $out . $alpha[$r];
}
return $out . $alpha[$num];
}
function decodeToEncode ($str) {
static $from = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*~=$";
static $to = "0123456789ABCDEFGH1JK1MN0PQRSTUVWXYZABCDEFGH1JK1MN0PQRSTUVWXYZ*~=$";
return strtr ($str, $from, $to);
}
Though clearly the real challenge is to write a encodeToSymbol() function. I am not really a PHP expert (my $'s in the strings probably needs to be escaped somehow -- hints?), so I will leave that to others.

Categories