Jump to content

Counter for repeat years


morrism35

Recommended Posts

instructor wants us to display and write to a file how many times a certain year was entered by the user.

My code is listed below. I left out of lot of the irrelevent code. I have the user selecting a birthyear and if the birthyear matches one of those birthyears in my "if" statement it displays an emage and writes that year to count. My

instructor wants that txt file updated frequently with the year and how many times that number appears. I was able to get only far as reading the file and iterating it with a foreach and printing what is in the count.txt. I've been at this program for 4 days someone please help. Lost a lot a time with other assignments thanks to this assignments.

 

if($BirthYear==2019 || $BirthYear==2007 || $BirthYear==1995 || $BirthYear==1983 || $BirthYear==1971){ 
$CountFile = 'statistics/count.txt';
if(file_exists($CountFile)){
echo"file accepted";
$handle = fopen('statistics/count.txt', 'a'); 
chmod("count.txt", 0777);
fwrite($handle, $BirthYear. PHP_EOL); 
fclose($handle);}




else{


mkdir("statistics");
$handle = fopen('statistics/count.txt', 'w'); 
chmod("", 0777);
fwrite($handle, $BirthYear. PHP_EOL);
fclose($handle);}
echo "<p>You were born under the sign of the <img src='Images/pig-zodiac.jpg' alt='' />, </p>\n ";}






$readin = file('statistics/count.txt');
foreach($readin as $year){ 


if($year == $BirthYear){
echo $year. $BirthYear;}




}


echo "You are person $count to enter $BirthYear";

EDIT: make use of our

 tags
Edited by Zane
Link to comment
Share on other sites

Not sure why you are changing the permissions on the file. If your script creates the file, it has the permissions to write to it.

I did a little rewriting of your script to try and make sense of it.

if ($BirthYear == '2019' || $BirthYear == '2007' || 
    $BirthYear == '1995' || $BirthYear == '1983' || $BirthYear == '1971')
{
	$CountFile = 'statistics/count.txt';
	
	if (file_exists($CountFile))
	{
		echo"file accepted";
		$handle = fopen($CountFile, 'a');
		//chmod($CountFile, 0777);
		fwrite($handle, $BirthYear. PHP_EOL);
		fclose($handle);
	}
	else
	{
		mkdir("statistics");
		$handle = fopen($CountFile, 'w');
		//chmod($CountFile, 0777);
		fwrite($handle, $BirthYear. PHP_EOL);
		fclose($handle);
	}
	echo "<p>You were born under the sign of the <img src='Images/pig-zodiac.jpg' alt=''/></p>\n";

	$readin = file($CountFile);
	$count = 0;
	
	foreach ($readin as $year)
	{
		// need to trim the newline/carriage return
		// or year will never match
		if (trim($year) == $BirthYear)
		{
			//echo $year. $BirthYear;
			$count++;
		}
	}
	
	echo "You are person $count to enter $BirthYear";	
}
else 
{
	echo "Your birth year is apparently not that important";
}

Edited by hansford
Link to comment
Share on other sites

Thank you so much, I really appreciate this. I never thought about trimming the file when using my if statement. Couldn't figure out why my if wasn't making the comparison correctly. I have struggled with php much more than i have with java or C++. It doesn't help that my instructor is hard to get in touch with and is always mia so I'm really teaching myself. One thing that I was supposed to do in this assignment was to store a running counter in a file for each year that the specific year was entered. My count.txt file only stores the year but not how many times it was entered. Example 1985 1999 etc.

The assignment should say 1985-5 times or some type of format like that. Any help or pointing me in the correct directions would help.

Link to comment
Share on other sites

Here is the deal. Our goal here is to help you become a better programmer because we've all been in the same position you are now.

You made an attempt and posted your code, so I attempted to help you in hopes that you would understand the logic and be able to apply it in similar coding problems. So, make an attempt at how you think you could solve the problem of keeping track of the number of times a year was entered.

It may help to reread the assignment and even post it on here. Does the instructor want it stored in the same file as the year or another file ?

Link to comment
Share on other sites

same file and I would never ask someone to right my code. I'm a grown midlife career changer not a high school or young college kid. What I would need a hand on is maybe some logic of how to go about this, not specific code unless I get really stuck like before. I have been on that previous assignments for quite a few days and wrote over 300 lines of code so no I'm not asking someone to do my work for me.

Link to comment
Share on other sites

The more sensible approach to this would be use a csv file. But it can still be accomplished using a plain text file.

if ($BirthYear == '2019' || $BirthYear == '2007' || 
    $BirthYear == '1995' || $BirthYear == '1983' || $BirthYear == '1971')
{
	$CountFile = 'statistics/count.txt';
	$count = 1;
	
	if (file_exists($CountFile))
	{
		$handle = fopen($CountFile, 'r+');
		//chmod($CountFile, 0777);
		$count = updateFile($handle, $BirthYear);
		fclose($handle);
	}
	else
	{
		mkdir("statistics");
		$handle = fopen($CountFile, 'w');
		//chmod($CountFile, 0777);
		fwrite($handle, $BirthYear . ':1' . PHP_EOL);
		fclose($handle);
	}
	echo "<p>You were born under the sign of the <img src='Images/pig-zodiac.jpg' alt=''/></p>\n";
	echo "You are person $count to enter $BirthYear";	
}
else 
{
	echo "Your birth year is apparently not that important";
}

/**
 * reads each file line and attempts to find matching year
 * if match found, number is updated
 * file is rewritten from buffer
 * line format - year:number example; 1995:2
 * @param file pointer $fp
 * @param string $year
 * @return number
 */
function updateFile($fp, $year)
{
    // string buffer to rewrite file
    $buffer = ""; 
    // counter, default is 1
    $num = 1;
    // flag if match was found
    $found = false;
    
    // read each line of file
	while (($line = fgets($fp)) !== false)	  
	{   
	    // place line parts in array
	    $args = explode(':', $line);
	    
	    // attempt to match year
	   	if ($args[0] == $year)
	   	{
	   	    // extract number and increment by 1
	   	    $num = (int) trim($args[1]);
	   	    $num++;
	   	    // add update to buffer
	   	    $buffer.= $args[0] . ':' . $num . PHP_EOL;
	   	    $found = true;
	   	}
	   	else 
	   	{
	   	    $buffer .= $line;
	   	}
	}
	// no match found, so add new year to the file
	if ( ! $found)
	{
	    $buffer .= $year . ':1' . PHP_EOL;
	}	
	
	// place the file pointer at the beginning of the file
	rewind($fp);
	// rewrite the file
	fwrite($fp, $buffer);
	// return the number of times year was accessed
	return $num;
}
Link to comment
Share on other sites

Here is a csv option if you want to look at that. We aren't writing the year multiple times in either script as there is no need. We write the year one time and then just update the number of times it was accessed. We don't need to use a temp file here, but it's good practice to get in the habit as some files can be massive in size and you could exhaust your memory attempting to read the file all at once into a buffer.

if ($BirthYear == '2019' || $BirthYear == '2007' || 
    $BirthYear == '1995' || $BirthYear == '1983' || $BirthYear == '1971')
{
	$CountFile = 'statistics/count.csv';
	$count = 1;
	
	if (file_exists($CountFile))
	{
		if(($handle = fopen($CountFile, 'r+')) === false)
		{
		    exit;
		}
		//chmod($CountFile, 0777);
		$count = updateFile($handle, $BirthYear);
		fclose($handle);
	}
	else
	{
		if(mkdir("statistics") === false)
		{
		    exit;
		}
		if(($handle = fopen($CountFile, 'w')) === false)
		{
		    exit;
		}
		//chmod($CountFile, 0777);
		fputcsv($handle, array($BirthYear, 1));
		fclose($handle);
	}
	echo "<p>You were born under the sign of the <img src='Images/pig-zodiac.jpg' alt=''/></p>\n";
	echo "You are person $count to enter $BirthYear";	
}
else 
{
	echo "Your birth year is apparently not that important";
}

/**
 * read cvs file and attempts to find matching year
 * if match found, number is updated
 * file is rewritten from temp file
 * @param file pointer $fp
 * @param string $year
 * @return number
 */
function updateFile($fp, $year)
{
    // counter, default is 1
    $num = 1;
    // flag if match was found
    $found = false;
    
    // open temp file for reading/writing and truncate to zero length
    $temp_path = 'statistics/temp.csv';
    
    if(($tp = fopen($temp_path, 'w+')) === false)
    {
        exit;
    }    
    
    // read each line of csv file
	while (($data = fgetcsv($fp, 1000, ',')) !== false)	  
	{   	    
	    // attempt to match year
	   	if (trim($data[0]) == $year)
	   	{
	   	    // extract number and increment by 1
	   	    $num = (int) trim($data[1]);
	   	    $num++;
	   	    // add to temp file
	   	    fputcsv($tp, array($data[0],$num));
	   	    $found = true;
	   	}
	   	else 
	   	{
	   	    // add to temp file
	   	    fputcsv($tp, $data);
	   	}
	}
	// no match found, add new year to the temp file
	if ( ! $found)
	{
	    fputcsv($tp, array($year,1));
	}	
	
	// place the file pointers at the beginning of each file
	rewind($fp);
	rewind($tp);
	// read line from temp file and then write to main file
	while(($data = fgetcsv($tp,1000,',')) !== false)
	{
	    fputcsv($fp, $data);	    
	}
    // close temp file
    fclose($tp);
	// return the number of times year was accessed
	return $num;
}
Edited by hansford
  • Like 1
Link to comment
Share on other sites

Hansford's post is the right way to do it.

Many lines in a file grows too large.

 

Having a file each year actually does less work.

You can make multiple text files in a folder with each year and file named as the year.

Inside is just a number count. When you add to it are fetching the single number count that is in the file and incrementing it +1 and save.

 

If you do all dates a single file, it would be like an array except the values use a delimiter like a csv.

When you access the file would explode the line by it's delimiters and is an array.

Using a switch or if/elseif/else when the date matches would increment that count +1

Save the files new data while imploding it with the delimiters.

  • Like 1
Link to comment
Share on other sites

Other thoughts:

I know it probably doesn't apply to this assignment, but this wouldn't fly in the real world.

If there is any chance that two users would be accessing the file at the same time, you can experience data loss. Only way around this is by using a database or applying exclusive file locks which would prevent 2 people from being able to write to the file at the same time. Problem there is...one person will be shut out whereas with a database they would simply be standing in line (queue).

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.