I have a chunk of PHP code that I'd like to include on a number of different pages but be able to update in one location (hence my use of an include file). However, the chunk of code needs to appear inside a while loop -- specifically inside a while loop that is echoing out MySQL rows.
However, there are roughly 200 rows in the MySQL query I'm echoing, so having an include in the loop really slows things down. I've tried making what's in the include file a function, like shown below, then including once at the top of the page and referencing the function inside the loop, but it it doesn't seem to work (I just don't get any data in the variables I'm setting, etc.)
How does one put a chunk of code inside a loop without using include?
Thanks very much.
function CYCalc()
{
// If the company's current fiscal quarter
// is equal to the current calendar quarter,
// use the company's fiscal years as calendar years
if ($UniverseResult[CurQ] == "Q1" && $UniverseResult[CurYear] == "2012") {
$C2011Sales = number_format($UniverseResult[SalesYear2]/1000000,1);
$C2012Sales = number_format($UniverseResult[SalesYear3]/1000000,1);
$C2011EPS = $UniverseResult[EPSYear2];
$C2012EPS = $UniverseResult[EPSYear3];
}
}
Remember PHP's scoping rules. Variables defined in the global scope are not visible inside functions unless you explicitly declare them as global within the function:
<?php
$x = 7;
function y() {
echo $x; // undefined
}
function z() {
global $x;
echo $x; // 7
}
function a($x) {
echo $x; // 7
}
For your CYCalc() to work, you'd need to declare $UniverseResult global as per z() above, or pass it in as a parameter as per a() above.
Related
I am estimating several regressions in Stata with the same functional form. I'd like to perform my estimations by looping over a .do file that contains the "program" for my regression. The (simplified) code I have attempted is as follows:
local vars waz haz whz cough fever diar
foreach depvar of local vars {
forvalues i = 10(5)15 {
do "Regression.do"
}
}
Where "Regression.do" is this code:
reg `depvar' distance_`i'
est store `depvar'_`i'
Stata returns an error message: "Error: last estimates not found." How can I amend my code so that I can execute the .do file in a loop?
Simplifying your code as suggested by #Nick Cox is best, however, to answer your question the solution is below:
main do-file
local vars waz haz whz cough fever diar
foreach depvar of local vars {
forvalues i = 10(5)15 {
do "Regression.do" "`i'"
}
}
regression.do
reg `depvar' distance_`1'
est store `depvar'_`1'
The do-file is hardly needed in this example. Using its contents directly avoids the problem that local macros are ... local ... meaning only visible within the same program space.
foreach depvar in waz haz whz cough fever diar {
foreach num in 10 15 {
reg `depvar' distance_`num'
est store `depvar'_`num'
}
}
is one way to simplify your code. although that is partly a matter of taste.
See also https://journals.sagepub.com/doi/pdf/10.1177/1536867X20931028 for more on what bit you.
I see a lot of Stata code which puts content into a local macro only to take it out again just once and immediately. This is like "I have a pen. I put it in a box. I take it out of the box. I now have my pen again." Sometimes the box (meaning, local macro) is a good idea; but other times there is no gain to writing the code that way.
You do flag that you have fuller code, which is fair enough, and at some point having a do-file and passing arguments to it may appear to be better style.
As partly explained in the answer of #24thDan, you can pass arguments to a do-file, which is how a local macro's contents can become visible to and within a do-file.
You can rewrite your do-file this way
* regression.do
args depvar num
regress `depvar' distance_`num'
est store `depvar'_`num'
and within your loops call it with
do regression.do `depvar' `num'
As in the other answer, you can within the do-file refer to the first, second, ... arguments numbering them as 1, 2, and so on, but I recommend the use of args to map those local macros to other macros with intelligible names.
I am trying to generate variables in the form varyear based on a list of original variables with random variable names. For example, based on the first variable E4252, I'll get a new variable called var2013; then var2011,
var2009, var2007 and so on to var1999.
Here is what I wrote, but didn't work:
local myvar "E4252 E5219 E4693 E4102 E2803 E2046 E1462 E1079"
local i = 2015
foreach x of myvar {
local i = `i' - 2
gen var`i' = `x'
}
You need to tell Stata that myvar is a local in your loop:
local myvar "E4252 E5219 E4693 E4102 E2803 E2046 E1462 E1079"
local i = 2015
foreach x of local myvar {
local i = `i' - 2
gen var`i' = `x'
}
Alternatively, you can refer the contents of the local directly:
foreach x in `myvar' {
...
}
Some alternatives to #Dimitriy's good answer.
For a short list of names like this, you can be direct and avoid a local macro. It's just an extra level of indirection.
Why generate at all? It sounds as if you are adopting a better set of variable names, so rename saves you having the same information repeated in two sets of variables.
I'd start with the first year used, i.e. 2013 not 2015.
local i = 2013
foreach x in E4252 E5219 E4693 E4102 E2803 E2046 E1462 E1079 {
rename `x' var`i'
local i = `i' - 2
}
You could just use rename all at once.
rename (E4252 E5219 E4693 E4102 E2803 E2046 E1462 E1079) (var2013 var2011 var2009 var2007 var2005 var2003 var2001 var1999)
There is a simple trade-off here.
The last code example is simple and direct and it's easy to see at a glance what has been done.
But if you don't play with loops, you never learn good technique.
I wouldn't want to type out any (much) longer list of names, but people are going to have different thresholds here. Also, you may have other problems of the same type, which makes mastering loop technique more important.
I've created a game which loops through a table of properties to create enemies to place on screen. The created enemies are stored in a variable called "baddie", and things like their x and y value are determined by the properties I gave them in the table. Currently, "baddie" creates 3 enemies at varying spots on screen. It looks something like this.
for i=1, #level[section]["enemies"] do
local object = level[section]["enemies"][i]
baddie = display.newSprite(baddieSheet, baddieData)
baddie.anchorX = 0.5
baddie.anchorY = 1
baddie.x = object["position"][1]; baddie.y = object["position"][2];
baddie.xScale = -1
baddie.myName = "Baddie"
baddie.health = 15
baddie:setSequence("standrt"); baddie:play()
physics.addBody(baddie, "dynamic", {radius=22, density=0.1, friction=10.0, bounce=0.0})
baddie.isFixedRotation = true
enemyGroup:insert(baddie)
end
I then inserted all of the created instances stored in the baddie variable, into a display group called "enemyGroup."
Now here's my question. I'm working on my game's AI and storing it all in an enterFrame listener. I want to make a "True/False" flag called "inRange." When the enemy's x position is within 20 pixels of the player's x, inRange = true. When it's true, the enemy will attack him. But I haven't figured out a way to make the inRange flag check for each individual enemy, instead of all of them.
I was thinking of something like,
for i = 1, enemyGroup.numChildren do
enemyGroup[i].widthBetween = enemyGroup[i].x - sprite.x
if enemyGroup[i].widthBetween <= 20 and enemyGroup[i].widthBetween >= -20 then
enemyGroup[i].inRange = true
else
enemyGroup[i].inRange = false
end
end
But the issue is, enemyGroup[i].inRange is a local value and I can't call for it in outside of the loop or in other functions. This is obviously problematic, because in another function I want to have each individual enemy punch, roll, jump, etc when their individual inRange property is true. Is there a way I can store enemyGroup[i].inRange so that I can call for it whenever?
Sorry if this question is confusing. It's been a struggle to word it.
I'm not sure why this isn't working for you. enemyGroup[i].inRange is not local, its an attribute of the object at enemyGroup[i]. It should be avalble anywhere you can access enemyGroup[i].
Personally I would have not used a display.newGroup() for this, instead I would have just created an array/table that's scoped for the whole scene.
local baddies = {}
then in your loop:
--enemyGroup:insert(baddie) instead of this, do this:
baddies[#baddies + 1] = baddie
Then you have a table that you can loop over, but it's really more code style than functionality. As long as your enemyGroup is scoped at a high enough level that any function that the scene can see.
you should create a file in the structure below:
module(..., package.seeall)
enemyGroup = {}
and in all your files where you want to use this table, first of all require this file( assume you named this file enemies.lua):
local enemiesArray = require "enemies"
-- somewhere in your code:
enemiesArray.enemyGroup[i].isRange = true -- or whatever you like to do
there is one better option for you to use _G variable. when you store an object to _G you can access that wherever you want( like the famous design pattern Singleton ). just set the variable one time and use it anywhere and as much as you want. for example:
-- in one file you set enemy table:
_G.enemies = enemyGroup
-- somewhere else in nowhere :)
print(_G.enemies.isRange)
I'm running a script that extracts links from a webpage but the webpage outputs a different number of correct urls everytime something on the webpage changes, which happens very often for the purpose of this script. My 'constraint' is the $tco it makes sure that the urls onyl start with http://t.co
$tconike = (grep /$tco/, #links);
print "$tconike\n";
This determines the number of urls that satifsy my needs, this prints '2'.
my #found = (grep /$tco/, #links);
if (#found) {
for my $url (#found) {
print "$found[0]\n";
print "$found[1]\n";
}
}
This prints the accual urls in this case there is two. ex
http://t.co/5
http://t.co/r
Can I have the perl script recignize the number of urls starting with t.co and add more varaibles (the $found[0] and $found[1]) based on what $tconike (the number of useable urls) outputs?
I NEED TO ACCESS THE URLS LATER WHEN I USE WWW::Mechanize TO FILL OUT FORMS ON THE URLS.
As choroba said, you don't need to do that. You can just use print "$url\n" instead of each array element individually, because it will call the block of the loop for each element inside #found.
If you still want more variables based on the number of urls, you could do the following. But this is not code that you should use in production. In fact, don't use it. It works, but it's intended as a joke. :)
my $code;
my #found = (grep /$tco/, #links);
if (#found) {
for (my $i=0; $i<= $#found; $i++) {
$code .= q{print "$found[$i]\n"} . qq{\n};
}
eval $code for #found; # this is very evil
}
I run Lua scripts inside c application in a separate task, I added a feature to check on the status of the running script if it's still running or completed.
I want to add some info in case of running script, I want to add the percentage executed from the running script, does Lua support this info by any mean.
I tried to use the info reported in Lua_debug, but it doesn't look to be correct (Like currentlin, definedline), I need the percentage over the whole script not just for a specific function.
You could set a debug hook and listen to the hook events:
Ideone
local script = [[
print 'hello'
print 'world'
for i=0,3 do
local answer = 42
end
]]
local script_function = loadstring(script)
local function count_lines ()
local count = 0
for k,v in script:gmatch '\n' do count = count+1 end
return count
end
local function trace(total_lines)
local max_last_line = 0
return function(info,line_number)
if line_number > max_last_line then
print(tostring(line_number/total_lines*100)..'%')
max_last_line = line_number
end
end
end
local lines = count_lines()
local thread = coroutine.create( script_function )
debug.sethook(thread, trace(lines), "l")
coroutine.resume(thread)
output:
20%
hello
40%
world
60%
80%
100%
However, it is to mention that it's still quite hard to get meaningful numbers from such a progress report - if you organize your code and the only statement at the end is the call to some kind of main, the progress will be 100%, whereas the number wouldn't represent anything useful. You could also track the lines and measure coverage, but naturally, 100% coverage is not something that you normally have during an execution run. You could also try to build a system for progress reporting and call a function like
ReportProgress( tasks / all_tasks )
which would be bound to C and would generate the necessary progress update