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

Store Program

Started by grand_mind1, 20 January 2013 - 08:16 AM
grand_mind1 #1
Posted 20 January 2013 - 09:16 AM
So I wrote a store program where you have a floppy disk with some "money" on it and you can put it into a drive at a shop and buy things. Unfortunately I have recently been getting an error that I cannot solve.
This is my code:

local money = 100
local coffeepr = 5
local cookiepr = 3
rednet.open("back")
term.clear()
term.setCursorPos(1, 1)
sleep(.25)
print("What would you like to do?")
print("-------------   ")
print("Buy			 ")
print("-------------   ")
print("Check Balance   ")
print("-------------   ")
print("Help		    ")
term.setCursorPos(1, 9)			
input=read()
if input == "Check Balance" then
    print("You have ", money ," dollars")
    sleep(3)
    shell.run("credit")
elseif input == "Help" then
  print("Automated Store Vendor by Grand_Panda!")
  print("This system is very straight forward ")
  print("when it comes to using and setting up.")
  print("By typing 'edit credit' you can edit ")
  print("the prices and the menu. Even this help ")
  print("menu! If you are a customer then everything ")
  print("is pretty much layed out for you! Just put ")
  print("in your credit card-floppy disk- and select ")
  print("your items!")
  sleep(20)
  shell.run("credit") 
  function Buy()
	  term.clear()
	  term.setCursorPos(1, 1)
	  print("What would you like to buy?")
	  print("						   ")
	  print("Coffee...........$",coffeepr)
	  print("Cookie...........$",cookiepr)
	  print("						   ")
	  print("						   ")
	  print("						   ")  
	  print("						   ")
	  print("Back					   ")	
	  term.setCursorPos(1, 11)
	  input = read()
	  if input == "Coffee" then
	    rednet.send(40, "Coffee")
	    local file = fs.open("disk/creditc","r")
	    local contents = file:readAll()
	    rednet.send(40, contents)
	    redstone.setBundledOutput("back", colors.white)
	    money = money-coffeepr
	    print("You have purchased a Coffee!")
	    print("You now have ", money ," dollars")
	    sleep(2)
	    Buy()
	  elseif input == "Cookie" then
	    rednet.send(40, "Cookie")
	    money = money-cookiepr
	    print("You have purchased a Cookie!")
	    print("You now have ", money ," dollars")
	    sleep(2)
	    Buy()
	  elseif input == "Back" then
		  shell.run("credit")
	  else
	    print("Command not recognized!")
	    sleep(1)
	    Buy()
	  end
  end
elseif input == "Buy" then
  Buy()<--------------------------------------------------------RIGHT HERE!
end
I keep getting 'attempt to call nil' on line 75. I used to have it above the function buy, I thought this was the problem so I moved it below but it still doesn't work. If someone could please tell me what I am doing wrong that would be great.
Thanks! :D/>
TheOddByte #2
Posted 20 January 2013 - 09:18 AM
Can you please post what error you r getting?
It's much easier to help then.

EDIT: Nevermind just saw it…
mibac138 #3
Posted 20 January 2013 - 09:18 AM
1.

print("You have ", money ," dollars")
is wrong you have to set it like this:

print("You have "..money.." dollars")

this one too!

print("Coffee...........$",coffeepr)
print("Cookie...........$",cookiepr)
you have to change it too!

print("Coffee...........$"..coffeepr)
print("Cookie...........$"..cookiepr)

@Edit if (for example) money is 1 and i want to buy cookie then it gives it me :P/> "Repaired":


		  if input == "Coffee" then
		    rednet.send(40, "Coffee")
		    local file = fs.open("disk/creditc","r")
		    local contents = file:readAll()
		    if money >= coffepr then money = money-coffepr
		    rednet.send(40, contents)
		    redstone.setBundledOutput("back", colors.white)
		    print("You have purchased a Coffee!")
		    print("You now have "..money.." dollars")
		    sleep(2)
		    Buy()
		    else
		    print("You don't have enought money!")
		  elseif input == "Cookie" then
		    if money >= cookiepr then money = money-cookiepr
		    rednet.send(40, "Cookie")
		    print("You have purchased a Cookie!")
		    print("You now have "..money.." dollars")
		    sleep(2)
		    Buy()
		    else
		    print("You don't have enought money!")
		    end
ChunLing #4
Posted 20 January 2013 - 09:23 AM
Try using your help option first. That's where the Buy function gets defined, so Buy is nil until help has been used. Normally, you'd just move the function definitions to the top of the program.

Also, don't just recurse Buy like that, it will continually call itself and eventually overflow the stack. Just loop it.
Edited on 20 January 2013 - 08:25 AM
TheOddByte #5
Posted 20 January 2013 - 09:23 AM
1.

print("You have ", money ," dollars")
is wrong you have to set it like this:

print("You have "..money.." dollars")

this one too!

print("Coffee...........$",coffeepr)
print("Cookie...........$",cookiepr)
you have to change it too!

print("Coffee...........$"..coffeepr)
print("Cookie...........$"..cookiepr)

And yeah that's correct, don't know why people use ","
Since I saw that earlier today in someone elses code.
ChunLing #6
Posted 20 January 2013 - 09:28 AM
Print accepts multiple arguments and prints them all regardless of type, while concatenation will fail with certain types. I typically use the multiple arguments in print when I'm debugging or such (and might be encountering values that won't concatenate properly), but there's no really good reason not to use them otherwise.
remiX #7
Posted 20 January 2013 - 10:14 AM
1.

print("You have ", money ," dollars")
is wrong you have to set it like this:

print("You have "..money.." dollars")

this one too!

print("Coffee...........$",coffeepr)
print("Cookie...........$",cookiepr)
you have to change it too!

print("Coffee...........$"..coffeepr)
print("Cookie...........$"..cookiepr)

Don't give the people incorrect information. Using commas within prints is another way to concatenate strings.

As ChunLing said, the Buy function is defined only within the Help part, so define the Buy function outside the if block:


local money = 100
local coffeepr = 5
local cookiepr = 3
rednet.open("back")
term.clear()
term.setCursorPos(1, 1)
sleep(.25)

  function Buy()
          term.clear()
          term.setCursorPos(1, 1)
          print("What would you like to buy?")
          print("                                                  ")
          print("Coffee...........$",coffeepr)
          print("Cookie...........$",cookiepr)
          print("                                                  ")
          print("                                                  ")
          print("                                                  ")  
          print("                                                  ")
          print("Back                                      ")   
          term.setCursorPos(1, 11)
          input = read()
          if input == "Coffee" then
            rednet.send(40, "Coffee")
            local file = fs.open("disk/creditc","r")
            local contents = file:readAll()
            rednet.send(40, contents)
            redstone.setBundledOutput("back", colors.white)
            money = money-coffeepr
            print("You have purchased a Coffee!")
            print("You now have ", money ," dollars")
            sleep(2)
            Buy()
          elseif input == "Cookie" then
            rednet.send(40, "Cookie")
            money = money-cookiepr
            print("You have purchased a Cookie!")
            print("You now have ", money ," dollars")
            sleep(2)
            Buy()
          elseif input == "Back" then
                  shell.run("credit")
          else
            print("Command not recognized!")
            sleep(1)
            Buy()
          end
  end

print("What would you like to do?")
print("-------------   ")
print("Buy                       ")
print("-------------   ")
print("Check Balance   ")
print("-------------   ")
print("Help                 ")
term.setCursorPos(1, 9)                 
input=read()
if input == "Check Balance" then
    print("You have ", money ," dollars")
    sleep(3)
    shell.run("credit")
elseif input == "Help" then
  print("Automated Store Vendor by Grand_Panda!")
  print("This system is very straight forward ")
  print("when it comes to using and setting up.")
  print("By typing 'edit credit' you can edit ")
  print("the prices and the menu. Even this help ")
  print("menu! If you are a customer then everything ")
  print("is pretty much layed out for you! Just put ")
  print("in your credit card-floppy disk- and select ")
  print("your items!")
  sleep(20)
  shell.run("credit") 

elseif input == "Buy" then
  Buy()<--------------------------------------------------------RIGHT HERE!
end
grand_mind1 #8
Posted 20 January 2013 - 10:24 AM
Also, don't just recurse Buy like that, it will continually call itself and eventually overflow the stack. Just loop it.
Could you please explain this to me? I don't really understand what you mean and I really want my program to be good.
remiX #9
Posted 20 January 2013 - 11:10 AM
Recursion is when you call a function within itself.

Try this for example.

function func()
  print("hello")
  sleep(1)
  func()
end

func()

It will eventually error out because you're calling the function within itself.

You can solve this by using while true do loops and breaking the loops when you're going 'Back'

local money = 100
local coffeepr = 5
local cookiepr = 3
rednet.open("back")
term.clear()
term.setCursorPos(1, 1)
sleep(.25)

function Buy()
	while true do -- infinite loop
		term.clear()
		term.setCursorPos(1, 1)
		print("What would you like to buy?")
		print("")
		print("Coffee...........$",coffeepr)
		print("Cookie...........$",cookiepr)
		print("")
		print("")
		print("")  
		print("")
		print("Back        ")   
		term.setCursorPos(1, 11)
		input = read()
		if input == "Coffee" then
		  rednet.send(40, "Coffee")
		  local file = fs.open("disk/creditc","r")
		  local contents = file:readAll()
		  rednet.send(40, contents)
		  redstone.setBundledOutput("back", colors.white)
		  money = money-coffeepr
		  print("You have purchased a Coffee!")
		  print("You now have ", money ," dollars")
		  sleep(2)
		elseif input == "Cookie" then
		  rednet.send(40, "Cookie")
		  money = money-cookiepr
		  print("You have purchased a Cookie!")
		  print("You now have ", money ," dollars")
		  sleep(2)
		elseif input == "Back" then
		  return -- so it stops the loop, break can also be used here.
		else
		  print("Command not recognized!")
		  sleep(1)
		end
	end
end

while true do -- infinite loop
	print("What would you like to do?")
	print("-------------   ")
	print("Buy   ")
	print("-------------   ")
	print("Check Balance   ")
	print("-------------   ")
	print("Help       ")
	term.setCursorPos(1, 9)       
	input=read()
	if input == "Check Balance" then
		print("You have ", money ," dollars")
		sleep(3)
	elseif input == "Help" then
	  print("Automated Store Vendor by Grand_Panda!")
	  print("This system is very straight forward ")
	  print("when it comes to using and setting up.")
	  print("By typing 'edit credit' you can edit ")
	  print("the prices and the menu. Even this help ")
	  print("menu! If you are a customer then everything ")
	  print("is pretty much layed out for you! Just put ")
	  print("in your credit card-floppy disk- and select ")
	  print("your items!")
	  sleep(20)

	elseif input == "Buy" then
	  Buy()
	end
end
TheOddByte #10
Posted 20 January 2013 - 11:52 AM
Recursion is when you call a function within itself.

Try this for example.

function func()
  print("hello")
  sleep(1)
  func()
end

func()

It will eventually error out because you're calling the function within itself.

You can solve this by using while true do loops and breaking the loops when you're going 'Back'

local money = 100
local coffeepr = 5
local cookiepr = 3
rednet.open("back")
term.clear()
term.setCursorPos(1, 1)
sleep(.25)

function Buy()
	while true do -- infinite loop
		term.clear()
		term.setCursorPos(1, 1)
		print("What would you like to buy?")
		print("")
		print("Coffee...........$",coffeepr)
		print("Cookie...........$",cookiepr)
		print("")
		print("")
		print("")  
		print("")
		print("Back		")  
		term.setCursorPos(1, 11)
		input = read()
		if input == "Coffee" then
		  rednet.send(40, "Coffee")
		  local file = fs.open("disk/creditc","r")
		  local contents = file:readAll()
		  rednet.send(40, contents)
		  redstone.setBundledOutput("back", colors.white)
		  money = money-coffeepr
		  print("You have purchased a Coffee!")
		  print("You now have ", money ," dollars")
		  sleep(2)
		elseif input == "Cookie" then
		  rednet.send(40, "Cookie")
		  money = money-cookiepr
		  print("You have purchased a Cookie!")
		  print("You now have ", money ," dollars")
		  sleep(2)
		elseif input == "Back" then
		  return -- so it stops the loop, break can also be used here.
		else
		  print("Command not recognized!")
		  sleep(1)
		end
	end
end

while true do -- infinite loop
	print("What would you like to do?")
	print("-------------   ")
	print("Buy   ")
	print("-------------   ")
	print("Check Balance   ")
	print("-------------   ")
	print("Help	   ")
	term.setCursorPos(1, 9)	  
	input=read()
	if input == "Check Balance" then
		print("You have ", money ," dollars")
		sleep(3)
	elseif input == "Help" then
	  print("Automated Store Vendor by Grand_Panda!")
	  print("This system is very straight forward ")
	  print("when it comes to using and setting up.")
	  print("By typing 'edit credit' you can edit ")
	  print("the prices and the menu. Even this help ")
	  print("menu! If you are a customer then everything ")
	  print("is pretty much layed out for you! Just put ")
	  print("in your credit card-floppy disk- and select ")
	  print("your items!")
	  sleep(20)

	elseif input == "Buy" then
	  Buy()
	end
end
You should also have mentioned that he can exit the 'while true do'(infinite loops) by writing break
Like this:


while true do
term.clear()
term.setCursorPos(1,1)
if exit == true then
break  -- Here it Exits if exit == true
end
write("Do You Like Pepsi?:")
input = read()
if input == "Yes" or input == "yes" then
print("Great, I also like Pepsi!")
sleep(2)
exit = true
elseif input == "No" or input == "no" then
print("Shame On You!")
sleep(2)
								end
									  end



EDIT: Oh sorry just read your code an saw that you did.. Me Derp :wacko:/>
dan14941 #11
Posted 20 January 2013 - 12:09 PM
Recursion is when you call a function within itself.

Try this for example.

function func()
  print("hello")
  sleep(1)
  func()
end

func()

It will eventually error out because you're calling the function within itself.
i never get errors when i do it?
remiX #12
Posted 20 January 2013 - 12:14 PM
Recursion is when you call a function within itself.

Try this for example.

function func()
  print("hello")
  sleep(1)
  func()
end

func()

It will eventually error out because you're calling the function within itself.
i never get errors when i do it?

It takes a while… change the sleep(1) to sleep(0.1) and then it will be quicker…
TheOddByte #13
Posted 20 January 2013 - 12:17 PM
Recursion is when you call a function within itself.

Try this for example.

function func()
  print("hello")
  sleep(1)
  func()
end

func()

It will eventually error out because you're calling the function within itself.
i never get errors when i do it?

It takes a while… change the sleep(1) to sleep(0.1) and then it will be quicker…
Or even… sleep (0.0001)
Then it's super quick
PixelToast #14
Posted 20 January 2013 - 12:19 PM
Or even… sleep (0.0001)
Then it's super quick
minimum is 0.05 ;)/>
in wich case will take around 12 seconds do error
TheOddByte #15
Posted 20 January 2013 - 12:25 PM
Or even… sleep (0.0001)
Then it's super quick
minimum is 0.05 ;)/>
in wich case will take around 12 seconds do error
Does it convert itself from 0.0001 to 0.05 since I don't get an error or something when doing it,
Anyway goodnight for now since i'm pretty tired right now.. Wish I never got tired and had to sleep and just could sit and program all day and night.
ChunLing #16
Posted 20 January 2013 - 05:05 PM
Weell, there's the theoretical and then there's the practical. Sleep yeilds, and when CC is going around doing other things before getting back to your computer, it is pretty likely to take at least a world tick to get back to your program (it could take longer, like a lot longer, if you have programs on other computers that aren't written to yield very often). I don't know that yielding necessarily takes a full tick though.

To the OP's question about erroring, your function requires continued input for each recursive call. So you'll have to sit there pushing Enter for a while before you get an error…but that error is inevitable if you leave the program running long enough, and you've designed it to run continuously.

Calling the entire program again through the "Back" option is also recursion, and is actually worse because your recursing shell and your main program at the same time, then calling Buy() again…that's like a triple wham every time you do it.
grand_mind1 #17
Posted 20 January 2013 - 07:35 PM
I followed your advice and did the loops instead, but now it behaves very weirdly when trying to check the balance and also going back from the buying screen. Although very weird, I think it is actually behaving exactly how it should. When ever I run credit(the name of the program) from inside the program, it will wait for the user information from the central computer again, but the central computer is no longer expecting to be asked for user info. This causes it to just wait forever. Is there a good way to fix this?
This is the new code for the store:

rednet.open("back")
local file = fs.open("disk/creditc","r")
local contents = file:readAll()
rednet.send(40, contents)
senderId, msg = rednet.receive()
msg = tonumber( msg )
local coffeepr = 5
local cookiepr = 3
  function Buy()
    while true do
	    term.clear()
	    term.setCursorPos(1, 1)
	    print("What would you like to buy?")
	    print("						   ")
	    print("Coffee...........$",coffeepr)
	    print("Cookie...........$",cookiepr)
	    print("						   ")
	    print("						   ")
	    print("						   ")  
	    print("						   ")
	    print("Back					   ")	
	    term.setCursorPos(1, 11)
	    input = read()
	    if input == "Coffee" then
		  rednet.send(40, "Coffee")
		  redstone.setBundledOutput("back", colors.white)
		  money = money-coffeepr
		  print("You have purchased a Coffee!")
		  print("You now have ", msg ," dollars")
		  sleep(2)
		  Buy()
	    elseif input == "Cookie" then
		  rednet.send(40, "Cookie")
		  money = money-cookiepr
		  print("You have purchased a Cookie!")
		  print("You now have ", msg ," dollars")
		  sleep(2)
		  Buy()
	    elseif input == "Back" then
		    return
		    sleep(1)
	    else
		  print("Command not recognized!")
		  sleep(1)
		  Buy()
	    end
    end
  end
rednet.open("back")
term.clear()
term.setCursorPos(1, 1)
sleep(.25)
while true do
  print("What would you like to do?")
  print("-------------   ")
  print("Buy			 ")
  print("-------------   ")
  print("Check Balance   ")
  print("-------------   ")
  print("Help		    ")
  term.setCursorPos(1, 9)			
  input=read()
  if input == "Check Balance" then
	  print("You have ", msg ," dollars")
	  sleep(3)
	  shell.run("credit")
  elseif input == "Help" then
    print("Automated Store Vendor by Grand_Panda!")
    print("This system is very straight forward ")
    print("when it comes to using and setting up.")
    print("By typing 'edit credit' you can edit ")
    print("the prices and the menu. Even this help ")
    print("menu! If you are a customer then everything ")
    print("is pretty much layed out for you! Just put ")
    print("in your credit card-floppy disk- and select ")
    print("your items!")
    sleep(20)
    shell.run("credit") 
  elseif input == "Buy" then
    Buy()
  else
    print("Command not recognized!")
    sleep(1)
    shell.run("credit")
  end
end
And the code for the central computer if you need it:

rednet.open("left")
local senderId, message = rednet.receive()
if message == "Alex" then
  money = 100
  print(message)
elseif message == "David" then
  money = 20000
  rednet.send(senderId, tostring(money))
  print(message)
end

senderId, message = rednet.receive()
if senderId == 33 then
  store = "Store1"
  if message == "Coffee" then
    print("A "..message.." was bought from "..store)
  elseif message == "Cookie" then
    print("A "..message.." was bought from "..store)
  end
elseif senderId == 41 then
  store = "Store2"
else
  store = "Unknown"
end
remiX #18
Posted 20 January 2013 - 08:23 PM
Remove all shell.run("credit" codes within your code because it has an infinite loop and there is no need to run the program again.

Also, move the term.setCursorPos(1,1) term.clear() before the main loop into the main loop.
ChunLing #19
Posted 20 January 2013 - 10:14 PM
Also, remove all Buy() calls from the definition of Buy().