i’m wanting some project stats, and getting a list of all classes would be of great value. offhand i don’t see how to do it. ideas? thanks!
@RonJeffries Would something like this help. If not I might have something else.
viewer.mode=FULLSCREEN
function setup()
project="Examples:Cargo-Bot"
lst=listProjectTabs(project)
for a,b in pairs(lst) do
str=readProjectTab(project..":"..b)
end
font("Courier")
textMode(CORNER)
dy=0
tab={}
r=listProjectTabs(project)
for a,b in pairs(r) do
str=readProjectTab(project..":"..b)
table.insert(tab,"\
")
table.insert(tab,"\
")
table.insert(tab,project.." : "..b)
b1=1
s=1
comment=false
startComment=false
while true do
s,e=string.find(str,"\
",s)
if s==nil then
break
end
s=e+1
str1=string.sub(str,b1,e)
sc1,ec1=string.find(str1,"%-%-%[%[")
if sc1 ~= nil then
startComment=true
end
--sc2,ec21=string.find(str1,"%-%-%]%]")
sc2,ec21=string.find(str1,"%]%]")
if sc2 ~= nil then
startComment=false
end
comment=false
sc3,ec3=string.find(str1,"%-%-")
if sc3 ~= nil then
comment=true
sc4,ec4=string.find(str1,"class")
if sc4~=nil and sc4<sc3 then
comment=false
end
sc5,ec5=string.find(str1,"function")
if sc5~=nil and sc5<sc3 then
comment=false
end
end
process=true
if comment or startComment then
process=false
end
if process then
s1,e1=string.find(str1,"class")
if s1~=nil then
s2,e2=string.find(str1,")")
if s2~= nil then
str1=removeSpaces(string.sub(str1,1,e2))
table.insert(tab," "..str1)
b1=e2+1
end
else
s2,e2=string.find(str1,"function ")
if s2~=nil then
s3,e3=string.find(str1,")")
if s3~= nil then
table.insert(tab," "..string.sub(str1,s2,e3))
b1=e3+1
end
end
end
if s==nil then
break
end
end
if e~=nil then
b1=e+1
end
end
end
table.insert(tab,"\
")
table.insert(tab,"\
")
table.insert(tab,"END of "..project)
end
function removeSpaces(s)
for z=1,#s do
if string.sub(s,z,z)~=" " then
return(string.sub(s,z))
end
end
end
function draw()
background(40, 40, 50)
fill(255)
for a,b in pairs(tab) do
text(b,100,HEIGHT-a*20+dy)
end
end
function touched(t)
if t.state==BEGAN or t.state==MOVING then
dy=dy+t.deltaY
if dy<0 then
dy=0
end
end
end
that’s quite nice!
yes, i was thinking i can search for “class()”, etc. was hoping for something less fragile, in runtime memory, but maybe source analysis is better. thanks!
you’re right on find, i removed the discussion
@dave1707 at the top of that program there is a loop reading tabs. Is there a purpose for that, or is it a leftover? Thanks!
@RonJeffries The listProjectTab and readProjectTab code at the very beginning isn’t needed. Those are probably leftover from when I started.
yes, thought so. today’s article is about your prog, check it out. let me know if i said anything bad.
@RonJeffries I like the article. Interesting to see how someone else would redo my code. Generally when I write something, I write something small to get it to work and then start expanding it until it does what I want. I never wrote any class code until I started playing with Codea. At work when I switched from C to C++, I was totally lost as to why anyone would want to use classes. I had newly hired programmers who learned C++ as their only language try to explain the purpose of classes to me, but for some reason it didn’t make sense. I now know the purpose, but still don’t use it that often.
Here’s the companion program to the first one. It displays two columns on the screen. The left column shows “Classes defined within “. The right column shows “Instances created within ”. The titles are at the top of each column. Not sure if this is anymore useful or useless than the first. It was just something to write when I couldn’t think of anything else to do.
-- find classes and instances of those classes
function setup()
parameter.action("list projects",listProj)
parameter.text("project")
parameter.action("search",srch)
sTab={}
dy=-80
listProj()
end
function listProj()
project=""
sTab={}
output.clear()
tab=listProjects()
for a,b in pairs(tab) do
print(b)
end
end
function srch()
s,e=string.find(project,"\
")
if s~=nil then
project=string.sub(project,1,s-1)
end
textMode(CORNER)
sTab={}
iTab={}
cls={}
tab={}
ins={}
print("Find classes")
findClasses()
for a,b in pairs(cls) do
print("Find instances in "..b)
findInstances("="..b.."(")
end
table.sort(sTab)
viewer.mode=FULLSCREEN
output.clear()
end
function draw()
background(40, 40, 50)
fill(255)
if #sTab>0 then
text("Classes defined within < tabs >",50,HEIGHT+50+dy)
text("Instances created within < tabs >",WIDTH/2,HEIGHT+50+dy)
text(project,300,HEIGHT+20+dy)
cnt=0
for _,a in pairs(sTab) do
b=tab[a]
cnt=cnt+1
text("< "..a.." >",50,HEIGHT-cnt*20+dy)
for c,d in pairs(b) do
cnt=cnt+1
text(d,50,HEIGHT-cnt*20+dy)
end
cnt=cnt+2
end
cnt=0
for _,a in pairs(sTab) do
b=iTab[a]
if b~=nil and #iTab[a]>0 then
cnt=cnt+1
text("< "..a.." >",WIDTH/2,HEIGHT-cnt*20+dy)
for c,d in pairs(b) do
cnt=cnt+1
text(d,WIDTH/2+20,HEIGHT-cnt*20+dy)
end
cnt=cnt+2
end
end
end
end
function touched(t)
if t.state==BEGAN or t.state==MOVING then
dy=dy+t.deltaY
if dy<-80 then
dy=-80
end
end
end
function findClasses()
local r=listProjectTabs(project)
for a,b in pairs(r) do
local str=readProjectTab(project..":"..b)
table.insert(tab,b)
tab[b]={}
table.insert(sTab,b)
local b1=1
local s,e=1,0
while true do
s,e=string.find(str,"\
",s)
if s==nil then
break
end
local str1=leaveSpaces(0,string.sub(str,b1,e+1))
local s1,e1=string.find(str1,"=class(",1,true)
if s1~=nil then
table.insert(tab[b]," "..string.sub(str,b1,e-1))
local s2,e2=string.find(str1,"=")
if s2~=nil then
table.insert(cls,string.sub(str1,1,e2-1))
end
end
b1=e+1
s=b1
end
end
end
function findInstances(class)
local r=listProjectTabs(project)
for a,b in pairs(r) do
local str=readProjectTab(project..":"..b)
if iTab[b]==nil then
iTab[b]={}
end
local b1=1
local s,e=1,0
while true do
s,e=string.find(str,"\
",s)
if s==nil then
break
end
local str1=string.sub(str,b1,e+1)
local str2=leaveSpaces(0,str1)
local s1,e1=string.find(str2,class,1,true)
if s1~=nil then
local s2,e2=string.find(str1,"(",1,true)
table.insert(iTab[b],leaveSpaces(1,string.sub(str1,1,e2-1)))
end
b1=e+1
s=b1
end
end
end
function leaveSpaces(nbr,str) -- nbr spaces between words in str (0 or 1)
local str1=""
local sp=0
for z=1,#str do
local c=string.sub(str,z,z)
if c~=" " then
sp=0
str1=str1..c
elseif sp<nbr then
sp=sp+1
str1=str1..c
end
end
return str1
end
cool, i’ll check it out right now!
interesting trick with leaveSpaces(0). Evil, but works. i’d have done that the hard way, i think.
@RonJeffries Enjoying your article. Nice having someone pointing out my sloppy coding which I do mostly by choice. I hate coming up with long variable names, hence my 1 or 2 character names. One thing I’d like you to mention in your writings so that everyone reading them don’t think that I’m such a terrible coder, is that I write all of my code while I’m watching TV. There’s no pre-planning for my programs and most of the time no planning in what I’m actually writing. That’s why you’ll sometimes find code that doesn’t need to be there. It was something I was trying and forgot to remove it. If it works, it goes in the code. A comment on TV will remind me of something or if I see someone make a comment on the forum, I’ll think that might be an interesting program and start writing. Anyways, I’m interested to see how well you’ll condense my code and make it more readable and understandable.
i’ll do that. it’s not bad code, as i’ve tried to say a couple of times. just not to my liking.
@RonJeffries I didn’t mean to say that you think my code is bad. Well, it is bad from a readability point of view. My meaningless variable names, and everything packed into large function. Half the time when I look a my code I don’t know what’s happening. It takes awhile to figure it out. We have different coding styles and I like yours better than mine. I write quick code, so I don’t plan it very well. I just write it to get the job done with no plans to expand on it at a later time. Interested to see how your version turns out.
@RonJeffries Liked your latest article. I also like the approach you did about removing the comments from the code before parsing thru it. The only problem is the multi line comment can take on various forms. See the example below. If there are nested multi line comments, a matching number of = can be placed between the beginning and ending square brackets. Not sure what the max number of = are. The line that would kill a normal multi line comment would be something like
a=b[c[d]] . The = in [[ works to ignore that and other multi line comments.
function setup()
--[=[
print("aaa")
b={2,4,6,8}
c={1,2,3}
d=2
--[[
print("comment 1")
print("comment 2")
--]]
a=b[c[d]]
print("a",a)
print("yy")
--]=]
end
yes. i should have mentioned that i’m consciously ignoring some cases of the multi-line thing. i don’t recall, does your original deal with those properly?
@RonJeffries My original code doesn’t deal with them. I never used the = sign with the multi line comment, so I didn’t look for it. My programs don’t usually cover all possibilities of problems, I just get them to work on normal things. A lot of my code is never seen except by me so I just code for what I need.
yes, i feel much the same, esp with tools like these
@RonJeffries Just finished reading your latest article. Two things I’d like to mention.
The first is with the multi line comments with the = signs. I don’t know how many people will nest comments, but my immediate use is trying to comment out a function that contains a line of code similar to a = b[c[d]] or something that has ]] . The ]] will mess up the multi line comment. By using the = sign in the multi line comment, you can successfully comment out a function containing that line of code.
The second has to do with my second program. When I list all the projects in the print area, if you tap on one of the project names, you’ll notice that it’s background will darken more. Then if you long press in the parameter Project text area, you’ll get a paste option. Tapping paste, that project name will be copied there. Then you’ll have to press backspace to get rid of the new line character so the project name is just one line. So you don’t have to type the name there.
Just so you know, I have a bookmark to your articles. Every now and then I just pop in and read some of what you’re doing.
yes … i haven’t needed the nested comments but i am confident the program handles them correctly now. i hadn’t thought of the copy paste but makes sense. i’m glad you check out the articles and hope you find them amusing if not valuable