0

Compare the CSV file of two, in the case of the same identifier, I want to make the calculation at a certain formula. And Always, I can't get The first row result.

My code (test.php)

<html>
<head>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD XTHML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" type="text/css" href="it_test_check_uesr_list_table.css" /></head>
<body>
<?php 
    $data = fopen("rate.csv", "r");
    /*  rate.csv

        code,codename,data,.......
        3668,A, 3325,+50(+1.53%),410518,A
        3765,B, 606,+1(+0.17%),698118,B
        7832,C, 2557,+10(+0.39%),567654,C
        6460,D, 2048,-11(-0.53%),545238,D
    */
    $baserate = fopen("baserate.csv", "r");
    /*  baserate.csv

        code,data
        7832,2312
        3765,734
        3668,3025
        6460,2682
    */
    if($baserate){
        while ($baserate_line = fgets($baserate)) 
        {
            list($temp_code,$temp_data) = explode(",", rtrim($baserate_line));
            $base_rate[] = (object)array('code' => $temp_code,
            'data' =>  mb_convert_encoding($temp_data, "UTF-8", "auto"));
        }
    }
    if($data){
        while ($line = fgets($data)) 
        {
            list($temp_code,$temp_codename,$temp_data,$temp_comparison_previous_day,$temp_market_capitalization,$temp_market) = explode(",", rtrim($line));
            for($i = 0; $i< count($base_rate); $i++) 
            {
                if($temp_code == $base_rate[$i]->code)
                {   
                    //What I want (temp_data_index)
                    $temp_data_index = number_format($temp_data / $base_rate[$i]->data * 100,2); 
                }
            }
            $company[] = (object)array('code' => $temp_code,
            'codename' =>  mb_convert_encoding($temp_codename, "UTF-8", "auto"),
            'data' => mb_convert_encoding($temp_data, "UTF-8", "auto"),
            'comparison_previous_day' => mb_convert_encoding($temp_comparison_previous_day, "UTF-8", "auto"),
            'market_capitalization' => mb_convert_encoding($temp_market_capitalization, "UTF-8", "auto"),
            'market' => mb_convert_encoding($temp_market, "UTF-8", "auto"),
            'data_index' => mb_convert_encoding($temp_data_index, "UTF-8", "auto"));
        }
    }
    // A(The first row ) Always don't work
    for($i = 0; $i< count($company); $i++) 
    {
        echo $company[$i]->codename." - ".$company[$i]->data_index."<br>";
    }
    ?>
</body>
</html>

Result is

A - 
B - 82.56
C - 82.56
D - 76.36

'A'(The first row in csv file) Doesn't work for loop.(There is same code, I checked var_dump) What's my problem?

3
  • Are those header rows in your files? They will be causing you issues, because 'code' == 'code' Commented Jul 31, 2014 at 2:43
  • Header Row mean, [code,data] row? No, First row of the CSV file is being recognized as a header always? @redreinard Commented Jul 31, 2014 at 2:49
  • debug 101, log lines. try to log the value of $temp_data, $base_rate[$i]->data, $temp_data_index, mb_convert_encoding($temp_data_index, "UTF-8", "auto"), $company[$i]->data_index when it's first created Commented Jul 31, 2014 at 3:53

1 Answer 1

1

OK, I'll take a swing, but first, let's clean up your code. it's hard to follow, has some horrible programming practices and for this example had a lot of stuff not relevant. So here is what i did:

  • remove the html, there's no reason for it in this context
  • php knows how to parse csv. much safer than exploding
  • calling a variable "data" should be a crime. it's a file descriptor pointing to a file of rates. that's hard to remember if it's called data. and then you also call a column in the rates file data and one in the baserate file also data - to make things extra clear i suppose. I renamed the first one, and left the others because i don't know what it represents, but holy confucious batman.
  • group related things together. open a file, load the data. then open the next file and load it's data. then process. doing all this at the same time makes it hard to follow in an example
  • don't use array's as objects unless you really really need to. it makes your code hard to read.
  • don't worry about encoding in an example. sure, have it in your production code, but in this example it just again makes it hard to follow your code - it's not relevant to your question
  • instead of looping through all baserates each time to find the one you want, index the array of them by what you're looking for
  • at least one of your csv files (rate.csv) has spaces as the beginning of some columns ("data" column), so to be safe you should trim each field, not just each row

// load rates
$fd_rates = fopen("rate.csv", "r");
if (!$fd_rates) die("Unable to open rate.csv");
$rates = array();
while (($rate_row = fgetcsv($fd_rates)) !== FALSE) {
    // key by code, turn into associative array
    $rates[ trim($rate_row[0]) ] = array(
        'code' => trim($rate_row[0]),
        'codename' => trim($rate_row[1]),
        'data' => trim($rate_row[2]),
        'comparison_previous_day' => trim($rate_row[3]),
        'market_capitalization' => trim($rate_row[4]),
        'market' => trim($rate_row[5]),
    );
}
fclose($fd_rates);
/*  rate.csv / $rates

    code,codename,data,....... // this line not in file
    3668,A, 3325,+50(+1.53%),410518,A
    3765,B, 606,+1(+0.17%),698118,B
    7832,C, 2557,+10(+0.39%),567654,C
    6460,D, 2048,-11(-0.53%),545238,D
*/

// load baserates
$fd_baserates = fopen("baserate.csv", "r");
if (!$fd_baserates) die("Unable to open baserate.csv");
$baserates = array();
while (($baserate_row = fgetcsv($fd_baserates)) !== FALSE) {
    // code => data
    $baserates[ trim($baserate_row[0]) ] = trim($baserate_row[1]);
}
fclose($fd_baserates);
/*  baserate.csv

    code,data // this line not in file
    7832,2312
    3765,734
    3668,3025
    6460,2682
*/

// calculate
foreach ($rates as $code => $rate) {
    if (isset($baserates[$code])) {
        $rates[$code]['data_index'] = number_format($rate['data'] / $baserates[$code] * 100, 2);
    } else {
        $rates[$code]['data_index'] = 'no baserate found';
    }
}

// display
foreach ($rates as $code => $rate) {
    echo "{$rate['codename']} - {$rate['data_index']}\n";
}

And then I just ran the code... and it works. I'm not going to bother trying to find the specific bug in your code, but honestly, in my opionion, it's due to bad programming practices. Name your variables. Simplify. Good luck!

$ php index.php 
A - 109.92
B - 82.56
C - 110.60
D - 76.36

$ php -v
PHP 5.5.9-1ubuntu4.4 (cli) (built: Sep  4 2014 06:56:34) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.