loop over variables and years - loops

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.

Related

Loop over a do file with regression model in Stata

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.

Package-qualified names. Differences (if any) between Package::<&var> vs &Package::var?

Reading through https://docs.perl6.org/language/packages#Package-qualified_names it outlines qualifying package variables with this syntax:
Foo::Bar::<$quux>; #..as an alternative to Foo::Bar::quux;
For reference the package structure used as the example in the document is:
class Foo {
sub zape () { say "zipi" }
class Bar {
method baz () { return 'Þor is mighty' }
our &zape = { "zipi" }; #this is the variable I want to resolve
our $quux = 42;
}
}
The same page states this style of qualification doesn't work to access &zape in the Foo::Bar package listed above:
(This does not work with the &zape variable)
Yet, if I try:
Foo::Bar::<&zape>; # instead of &Foo::Bar::zape;
it is resolves just fine.
Have I misinterpreted the document or completely missed the point being made? What would be the logic behind it 'not working' with code reference variables vs a scalar for example?
I'm not aware of differences, but Foo::Bar::<&zape> can also be modified to use {} instead of <>, which then can be used with something other than literals, like this:
my $name = '&zape';
Foo::Bar::{$name}()
or
my $name = 'zape';
&Foo::Bar::{$name}()
JJ and Moritz have provided useful answers.
This nanswer is a whole nother ball of wax. I've written and discarded several nanswers to your question over the last few days. None have been very useful. I'm not sure this is either but I've decided I've finally got a first version of something worth publishing, regardless of its current usefulness.
In this first installment my nanswer is just a series of observations and questions. I also hope to add an explanation of my observations based on what I glean from spelunking the compiler's code to understand what we see. (For now I've just written up the start of that process as the second half of this nanswer.)
Differences (if any) between Package::<&var> vs &Package::var?
They're fundamentally different syntax. They're not fully interchangeable in where you can write them. They result in different evaluations. Their result can be different things.
Let's step thru lots of variations drawing out the differences.
say Package::<&var>; # compile-time error: Undeclared name: Package
So, forget the ::<...> bit for a moment. P6 is looking at that Package bit and demanding that it be an already declared name. That seems simple enough.
say &Package::var; # (Any)
Quite a difference! For some reason, for this second syntax, P6 has no problem with those two arbitrary names (Package and var) not having been declared. Who knows what it's doing with the &. And why is it (Any) and not (Callable) or Nil?
Let's try declaring these things. First:
my Package::<&var> = { 42 } # compile-time error: Type 'Package' is not declared
OK. But if we declare Package things don't really improve:
package Package {}
my Package::<&var> = { 42 } # compile-time error: Malformed my
OK, start with a clean slate again, without the package declaration. What about the other syntax?:
my &Package::var = { 42 }
Yay. P6 accepts this code. Now, for the next few lines we'll assume the declaration above. What about:
say &Package::var(); # 42
\o/ So can we use the other syntax?:
say Package::<&var>(); # compile-time error: Undeclared name: Package
Nope. It seems like the my didn't declare a Package with a &var in it. Maybe it declared a &Package::var, where the :: just happens to be part of the name but isn't about packages? P6 supports a bunch of "pseudo" packages. One of them is LEXICAL:
say LEXICAL::; # PseudoStash.new(... &Package::var => (Callable) ...
Bingo. Or is it?
say LEXICAL::<&Package::var>(); # Cannot invoke this object
# (REPR: Uninstantiable; Callable)
What happened to our { 42 }?
Hmm. Let's start from a clean slate and create &Package::var in a completely different way:
package Package { our sub var { 99 } }
say &Package::var(); # 99
say Package::<&var>(); # 99
Wow. Now, assuming those lines above and trying to add more:
my Package::<&var> = { 42 } # Compile-time error: Malformed my
That was to be expected given our previous attempt above. What about:
my &Package::var = { 42 } # Cannot modify an immutable Sub (&var)
Is it all making sense now? ;)
Spelunking the compiler code, checking the grammar
1 I spent a long time trying to work out what the deal really is before looking at the source code of the Rakudo compiler. This is a footnote covering my initial compiler spelunking. I hope to continue it tomorrow and turn this nanswer into an answer this weekend.
The good news is it's just P6 code -- most of Rakudo is written in P6.
The bad news is knowing where to look. You might see the doc directory and then the compiler overview. But then you'll notice the overview doc has barely been touched since 2010! Don't bother. Perhaps Andrew Shitov's "internals" posts will help orient you? Moving on...
In this case what I am interested in is understanding the precise nature of the Package::<&var> and &Package::var forms of syntax. When I type "syntax" into GH's repo search field the second file listed is the Perl 6 Grammar. Bingo.
Now comes the ugly news. The Perl 6 Grammar file is 6K LOC and looks super intimidating. But I find it all makes sense when I keep my cool.
Next, I'm wondering what to search for on the page. :: nets 600+ matches. Hmm. ::< is just 1, but it is in an error message. But in what? In token morename. Looking at that I can see it's likely not relevant. But the '::' near the start of the token is just the ticket. Searching the page for '::' yields 10 matches. The first 4 (from the start of the file) are more error messages. The next two are in the above morename token. 4 matches left.
The next one appears a quarter way thru token term:sym<name>. A "name". .oO ( Undeclared name: Package So maybe this is relevant? )
Next, token typename. A "typename". .oO ( Type 'Package' is not declared So maybe this is relevant too? )
token methodop. Definitely not relevant.
Finally token infix:sym<?? !!>. Nope.
There are no differences between Package::<&var> and &Package::var.
package Foo { our $var = "Bar" };
say $Foo::var === Foo::<$var>; # OUTPUT: «True␤»
Ditto for subs (of course):
package Foo { our &zape = { "Bar" } };
say &Foo::zape === Foo::<&zape>;# OUTPUT: «True␤»
What the documentation (somewhat confusingly) is trying to say is that package-scope variables can only be accessed if declared using our. There are two zapes, one of them has got lexical scope (subs get lexical scope by default), so you can't access that one. I have raised this issue in the doc repo and will try to fix it as soon as possible.

AI help for Corona SDK

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)

can't read : variable isn't array

I have the following code :
set arr1(a1) t1
set arr2(a2) t2
set l1 {}
lappend l1 arr1
lappend l1 arr2
set arr3(a3) $l1
foreach names [array names arr3] {
set value $arr3($names)
puts "names = $names, value = $value"
foreach ar $value {
if {[array exists $ar]} {
puts "$ar is an array"
foreach {key val} [array get $ar] {
set d1 $ar($key)
puts "ar key = $key value = $val "
}
}
}
}
but when I run the tcl script it fails for the line "set d1 $ar($key)" . The error msg is 'can't read "ar(a1)": variable isn't array' . Can you please suggest what is causing the error and how do I resolve the same.
When you use the syntax $ar($key), you are looking up the key $key in the array ar and returning its value. This is how Tcl is defined to work, it's in the basic language syntax. However, you're using the ar variable to hold a scalar value, not an array (the two are completely separate; arrays aren't values, though lists and dictionaries are). That's why you're getting the error message.
To read from an array that is named in a variable, you either need to use a longer piece of syntax so that you substitute the variable name and then read from that variable (Tcl doesn't do this for you by default, since it's quite dangerous if you're not prepared for it) or you need to make an alias to the named array variable.
Double-Substitution via set
set d1 [set ${ar}($key)]
This works because $… is really (under the hood) an alias for set with a single argument. (Well, except that it doesn't actually call the command; they both call the same C API.) We use the ${...} form to limit what the initial $ uses as its variable name. Be aware that if you put an array element name in ar, you'll get odd results from this.
Aliasing an Array or an Element
upvar 0 $ar theAlias
set d1 $theAlias($key)
The upvar command links variables together, and in particular when used with 0 as its first argument, it aliases variables in the current scope. By establishing theAlias as a fixed alias to the actual array (the one named by $ar), we can then access it just like a normal array. You could also alias directly to an element:
upvar 0 ${ar}($key) theAlias
set d1 $theAlias
Note the same syntax as used with the set solution above; we want the name of the element, not to read it. (Warning: do not alias to elements of the global env array; the code that couples to the system environment variables does not work in a friendly way with aliases.)
The main issue with using upvar is that you can't turn theAlias back into a non-aliased variable (though you can retarget the alias by calling upvar again) other than by throwing away the current stack frame (trivial for a procedure body, not too hard for a namespace via namespace delete, but problematic with the global namespace as deleting that terminates the whole Tcl interpreter).

Alternative to putting an include inside a While loop

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.

Resources