How to use an array as arguments in a function?

Hello! 

I'm working in a analog watch face, in which there is a filled circle at the end of the hour, minute and second hands. The code was working well, until I tried to condense it and write a function to set the hand coordinates (like the analog example, provided in the SDK). Then I will only get a "Error: Not Enough Arguments Error" console response.

This is the code, working as it should:

        targetDc.fillCircle(
        	center[0] + (center[0] - 50) * Math.cos(hourHandAngle),
        	center[1] + (center[1] - 50) * Math.sin(hourHandAngle), 
        	7
        );

And there goes the function, arguments returned of it, and the console error log:

	function handAttributes(center, distance, angle, radius) {
		var attrib = new [3];
		attrib = [
			center[0] + (center[0] - distance) * Math.cos(angle),
			center[1] + (center[1] - distance) * Math.sin(angle),
			radius];
		return attrib;
	}
	
    function onUpdate(dc) {
        var width = targetDc.getWidth();
        var height = targetDc.getHeight();
        var clockTime = System.getClockTime();
        var center = [width/2, height/2];

        System.println(handAttributes(center, 50, hourHandAngle, 7));
        
        targetDc.fillCircle(handAttributes(center, 50, hourHandAngle, 7)
        );
    }

[130.000000, 50.000000, 7] <--- It seems the function is working fine, returning an array with 3 values in it.

Error: Not Enough Arguments Error

Details: Failed invoking <symbol>

I am an absolute newbie in coding in general, and I'm probably missing something silly here, but can't figure it out! I'm using the latest SDK, and using mostly the Vivoactive 3 music as a simulator. Any suggestions?

Top Replies

All Replies

  • fillCircle takes three parameters (line 18)

    dc.fillcircle(x,y,r)

    You're only passing 1 (an array with 3 values in it)

    do this:

    var x=handAttributes(center, 50, hourHandAngle, 7);

    then

    dc.fillCircle(x[0],x[1],x[2]);

  • You could also do

    dc.fillCircle(handAttributes(center, 50, hourHandAngle, 7)[0],handAttributes(center, 50, hourHandAngle, 7)[1], handAttributes(center, 50, hourHandAngle, 7)[2]);

    but then you would be calling handAttributes() three times, recalculating everything.  Only calculating the values once is more efficient.

  • As pointed out, you have to unpack the array returned from your handAttributes function. Some languages support unpacking sequences into parameter lists:

    >>> def f(a, b, c):
    ...     print('a={} b={} c={}'.format(a, b, c))
    ... 
    >>> array = [ 1, 2, 3 ]
    >>> f(*array)
    a=1 b=2 c=3
    >>> tuple = ( 4, 5, 6 )
    >>> f(*tuple)
    a=4 b=5 c=6

    Unfortunately, MonkeyC doesn't support this feature. You have to do it yourself.

    One other note. Your code handAttributes is allocating an array for attrib twice. You can save yourself one allocation by making one of these small tweaks:

    function handAttributes(center, distance, angle, radius) {
    	return [
    		center[0] + (center[0] - distance) * Math.cos(angle),
    		center[1] + (center[1] - distance) * Math.sin(angle),
        	radius
        ];
    }
    
    // or
    
    function handAttributes(center, distance, angle, radius) {
    	var attrib = new [3];
    	attrib[0] = center[0] + (center[0] - distance) * Math.cos(angle);
    	attrib[1] = center[1] + (center[1] - distance) * Math.sin(angle);
        attrib[2] = radius;
    	return attrib;
    }