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

Redstone bundle cable script help

Started by eddieo, 10 June 2012 - 10:08 AM
eddieo #1
Posted 10 June 2012 - 12:08 PM
Hello everyone
My Name is Ed and in my real job I do a lot of machine programming, process control and batching type systems. I haven't had any formal training in programming but have learned quite a lot on my own. I love Minecraft and computercraft is an excellent mod for other mods like redpower and powercraft etc. I am currently working on a program that will poll all the wires in a bundle and give its status. If someone would please look at what I've written and show me how to use maybe a table and loops to polish it up. Also maybe show me how to have it change sides or poll the sides to see which has a bundle then test it for status. It does work as is but I think someone with a little more knowledge than me could make it look better.
Please note I know I didn't add all the colors it would have been to long :(/>/>


function cls()
term.clear()
term.setCursorPos(1,1)
end

function startdisplay()
display = peripheral.wrap("top")
display.setTextScale(2)
display.clear()
display.setCursorPos(1,1)
end

function testbundleback()
cwhite = rs.testBundledInput("back", 1) – white true = on False = off
corange = rs.testBundledInput("back", 2) – orange
cmagenta = rs.testBundledInput("back", 4) – magenta
clightBlue = rs.testBundledInput("back", 8) – lightBlue
cyellow = rs.testBundledInput("back", 16) – yellow
clime = rs.testBundledInput("back", 32) – lime
cpink = rs.testBundledInput("back", 64) – pink
cgrey = rs.testBundledInput("back", 128) – grey
clightgrey = rs.testBundledInput("back", 256) – light-grey
ccyan = rs.testBundledInput("back", 512) – cyan
cpurple = rs.testBundledInput("back", 1024) – purple
cblue = rs.testBundledInput("back", 2048) – blue
cbrown = rs.testBundledInput("back", 4096) – brown
cgreen = rs.testBundledInput("back", 8192) – green
cred = rs.testBundledInput("back", 16384) – red
cblack = rs.testBundledInput("back", 32768) – black
end

for i=1,10 do
cls()
startdisplay()
testbundleback()
display.setCursorPos(1,1)
display.write("Test ")
display.write(i)

if cwhite == true then
[indent=1]display.setCursorPos(1,2)[/indent]
[indent=1]display.write("White is On")[/indent]
else
[indent=1]display.setCursorPos(1,2)[/indent]
[indent=1]display.write("White is Off")[/indent]
end
if corange == true then
[indent=1]display.setCursorPos(1,3)[/indent]
[indent=1]display.write("Orange is On")[/indent]
else
[indent=1]display.setCursorPos(1,3)[/indent]
[indent=1]display.write("Orange is Off")[/indent]
end
if cmagenta == true then
[left]display.setCursorPos(1,4)[/left]
[indent=1]display.write("Magenta is On")[/indent]
else
[indent=1]display.setCursorPos(1,4)[/indent]
[indent=1]display.write("Magenta is Off")[/indent]
end

sleep(2)
end
startdisplay()
display.write("Test Complete")
my_hat_stinks #2
Posted 10 June 2012 - 06:02 PM
Use
 
tags around your code so we can see what's happening :(/>/>

A for loop down the colors table should give you all the colours you need
for k,v in pairs( colors ) do
  --Code
end

But there's some functions in there you don't need, so you'll want to filter it down to the numbers only

for k,v in pairs( colors ) do
   if type(v)=="number" then
	  --Code
   end
end

Then you've got k as the colour (string), and v as the matching number
you could then save that to a table, or use it straight away
Simple :)/>/>

If you're not sure about lua tables, see here, it might help


Also, looks like you're not using any locals there
If you want a variable to stay within a script/function type "local" before you define it
ie,
local Variable = 1[/cpde] rather than [code]Variable = 1
After you've defined it for the first itme, you don't need to use local again, though
kazagistar #3
Posted 10 June 2012 - 06:26 PM
I pulled out all the magic numbers in front, refactored out the functions that didn't seem to be making the code easier to read, made it loop over a table to run the test, and used indentation to make it easy to see what is inside or outside a function. I also didn't test it yet, so it probably does not work right yet, but hopefully this helps you out.


-- Constants
MONITOR = "top"
CABLE = "back"
TESTS = 10
WAIT = 2

-- Clear screen
term.clear()
term.setCursorPos(1,1)

-- initialize display here
local display = peripheral.wrap(MONITOR)
display.setTextScale(2)

-- list of colors to display and their names, indexed by log2
local testcolors = {0="White",1="Orange",2="Magenta",3="Light Blue"}

-- translation table from booleans to On/Off
local status = {true="On",false="Off"}

-- Run a test for each number between 1 and TESTS
for i=1,TESTS do
    -- Reset screen between tests
    display.clear()
    display.setCursorPos(1,1)
    display.write("Test ")
    display.write(i)
   
    -- For each index and color name in our table, we want to print the color,
    -- get its test result, and combine it
    for index,name in pairs(testcolors) do
	    display.setCursorPos(1,2+index)
	    display.write(name.." is "..status[rs.testBundledInput(CABLE, 2^index)])
    end
   
    sleep(WAIT)
end
display.clear()
display.setCursorPos(1,1)
display.write("Test Complete")

To explain a little deeper, the line you are probably most interested in is "for index, name in pairs(testcolors) do". This is called an iterative for loop, and a lot of higher level scripting languages have this feature (lua, python, ruby, javascript) and a lot of older ones have started adding it too (java, C#, C++). Basically, instead of using an index to go though your lists, the for loop grabs each item in the list one by one and puts the contents into a variable, so you can use them directly. In lua, the above structure sets the two variables to be each key and value in the table respectively, one by one.

Tables are like lists in any other language, only they can have any number or string as their key. So to access one, I would type table[4] or table["hello"] or table[true], and it would return or set that entry in the table. You can initialize them empty by doing table={}, or prefilled as above. Go ahead and try writing a loop that scans the various sides yourself if you want by giving it a table of sides, and see what you can do?
my_hat_stinks #4
Posted 10 June 2012 - 08:07 PM
That code is… Pretty bad, to say the least

-- Constants
MONITOR = "top"
CABLE = "back"
TESTS = 10
WAIT = 2
Why are these global? They are only used within this script

-- initialize display here
local display = peripheral.wrap(MONITOR)
display.setTextScale(2)
What about failsafes? What if it doesn't find a monitor there?

-- list of colors to display and their names, indexed by log2
local testcolors = {0="White",1="Orange",2="Magenta",3="Light Blue"}
Isn't listing it all explicitly exactly what he wanted to avoid?

-- translation table from booleans to On/Off
local status = {true="On",false="Off"}
This simply won't work, which means the output won't work either

No, this certainly is not a good example…

Something like this is far more appropriate:
Spoiler
local Pause = 2 --Delay before it loops again
local Iterations = 10 --Number of times to loop
local pos = {cable="back", mon="top"} --Sides for the cable and monitor
local scale = 1 --Text scale for monitor

term.clear() term.setCursorPos(1,1) --Clear

local mon = peripheral.wrap( pos.mon )
if not mon then
   print("Monitor not found!")
   mon = term --Failsafe, use the screen
else
   mon.clear() mon.setCursorPos(1,1) --Clear
   mon.setTextScale( scale ) --Set the text size
   print("Testing wires\nSee Monitor ("..pos.mon..") for output")
end

local col = {}
for colour,number in pairs( colors ) do
   if type(number) == "number" then
	  col[colour] = number --Insert colour to table
   end
end

local line --Line numbering
for i=1,Iterations do
   mon.clear() mon.setCursorPos(1,1) --Clear
   mon.write("Test "..tostring(i).." on side \""..pos.cable.."\"") --Header

   line = 1 --Reset line number
   for colour,num in pairs( col ) do
	  line = line+1
	  mon.setCursorPos(1,line) --Go to line
	  local On = rs.testBundledInput( pos.cable, num ) --Test wire

	  mon.write("Colour "..colour.." is ".. (On and "On" or "Off") ) --Output to monitor
	  --[[ Note that (On and "On" or "Off") can be read as
	  if On is true then "On", otherwise "Off"
	  --]]
   end

   sleep( Pause )
end
mon.setCursorPos(1,line+1)
mon.write("Completed test successfully")
eddieo #5
Posted 10 June 2012 - 08:29 PM
After reading the suggestions i refined the code down to this

function cls()  --clears the screen
term.clear()
term.setCursorPos(1,1)  
end

local colorname = {"white", "orange", "magenta", "lightBlue","yellow", "lime", "pink", "grey",
	 "light-grey", "cyan", "purple", "blue","brown", "green", "red", "black"}

local colornum = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}

cls()

for i=1,#colornum do
status = rs.testBundledInput("back", colornum[i])
  if status == true then
   print(colorname[i]," is On")
  else
   print(colorname[i]," is Off")
  end
end

this is just a start I will take it further to include all the sides and options to omit the colors that are not being used.
also to have the information do something like inform the user that a chest is empty or full or a roaster is empty and needs fuel the uses are endless.
thanks for the help my_hat_stinks and kazagistar