How do I get a random number in template toolkit? - template-toolkit

I want to get a random number using template toolkit. It doesn't have to be particularly random. How do I do it?

Hmm, you might have issues if you don't have (or cannot import) Slash::Test.
From a "vanilla" installation of TT, you can simply use the Math plugin:
USE Math;
GET Math.rand; # outputs a random number from 0 to 1
See this link in the template toolkit manual for more information on the Math plugin and the various methods.
Update: Math.rand requires a parameter. Therefore to get a random number from 0 to 1, use:
GET Math.rand(1);

From this post at Slashcode:
[slash#yaz slash]$ perl -MSlash::Test -leDisplay
[%
digits = [ 0 .. 9 ];
anumber = digits.rand _ digits.rand _ digits.rand;
anumber;
%]
^D
769

Related

Lua Patterns - World of Warcraft Vanilla

I'm trying to get some data from the chat of the game but I can't figure out the pattern.
It's for an AddOn for a World of Warcraft Vanilla (private server).
gsub function:
http://wowprogramming.com/docs/api/gsub
http://wowwiki.wikia.com/wiki/API_gsub
I have been doing well with this explanation but now there's a part where I have something like this:
variable = gsub(string, "([%d+d]+)?...", "")
I don't know what the pattern should be since the string can be like one the following examples:
2d17h6m31s
1d8h31m40s
22h40m4s
8h6m57s
5m25s
37s
The "([%d+d]+)?" is actually multiple attempts of mine put in together.
I did read about the magic characters ( ) . % + - * ? [ ^ $ but there's still some that I don't understand. If I could get a simple resume explanation it would be great!
The important part of how the chat looks like:
Edit (ktb's comment):
Question: How can I take the full "99d23h59m59s" (^(.*s) didn't did the trick)?
In 99d23h59m59s, the 99 can be from 1 to 99 and it always has a d right after but it's optional if there's actually a <number>d or not. Then the same to <number>h (number's range goes from 1 to 24), <number>m (number's range goes from 1 to 59). There's always a ago in the end.
Update:
/run for key in pairs(string)do ChatFrame1:AddMessage(key)end
With that command I got all the functions's names of string.functionName(), here's the list:
string.sub()
string.gfind()
string.rep()
string.gsub()
string.char()
string.dump()
string.find()
string.upper()
string.len()
string.format()
string.byte()
string.lower()
Information update:
Unlike several other scripting languages, Lua does not use POSIX regular expressions (regexp) for pattern matching. The main reason for this is size: A typical implementation of POSIX regexp takes more than 4,000 lines of code. This is bigger than all Lua standard libraries together. In comparison, the implementation of pattern matching in Lua has less than 500 lines. Of course, the pattern matching in Lua cannot do all that a full POSIX implementation does. Nevertheless, pattern matching in Lua is a powerful tool and includes some features that are difficult to match with standard POSIX implementations.
Source.
Unlike some other systems, in Lua a modifier can only be applied to a character class; there is no way to group patterns under a modifier. For instance, there is no pattern that matches an optional word (unless the word has only one letter). Usually you can circumvent this limitation using some of the advanced techniques that we will see later.
Source.
I can't find the "advanced techniques" told in the quote above. I only found this which I'm not sure yet.
function get_time_stamp(str)
local s,m,h,d = string.match(str:reverse(),"oga s(%d*)m?(%d*)h?(%d*)d?(%d*)")
return d and d:reverse() or 0, h and h:reverse() or 0, m and m:reverse() or 0, s and s:reverse() or 0
end
local day,hour,minute,second = get_time_stamp("2d17h6m31s ago")
print (day,hour,minute,second) -- output: 2 17 6 31
day,hour,minute,second = get_time_stamp("5m25s ago")
print (day,hour,minute,second) -- output: 0 0 5 25
If you are wondering why I use reverse, it's because we know for sure second will always exist but the others won't, if we don't use reverse then we won't know what order the numbers are in when output by string.match. Here is example what I mean, if you did local d,h,m,s = string.match("5m25s ago","(%d*)d?(%d*)h?(%d*)m?(%d+)s ago") Then print(d,h,m,s) would say that days was 5 and seconds were 25. In reverse we know with absolute certainty the order of output.
I ran into the same pattern limitations several years ago with a WoW addon. It took a bit of searching, but I dug up my parsing function.
parse_duration.lua
--
-- string:parseDuration() - parse a pseudo ISO-8601 duration of the form
-- [nd][nh][nm][ns], where 'n' is the numerical value of the time unit and
-- suffix designates time unit as follows: 'd' - days, 'h' - hours,
-- 'm' - minutes, and, 's' - seconds. Unspecified time units have a value
-- of 0.
--
function string:parseDuration()
local ts = {d=0, h=0, m=0, s=0}
for v in self:lower():gfind("%d+[dhms]") do
ts[v:sub(-1)] = tonumber(v:sub(1,-2))
end
return ts
end
The following tests your sample data.
duration_utest.lua
require "parse_duration"
local function main()
local testSet = {
"2d17h6m31s ago something happened",
"1d8h31m40s ago something happened",
"22h40m4s ago something happened",
"8h6m57s ago something happened",
"5m25s ago something happened",
"37s ago something happened",
"10d6s alias test 1d2h3m4s should not be parsed"
}
for i,testStr in ipairs(testSet) do
-- Extract timestamp portion
local tsPart = testStr:match("%S+")
local ts = tsPart:parseDuration()
io.write( tsPart, " -> { ")
for k,v in pairs(ts) do
io.write(k,":",v," ")
end
io.write( "}\n" )
end
end
main()
Results
2d17h6m31s -> { m:6 d:2 s:31 h:17 }
1d8h31m40s -> { m:31 d:1 s:40 h:8 }
22h40m4s -> { m:40 d:0 s:4 h:22 }
8h6m57s -> { m:6 d:0 s:57 h:8 }
5m25s -> { m:5 d:0 s:25 h:0 }
37s -> { m:0 d:0 s:37 h:0 }
10d6s -> { m:0 d:10 s:6 h:0 }

How to combine search text with other criteria using Redis?

I successfully wrote an intersection of text search and other criteria using Redis. To achieve that I'm using a Lua script. The issue is that I'm not only reading, but also writing values from that script. From Redis 3.2 it's possible to achieve that by calling redis.replicate_commands(), but not before 3.2.
Below is how I'm storing the values.
Names
> HSET product:name 'Cool product' 1
> HSET product:name 'Nice product' 2
Price
> ZADD product:price 49.90 1
> ZADD product:price 54.90 2
Then, to get all products that matches 'ice', for example, I call:
> HSCAN product:name 0 MATCH *ice*
However, since HSCAN uses a cursor, I have to call it multiple times to fetch all results. This is where I'm using a Lua script:
local cursor = 0
local fields = {}
local ids = {}
local key = 'product:name'
local value = '*' .. ARGV[1] .. '*'
repeat
local result = redis.call('HSCAN', key, cursor, 'MATCH', value)
cursor = tonumber(result[1])
fields = result[2]
for i, id in ipairs(fields) do
if i % 2 == 0 then
ids[#ids + 1] = id
end
end
until cursor == 0
return ids
Since it's not possible to use the result of a script with another call, like SADD key EVAL(SHA) .... And also, it's not possible to use global variables within scripts. I've changed the part inside the fields' loop to access the list of ID's outside the script:
if i % 2 == 0 then
ids[#ids + 1] = id
redis.call('SADD', KEYS[1], id)
end
I had to add redis.replicate_commands() to the first line. With this change I can get all ID's from the key I passed when calling the script (see KEYS[1]).
And, finally, to get a list 100 product ID's priced between 40 and 50 where the name contains "ice", I do the following:
> ZUNIONSTORE tmp:price 1 product:price WEIGHTS 1
> ZREMRANGEBYSCORE tmp:price 0 40
> ZREMRANGEBYSCORE tmp:price 50 +INF
> EVALSHA b81c2b... 1 tmp:name ice
> ZINTERSTORE tmp:result tmp:price tmp:name
> ZCOUNT tmp:result -INF +INF
> ZRANGE tmp:result 0 100
I use the ZCOUNT call to know in advance how many result pages I'll have, doing count / 100.
As I said before, this works nicely with Redis 3.2. But when I tried to run the code at AWS, which only supports Redis up to 2.8, I couldn't make it work anymore. I'm not sure how to iterate with HSCAN cursor without using a script or without writing from the script. There is a way to make it work on Redis 2.8?
Some considerations:
I know I can do part of the processing outside Redis (like iterate the cursor or intersect the matches), but it'll affect the application overall performance.
I don't want to deploy a Redis instance by my own to use version 3.2.
The criteria above (price range and name) is just an example to keep things simple here. I have other fields and type of matches, not only those.
I'm not sure if the way I'm storing the data is the best way. I'm willing to listen suggestion about it.
The only problem I found here is storing the values inside a lua scirpt. So instead of storing them inside a lua, take that value outside lua (return that values of string[]). Store them in a set in a different call using sadd (key,members[]). Then proceed with intersection and returning results.
> ZUNIONSTORE tmp:price 1 product:price WEIGHTS 1
> ZREVRANGEBYSCORE tmp:price 0 40
> ZREVRANGEBYSCORE tmp:price 50 +INF
> nameSet[] = EVALSHA b81c2b... 1 ice
> SADD tmp:name nameSet
> ZINTERSTORE tmp:result tmp:price tmp:name
> ZCOUNT tmp:result -INF +INF
> ZRANGE tmp:result 0 100
IMO your design is the most optimal one. One advice would be to use pipeline wherever possible, as it would process everything at one go.
Hope this helps
UPDATE
There is no such thing like array ([ ]) in lua you have to use the lua table to achieve it. In your script you are returning ids right, that itself is an array you can use it as a separate call to achieve the sadd.
String [] nameSet = (String[]) evalsha b81c2b... 1 ice -> This is in java
SADD tmp:name nameSet
And the corresponding lua script is the same as that of your 1st one.
local cursor = 0
local fields = {}
local ids = {}
local key = 'product:name'
local value = '*' .. ARGV[1] .. '*'
repeat
local result = redis.call('HSCAN', key, cursor, 'MATCH', value)
cursor = tonumber(result[1])
fields = result[2]
for i, id in ipairs(fields) do
if i % 2 == 0 then
ids[#ids + 1] = id
end
end
until cursor == 0
return ids
The problem isn't that you're writing to the database, it's that you're doing a write after a HSCAN, which is a non-deterministic command.
In my opinion there's rarely a good reason to use a SCAN command in a Lua script. The main purpose of the command is to allow you to do things in small batches so you don't lock up the server processing a huge key space (or hash key space). Since scripts are atomic, though, using HSCAN doesn't help—you're still locking up the server until the whole thing's done.
Here are the options I can see:
If you can't risk locking up the server with a lengthy command:
Use HSCAN on the client. This is the safest option, but also the slowest.
If you're want to do as much processing in a single atomic Lua command as possible:
Use Redis 3.2 and script effects replication.
Do the scanning in the script, but return the values to the client and initiate the write from there. (That is, Karthikeyan Gopall's answer.)
Instead of HSCAN, do an HKEYS in the script and filter the results using Lua's pattern matching. Since HKEYS is deterministic you won't have a problem with the subsequent write. The downside, of course, is that you have to read in all of the keys first, regardless of whether they match your pattern. (Though HSCAN is also O(N) in the size of the hash.)

py3k print significant figures

In python3 is there a nice way to set significant figures - i.e if I have a list:
l = [2.2738257169723513, 2.2725769281387329, 2.3101812601089478]
I can use the nice new print system and do
print(*l,sep="\t")
But I'm unclear as to how to set the sigfig with out doing
m = "%.2f, %.2f, %.2f" % (l[0], l[1], l[2])
print(m)
I was wondering if there was an option to print to just say - print all floats to 2 dp?
I guess I could use a loop but that seems not very Python like
Actually, it is definitely pythonic, and it is the only way to do what you're asking. That said, you can still use a comprehension to make this more concise (in this cause a tuple, but you can use a list or use list(map():
# I've changed the name to float_list because l should not be
# used as a variable name in Python according to the standard
# style recommendations
print(*('{0:.2f}'.format(x) for x in float_list), sep="\t")

matlab indexing into nameless matrix [duplicate]

For example, if I want to read the middle value from magic(5), I can do so like this:
M = magic(5);
value = M(3,3);
to get value == 13. I'd like to be able to do something like one of these:
value = magic(5)(3,3);
value = (magic(5))(3,3);
to dispense with the intermediate variable. However, MATLAB complains about Unbalanced or unexpected parenthesis or bracket on the first parenthesis before the 3.
Is it possible to read values from an array/matrix without first assigning it to a variable?
It actually is possible to do what you want, but you have to use the functional form of the indexing operator. When you perform an indexing operation using (), you are actually making a call to the subsref function. So, even though you can't do this:
value = magic(5)(3, 3);
You can do this:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Ugly, but possible. ;)
In general, you just have to change the indexing step to a function call so you don't have two sets of parentheses immediately following one another. Another way to do this would be to define your own anonymous function to do the subscripted indexing. For example:
subindex = #(A, r, c) A(r, c); % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3); % Use the function to index the matrix
However, when all is said and done the temporary local variable solution is much more readable, and definitely what I would suggest.
There was just good blog post on Loren on the Art of Matlab a couple days ago with a couple gems that might help. In particular, using helper functions like:
paren = #(x, varargin) x(varargin{:});
curly = #(x, varargin) x{varargin{:}};
where paren() can be used like
paren(magic(5), 3, 3);
would return
ans = 16
I would also surmise that this will be faster than gnovice's answer, but I haven't checked (Use the profiler!!!). That being said, you also have to include these function definitions somewhere. I personally have made them independent functions in my path, because they are super useful.
These functions and others are now available in the Functional Programming Constructs add-on which is available through the MATLAB Add-On Explorer or on the File Exchange.
How do you feel about using undocumented features:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
or for cell arrays:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Just like magic :)
UPDATE:
Bad news, the above hack doesn't work anymore in R2015b! That's fine, it was undocumented functionality and we cannot rely on it as a supported feature :)
For those wondering where to find this type of thing, look in the folder fullfile(matlabroot,'bin','registry'). There's a bunch of XML files there that list all kinds of goodies. Be warned that calling some of these functions directly can easily crash your MATLAB session.
At least in MATLAB 2013a you can use getfield like:
a=rand(5);
getfield(a,{1,2}) % etc
to get the element at (1,2)
unfortunately syntax like magic(5)(3,3) is not supported by matlab. you need to use temporary intermediate variables. you can free up the memory after use, e.g.
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
Note that if you compare running times with the standard way (asign the result and then access entries), they are exactly the same.
subs=#(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0103
>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0101
To my opinion, the bottom line is : MATLAB does not have pointers, you have to live with it.
It could be more simple if you make a new function:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
and then use it:
value = getElem(magic(5), 3, 3);
Your initial notation is the most concise way to do this:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
If you are doing this in a loop you can just reassign M every time and ignore the clear statement as well.
To complement Amro's answer, you can use feval instead of builtin. There is no difference, really, unless you try to overload the operator function:
BUILTIN(...) is the same as FEVAL(...) except that it will call the
original built-in version of the function even if an overloaded one
exists (for this to work, you must never overload
BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
What's interesting is that feval seems to be just a tiny bit quicker than builtin (by ~3.5%), at least in Matlab 2013b, which is weird given that feval needs to check if the function is overloaded, unlike builtin:
>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

How do I format a PRINT or WRITE statement to overwrite the current line on the console screen?

I want to display the progress of a calculation done with a DO-loop, on the console screen. I can print out the progress variable to the terminal like this:
PROGRAM TextOverWrite_WithLoop
IMPLICIT NONE
INTEGER :: Number, Maximum = 10
DO Number = 1, MAXIMUM
WRITE(*, 100, ADVANCE='NO') REAL(Number)/REAL(Maximum)*100
100 FORMAT(TL10, F10.2)
! Calcultations on Number
END DO
END PROGRAM TextOverWrite_WithLoop
The output of the above code on the console screen is:
10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00
90.00 100.00
All on the same line, wrapped only by the console window.
The ADVANCE='No' argument and the TL10 (tab left so many spaces) edit descriptor works well to overwrite text on the same line, e.g. the output of the following code:
WRITE(*, 100, ADVANCE='NO') 100, 500
100 FORMAT(I3, 1X, TL4, I3)
Is:
500
Instead of:
100 500
Because of the TL4 edit descriptor.
From these two instances one can conclude that the WRITE statement cannot overwrite what has been written by another WRITE statement or by a previous execution of the same WRITE satement (as in a DO-loop).
Can this be overcome somehow?
I am using the FTN95 compiler on Windows 7 RC1. (The setup program of the G95 compiler bluescreens Windows 7 RC1, even thought it works fine on Vista.)
I know about the question Supressing line breaks in Fortran 95 write statements, but it does not work for me, because the answer to that question means new ouput is added to the previous output on the same line; instead of new output overwriting the previous output.
Thanks in advance.
The following should be portable across systems by use of ACHAR(13) to encode the carriage return.
character*1 creturn
! CODE::
creturn = achar(13) ! generate carriage return
! other code ...
WRITE( * , 101 , ADVANCE='NO' ) creturn , i , npoint
101 FORMAT( a , 'Point number : ',i7,' out of a total of ',i7)
There is no solution to this question within the scope of the Fortran standards. However, if your compiler understand backslash in Fortran strings (GNU Fortran does if you use the option -fbackslash), you can write
write (*,"(A)",advance="no") "foo"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bbar"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bgee"
call sleep(1)
write (*,*)
end
This uses the backslash character (\b) to erase previously written characters on that line.
NB: if your compiler does not understand advance="no", you can use related non-standard tricks, such as using the $ specifier in the format string.
The following worked perfectly using g95 fortran:
NF = NF + 1
IF(MOD(NF,5).EQ.0) WRITE(6,42,ADVANCE='NO') NF, ' PDFs'//CHAR(13)
42 FORMAT(I6,A)
gave:
5 PDFs
leaving the cursor at the #1 position on the same line. On the next update,
the 5 turned into a 10. ASCII 13 (decimal) is a carriage return.
OPEN(6,CARRIAGECONTROL ='FORTRAN')
DO I=1,5
WRITE(6,'(1H+" ",I)') I
ENDDO

Resources