Archive for the ‘Algorithms’ Category

Some images are more corrupt than others

Tuesday, August 10th, 2010

Today I tried to make a Visual FoxPro report with images of teachers and students. I did not want to store the images in tables, neither did I want to store their file names in tables. All I wanted was to use the images as they were stored in a folder on the hard disk.

As I did not get it to work I posted a cry for help here.

I use vfp9 sp2 and winxp.

The cursor for the report has two field: id and lastname.

SELECT id, lastname FROM teachers02 INTO CURSOR cur_temp
SELECT cur_temp
SET SYSMENU OFF
npages = 10
REPORT FORM report1 TO PRINTER PROMPT PREVIEW Range 1, npages
SET SYSMENU ON

In a folder I have images of the teachers named id.jpg, so the teacher with id = 3 has image 3.jpg.

In the detail band I have a textbox for the id, a textbox for the lastname, and a Picture/Ole control for the image. For the image;s control source property I have: MYUDF().

PROCEDURE MYUDF()
LOCAL cid
cid = ALLTRIM(STR((cur_temp.id)))
MESSAGEBOX(cid)
** image path
LOCAL imgpath
imgpath = app_path + 'images\'+cid+'.jpg'
** check if image exists
IF ADIR(arr_temp,imgpath) = 0
 MESSAGEBOX(imgpath + " does not exist")
 imgpath = app_path + 'images\7xx.jpg'
ELSE
 MESSAGEBOX(imgpath + " does exist")
ENDIF
&& imgpath = app_path + 'images\7xx.jpg'
MESSAGEBOX(imgpath)
RETURN imgpath

If the image does not exist the image 7xx.jpg will be shown.

I have stepped through the MYUDF and it behaves as it should, i.e. till it has executed for the first page. cid is 1, 3, and 4, and it finds out correctly if 1.jpg, 3.jpg, and 4.jpg exists or not, and the correct imgpath is returned.

However, after it has run for the first page (three images) it displays the error: Picture too big, corrupt or in wrong format.’

If I change the last lines of MYUDF to:

imgpath = app_path + 'images\7xx.jpg'
MESSAGEBOX(imgpath)
RETURN imgpath

it works perfectly, i.e. if one is happy with showing the same picture for all the teachers. :)

What am I doing wrong?

Due to Internet searches and intensive trying and failing, I found the solution. I discovered that corrupt files can be mad OK with a little bit of careful attention.

Searching the Internet I found a workaround.

Using the free IrfanView – File – Batch Conversion/Rename… I checked Batch conversion, set JPG as output format and in Options for output format unchecked all the check boxes (from what Internet told me the EXIF data should be removed). I used as input files my folder of jpg images, set Files of type to JPG and clicked Add all to have the input files ready. Four output directory I chose an empty folder. Then I clicked Start Batch and all jpgs that before was vfp-corrupt were now accepted.

Problem solved!

My udf is now simply:

PROCEDURE MYUDF()

LOCAL cid as string

cid = ALLTRIM(STR(cur_temp.id))

LOCAL imgpath as string

imgpath = app_path + ‘images\’ + cid + ‘.jpg’

** check if image exists

IF ADIR(arr_temp,imgpath) = 0

imgpath = app_path + ‘images\missing.bmp’

ENDIF

RETURN imgpath

Students with the same nick name

Sunday, August 8th, 2010

I am working on a school administration program in Visual FoxPro 9. To recognise students sometimes only the nick name is wanted. But what if two students have the same nick name? How does one tell who is who?

This code says who share the same nick name:

select nname, COUNT(id) as x from students WHERE statusid = 1 group by nname HAVING x > 1

This was the result:

Alex 3 Anna 2 Anushka 2 Ben 3 Benjamin 2 David 2 Grace 2 Harry 2 Jack 2 James 4 Jan 2 Jason 3 John 2 Kevin 3 Lily 2 Mai 2 Max 2 Nan 2 Nancy 2 Nicky 2 Nuk 2 Peter 3 Philipp 2 Ploy 3 Pop 2 Poppy 2 Sabrina 2 Sam 2 Sarah 2 Tan 2 Vanessa 2 Vishal 2

But how does one only find those who share the same nick name who are in the same tutor group.

SELECT id, nname, formid ;

FROM students as a ;

WHERE (statusid = 1 ;

AND nname in ;

(SELECT nname FROM students WHERE id <> a.id AND formid=a.formid and statusid = 1)) ORDER BY formid

The code worked like a dream:

id nname formid 457 Ben 4 458 Ben 4 297 James 5 523 James 5 194 James 12 200 James 12

There are 2 Bens in the form with id 2, 2 James in 5, and 2 James in 12.

When I extracted the nname I added the first character in the last name of those students who shared last name. For one form group it looked like this.

Luckily enough the first letter of the last name separated the students. But what if it had not? The next step of improvement is to find all who share the same nick name, give them a character from their last name, see who has the same name now, give those another character in the last name, and so on till no one shares the same name.

It should not be too difficult to program. A loop is all that is needed.

If this problem crops up in many situations one could even write a general function for field1, field2, and table1. Lo and behold, someone has probably already written one. :)

Creating algorithms at the spot

Tuesday, August 5th, 2008

JT and Sebastian were playing with clothes pegs making air planes out of them. This conversation between JT and me took place.

Me: Do you and Sebastian have the same number of pegs?
JT: No, I have more.
Me: OK. Please give one to Sebastian.
JT gave one to Sebastian.
Me: Do you have equally many now?
JT: No, I have more.
Me: OK. Please give one to Sebastian.
JT gave one to Sebastian.
Me: Do you have equally many now?
JT: No, I have more.
Me: OK. Please give one to Sebastian.
JT gave one to Sebastian.
Me: Do you have equally many now?
JT: Yes.
Me: Great!