This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Termanater13's profile picture

Unexpected output from function

Started by Termanater13, 16 July 2013 - 11:41 PM
Termanater13 #1
Posted 17 July 2013 - 01:41 AM
Im tring to make a way so a user can type out the color rather then supplying a number or API call for a color and I cant get it to out put the righ value.
function colorchk(color, defultcolor)
-- checks to see if color given is a number then check if its a valid color number
if type(color) == "number" then
  for i = 0, 15, 1 do
   if (2^i) == color then
	return color
   else
	return defultcolor
   end
  end
-- if color is not a number it compairs the string values for the color number
elseif type(color) == "string" then
  if color == "white" then
   return colors.white
  elseif color == "orange" then
   return colors.orange
  elseif color == "magenta" then
   return colors.magenta
  elseif color == "lightBlue" then
   return colors.lightBlue
  elseif color == "yellow" then
   return colors.yellow
  elseif color == "lime" then
   return colors.lime
  elseif color == "pink" then
   return colors.pink
  elseif color == "gray" or color == "grey" then
   return colors.gray
  elseif color == "lightGray"  or color == "lightGrey" then
   return colors.lightGray
  elseif color == "cyan" then
   return colors.cyan
  elseif color == "purple" then
   return colors.purple
  elseif color == "blue" then
   return colors.blue
  elseif color == "brown" then
   return colors.brown
  elseif color == "green" then
   return colors.green
  elseif color == "red" then
   return colors.red
  elseif color == "black" then
   return colors.black
  end
-- sets color to background color if it fails
else
  return defultcolor
end
end
if I do colorchk(1,2) I get attempt to index nil if I run it in the lua test area and 2 if I store it in a function.
but for an example If I get and output for the following
colorchk("red", 128) output: 128 (should be 16384)
colorchk(colors.red, 128) output same as above
colorchk(nil, 128) output 128 in (this case it should be 128)

this may just be a simple error in my if statments.
theoriginalbit #2
Posted 17 July 2013 - 03:18 AM
At a quick glance I cannot see the problem with your code…

Telling us what line number the "attempt to index nil" at would be nice to help…

In any case, here is some code that removes the if statements and does some easier checking. If you have any questions how it works, just ask…



--# a function to calculate n from the result of 2^n
math.log2 = function( num )
  --# we need to floor the result because of how casting a Double to an int works in Java
  return math.floor( math.log(num) / math.log(2) )
end

--# a function to round an invalid colour to a valid one
local function parseColor( col )
  --# turn the colour from binary scale to a normalized integer between 0-15 with math.log2
  --# then put it back to binary scale with 2 ^
  return 2 ^ math.log2( col )
end

local function colorchk( col, default )
  --# make sure they're giving a valid colour
  if type(default) ~= "number" and parseColor(default) ~= default then
    error("Default is not a valid color", 2)
  end

  --# if col is a string
  if type(col) == "string" then
    --# does it exist in the colours table
    if colors[col] then
      col = colors[col]
    else
      error("Col is not a valid color", 2)
    end
  end

  --# if col is a number (which is should be unless it's nil)
  if type(col) == "number" then
    --# this line corrects invalid colours to what would be displayed on the screen if the number was given to CC code
    local correctedColor = parseColor( col )
    --# make sure it's the same colour
    if correctetedColor == default then
      return correctetedColor
    else
      return default
    end
  end

  return default
end
immibis #3
Posted 17 July 2013 - 04:51 AM
The problem with the number case, at least, is this:

1  for i = 0, 15, 1 do
2   if (2^i) == color then
3        return color
4   else
5        return defultcolor
6   end
7  end


"Is the color 2^0? No, so return defultcolor"
It doesn't even get to to 2^1.
Termanater13 #4
Posted 17 July 2013 - 01:25 PM
The problem with the number case, at least, is this:

1  for i = 0, 15, 1 do
2   if (2^i) == color then
3        return color
4   else
5        return defultcolor
6   end
7  end


"Is the color 2^0? No, so return defultcolor"
It doesn't even get to to 2^1.
what if I pass a string? then that would not be the issue. I can fix the number problem by moving the else for number to just after the for loop , this would make the function pass defultcolor if the if does nothing.
albrat #5
Posted 17 July 2013 - 08:44 PM
This should work though.

1  for i = 0, 15, 1 do
2   if (2^i) == color then
3		return color
4
5
6   end
7   return defultcolor
8  end

immibis #6
Posted 17 July 2013 - 10:28 PM
Ignore the post above mine, albrat's code does exactly the same thing as your code did before, and is still wrong in exactly the same way.

Your function, as posted in the OP, works fine for strings.


It doesn't work for invalid strings, though.

I assume you want colorchk("blurp", 128) to return 128, which is easy to fix.
theoriginalbit #7
Posted 17 July 2013 - 11:42 PM
Ok I can definitely confirm that changing your code to this


if type(color) == "number" then
  for i = 0, 15 do
	if 2^1 == color then
	  return color
	end
  end
  return defaultcolor
elseif type(color) == "string" then
  --# insert code here
else
  --# insert code here
end

will make it work perfectly

I do also suggest fixing your massive if … elseif statements for your string checking to this


if colors[color] then
  return colors[color]
else
  return defaultcolor
end

will also fix the above problem posted…
Edited on 17 July 2013 - 09:43 PM
Termanater13 #8
Posted 18 July 2013 - 01:03 AM
Just the Change I mentioned in my second post in this thread fixed it. I did not have to do anything else.

Ok I can definitely confirm that changing your code to this


if type(color) == "number" then
  for i = 0, 15 do
	if 2^1 == color then
	  return color
	end
  end
  return defaultcolor
elseif type(color) == "string" then
  --# insert code here
else
  --# insert code here
end

will make it work perfectly

I do also suggest fixing your massive if … elseif statements for your string checking to this


if colors[color] then
  return colors[color]
else
  return defaultcolor
end

will also fix the above problem posted…
I will look into that change. Thanks.

Ignore the post above mine, albrat's code does exactly the same thing as your code did before, and is still wrong in exactly the same way.

Your function, as posted in the OP, works fine for strings.


It doesn't work for invalid strings, though.

I assume you want colorchk("blurp", 128) to return 128, which is easy to fix.
thanks for the heads up on that.
albrat #9
Posted 18 July 2013 - 06:54 AM
This should work though.

1  for i = 0, 15, 1 do
2   if (2^i) == color then
3		return color
4
5
6   end
7   return defultcolor
8  end


ok, 2.44am in the morning is not a good time to be posting for me. lol (what the heck was I thinking!!) I should have switched line 7 and 8 to make it end first then return defaultcolor… eurgh.. (would that work… it should).