Problem returning a value

not all code paths return a value

Page 1 of 1

14 Replies - 1865 Views - Last Post: 28 January 2010 - 02:34 PM Rate Topic: -----

#1 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Problem returning a value

Posted 23 January 2010 - 09:20 AM

Hi,

I am trying to return a result from one of my methods but i keep getting an error message "not all code paths return a value".

I would appreciate if somebody could take a look at my code and advise where I am going wrong please?

DoComparsion method returns true or false;

I am just trying to test a method i have written:

 
private bool Comparison(Bitmap bitmap)
		{
			bool result;

			foreach (DataGridViewRow dgrow in dataGridView1.Rows)
			{
				if (!dgrow.IsNewRow)
				{
					String fullPath = dgrow.Cells[1].Value.ToString();
					try
					{
						if (File.Exists(fullPath))
						{
							Bitmap servBitmap = new Bitmap(fullPath);
							result= DoComparison(bitmap, servBitmap);
							return result;
						}
					}
					catch (Exception ex)
					{
						Console.WriteLine(ex.StackTrace.ToString());
					}
				}



Thanks in advance.

Is This A Good Question/Topic? 0
  • +

Replies To: Problem returning a value

#2 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,412
  • Joined: 29-May 08

Re: Problem returning a value

Posted 23 January 2010 - 09:25 AM

An IF statement has two possible code paths
1. The expression evaluates to TRUE
2. The expression evaluates to FALSE

"not all code paths return a value" means that that one of those paths doesn't return a value.
Was This Post Helpful? 0
  • +
  • -

#3 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 23 January 2010 - 09:42 AM

View PostAdamSpeight2008, on 23 Jan, 2010 - 07:25 AM, said:

An IF statement has two possible code paths
1. The expression evaluates to TRUE
2. The expression evaluates to FALSE

"not all code paths return a value" means that that one of those paths doesn't return a value.


Ok, I have amended my code and below is the new code but i still get the same error message and additonal error message stating "use of unassigned local variable result". Can you assist me further please? Thanks

private bool Comparison(Bitmap bitmap)
		{
			bool result;

			foreach (DataGridViewRow dgrow in dataGridView1.Rows)
			{
				if (!dgrow.IsNewRow)
				{
					String fullPath = dgrow.Cells[1].Value.ToString();
					try
					{
						if (File.Exists(fullPath))
						{
							Bitmap servBitmap = new Bitmap(fullPath);
							result= DoComparison(bitmap, servBitmap);
							return result;
						}
						else
						{
						   return result;
						}
					}
					catch (Exception ex)
					{
						Console.WriteLine(ex.StackTrace.ToString());
					}
				}
				else
				{
				  return result;
				}
		   }


Was This Post Helpful? 0
  • +
  • -

#4 papuccino1  Icon User is offline

  • His name was Robert Paulson.
  • member icon

Reputation: 63
  • View blog
  • Posts: 1,121
  • Joined: 02-March 08

Re: Problem returning a value

Posted 23 January 2010 - 09:50 AM

Try declaring the bool with a value first. And in your if statements assign whatever logic result you need.
Was This Post Helpful? 0
  • +
  • -

#5 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 23 January 2010 - 10:22 AM

View Postpapuccino1, on 23 Jan, 2010 - 07:50 AM, said:

Try declaring the bool with a value first. And in your if statements assign whatever logic result you need.


Ok I had a go at it again and the code seems to compile now. By the way I have set return result; outside the for loop so is that is correct?

This post has been edited by MarmiteX1: 23 January 2010 - 12:37 PM

Was This Post Helpful? 0
  • +
  • -

#6 FlashM  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 382
  • View blog
  • Posts: 1,195
  • Joined: 03-December 09

Re: Problem returning a value

Posted 23 January 2010 - 02:20 PM

Do you want to get the true/false value for each image in your data grid view. because your method that does the comaprison, return when first image is evaluated and does not continue to run for the rest of the rows in grid view.
Was This Post Helpful? 0
  • +
  • -

#7 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 23 January 2010 - 02:37 PM

View PostFlashM, on 23 Jan, 2010 - 12:20 PM, said:

Do you want to get the true/false value for each image in your data grid view. because your method that does the comaprison, return when first image is evaluated and does not continue to run for the rest of the rows in grid view.


Oh ok, yes I would like to return true of false for each image thats in the database because I am trying to compare an image from a chosen directory with all the images in the database at that time.

Can you advise please based on my code i have provided?

Thanks
Was This Post Helpful? 0
  • +
  • -

#8 crepitus  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 84
  • View blog
  • Posts: 383
  • Joined: 08-September 09

Re: Problem returning a value

Posted 23 January 2010 - 04:17 PM

You needed the return statement after the loop because of a final path through the code - if the DataGridView had no rows.

Anyway, the logic is wrong now, as mentioned, - it will return a value far too soon.

I think your function should be:

return true if bitmap matches any of the Bitmaps whose paths are listed in dataGridView1
return false otherwise.

At the moment it is more like:

return undefined if the datagridview has no rows
return false if the first row in the datagridview is new
if the first row identifies a file that exists then return true or false depending on the result of DoComparison
return false otherwise.

You probably want something like this:
private bool Comparison(Bitmap bitmap)
{
   foreach (DataGridViewRow dgrow in dataGridView1.Rows)
   {
      if (!dgrow.IsNewRow)
      {
         String fullPath = dgrow.Cells[1].Value.ToString();
         if (File.Exists(fullPath))
         {
            using (Bitmap servBitmap = new Bitmap(fullPath))
            {
               if (DoComparison(bitmap, servBitmap)) return true;
            }
         }
      }
   }
   return false;
}

Was This Post Helpful? 1
  • +
  • -

#9 MentalFloss  Icon User is offline

  • "ADDICTED"[2:5]
  • member icon

Reputation: 526
  • View blog
  • Posts: 1,397
  • Joined: 02-September 09

Re: Problem returning a value

Posted 23 January 2010 - 10:54 PM

Ah don't feel too bad about this one. Everyone's bit by it eventually.

Some people declare a return value and return that at the end.

public bool IsValid()
{
	bool result = false;

	/* Some logic */

   return result;
}



Some people return at the branches

public bool IsValid()
{
	if (condition == true)
		return true;
	else
		return false;
}



Some people mix them:

public bool IsValid()
{
	bool result = false;

	if(condition == true)
		return true;
   else
   {
	   / * buncha logic... */

	   return result;
   }
}



That all depends on the situation. At any rate, when it says that not all code paths return a value, it's because a branch of logic does not return anything. More importantly, your method doesn't return anything after all the work's been completed.

Here's how you assure yourself that all return values are met. (Eventually you can fine-tune this to be better conveyed)

// You have a method that returns a boolean.
public bool IsValid()
{
	// declare a result that will be returned
	bool result = false;

   // return it
   return result;
}



There. Now stick all of your logic in between the bool declaration and the return.

public bool IsValid()
{
	// declare a result that will be returned
	bool result = false;


	// Now stick anything here and no matter what, all code paths always return a value.


   // return it
   return result;
}


This post has been edited by MentalFloss: 23 January 2010 - 10:55 PM

Was This Post Helpful? 1
  • +
  • -

#10 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 26 January 2010 - 02:16 PM

Hi

Thanks for your help. I would like further help please if you dont mind assisting me. What i would like to do with my code is if the images from my chosen directory match any of the images in the datagridview, i want to loop out and not attempt to insert a record in the database. I have tried to do this but it does have a slight problem which i will explain.

At the moment what happens is that for the first image in my folder the logic wont try to insert a record in my database because the record already exists so it will execute the following block of code and wont execute the else statement as expected.

//call the method for comparison. 
	pictureMatch = Comparison(pic);
	if(pictureMatch==true)
	{
	   //do nothing.
	}



But for the subsequent images in the folder it will try to insert an image but those particular images already exist in the database just like the first image. Therefore the following block of code i.e the else statement shouldnt be executed :

//if the image from the folder does not match any of the images in the database, add the row
else 
{
	  
	  staffImagesDataSet.StaffRow newRow = this.staffImagesDataSet.Staff.NewStaffRow();
	  newRow.ID = myPicID;
	  newRow.Thumbnail = myThumbnailPic;
	  newRow.FilePath = fullPath;

	 try 
	{
	   this.staffImagesDataSet.Staff.AddStaffRow(newRow);
	   this.staffTableAdapter.Update(staffImagesDataSet.Staff);
	 }
	 catch(Exception ex)
	{
   
	 }

  }



Below is my Database Structure. I am using SQL CE database.
ID [GUID]
Title[varchar]
Thumbnail[byte]
FilePath[varchar]

When i use the debugger I see an exception is being thrown when subsequent pictures from my sample pictures folder are being inserted into the database as they already exist.

As i mentioned before the second block of code above shouldnt be executed if the images exist already in the database. It should just loop out.

I would appreciate if you could help me please?

My DoComparison method has to return true or false.

Here is my DoComparison method:
		public bool DoComparison(Bitmap bmp, Bitmap bmpTwo)
		{
			//some logic to compare the images.

			if (firstImage.Equals(secondImage))
			{
				return true;
			}
			else
			{
				return false;
			}
		}


Here is the method that cycles through the datagrid rows and calls DoComparison method.

@param bitmap - the image(s) from the selected folder
private bool Comparison(Bitmap bitmap)
{
   bool theResult = false;
   foreach (DataGridViewRow dgrow in dataGridView1.Rows)
   {
	  if (!dgrow.IsNewRow)
	  {
		 String fullPath = dgrow.Cells[1].Value.ToString();
		 if (File.Exists(fullPath))
		 {
			 Bitmap servBitmap = new Bitmap(fullPath);
			   theResult = DoComparison(bitmap, servBitmap);
			  return theResult;
		 }
	  }
   }
   return theResult;
}


This function below is in a method which scans for images from a directory folder:

private bool pictureMatch = false;
//other global variables etc etc

//store the pictures in a collection
String[] pictures = //get pictures from folder
foreach(pic in pictures)
{
   Bitmap bmp = new Bitmap(pic);
   
   //here i get the image information such as title, filePath etc etc
   // i set the GUID for the image here as well

	//Call the method for comparison. 
	pictureMatch = Comparison(bmp);
	if(pictureMatch==true)
	{

	   //do nothing. I could output something to Console.

	}
   else //if the picture doesnt match any of the images in the database then insert it
	{
   
	  staffImagesDataSet.StaffRow theRow = this.staffImagesDataSet.Staff.NewStaffRow();
	  theRow.ID = myPicID;
	  theRow.Thumbnail = myThumbnailPic;
	  theRow.FilePath = fullPath;

	 try 
	{
	  this.staffImagesDataSet.Staff.AddStaffRow(newRow);
	   this.staffTableAdapter.Update(staffImagesDataSet.Staff);
	 }
	 catch(Exception ex)
	{
   
	 }

	 }

}

Was This Post Helpful? 0
  • +
  • -

#11 FlashM  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 382
  • View blog
  • Posts: 1,195
  • Joined: 03-December 09

Re: Problem returning a value

Posted 26 January 2010 - 02:44 PM

I think the problem is because you are comparing every image with every image. So the first image is compared with the first image and your comparison method says they are the same so it doesn't get inserted in you database. Then the first image is compared with a second image and since they are not the same, you try to insert it in a database and that's where your exception happens.

How do you compare your images? Do you compute the HASH code or you compare it pixel by pixel or do you have any more advanced comparing solution?
I'm asking you this because I have some idea, but it depends on your comparing method.
Was This Post Helpful? 0
  • +
  • -

#12 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 26 January 2010 - 03:43 PM

View PostFlashM, on 26 Jan, 2010 - 12:44 PM, said:

I think the problem is because you are comparing every image with every image. So the first image is compared with the first image and your comparison method says they are the same so it doesn't get inserted in you database. Then the first image is compared with a second image and since they are not the same, you try to insert it in a database and that's where your exception happens.

How do you compare your images? Do you compute the HASH code or you compare it pixel by pixel or do you have any more advanced comparing solution?
I'm asking you this because I have some idea, but it depends on your comparing method.


Thanks, how could i go about solving that particular problem?

In regards to the comparison I am most likely going to do pixel by pixel but i thought id try something simple first and then do advanced implementation later.

At the moment i am just experimenting so to compare i do the following:

MemoryStream memStream = new MemoryStream();
			bmp.Save(memStream, ImageFormat.Jpeg);
			String firstImage = Convert.ToBase64String(myStream.ToArray());
			memStream.Position = 0;

			bmpTwo.Save(memStream, ImageFormat.Jpeg);
			String secondImage =Convert.ToBase64String(myStream.ToArray());

			if (firstImage.Equals(secondImage))
			{
				return true;
			}
			else
			{
				return false;
			}



I know the above is not the best way of doing comparison, so I am going to attempt to do pixel by pixel and use a Hash to do the comparison later.

Thanks
Was This Post Helpful? 0
  • +
  • -

#13 FlashM  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 382
  • View blog
  • Posts: 1,195
  • Joined: 03-December 09

Re: Problem returning a value

Posted 26 January 2010 - 03:58 PM

This is how I would do it:


using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Npgsql;

namespace ImagesApplication
{
	public partial class Form1 : Form
	{
		private ImageConverter m_converter;
		private NpgsqlConnection m_db_conn;
		private DirectoryInfo m_sample_dir;


		public Form1()
		{
			InitializeComponent();

			m_sample_dir = new DirectoryInfo(@"C:\SampleImagesDir");
			m_converter = new ImageConverter();
		}


		private void OpenDbConnection()
		{
			try
			{
				m_db_conn = new NpgsqlConnection(@"Server=127.0.0.1;Port=5432;Database=imagesdb;User Id=uname;Password=pwd;");
				m_db_conn.Open();
			}
			catch (NpgsqlException e)
			{
				m_db_conn = null;
				Console.WriteLine(e.Message);
				throw;
			}
		}


		private void CloseDbConnections()
		{
			try
			{
				if (m_db_conn != null)
				{
					m_db_conn.Close();
				}
			}
			catch (NpgsqlException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		private void StartTransaction()
		{
			try
			{
				using (NpgsqlCommand cmd = new NpgsqlCommand("start transaction", m_db_conn))
				{
					cmd.ExecuteNonQuery();
				}
			}
			catch (NpgsqlException e)
			{
				Console.WriteLine(e.Message);
				throw;
			}
		}


		private void CommitTransaction()
		{
			try
			{
				using (NpgsqlCommand cmd = new NpgsqlCommand("commit transaction", m_db_conn))
				{
					cmd.ExecuteNonQuery();
				}
			}
			catch (NpgsqlException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		private void RollbackTransaction()
		{
			if (m_db_conn == null) return;

			try
			{
				using (NpgsqlCommand cmd = new NpgsqlCommand("rollback transaction", m_db_conn))
				{
					cmd.ExecuteNonQuery();
				}
			}
			catch (NpgsqlException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		private IList<string> GetDatabaseHashCodes()
		{
			IList<string> hc_list = new List<string>();
			string input_query = "select hashcode from images";

			using (NpgsqlCommand cmd = new NpgsqlCommand(input_query, m_db_conn))
			{
				NpgsqlDataReader reader = cmd.ExecuteReader();
				if (reader.HasRows)
				{
					while (reader.Read())
					{
						hc_list.Add(Convert.ToString(reader[0]));
					}
				}
			}

			return hc_list;
		}


		private void InsertNewImage(FileInfo file, byte[] imageBytes, string hash)
		{
			string input_query = "insert into images (title, thumbnail, hashcode, filepath) " +
								 "values (:title, :thumbnail, :hashcode, :filepath)";

			using (NpgsqlCommand cmd = new NpgsqlCommand(input_query, m_db_conn))
			{
				cmd.Parameters.Add("title", file.Name);
				cmd.Parameters.Add("thumbnail", imageBytes);
				cmd.Parameters.Add("hashcode", hash);
				cmd.Parameters.Add("filepath", file.FullName);

				cmd.ExecuteNonQuery();
			}
		}


		private void button1_Click(object sender, EventArgs e)
		{
			try
			{
				if (!m_sample_dir.Exists)
					throw new DirectoryNotFoundException("m_sample_dir");

				FileInfo[] files = m_sample_dir.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);

				if (files != null)
				{
					OpenDbConnection();
					StartTransaction();

					IList<string> hashcodesList = GetDatabaseHashCodes();

					if (hashcodesList != null)
					{
						foreach (FileInfo file in files)
						{
							Bitmap image = new Bitmap(file.FullName);
							byte[] imageBytes = (byte[])m_converter.ConvertTo(image, typeof(byte[]));
							string hashcode = CryptoTools.ComputeHashCode(imageBytes);

							if (!hashcodesList.Contains(hashcode))
							{
								InsertNewImage(file, imageBytes, hashcode);
								hashcodesList.Add(hashcode);
							}
						}
					}

					CommitTransaction();
				}
			}
			catch (Exception ex)
			{
				RollbackTransaction();
				Console.WriteLine(ex.Message);
			}
			finally
			{
				CloseDbConnections();
			}
		}
	}
}




My database schema:

TABLE: images
id INTEGER
title VARCHAR 255
thumbnail BYTE ARRAY
hashcode VARCHAR 255
filepath VARCHAR 255



SAMPLE FROM MY DATABASE:

1;"04112008044.jpg";"<binary data>";"MmPPpCuvYWUorBbpcF4cSUtvvnx4HCnuMOLEt+GbYRg=";"C:\SampleImagesDir\04112008044.jpg"
2;"04112008045.jpg";"<binary data>";"enNg5B5bp2UmtfdkMxtnB6U8TXion8HArNcBTTdFyEE=";"C:\SampleImagesDir\04112008045.jpg"
3;"04112008046.jpg";"<binary data>";"IwKmuXS0fIp3tDcaEHXXXLA/5oEA2MkauQ9LRgGvKA0=";"C:\SampleImagesDir\04112008046.jpg"
4;"04112008047.jpg";"<binary data>";"V7/Fr8bJIx7ggzLgg3JDbPv6CyowBDNnvZJR3eI1vEM=";"C:\SampleImagesDir\04112008047.jpg"
5;"04112008048.jpg";"<binary data>";"IprzX98HtxtLt62FLpF4nYjimz6UQzFOuiz2O9VXhrI=";"C:\SampleImagesDir\04112008048.jpg"


And of course my CryptoTools class:
using System;
using System.Security.Cryptography;

namespace ImagesApplication
{
	public static class CryptoTools
	{
		private static SHA256Managed shaEncryptor = new SHA256Managed();

		public static string ComputeHashCode(byte[] imgBytes)
		{
			byte[] hash = shaEncryptor.ComputeHash(imgBytes);
			return Convert.ToBase64String(hash);
		}

	}
}




Hope this helps...

This post has been edited by FlashM: 26 January 2010 - 04:45 PM

Was This Post Helpful? 1
  • +
  • -

#14 MarmiteX1  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 159
  • Joined: 17-October 09

Re: Problem returning a value

Posted 28 January 2010 - 12:36 PM

Hi,

Thanks for the help. Much appreciated. I had a go at it, it seems to be working. Regarding the hash, I computed a hash on byte[]array of pixels only so it doesnt take into account of the header information.

I am going to edit the header information of the image such as the title, description etc and see if i can add it to the database

I will then use the original image which had no header information set and see if the hash identical.



*Just tried to load the graphically identical image again and it doenst insert it which is good. The attempt to insert a record in the database is not being executed as expected.

Thanks again.

This post has been edited by MarmiteX1: 28 January 2010 - 02:19 PM

Was This Post Helpful? 0
  • +
  • -

#15 FlashM  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 382
  • View blog
  • Posts: 1,195
  • Joined: 03-December 09

Re: Problem returning a value

Posted 28 January 2010 - 02:34 PM

No problem. Glad it worked.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1