Function

Started by Konrad, August 28, 2023, 12:14:29

Previous topic - Next topic

Konrad

Good morning

I am a very novice BlitzMax user. I wrote myself a console application for simple graphics processing. I am satisfied with the performance of the program, everything is OK. Now I wanted to sort out the algorithm. There are several loops in it. Two long ones that I would like to put in a function. Unfortunately, they do not work.

Global photo:TPixmap=(LoadPixmap(file))
...........................

For x=1 To width-1
For y=1 To wys-1
    If ReadPixel(photo,x,y)= -1 Exit
        ................................
Next
Next

There are still several loops one after another.

This is how everything works fine.


If I change to

For x=1 To width-1
For y=1 To wys-1
    If ReadPixel(photo,x+1,y+1)=-1 Pixel_1
.........................................................

Function Pixel_1()

    If ReadPixel(photo,x+1,y+1)<> -1 Exit

End function

I get the message "Identifier 'foto' not found".

Please help me correct the algorithm and explain why it should be like this.

Derron

That code is a bit ...not that easy to understand

so you want to change:
For x=1 To width-1
  For y=1 To wys-1
    If ReadPixel(photo,x,y)= -1 Exit
        ................................
  Next
Next


to
For x=1 To width-1
  For y=1 To wys-1
    If ReadPixel(photo,x+1,y+1)=-1 Pixel_1
      .........................................................
  Next
Next

Function Pixel_1()
    If ReadPixel(photo,x+1,y+1)<> -1 Exit
End function

"Pixel_1" does not accept a parameter, anything you use inside that function must be a "global". Compare this sample code:

SuperStrict
Framework Brl.StandardIO


Local x:int
For local i:int = 0 until 100
CallFunc()
Next
print x

Function CallFunc()
x = 10
End Function

It will fail to compile with "Compile Error: Identifier 'x' not found."
Change "Local x" to "Global x" and it works.


This aside your code has a simple flaw - easy to correct. The original code are two for loops - and the "exit" command will exit the "inner" for loop.
When now replacing that "exit" with a Function you cannot simply call "exit" inside the function and hope it "exits" the inner for loop. It should not compile at all (for now it throws a error when it tries to compile the generated C code, but it should better be already failing from within the blitzmax sources).


You need to do it this way:
For x=1 To width-1
  For y=1 To wys-1
    If ReadPixel(photo,x+1,y+1)=-1 Then Pixel_1();Exit '2 commands chained together
'or
    If ReadPixel(photo,x+1,y+1)=-1
      Pixel_1()
      Exit
    EndIf
      .........................................................
  Next
Next

Function Pixel_1()
'...
End function


bye
Ron

Midimaster

#2
As I do understand him, he wants not to exit already when the first condition is TRUE but add a second query.... so... why not this way:


....
For Local x:Int =1 Until width
    For Local y:Int=1 Until Wys
        If ReadPixel(photo,x,y)= -1
            If ReadPixel(photo,x+1,y+1)=-1
                Exit
            EndIf
        EndIf
        ' here come your additional code lines
        '..........
    Next
Next
....

And now in a combination with a function:

SuperStrict
Global Width:Int = 1234
Global Wys:Int   =  123
Global X:Int, Y:Int
Global File:String="test.png"

Global photo:TPixmap = LoadPixmap(File)
'...........................
For X=1 Until width
    For Y=1 Until Wys
        If PixelProcess() Then Exit
    Next
Next

Function  PixelProcess:Int()
    If ReadPixel(Photo, X, Y)= -1
        If ReadPixel(Photo, X+1, Y+1)<> -1
            Return True
        EndIf
    EndIf
    ' here come your additional code lines
    '..........
    ' last code line need to return something:
    Return False
End Function

@Konrad: We would need more code to understand what you plan to do. In your example a function makes no sense, because it contains only one code line
...crossing the alps with my bike at the moment

Konrad

Thank you for your answer

So far I had this:
For x=1 To width-1
  For y=1 To wys-1
    If ReadPixel(photo,x,y)= -1 Exit
    20 more lines like this
Execute WritePixel
  Next
Next

I would like it like this:

For x=1 To width-1
  For y=1 To wys-1
    If ReadPixel(photo,x,y)<>-1 Pixel_1
  Next
Next

Pixel_1 function
If ReadPixel(photo,x,y)= -1 Exit -
and here's where the compilation error occurs -
I get the message "Identifier 'photo' not found"
next 20 lines
execute WritePixel

End Function

And yet at the beginning of the program I have
Global photo:TPixmap=(LoadPixmap(file))
and without using the function the program works fine.

Derron

Re-read my reply ... I already explained your issue ("exit" inside the function).

TLDR: you cannot simply "exit" inside a function call instead straight in the loop


bye
Ron

Midimaster

#5
@Konrad
Did my second example not help you? I showed you a way to integrate a EXIT-possibility into the function.

The functions needs to return a FLAG, and the For/Next-loop can react on this:

For y=1 Until Wys
        If PixelProcess() =TRUE Then Exit
    Next
Next

Function  PixelProcess:Int()
    If ReadPixel(photo,x,y)= -1 Then Return TRUE
    Return False
End Function

The function PixelProcess() returns values. In case of -1 it returns TRUE, in case of nothing happened it returns FALSE. This flag is observed by the For/Next-loop and leads to th EXIT.

As you ee in my example code: In functions the EXIT needs to be replaced by a RETURN. This means the function reports something back to the main loop. The main loop receives this answer and can react on this.

Advise:
Please use the CODE-Tag in the forum to format BASIC code in a box. You can click in in the text-editor
This is code
You need not to send the same snipplet again! If we ask for further informations we mean FURTHER INFORMATONS!


Photo Bug

As I see you already made your variable photo GLOBAL. This is correct and this should not cause an error message. But as you only sent ugly snipplets of your code we cannot see, whether there is perhaps a second problem. Please send your examples carefully and complete, so that you can be helped.
...crossing the alps with my bike at the moment

TomToad

Your example as posted doesn't make sense to me.  Neither "working" version, nor "non-working" version.  I tried compiling your example in BlitzMax and cannot replicate your error (I do get a "Exit not in Loop" error which Darron already mentioned to you, but cannot get a "Identifier photo not found" error while photo is Global). This tells me that this is not your actual code, and are instead typing up an "example" for us.  If you don't want to give us the code you have,  you can always try typing a short version into BlitzMax, try compiling it to verify you get the same error, then post the short version here.  Be sure to try it on your computer first, as it doesn't help anyone if you cut out the lines that contain the actual errors.

Doing things this way will give you advantages other than keeping your project secret.  Often, the compiler is able to give you better error reporting on shorter code.  Shorter code is easier for us to read and so track down the error for you.  Also, at least in my experiences, 90% of the time I edit the code for posting here, I find the error on my own.

First things first, fix your problem with the Exit command as both Derron and Midimaster have mentioned.  If you still have problems, then post here.  Be sure to use code tags {code}MyCode....{/code} (replace the {} with []) or click the code icon above (looks like a page with <> on it, or you can just hover the mouse over the icon until the hint pops up, look for the one that says "Code").  That will help make the code more readable for us.

------------------------------------------------
8 rabbits equals 1 rabbyte.