[%# DO NOT EDIT THIS FILE: generated from perlfaq (https://github.com/perl-doc-cats/perlfaq) -%] [%- # Used to get info from htmlify to ttree page.import({ title => "perlfaq5", section => "faq", description => "Perl Frequently Asked Questions, Perl FAQ", keywords => "perl, perl faq, perlfaq" }); perlfaq_version = 5.021011; -%]
perlfaq5 - Files and Formats
version 5.021011
This section deals with I/O and the "f" issues: filehandles, flushing, formats, and footers.
(contributed by brian d foy)
You might like to read Mark Jason Dominus's "Suffering From Buffering" at http://perl.plover.com/FAQs/Buffering.html .
Perl normally buffers output so it doesn't make a system call for every bit of output. By saving up output, it makes fewer expensive system calls. For instance, in this little bit of code, you want to print a dot to the screen for every line you process to watch the progress of your program. Instead of seeing a dot for every line, Perl buffers the output and you have a long wait before you see a row of 50 dots all at once:
# long wait, then row of dots all at once while( <> ) { print "."; print "\n" unless ++$count % 50; #... expensive line processing operations }
To get around this, you have to unbuffer the output filehandle, in this case, STDOUT
. You can set the special variable $|
to a true value (mnemonic: making your filehandles "piping hot"):
$|++; # dot shown immediately while( <> ) { print "."; print "\n" unless ++$count % 50; #... expensive line processing operations }
The $|
is one of the per-filehandle special variables, so each filehandle has its own copy of its value. If you want to merge standard output and standard error for instance, you have to unbuffer each (although STDERR might be unbuffered by default):
{ my $previous_default = select(STDOUT); # save previous default $|++; # autoflush STDOUT select(STDERR); $|++; # autoflush STDERR, to be sure select($previous_default); # restore previous default } # now should alternate . and + while( 1 ) { sleep 1; print STDOUT "."; print STDERR "+"; print STDOUT "\n" unless ++$count % 25; }
Besides the $|
special variable, you can use binmode
to give your filehandle a :unix
layer, which is unbuffered:
binmode( STDOUT, ":unix" ); while( 1 ) { sleep 1; print "."; print "\n" unless ++$count % 50; }
For more information on output layers, see the entries for binmode
and open in perlfunc, and the PerlIO module documentation.
If you are using IO::Handle or one of its subclasses, you can call the autoflush
method to change the settings of the filehandle:
use IO::Handle; open my( $io_fh ), ">", "output.txt"; $io_fh->autoflush(1);
The IO::Handle objects also have a flush
method. You can flush the buffer any time you want without auto-buffering
$io_fh->flush;
(contributed by brian d foy)
The basic idea of inserting, changing, or deleting a line from a text file involves reading and printing the file to the point you want to make the change, making the change, then reading and printing the rest of the file. Perl doesn't provide random access to lines (especially since the record input separator, $/
, is mutable), although modules such as Tie::File can fake it.
A Perl program to do these tasks takes the basic form of opening a file, printing its lines, then closing the file:
open my $in, '<', $file or die "Can't read old file: $!"; open my $out, '>', "$file.new" or die "Can't write new file: $!"; while( <$in> ) { print $out $_; } close $out;
Within that basic form, add the parts that you need to insert, change, or delete lines.
To prepend lines to the beginning, print those lines before you enter the loop that prints the existing lines.
open my $in, '<', $file or die "Can't read old file: $!"; open my $out, '>', "$file.new" or die "Can't write new file: $!"; print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC while( <$in> ) { print $out $_; } close $out;
To change existing lines, insert the code to modify the lines inside the while
loop. In this case, the code finds all lowercased versions of "perl" and uppercases them. The happens for every line, so be sure that you're supposed to do that on every line!
open my $in, '<', $file or die "Can't read old file: $!"; open my $out, '>', "$file.new" or die "Can't write new file: $!"; print $out "# Add this line to the top\n"; while( <$in> ) { s/\b(perl)\b/Perl/g; print $out $_; } close $out;
To change only a particular line, the input line number, $.
, is useful. First read and print the lines up to the one you want to change. Next, read the single line you want to change, change it, and print it. After that, read the rest of the lines and print those:
while( <$in> ) { # print the lines before the change print $out $_; last if $. == 4; # line number before change } my $line = <$in>; $line =~ s/\b(perl)\b/Perl/g; print $out $line; while( <$in> ) { # print the rest of the lines print $out $_; }
To skip lines, use the looping controls. The next
in this example skips comment lines, and the last
stops all processing once it encounters either __END__
or __DATA__
.
while( <$in> ) { next if /^\s+#/; # skip comment lines last if /^__(END|DATA)__$/; # stop at end of code marker print $out $_; }
Do the same sort of thing to delete a particular line by using next
to skip the lines you don't want to show up in the output. This example skips every fifth line:
while( <$in> ) { next unless $. % 5; print $out $_; }
If, for some odd reason, you really want to see the whole file at once rather than processing line-by-line, you can slurp it in (as long as you can fit the whole thing in memory!):
open my $in, '<', $file or die "Can't read old file: $!" open my $out, '>', "$file.new" or die "Can't write new file: $!"; my $content = do { local $/; <$in> }; # slurp! # do your magic here print $out $content;
Modules such as Path::Tiny and Tie::File can help with that too. If you can, however, avoid reading the entire file at once. Perl won't give that memory back to the operating system until the process finishes.
You can also use Perl one-liners to modify a file in-place. The following changes all 'Fred' to 'Barney' in inFile.txt, overwriting the file with the new contents. With the -p
switch, Perl wraps a while
loop around the code you specify with -e
, and -i
turns on in-place editing. The current line is in $_
. With -p
, Perl automatically prints the value of $_
at the end of the loop. See perlrun for more details.
perl -pi -e 's/Fred/Barney/' inFile.txt
To make a backup of inFile.txt
, give -i
a file extension to add:
perl -pi.bak -e 's/Fred/Barney/' inFile.txt
To change only the fifth line, you can add a test checking $.
, the input line number, then only perform the operation when the test passes:
perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt
To add lines before a certain line, you can add a line (or lines!) before Perl prints $_
:
perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt
You can even add a line to the beginning of a file, since the current line prints at the end of the loop:
perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt
To insert a line after one already in the file, use the -n
switch. It's just like -p
except that it doesn't print $_
at the end of the loop, so you have to do that yourself. In this case, print $_
first, then print the line that you want to add.
perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt
To delete lines, only print the ones that you want.
perl -ni -e 'print if /d/' inFile.txt
(contributed by brian d foy)
Conceptually, the easiest way to count the lines in a file is to simply read them and count them:
my $count = 0; while( <$fh> ) { $count++; }
You don't really have to count them yourself, though, since Perl already does that with the $.
variable, which is the current line number from the last filehandle read:
1 while( <$fh> ); my $count = $.;
If you want to use $.
, you can reduce it to a simple one-liner, like one of these:
% perl -lne '} print $.; {' file % perl -lne 'END { print $. }' file
Those can be rather inefficient though. If they aren't fast enough for you, you might just read chunks of data and count the number of newlines:
my $lines = 0; open my($fh), '<:raw', $filename or die "Can't open $filename: $!"; while( sysread $fh, $buffer, 4096 ) { $lines += ( $buffer =~ tr/\n// ); } close $fh;
However, that doesn't work if the line ending isn't a newline. You might change that tr///
to a s///
so you can count the number of times the input record separator, $/
, shows up:
my $lines = 0; open my($fh), '<:raw', $filename or die "Can't open $filename: $!"; while( sysread $fh, $buffer, 4096 ) { $lines += ( $buffer =~ s|$/||g; ); } close $fh;
If you don't mind shelling out, the wc
command is usually the fastest, even with the extra interprocess overhead. Ensure that you have an untainted filename though:
#!perl -T $ENV{PATH} = undef; my $lines; if( $filename =~ /^([0-9a-z_.]+)\z/ ) { $lines = `/usr/bin/wc -l $1` chomp $lines; }
(contributed by brian d foy)
The easiest conceptual solution is to count the lines in the file then start at the beginning and print the number of lines (minus the last N) to a new file.
Most often, the real question is how you can delete the last N lines without making more than one pass over the file, or how to do it without a lot of copying. The easy concept is the hard reality when you might have millions of lines in your file.
One trick is to use File::ReadBackwards, which starts at the end of the file. That module provides an object that wraps the real filehandle to make it easy for you to move around the file. Once you get to the spot you need, you can get the actual filehandle and work with it as normal. In this case, you get the file position at the end of the last line you want to keep and truncate the file to that point:
use File::ReadBackwards; my $filename = 'test.txt'; my $Lines_to_truncate = 2; my $bw = File::ReadBackwards->new( $filename ) or die "Could not read backwards in [$filename]: $!"; my $lines_from_end = 0; until( $bw->eof or $lines_from_end == $Lines_to_truncate ) { print "Got: ", $bw->readline; $lines_from_end++; } truncate( $filename, $bw->tell );
The File::ReadBackwards module also has the advantage of setting the input record separator to a regular expression.
You can also use the Tie::File module which lets you access the lines through a tied array. You can use normal array operations to modify your file, including setting the last index and using splice
.
-i
option from within a program? -i
sets the value of Perl's $^I
variable, which in turn affects the behavior of <>
; see perlrun for more details. By modifying the appropriate variables directly, you can get the same behavior within a larger program. For example:
# ... { local($^I, @ARGV) = ('.orig', glob("*.c")); while (<>) { if ($. == 1) { print "This line should appear at the top of each file\n"; } s/\b(p)earl\b/${1}erl/i; # Correct typos, preserving case print; close ARGV if eof; # Reset $. } } # $^I and @ARGV return to their old values here
This block modifies all the .c
files in the current directory, leaving a backup of the original data from each file in a new .c.orig
file.
(contributed by brian d foy)
Use the File::Copy module. It comes with Perl and can do a true copy across file systems, and it does its magic in a portable fashion.
use File::Copy; copy( $original, $new_copy ) or die "Copy failed: $!";
If you can't use File::Copy, you'll have to do the work yourself: open the original file, open the destination file, then print to the destination file as you read the original. You also have to remember to copy the permissions, owner, and group to the new file.
If you don't need to know the name of the file, you can use open()
with undef
in place of the file name. In Perl 5.8 or later, the open()
function creates an anonymous temporary file:
open my $tmp, '+>', undef or die $!;
Otherwise, you can use the File::Temp module.
use File::Temp qw/ tempfile tempdir /; my $dir = tempdir( CLEANUP => 1 ); ($fh, $filename) = tempfile( DIR => $dir ); # or if you don't need to know the filename my $fh = tempfile( DIR => $dir );
The File::Temp has been a standard module since Perl 5.6.1. If you don't have a modern enough Perl installed, use the new_tmpfile
class method from the IO::File module to get a filehandle opened for reading and writing.
If you're committed to creating a temporary file by hand, use the process ID and/or the current time-value. If you need to have many temporary files in one process, use a counter:
BEGIN { use Fcntl; use File::Spec; my $temp_dir = File::Spec->tmpdir(); my $file_base = sprintf "%d-%d-0000", $$, time; my $base_name = File::Spec->catfile($temp_dir, $file_base); sub temp_file { my $fh; my $count = 0; until( defined(fileno($fh)) || $count++ > 100 ) { $base_name =~ s/-(\d+)$/"-" . (1 + $1)/e; # O_EXCL is required for security reasons. sysopen $fh, $base_name, O_WRONLY|O_EXCL|O_CREAT; } if( defined fileno($fh) ) { return ($fh, $base_name); } else { return (); } } }
The most efficient way is using pack() and unpack(). This is faster than using substr() when taking many, many strings. It is slower for just a few.
Here is a sample chunk of code to break up and put back together again some fixed-format input lines, in this case from the output of a normal, Berkeley-style ps:
# sample input line: # 15158 p5 T 0:00 perl /home/tchrist/scripts/now-what my $PS_T = 'A6 A4 A7 A5 A*'; open my $ps, '-|', 'ps'; print scalar <$ps>; my @fields = qw( pid tt stat time command ); while (<$ps>) { my %process; @process{@fields} = unpack($PS_T, $_); for my $field ( @fields ) { print "$field: <$process{$field}>\n"; } print 'line=', pack($PS_T, @process{@fields} ), "\n"; }
We've used a hash slice in order to easily handle the fields of each row. Storing the keys in an array makes it easy to operate on them as a group or loop over them with for
. It also avoids polluting the program with global variables and using symbolic references.
As of perl5.6, open() autovivifies file and directory handles as references if you pass it an uninitialized scalar variable. You can then pass these references just like any other scalar, and use them in the place of named handles.
open my $fh, $file_name; open local $fh, $file_name; print $fh "Hello World!\n"; process_file( $fh );
If you like, you can store these filehandles in an array or a hash. If you access them directly, they aren't simple scalars and you need to give print
a little help by placing the filehandle reference in braces. Perl can only figure it out on its own when the filehandle reference is a simple scalar.
my @fhs = ( $fh1, $fh2, $fh3 ); for( $i = 0; $i <= $#fhs; $i++ ) { print {$fhs[$i]} "just another Perl answer, \n"; }
Before perl5.6, you had to deal with various typeglob idioms which you may see in older code.
open FILE, "> $filename"; process_typeglob( *FILE ); process_reference( \*FILE ); sub process_typeglob { local *FH = shift; print FH "Typeglob!" } sub process_reference { local $fh = shift; print $fh "Reference!" }
If you want to create many anonymous handles, you should check out the Symbol or IO::Handle modules.
An indirect filehandle is the use of something other than a symbol in a place that a filehandle is expected. Here are ways to get indirect filehandles:
$fh = SOME_FH; # bareword is strict-subs hostile $fh = "SOME_FH"; # strict-refs hostile; same package only $fh = *SOME_FH; # typeglob $fh = \*SOME_FH; # ref to typeglob (bless-able) $fh = *SOME_FH{IO}; # blessed IO::Handle from *SOME_FH typeglob
Or, you can use the new
method from one of the IO::* modules to create an anonymous filehandle and store that in a scalar variable.
use IO::Handle; # 5.004 or higher my $fh = IO::Handle->new();
Then use any of those as you would a normal filehandle. Anywhere that Perl is expecting a filehandle, an indirect filehandle may be used instead. An indirect filehandle is just a scalar variable that contains a filehandle. Functions like print
, open
, seek
, or the <FH>
diamond operator will accept either a named filehandle or a scalar variable containing one:
($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR); print $ofh "Type it: "; my $got = <$ifh> print $efh "What was that: $got";
If you're passing a filehandle to a function, you can write the function in two ways:
sub accept_fh { my $fh = shift; print $fh "Sending to indirect filehandle\n"; }
Or it can localize a typeglob and use the filehandle directly:
sub accept_fh { local *FH = shift; print FH "Sending to localized filehandle\n"; }
Both styles work with either objects or typeglobs of real filehandles. (They might also work with strings under some circumstances, but this is risky.)
accept_fh(*STDOUT); accept_fh($handle);
In the examples above, we assigned the filehandle to a scalar variable before using it. That is because only simple scalar variables, not expressions or subscripts of hashes or arrays, can be used with built-ins like print
, printf
, or the diamond operator. Using something other than a simple scalar variable as a filehandle is illegal and won't even compile:
my @fd = (*STDIN, *STDOUT, *STDERR); print $fd[1] "Type it: "; # WRONG my $got = <$fd[0]> # WRONG print $fd[2] "What was that: $got"; # WRONG
With print
and printf
, you get around this by using a block and an expression where you would place the filehandle:
print { $fd[1] } "funny stuff\n"; printf { $fd[1] } "Pity the poor %x.\n", 3_735_928_559; # Pity the poor deadbeef.
That block is a proper block like any other, so you can put more complicated code there. This sends the message out to one of two places:
my $ok = -x "/bin/cat"; print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n"; print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";
This approach of treating print
and printf
like object methods calls doesn't work for the diamond operator. That's because it's a real operator, not just a function with a comma-less argument. Assuming you've been storing typeglobs in your structure as we did above, you can use the built-in function named readline
to read a record just as <>
does. Given the initialization shown above for @fd, this would work, but only because readline() requires a typeglob. It doesn't work with objects or strings, which might be a bug we haven't fixed yet.
$got = readline($fd[0]);
Let it be noted that the flakiness of indirect filehandles is not related to whether they're strings, typeglobs, objects, or anything else. It's the syntax of the fundamental operators. Playing the object game doesn't help you at all here.
There's no builtin way to do this, but perlform has a couple of techniques to make it possible for the intrepid hacker.
(contributed by brian d foy)
If you want to write
into a string, you just have to <open> a filehandle to a string, which Perl has been able to do since Perl 5.6:
open FH, '>', \my $string; write( FH );
Since you want to be a good programmer, you probably want to use a lexical filehandle, even though formats are designed to work with bareword filehandles since the default format names take the filehandle name. However, you can control this with some Perl special per-filehandle variables: $^
, which names the top-of-page format, and $~
which shows the line format. You have to change the default filehandle to set these variables:
open my($fh), '>', \my $string; { # set per-filehandle variables my $old_fh = select( $fh ); $~ = 'ANIMAL'; $^ = 'ANIMAL_TOP'; select( $old_fh ); } format ANIMAL_TOP = ID Type Name . format ANIMAL = @## @<<< @<<<<<<<<<<<<<< $id, $type, $name .
Although write can work with lexical or package variables, whatever variables you use have to scope in the format. That most likely means you'll want to localize some package variables:
{ local( $id, $type, $name ) = qw( 12 cat Buster ); write( $fh ); } print $string;
There are also some tricks that you can play with formline
and the accumulator variable $^A
, but you lose a lot of the value of formats since formline
won't handle paging and so on. You end up reimplementing formats when you use them.
(contributed by Peter J. Holzer<EMAIL_ADDRESS>Since Perl 5.8.0 a file handle referring to a string can be created by calling open with a reference to that string instead of the filename. This file handle can then be used to read from or write to the string:
open(my $fh, '>', \$string) or die "Could not open string for writing"; print $fh "foo\n"; print $fh "bar\n"; # $string now contains "foo\nbar\n" open(my $fh, '<', \$string) or die "Could not open string for reading"; my $x = <$fh>; # $x now contains "foo\n"
With older versions of Perl, the IO::String module provides similar functionality.
(contributed by brian d foy and Benjamin Goldberg)
You can use Number::Format to separate places in a number. It handles locale information for those of you who want to insert full stops instead (or anything else that they want to use, really).
This subroutine will add commas to your number:
sub commify { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; }
This regex from Benjamin Goldberg will add commas to numbers:
s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;
It is easier to see with comments:
s/( ^[-+]? # beginning of number. \d+? # first digits before first comma (?= # followed by, (but not included in the match) : (?>(?:\d{3})+) # some positive multiple of three digits. (?!\d) # an *exact* multiple, not x * 3 + 1 or whatever. ) | # or: \G\d{3} # after the last group, get three digits (?=\d) # but they have to have more digits after them. )/$1,/xg;
Use the <> (glob()
) operator, documented in perlfunc. Versions of Perl older than 5.6 require that you have a shell installed that groks tildes. Later versions of Perl have this feature built in. The File::KGlob module (available from CPAN) gives more portable glob functionality.
Within Perl, you may use this directly:
$filename =~ s{ ^ ~ # find a leading tilde ( # save this in $1 [^/] # a non-slash character * # repeated 0 or more times (0 means me) ) }{ $1 ? (getpwnam($1))[7] : ( $ENV{HOME} || $ENV{LOGDIR} ) }ex;
Because you're using something like this, which truncates the file then gives you read-write access:
open my $fh, '+>', '/path/name'; # WRONG (almost always)
Whoops. You should instead use this, which will fail if the file doesn't exist:
open my $fh, '+<', '/path/name'; # open for update
Using ">" always clobbers or creates. Using "<" never does either. The "+" doesn't change this.
Here are examples of many kinds of file opens. Those using sysopen
all assume that you've pulled in the constants from Fcntl:
use Fcntl;
To open file for reading:
open my $fh, '<', $path or die $!; sysopen my $fh, $path, O_RDONLY or die $!;

To open file for writing, create new file, file must not exist:
sysopen my $fh, $path, O_WRONLY|O_EXCL|O_CREAT or die $!; sysopen my $fh, $path, O_WRONLY|O_EXCL|O_CREAT, 0666 or die $!;

To open file for appending, file must exist:
sysopen my $fh, $path, O_WRONLY|O_APPEND or die $!;
To open file for update, file must exist:
open my $fh, '+<', $path or die $!; sysopen my $fh, $path, O_RDWR or die $!;

To open file for update, file must not exist:
sysopen my $fh, $path, O_RDWR|O_EXCL|O_CREAT or die $!; sysopen my $fh, $path, O_RDWR|O_EXCL|O_CREAT, 0666 or die $!;
To open a file without blocking, creating if necessary:
sysopen my $fh, '/foo/somefile', O_WRONLY|O_NDELAY|O_CREAT or die "can't open /foo/somefile: $!":
Be warned that neither creation nor deletion of files is guaranteed to be an atomic operation over NFS. That is, two processes might both successfully create or unlink the same file! Therefore O_EXCL isn't as exclusive as you might wish.
See also perlopentut.
The <>
operator performs a globbing operation (see above). In Perl versions earlier than v5.6.0, the internal glob() operator forks csh(1) to do the actual glob expansion, but csh can't handle more than 127 items and so gives the error message Argument list too long
. People who installed tcsh as csh won't have this problem, but their users may be surprised by it.
To get around this, either upgrade to Perl v5.6.0 or later, do the glob yourself with readdir() and patterns, or use a module like File::Glob, one that doesn't use the shell to do globbing.
(contributed by Brian McCauley)
The special two-argument form of Perl's open() function ignores trailing blanks in filenames and infers the mode from certain leading characters (or a trailing "|"). In older versions of Perl this was the only version of open() and so it is prevalent in old code and books.
Unless you have a particular reason to use the two-argument form you should use the three-argument form of open() which does not treat any characters in the filename as special.
open my $fh, "<", " file "; # filename is " file " open my $fh, ">", ">file"; # filename is ">file"
If your operating system supports a proper mv(1) utility or its functional equivalent, this works:
rename($old, $new) or system("mv", $old, $new);
It may be more portable to use the File::Copy module instead. You just copy to the new file to the new name (checking return values), then delete the old one. This isn't really the same semantically as a rename()
, which preserves meta-information like permissions, timestamps, inode info, etc.
Perl's builtin flock() function (see perlfunc for details) will call flock(2) if that exists, fcntl(2) if it doesn't (on perl version 5.004 and later), and lockf(3) if neither of the two previous system calls exists. On some systems, it may even use a different form of native locking. Here are some gotchas with Perl's flock():
Produces a fatal error if none of the three system calls (or their close equivalent) exists.
lockf(3) does not provide shared locking, and requires that the filehandle be open for writing (or appending, or read/writing).
Some versions of flock() can't lock files over a network (e.g. on NFS file systems), so you'd need to force the use of fcntl(2) when you build Perl. But even this is dubious at best. See the flock entry of perlfunc and the INSTALL file in the source distribution for information on building Perl to do this.
Two potentially non-obvious but traditional flock semantics are that it waits indefinitely until the lock is granted, and that its locks are merely advisory. Such discretionary locks are more flexible, but offer fewer guarantees. This means that files locked with flock() may be modified by programs that do not also use flock(). Cars that stop for red lights get on well with each other, but not with cars that don't stop for red lights. See the perlport manpage, your port's specific documentation, or your system-specific local manpages for details. It's best to assume traditional behavior if you're writing portable programs. (If you're not, you should as always feel perfectly free to write for your own system's idiosyncrasies (sometimes called "features"). Slavish adherence to portability concerns shouldn't get in the way of your getting your job done.)
For more information on file locking, see also "File Locking" in perlopentut if you have it (new for 5.6).
A common bit of code NOT TO USE is this:
sleep(3) while -e 'file.lock'; # PLEASE DO NOT USE open my $lock, '>', 'file.lock'; # THIS BROKEN CODE
This is a classic race condition: you take two steps to do something which must be done in one. That's why computer hardware provides an atomic test-and-set instruction. In theory, this "ought" to work:
sysopen my $fh, "file.lock", O_WRONLY|O_EXCL|O_CREAT or die "can't open file.lock: $!";
except that lamentably, file creation (and deletion) is not atomic over NFS, so this won't work (at least, not every time) over the net. Various schemes involving link() have been suggested, but these tend to involve busy-wait, which is also less than desirable.
Didn't anyone ever tell you web-page hit counters were useless? They don't count number of hits, they're a waste of time, and they serve only to stroke the writer's vanity. It's better to pick a random number; they're more realistic.

Here's a much better web-page hit counter:
$hits = int( (time() - 850_000_000) / rand(1_000) );
If the count doesn't impress your friends, then the code might. :-)
If you are on a system that correctly implements flock
and you use the example appending code from "perldoc -f flock" everything will be OK even if the OS you are on doesn't implement append mode correctly (if such a system exists). So if you are happy to restrict yourself to OSs that implement flock
(and that's not really much of a restriction) then that is what you should do.
If you know you are only going to use a system that does correctly implement appending (i.e. not Win32) then you can omit the seek
from the code in the previous answer.
If you know you are only writing code to run on an OS and filesystem that does implement append mode correctly (a local filesystem on a modern Unix for example), and you keep the file in block-buffered mode and you write less than one buffer-full of output between each manual flushing of the buffer then each bufferload is almost guaranteed to be written to the end of the file in one chunk without getting intermingled with anyone else's output. You can also use the syswrite
function which is simply a wrapper around your system's write(2)
system call.
There is still a small theoretical chance that a signal will interrupt the system-level write()
operation before completion. There is also a possibility that some STDIO implementations may call multiple system level write()
s even if the buffer was empty to start. There may be some systems where this probability is reduced to zero, and this is not a concern when using :perlio
instead of your system's STDIO.
If you're just trying to patch a binary, in many cases something as simple as this works:
perl -i -pe 's{window manager}{window mangler}g' /usr/bin/emacs
However, if you have fixed sized records, then you might do something more like this:
my $RECSIZE = 220; # size of record, in bytes my $recno = 37; # which record to update open my $fh, '+<', 'somewhere' or die "can't update somewhere: $!"; seek $fh, $recno * $RECSIZE, 0; read $fh, $record, $RECSIZE == $RECSIZE or die "can't read record $recno: $!"; # munge the record seek $fh, -$RECSIZE, 1; print $fh $record; close $fh;
Locking and error checking are left as an exercise for the reader. Don't forget them or you'll be quite sorry.
If you want to retrieve the time at which the file was last read, written, or had its meta-data (owner, etc) changed, you use the -A, -M, or -C file test operations as documented in perlfunc. These retrieve the age of the file (measured against the start-time of your program) in days as a floating point number. Some platforms may not have all of these times. See perlport for details. To retrieve the "raw" time in seconds since the epoch, you would call the stat function, then use localtime()
, gmtime()
, or POSIX::strftime()
to convert this into human-readable form.
Here's an example:
my $write_secs = (stat($file))[9]; printf "file %s updated at %s\n", $file, scalar localtime($write_secs);
If you prefer something more legible, use the File::stat module (part of the standard distribution in version 5.004 and later):
# error checking left as an exercise for reader. use File::stat; use Time::localtime; my $date_string = ctime(stat($file)->mtime); print "file $file updated at $date_string\n";
The POSIX::strftime() approach has the benefit of being, in theory, independent of the current locale. See perllocale for details.
You use the utime() function documented in "utime" in perlfunc. By way of example, here's a little program that copies the read and write times from its first argument to all the rest of them.
if (@ARGV < 2) { die "usage: cptimes timestamp_file other_files ...\n"; } my $timestamp = shift; my($atime, $mtime) = (stat($timestamp))[8,9]; utime $atime, $mtime, @ARGV;
Error checking is, as usual, left as an exercise for the reader.
The perldoc for utime also has an example that has the same effect as touch(1) on files that already exist.
Certain file systems have a limited ability to store the times on a file at the expected level of precision. For example, the FAT and HPFS filesystem are unable to create dates on files with a finer granularity than two seconds. This is a limitation of the filesystems, not of utime().
To connect one filehandle to several output filehandles, you can use the IO::Tee or Tie::FileHandle::Multiplex modules.
If you only have to do this once, you can print individually to each filehandle.
for my $fh ($fh1, $fh2, $fh3) { print $fh "whatever\n" }
The customary Perl approach for processing all the lines in a file is to do so one line at a time:
open my $input, '<', $file or die "can't open $file: $!"; while (<$input>) { chomp; # do something with $_ } close $input or die "can't close $file: $!";
This is tremendously more efficient than reading the entire file into memory as an array of lines and then processing it one element at a time, which is often--if not almost always--the wrong approach. Whenever you see someone do this:
my @lines = <INPUT>;
You should think long and hard about why you need everything loaded at once. It's just not a scalable solution.
If you "mmap" the file with the File::Map module from CPAN, you can virtually load the entire file into a string without actually storing it in memory:
use File::Map qw(map_file); map_file my $string, $filename;
Once mapped, you can treat $string
as you would any other string. Since you don't necessarily have to load the data, mmap-ing can be very fast and may not increase your memory footprint.
You might also find it more fun to use the standard Tie::File module, or the DB_File module's $DB_RECNO
bindings, which allow you to tie an array to a file so that accessing an element of the array actually accesses the corresponding line in the file.
If you want to load the entire file, you can use the Path::Tiny module to do it in one simple and efficient step:
use Path::Tiny; my $all_of_it = path($filename)->slurp; # entire file in scalar my @all_lines = path($filename)->lines; # one line per element
Or you can read the entire file contents into a scalar like this:
my $var; { local $/; open my $fh, '<', $file or die "can't open $file: $!"; $var = <$fh>; }
That temporarily undefs your record separator, and will automatically close the file at block exit. If the file is already open, just use this:
my $var = do { local $/; <$fh> };
You can also use a localized @ARGV
to eliminate the open
:
my $var = do { local( @ARGV, $/ ) = $file; <> };
For ordinary files you can also use the read
function.
read( $fh, $var, -s $fh );
That third argument tests the byte size of the data on the $fh
filehandle and reads that many bytes into the buffer $var
.
Use the $/
variable (see perlvar for details). You can either set it to ""
to eliminate empty paragraphs ("abc\n\n\n\ndef"
, for instance, gets treated as two paragraphs and not three), or "\n\n"
to accept empty paragraphs.
Note that a blank line must have no blanks in it. Thus "fred\n \nstuff\n\n"
is one paragraph, but "fred\n\nstuff\n\n"
is two.
You can use the builtin getc()
function for most filehandles, but it won't (easily) work on a terminal device. For STDIN, either use the Term::ReadKey module from CPAN or use the sample code in "getc" in perlfunc.
If your system supports the portable operating system programming interface (POSIX), you can use the following code, which you'll note turns off echo processing as well.
#!/usr/bin/perl -w use strict; $| = 1; for (1..4) { print "gimme: "; my $got = getone(); print "--> $got\n"; } exit; BEGIN { use POSIX qw(:termios_h); my ($term, $oterm, $echo, $noecho, $fd_stdin); my $fd_stdin = fileno(STDIN); $term = POSIX::Termios->new(); $term->getattr($fd_stdin); $oterm = $term->getlflag(); $echo = ECHO | ECHOK | ICANON; $noecho = $oterm & ~$echo; sub cbreak { $term->setlflag($noecho); $term->setcc(VTIME, 1); $term->setattr($fd_stdin, TCSANOW); } sub cooked { $term->setlflag($oterm); $term->setcc(VTIME, 0); $term->setattr($fd_stdin, TCSANOW); } sub getone { my $key = ''; cbreak(); sysread(STDIN, $key, 1); cooked(); return $key; } } END { cooked() }
The Term::ReadKey module from CPAN may be easier to use. Recent versions include also support for non-portable systems as well.
use Term::ReadKey; open my $tty, '<', '/dev/tty'; print "Gimme a char: "; ReadMode "raw"; my $key = ReadKey 0, $tty; ReadMode "normal"; printf "\nYou said %s, char number %03d\n", $key, ord $key;
The very first thing you should do is look into getting the Term::ReadKey extension from CPAN. As we mentioned earlier, it now even has limited support for non-portable (read: not open systems, closed, proprietary, not POSIX, not Unix, etc.) systems.
You should also check out the Frequently Asked Questions list in comp.unix.* for things like this: the answer is essentially the same. It's very system-dependent. Here's one solution that works on BSD systems:
sub key_ready { my($rin, $nfd); vec($rin, fileno(STDIN), 1) = 1; return $nfd = select($rin,undef,undef,0); }
If you want to find out how many characters are waiting, there's also the FIONREAD ioctl call to be looked at. The h2ph tool that comes with Perl tries to convert C include files to Perl code, which can be require
d. FIONREAD ends up defined as a function in the sys/ioctl.ph file:
require 'sys/ioctl.ph'; $size = pack("L", 0); ioctl(FH, FIONREAD(), $size) or die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size);
If h2ph wasn't installed or doesn't work for you, you can grep the include files by hand:
% grep FIONREAD /usr/include/*/* /usr/include/asm/ioctls.h:#define FIONREAD 0x541B
Or write a small C program using the editor of champions:
% cat > fionread.c #include <sys/ioctl.h> main() { printf("%#08x\n", FIONREAD); } ^D % cc -o fionread fionread.c % ./fionread 0x4004667f
And then hard-code it, leaving porting as an exercise to your successor.
$FIONREAD = 0x4004667f; # XXX: opsys dependent $size = pack("L", 0); ioctl(FH, $FIONREAD, $size) or die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size);
FIONREAD requires a filehandle connected to a stream, meaning that sockets, pipes, and tty devices work, but not files.
tail -f
in perl? First try
seek($gw_fh, 0, 1);
The statement seek($gw_fh, 0, 1)
doesn't change the current position, but it does clear the end-of-file condition on the handle, so that the next <$gw_fh>
makes Perl try again to read something.
If that doesn't work (it relies on features of your stdio implementation), then you need something more like this:
for (;;) { for ($curpos = tell($gw_fh); <$gw_fh>; $curpos =tell($gw_fh)) { # search for some stuff and put it into files } # sleep for a while seek($gw_fh, $curpos, 0); # seek to where we had been }
If this still doesn't work, look into the clearerr
method from IO::Handle, which resets the error and end-of-file states on the handle.
There's also a File::Tail module from CPAN.
If you check "open" in perlfunc, you'll see that several of the ways to call open() should do the trick. For example:
open my $log, '>>', '/foo/logfile'; open STDERR, '>&', $log;
Or even with a literal numeric descriptor:
my $fd = $ENV{MHCONTEXTFD}; open $mhcontext, "<&=$fd"; # like fdopen(3S)
Note that "<&STDIN" makes a copy, but "<&=STDIN" makes an alias. That means if you close an aliased handle, all aliases become inaccessible. This is not true with a copied one.
Error checking, as always, has been left as an exercise for the reader.
If, for some reason, you have a file descriptor instead of a filehandle (perhaps you used POSIX::open
), you can use the close()
function from the POSIX module:
use POSIX (); POSIX::close( $fd );
This should rarely be necessary, as the Perl close()
function is to be used for things that Perl opened itself, even if it was a dup of a numeric descriptor as with MHCONTEXT
above. But if you really have to, you may be able to do this:
require 'sys/syscall.ph'; my $rc = syscall(SYS_close(), $fd + 0); # must force numeric die "can't sysclose $fd: $!" unless $rc == -1;
Or, just use the fdopen(3S) feature of open()
:
{ open my $fh, "<&=$fd" or die "Cannot reopen fd=$fd: $!"; close $fh; }
Whoops! You just put a tab and a formfeed into that filename! Remember that within double quoted strings ("like\this"), the backslash is an escape character. The full list of these is in "Quote and Quote-like Operators" in perlop. Unsurprisingly, you don't have a file called "c:(tab)emp(formfeed)oo" or "c:(tab)emp(formfeed)oo.exe" on your legacy DOS filesystem.
Either single-quote your strings, or (preferably) use forward slashes. Since all DOS and Windows versions since something like MS-DOS 2.0 or so have treated /
and \
the same in a path, you might as well use the one that doesn't clash with Perl--or the POSIX shell, ANSI C and C++, awk, Tcl, Java, or Python, just to mention a few. POSIX paths are more portable, too.
Because even on non-Unix ports, Perl's glob function follows standard Unix globbing semantics. You'll need glob("*")
to get all (non-hidden) files. This makes glob() portable even to legacy systems. Your port may include proprietary globbing functions as well. Check its documentation for details.
-i
clobber protected files? Isn't this a bug in Perl?This is elaborately and painstakingly described in the file-dir-perms article in the "Far More Than You Ever Wanted To Know" collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz .
The executive summary: learn how your filesystem works. The permissions on a file say what can happen to the data in that file. The permissions on a directory say what can happen to the list of files in that directory. If you delete a file, you're removing its name from the directory (so the operation depends on the permissions of the directory, not of the file). If you try to write to the file, the permissions of the file govern whether you're allowed to.
Short of loading the file into a database or pre-indexing the lines in the file, there are a couple of things that you can do.
Here's a reservoir-sampling algorithm from the Camel Book:
srand; rand($.) < 1 && ($line = $_) while <>;
This has a significant advantage in space over reading the whole file in. You can find a proof of this method in The Art of Computer Programming, Volume 2, Section 3.4.2, by Donald E. Knuth.
You can use the File::Random module which provides a function for that algorithm:
use File::Random qw/random_line/; my $line = random_line($filename);
Another way is to use the Tie::File module, which treats the entire file as an array. Simply access a random array element.
(contributed by brian d foy)
If you are seeing spaces between the elements of your array when you print the array, you are probably interpolating the array in double quotes:
my @animals = qw(camel llama alpaca vicuna); print "animals are: @animals\n";
It's the double quotes, not the print
, doing this. Whenever you interpolate an array in a double quote context, Perl joins the elements with spaces (or whatever is in $"
, which is a space by default):
animals are: camel llama alpaca vicuna
This is different than printing the array without the interpolation:
my @animals = qw(camel llama alpaca vicuna); print "animals are: ", @animals, "\n";
Now the output doesn't have the spaces between the elements because the elements of @animals
simply become part of the list to print
:
animals are: camelllamaalpacavicuna
You might notice this when each of the elements of @array
end with a newline. You expect to print one element per line, but notice that every line after the first is indented:
this is a line this is another line this is the third line
That extra space comes from the interpolation of the array. If you don't want to put anything between your array elements, don't use the array in double quotes. You can send it to print without them:
print @lines;
(contributed by brian d foy)
The File::Find module, which comes with Perl, does all of the hard work to traverse a directory structure. It comes with Perl. You simply call the find
subroutine with a callback subroutine and the directories you want to traverse:
use File::Find; find( \&wanted, @directories ); sub wanted { # full path in $File::Find::name # just filename in $_ ... do whatever you want to do ... }
The File::Find::Closures, which you can download from CPAN, provides many ready-to-use subroutines that you can use with File::Find.
The File::Finder, which you can download from CPAN, can help you create the callback subroutine using something closer to the syntax of the find
command-line utility:
use File::Find; use File::Finder; my $deep_dirs = File::Finder->depth->type('d')->ls->exec('rmdir','{}'); find( $deep_dirs->as_options, @places );
The File::Find::Rule module, which you can download from CPAN, has a similar interface, but does the traversal for you too:
use File::Find::Rule; my @files = File::Find::Rule->file() ->name( '*.pm' ) ->in( @INC );
(contributed by brian d foy)
If you have an empty directory, you can use Perl's built-in rmdir
. If the directory is not empty (so, no files or subdirectories), you either have to empty it yourself (a lot of work) or use a module to help you.
The File::Path module, which comes with Perl, has a remove_tree
which can take care of all of the hard work for you:
use File::Path qw(remove_tree); remove_tree( @directories );
The File::Path module also has a legacy interface to the older rmtree
subroutine.
(contributed by Shlomi Fish)
To do the equivalent of cp -R
(i.e. copy an entire directory tree recursively) in portable Perl, you'll either need to write something yourself or find a good CPAN module such as File::Copy::Recursive.
Copyright (c) 1997-2010 Tom Christiansen, Nathan Torkington, and other authors as noted. All rights reserved.
This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself.
Irrespective of its distribution, all code examples here are in the public domain. You are permitted and encouraged to use this code and any derivatives thereof in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit to the FAQ would be courteous but is not required.
Version: 5.021011


Hiya! This is my website for stuff that I'll be exploring and working on over the next year. With this project I aim to document two goals I have for the upcoming year
I'm a bit bored in lockdown you see, and have had some more time to sharpen my computer skills while everything else got put on hold. Fun right?
This is a low-priority project for me and you can expect for it to be abandoned soon enough, but maybe I'll have some fun with it for a while.


| Solar Longitude on the Zodiac | from | to, not including[a] | Lunar longitude correction |
|---|---|---|---|
| middle of Pisces-middle of Taurus [b] | 315° | 15° | 0° |
| middle of Taurus-beginning of Gemini | 15° | 30° | 0°15′ |
| beginning of Gemini-beginning of Leo | 30° | 90° | 0°15′ |
| beginning of Leo-middle of Virgo | 90° | 135° | 0°15′ |
| middle of Virgo-middle of Libra | 135° | 165° | 0° |
| middle of Libra-beginning of Sagittarius | 165° | 210° | -0°15′ |
| beginning of Sagittarius-beginning of Aquarius | 210° | 270° | -0°30′ |
| beginning of Aquarius-middle of Pisces | 270° | 315° | -0°15′ |
|
[a] My understanding of the word usage in the original. [b] See Chapter 11, Law 7 on the start of Jewish Zodiac. (TODO reference) |
The value of mean [lunar longitude] after you add to it or subtract from it or leave it as it is - that is mean lunar longitude approximately a third of an hour after sunset on the date you are calculating it for. And this is what is called mean lunar longitude at observation time.


Today I'd like to critique the recent redesign of my former newspaper's website, The Telegraph/Macon.com, in Macon, Ga. For years we'd suffered with a cluttered, portal-styled homepage that devoted more screen real estate to aggregated national ne...
The latest delegate counts show that Mitt Romney nearly doubled his delegate total after Super Tuesday's primary elections. Click on the table to see how the delegates from Tuesday's vote broke down.Source: AP.
[View the story "A Twitter debate on newspaper opinion - what would Wheaties do?" on Storify]
For a lot of self-indulgent reasons, I secretly love The Huffington Post. But well-designed visualizations and interactive interfaces have never been the news organization's strong suit. While their live coverage of Tuesday night's GOP primary in ...
This map displays the results from Tuesday night's Michigan GOP primary by county. The darker shade blue represents a higher percentage of voters for Mitt Romney, who narrowly won the race despite Michigan being his native state. Click on each...


Keys To Move
We have a hero on the screen! But he's not very mighty... He can't even move! Let's fix that. In this section we're going to add the ability to walk around the map.
New Project
Make a new project, call it KeysToMove, we're going to be starting off from the On Your Own section of The Hero. Meaning your new project should pop up a window, the window has a room, link is in the room and pressing the directional buttons moves link around.
Player character
In The Hero section, we made a Character
class. This class contains the bare minimum information needed to display a character. We could add code to this class for handling input and moving around but that would get messy, after all not every Character
instance will be controlled by the player! We want enemies to be Character
s as well.
The best way to solve this delima is to create a new class, we're going to call PlayerCharacter
, this new class will extend Character
and add player specific functionality to it! Let's get started. Make a new file, call it PlayerCharacter.cs and add the following code:
using System.Drawing; // For Point
using TheHero; // For Character
namespace KeysToMove {
class PlayerCharacter : Character {
public PlayerCharacter(string spriteSheet, Point startPos) : base(spriteSheet, startPos) {
// ^ The Constructor which take a string and a Point of the base class (Character)
// is called using the : notation.
}
}
}
I don't know if we have used constructor chaining before. Constructor chaining is when a base class does not contain a default constructor, so the child class must call it's parents non-default constructor. This is done by adding : base(/*args*/)
after the consturctor. In our example, we pass the arguments from the PlayerCharacter
constructor to the Character
constructor (refered to as base
).
When chaining constructors you don't always have to forward arguments, the following code would have also been perfectly valid:
public PlayerCharacter() : base("Default string", new Point(-2, 5)) {
But we want the classes to work the same, so instead we take two arguments and forward them to the base class.
Updating the character
The PlayerCharacter
and Character
classes at this point are interchangable. Go into your Game.cs file and change this line:
protected Character hero = null;
To this:
protected PlayerCharacter hero = null;
Also find this line:
hero = new Character(heroSheet, new Point(SpawnTile.X * 30, SpawnTile.Y * 30));
And change it to this:
hero = new PlayerCharacter(heroSheet, new Point(SpawnTile.X * 30, SpawnTile.Y * 30));
Beacuse the PlayerCharacter
is specific to the hero, it's safe to put hero specific things in there. Take this bit of code from Game.cs:
hero.AddSprite("Down",new Rectangle(59,1,24,30));
hero.AddSprite("Up", new Rectangle(115,3,22,28));
hero.AddSprite("Left",new Rectangle(1,1,26,30));
hero.AddSprite("Right", new Rectangle(195, 1, 26, 30));
hero.SetSprite("Down");
And move it into the constructor of of the PlayerCharacter
class:
public PlayerCharacter(string spriteSheet, Point startPos) : base(spriteSheet, startPos) {
// ^ The Constructor which take a string and a Point of the base class (Character)
// is called using the : notation.
AddSprite("Down", new Rectangle(59, 1, 24, 30));
AddSprite("Up", new Rectangle(115, 3, 22, 28));
AddSprite("Left", new Rectangle(1, 1, 26, 30));
AddSprite("Right", new Rectangle(195, 1, 26, 30));
SetSprite("Down");
}
At this point you should be able to run the game. The game should display, and link should rotate when you press keys like nothing has happened.
Moving
Let's add code to actually move the character! In order to move the character we have to do a little bit of house cleaning first.
Currently we keep track of the Character
position in a Point. This won't work, in order to move around the screen we need to store values as floating points. Find the following line in Character.cs
public Point Position { get; set; }
and change it to
public PointF Position { get; set; }
If you try to compile now, the compiler will throw an error. This is because our render method is trying to pass a PointF variable when a Point is expected. Still in Character.cs, find this bit of code:
public void Render() {
TextureManager.Instance.Draw(Sprite, Position, 1.0f,spriteSource[currentSprite]);
}
and change it to:
public void Render() {
TextureManager.Instance.Draw(Sprite, new Point((int)Position.X, (int)Position.Y), 1.0f,spriteSource[currentSprite]);
}
And you should be able to compile again! Back in PlayerCharacter.cs lets add a speed variable. This varaible is going to determine how fast the player moves. I'm going to set it to 90.0f, that is, move 90 pixels every second or 3 tiles in one second.
namespace KeysToMove {
class PlayerCharacter : Character {
float speed = 90.0f; // NEW
public PlayerCharacter(string spriteSheet, Point startPos) : base(spriteSheet, startPos) {
Next let's add an Update
method to the PlayerCharacter
class. It should take one argument, deltaTime
.
public void Update(float deltaTime) {
// TODO: Add move code
}
This method is going to be responsible for checking Keyboard Input. When the appropriate keys are pressed it's going to update the inherited Position
property to make the character move (Remember, the character is rendered at Position
) Let's fill in the missing code:
public void Update(float deltaTime) {
InputManager i = InputManager.Instance;
PointF positionCpy = Position; // Don't forget to change to PointF in parent class
// The Position getter is inherited from the Character class.
// We simply store a COPY of it here, so we can modify the
// X and Y properties indevidually. We also make
if (i.KeyDown(OpenTK.Input.Key.Left) || i.KeyDown(OpenTK.Input.Key.A)) {
positionCpy.X -= speed * deltaTime;
}
else if (i.KeyDown(OpenTK.Input.Key.Right) || i.KeyDown(OpenTK.Input.Key.D)) {
positionCpy.X += speed * deltaTime;
}
if (i.KeyDown(OpenTK.Input.Key.Up) || i.KeyDown(OpenTK.Input.Key.W)) {
positionCpy.Y -= speed * deltaTime;
}
else if (i.KeyDown(OpenTK.Input.Key.Down) || i.KeyDown(OpenTK.Input.Key.S)) {
positionCpy.Y += speed * deltaTime;
}
Position = positionCpy; // Move the copy we made back into the Postion variable
}
Running the game now, pressing the arrow keys.... Nothing moves! What gives? Well, we added an Update
method to the PlayerCharacter
class, but we are not calling this method anywhere! Let's go into Game.cs and add this Update
call to the Game
s update method:
public void Update(float dt) {
InputManager i = InputManager.Instance; //local ref to input manager
//using i just saves time
if (i.KeyDown(OpenTK.Input.Key.Left) || i.KeyDown(OpenTK.Input.Key.A)) {
hero.SetSprite("Left");
}
if (i.KeyDown(OpenTK.Input.Key.Right) || i.KeyDown(OpenTK.Input.Key.D)){
hero.SetSprite("Right");
}
if (i.KeyDown(OpenTK.Input.Key.Up) || i.KeyDown(OpenTK.Input.Key.W)) {
hero.SetSprite("Up");
}
if (i.KeyDown(OpenTK.Input.Key.Down) || i.KeyDown(OpenTK.Input.Key.S)) {
hero.SetSprite("Down");
}
hero.Update(dt);
}
Run the game now, and TADA! Your hero is moving! He's not colliding with any walls.... But we can fix that later. For now what matters is that the hero moved!
Cleanup
One thing you may have noticed is that there is a lot of similar code between the Update method of Game
and PlayerCharacter
. Whenever you have a lot of similar code, chances are it's time to refactor (clean-up).
Let's move all of the SetSprite
methods for key input into the PlayerCharacter
class. Updating this code, the Update
method of Game.cs should now look like this:
public void Update(float dt) {
hero.Update(dt);
}
And the Update
method of PlayerCharacter.cs should look like this:
public void Update(float deltaTime) {
InputManager i = InputManager.Instance;
PointF positionCpy = Position; // Don't forget to change to PointF in parent class
// The Position getter is inherited from the Character class.
// We simply store a COPY of it here, so we can modify the
// X and Y properties indevidually. We also make
if (i.KeyDown(OpenTK.Input.Key.Left) || i.KeyDown(OpenTK.Input.Key.A)) {
positionCpy.X -= speed * deltaTime;
SetSprite("Left");
}
else if (i.KeyDown(OpenTK.Input.Key.Right) || i.KeyDown(OpenTK.Input.Key.D)) {
positionCpy.X += speed * deltaTime;
SetSprite("Right");
}
if (i.KeyDown(OpenTK.Input.Key.Up) || i.KeyDown(OpenTK.Input.Key.W)) {
positionCpy.Y -= speed * deltaTime;
SetSprite("Up");
}
else if (i.KeyDown(OpenTK.Input.Key.Down) || i.KeyDown(OpenTK.Input.Key.S)) {
positionCpy.Y += speed * deltaTime;
SetSprite("Down");
}
Position = positionCpy; // Move the copy we made back into the Postion variable
}
The SetSprite
method is callable because we inherited it from the Character
class. Sometimes it can get a little hard to follow what is and isn't accessable. If you are feeling brave, try using draw.io or ArgoUML (i suggest draw.io) to make a UML diagram the current project. If you end up making the UML check the exported PNG image into your repo.


Name Card Page Redesign
Goal:
Business Card is one service that has a lot of demand, Therefore, booking minimum fees can facilitate the user's need to purchase business card.
Goal:
Business Card is one service that has a lot of demand, Therefore, booking minimum fees can facilitate the user's need to purchase business card.


An error occured
Configure
Create a Cumulative Flow Diagram
Create chart
Help
For detailed instructions please look at
GitHub
Credits
Icons made by
Maxim Basinski
from
www.flaticon.com
is licensed by
CC 3.0 BY
Creating the Cumulative Flow Diagram...
Configure


Winesburg, Ohio
by Sherwood Anderson
Tandy, concerning Tandy Hard
Additional Information
- Year Published: 1919
- Language: English
- Country of Origin: United States of America
- Source: Anderson, S. (1919) Winesburg, Ohio. New York, NY: B.W. Huebsch.
-
Readability:
- Flesch–Kincaid Level: 5.6
- Word Count: 1,203
- Genre: Realism
- Keywords: 20th century literature, american literature, frustration, isolation, short stories, small-town life
- ✎ Cite This
Downloads
Until she was seven years old she lived in an old unpainted house on an unused road that led off Trunion Pike. Her father gave her but little attention and her mother was dead. The father spent his time talking and thinking of religion. He proclaimed himself an agnostic and was so absorbed in destroying the ideas of God that had crept into the minds of his neighbors that he never saw God manifesting himself in the little child that, half forgotten, lived here and there on the bounty of her dead mother's relatives.
A stranger came to Winesburg and saw in the child what the father did not see. He was a tall, redhaired young man who was almost always drunk. Sometimes he sat in a chair before the New Willard House with Tom Hard, the father. As Tom talked, declaring there could be no God, the stranger smiled and winked at the bystanders. He and Tom became friends and were much together.
The stranger was the son of a rich merchant of Cleveland and had come to Winesburg on a mission. He wanted to cure himself of the habit of drink, and thought that by escaping from his city associates and living in a rural community he would have a better chance in the struggle with the appetite that was destroying him.
His sojourn in Winesburg was not a success. The dullness of the passing hours led to his drinking harder than ever. But he did succeed in doing something. He gave a name rich with meaning to Tom Hard's daughter.
One evening when he was recovering from a long debauch the stranger came reeling along the main street of the town.  Beside him on the board sidewalk sat young George Willard. The stranger dropped into a chair beside them. His body shook and when he tried to talk his voice trembled.
It was late evening and darkness lay over the town and over the railroad that ran along the foot of a little incline before the hotel. Somewhere in the distance, off to the west, there was a prolonged blast from the whistle of a passenger engine. A dog that had been sleeping in the roadway arose and barked. The stranger began to babble and made a prophecy concerning the child that lay in the arms of the agnostic.
"I came here to quit drinking," he said, and tears began to run down his cheeks. He did not look at Tom Hard, but leaned forward and stared into the darkness as though seeing a vision. "I ran away to the country to be cured, but I am not cured. There is a reason." He turned to look at the child who sat up very straight on her father's knee and returned the look.
The stranger touched Tom Hard on the arm. "Drink is not the only thing to which I am addicted," he said. "There is something else. I am a lover and have not found my thing to love. That is a big point if you know enough to realize what I mean. It makes my destruction inevitable, you see. There are few who understand that."
The stranger became silent and seemed overcome with sadness, but another blast from the whistle of the passenger engine aroused him. "I have not lost faith. I proclaim that. I have only been brought to the place where I know my faith will not be realized," he declared hoarsely. He looked hard at the child and began to address her, paying no more attention to the father. "There is a woman coming," he said, and his voice was now sharp and earnest. "I have missed her, you see. She did not come in my time. You may be the woman. It would be like fate to let me stand in her presence once, on such an evening as this, when I have destroyed myself with drink and she is as yet only a child."
The shoulders of the stranger shook violently, and when he tried to roll a cigarette the paper fell from his trembling fingers. He grew angry and scolded. "They think it's easy to be a woman, to be loved, but I know better," he declared. Again he turned to the child. "I understand," he cried. "Perhaps of all men I alone understand."
His glance again wandered away to the darkened street. "I know about her, although she has never crossed my path," he said softly. "I know about her struggles and her defeats. It is because of her defeats that she is to me the lovely one. Out of her defeats has been born a new quality in woman. I have a name for it. I call it Tandy. I made up the name when I was a true dreamer and before my body became vile. It is the quality of being strong to be loved. It is something men need from women and that they do not get."
The stranger arose and stood before Tom Hard. His body rocked back and forth and he seemed about to fall, but instead he dropped to his knees on the sidewalk and raised the hands of the little girl to his drunken lips. He kissed them ecstatically. "Be Tandy, little one," he pleaded. "Dare to be strong and courageous. That is the road. Venture anything. Be brave enough to dare to be loved. Be something more than man or woman. Be Tandy."
The stranger arose and staggered off down the street. A day or two later he got aboard a train and returned to his home in Cleveland. On the summer evening, after the talk before the hotel, Tom Hard took the girl child to the house of a relative where she had been invited to spend the night. As he went along in the darkness under the trees he forgot the babbling voice of the stranger and his mind returned to the making of arguments by which he might destroy men's faith in God. He spoke his daughter's name and she began to weep.
"I don't want to be called that," she declared. "I want to be called Tandy—Tandy Hard." The child wept so bitterly that Tom Hard was touched and tried to comfort her. He stopped beneath a tree and, taking her into his arms, began to caress her. "Be good, now," he said sharply; but she would not be quieted. With childish abandon she gave herself over to grief, her voice breaking the evening stillness of the street. "I want to be Tandy. I want to be Tandy. I want to be Tandy Hard," she cried, shaking her head and sobbing as though her young strength were not enough to bear the vision the words of the drunkard had brought to her.


PROBLEM STATEMENT
In medicine, the next
frontier for AI is anomaly localization in medical imaging. Localization of
anomalies refers to both predicting anomalies and their boundaries. Automatic
detection algorithms to locate the position of inflammation in an image can
help the physicians in making the better clinical decisions. In this project we
analyze data with the knowledge of EDA, we build a detection model and we
present our findings based on the evaluations with the RSNA Pneumonia Detection
Challenge dataset.
OVERVIEW OF PNEUMONIA
Pneumonia is a form of
acute respiratory infection that affects the lungs. The lungs are comprised of
small sacs called alveoli that, as a healthy person breathes, fill up with
oxygen. The alveoli are filled with pus and fluid when a person has pneumonia,
which makes breathing difficult and reduces oxygen intake.
The single greatest
bacterial cause of death in children worldwide is pneumonia. In 2017, pneumonia
killed 808,694 children under the age of 5, accounting for 15 percent of all
deaths by children under the age of five. Children and families worldwide are
afflicted by pneumonia, but it is most common in South Asia and sub-Saharan
Africa. It can be avoided with easy procedures, and managed with low-cost,
low-tech treatment and care. Children can be shielded from pneumonia.
In 2015 spending for
maternal, infant, and child survival, the cost of antibiotic care for all
children with pneumonia is estimated at about US$ 109 million per year among 66
countries. The expense requires antibiotics and diagnostics for the treatment
of pneumonia.
CAUSES AND
TRANSMISSION
According to WHO,
pneumonia is caused by a number of infectious agents, including viruses,
bacteria and fungi. The most common are:
·
Streptococcus pneumoniae – the most common cause of
bacterial pneumonia in children;
·
Haemophilus influenzae type b
(Hib) – the second most common cause of bacterial pneumonia;
·
respiratory syncytial virus is the most common viral
cause of pneumonia;
·
in infants infected with HIV, Pneumocystis jiroveci is one of the most common causes of pneumonia,
responsible for at least one quarter of all pneumonia deaths in HIV-infected
infants.
Pneumonia can be
spread in a number of ways. The viruses and bacteria that are commonly found in
a child's nose or throat, can infect the lungs if they are inhaled. They may
also spread via air-borne droplets from a cough or sneeze. In addition,
pneumonia may spread through blood, especially during and shortly after birth.
More research needs to be done on the different pathogens causing pneumonia and
the ways they are transmitted, as this is of critical importance for treatment
and prevention.
TREATMENT AND
PREVENTION
Pneumonia should be
treated with antibiotics. Amoxicillin-dispersible tablets are the antibiotic of
choice. In most cases of pneumonia, oral antibiotics are needed, which are
mostly administered at a health clinic. These cases may also be diagnosed and
treated at the neighborhood level by qualified community health professionals
with affordable oral antibiotics. Only for serious cases of pneumonia is
hospitalization recommended.
DIAGNOSTIC PROCEDURE
Doctor will diagnose
pneumonia based on your medical history, a physical exam, and test results.
Sometimes pneumonia is hard to diagnose because symptoms may be the same as a
cold or flu. Patient may not realize that his/her condition is more serious
until it lasts longer than these other conditions.
If doctor thinks patient
may have pneumonia, he or she may do one or more of the following tests.
·
Chest X-ray to look for inflammation in patient’s
lungs. A chest X-ray is often used to diagnose pneumonia.
·
Blood tests, such as a complete blood count (CBC) to
see whether patient’s immune system is fighting an infection.
·
Pulse oximetry to measure how much oxygen is in his/her
blood. Pneumonia can keep patient’s lungs from moving enough oxygen into his/her
blood. To measure the levels, a small sensor called a pulse oximeter is
attached to patient’s finger or ear.
DATA AND FINDINGS
In 2018, RSNA
organized an AI challenge to detect pneumonia, one of the leading causes of
mortality worldwide, as part of its efforts to help improve artificial
intelligence (AI) instruments for radiology. RSNA Pneumonia dataset consists of
29684 thousand images. All the images are in dicom
format. There are 26684 images for training and 3000 images for testing.
Dicom images: In a special format
called DICOM files (*. dcm), medical images are
stored. They contain a mix of header metadata as well as pixel data underlying
raw image arrays.
There are three
classes featured in the dataset Normal, Not normal/No opacity and Lung opacity.
Normal class indicates there is no anomaly in the lungs. Not normal/No opacity
indicates while it was decided that pneumonia was not present, there was still
some sort of picture abnormality and sometimes this finding could mimic the
appearance of true pneumonia. Lung opacity class indicates there is definite
pneumonia in the lungs.
Along with the images
two csv files are provided. Detailed class info file consists of image name and
the class it belonged to. Train labels file consists of the bounding box
coordinates belonging to each image. Bounding box coordinates are given in the
following format as follows,
·
x -- the upper-left x coordinate of the bounding box.
·
y -- the upper-left y coordinate of the bounding box.
·
width -- the width of the bounding box.
·
height -- the height of the bounding box.
With these bounding
box coordinates target column is provided which discriminates classes into
categories of 0 and 1. All the images in the dataset belongs to stage 2
pneumonia.
EDA AND PREPROCESSING
There are two datasets each dataset has total 30227 number of rows and
the trian_labels.csv has 6 columns but in class_info.csv has 2 columns.
As we can see below, in train_labels.csv file contains patientId which is unique value per patient, for each patientId, it has one target column and 4 values which are
corresponding abnormality bounding box defined by the upper-left hand corner
‘x’ and ‘y’ coordinate and its corresponding width and height. Target column
has two values 0 and 1. 0 is for No Lung
Opacity / Not Normal, Normal and 1 is for Lung opacity.
In the class_info.csv file there are two columns patientId
and class column that describes the three conditions of lungs which are Normal,
Not Normal/No Lung Opacity and lung opacity. As we can see below
We have calculated each value for 3 different class and we got only 23.5
percent patient are Normal and 76 percent Not Normal and Lung opacity.
Now when it comes to the bounding
boxes dataset which has missing value in x, y, height and width column
Total number of missing values in each
column are same that is 20672. As shown below
The total percentage of missing is 54.9
percent and also, we can see from below in the target column 0 means No Lung
Opacity value is same with the missing values.
So, the remaining 16957 are the positive means
Lung Opacity case. Above bar graph of classes using count shows that.
There are 26684 training images are
there and 3000 test images. Visualizations of the few samples are shown below.
Now, the visualization of the images with the bounding box is presented
below. From that we can see that there are images with different numbers of
bounding boxes. And also, maximum images don’t have bounding boxes.
As we can determine from above visualizations task in hand is a
regression problem. There is a need for building a feasible model that can
regress the bounding box in the images. And there is an extra class which is
Not normal/ No lung opacity. This class shows there is a anomaly in the lungs which can be easily misread as
pneumonia. So, there is a need to examine that class little more briefly. The
visualization which shows the all three classes together is shown below. And
the bar plot of the target class which shows all the three class is shown
below.
There is patients and other information available in the meta data of the
Dicom images. Visualizations of that data may give
better understanding of the pneumonia disease itself.
Above picture shows the data frame of the extracted dicom
data.
As we can see that there is gender of the patients, we can explore the
diversity in the given data.
Now with this information we can visualize class diversity between male
and female.
From the above images we can clearly infer that dataset has more male
examples than the female examples. In this case there are more men with
pneumonia around 4800 when compared around 3300 women has pneumonia. The
abnormality in the lungs is very high in the men compared to women. There is a
huge difference in Not normal/ No lung opacity class in the between male and
female. This shows men tend to have abnormality in lungs more often than the
women.
There are other columns which can be explored more in the meta data. The
Visualization that summarizes useful meta data such as age, gender, body part
examined and view position of the machine can be seen in below picture.
Above picture gives the histogram of the age distribution, we can see
most of the patients are above 40years and below 65 years. Detailed plot is
examined below.
From the above visualization we can clearly see that patients of age
between 50 and 60 are more effect with the dominant being age 58. This clearly
shows that pneumonia becomes more prominent at the age above 50. And we can
also see that the dataset that is provided consists of people aged between 40
and 65.
We can explore a bit further by comparing Age with the class. The
visualization that summarizes that relationship is plotted in below picture.
From the above plot we can infer that Abnormalities in the lungs are more
prominent in the people of age between 45 and 65. So of no surprise the lung
opacities are maximum in that age group.
To summarize the Exploratory data analysis. We can say we are dealing
with class imbalance as the maximum images don’t have the bounding boxes. And
we can say that there is a need for the bounding box regressor model. The
metadata provided can give insight to the disease as whole. The visualizations
of the both original data and dicom meta data is
extremely useful for the stakeholders and also model evaluation.
MODEL BUILDING
Based on the findings from exploratory data analysis and problem
statement, it is evident that the model should be a bounding box regressor
which can identify the lung opacities in turn predicting the pneumonia. Model
should have ability to localize and identify the opacities. So, based on that
we came up with following models.
CNN MODEL WITH
RESNET BLOCKS:
This model consists of series of residual blocks in the middle with down
sampling then followed by output block which leads to up sampling.
Firstly, a convolutional neural network is used to segment the image,
using the bounding boxes directly as a mask. And connected components is used
to separate multiple areas of predicted pneumonia. Finally, a bounding box is
simply regressed around every connected component.
The network consists of a number of residual blocks with convolutions and
down sampling blocks with max pooling. At the end of the network a single up
sampling layer converts the output to the same shape as the input.
As the input to the network is 256 by 256 (instead of the original 1024
by 1024) and the network down samples a number of times without any meaningful up
sampling (the final up sampling is just to match in 256 by 256 mask) the final
prediction is very crude. If the network down samples 4 times the final
bounding boxes can only change with at least 16 pixels.
Results
This model is initially trained for 20 epochs. Which gave mean IOU of 0.76 on the validation set and model is a good
fit. Accuracy increased slightly as epochs increased and loss gradually
decreases. Results for the above network on the initial network is as shown in
below graphs.
U-NET WITH
MOBILENET BACKBONE
This model is predominantly used for the image segmentation problems. In
this case UNet model is modified for pneumonia
detection problem using the coordinates of the bounding boxes to construct the masks.
Mobile net model is loaded from keras library
with imagenet competition weights and the top of the network
is frozen. Image is given as an input with the corresponding bounding box and
feature maps are produced and down sampled gradually to fit the bounding box
and then returned to original shape of the input image. This process allows the
network to propagate context information to higher resolution layers.
Network
This network consists of u-shaped architecture as the name suggests.
During the down sampling features are generated gradually. Whereas on up
sampling the features are duplicated to that of the original image with mask
segmentation.
This network takes an image input of 224*224 pixels with three channels
read, green and blue. It has around 3 million parameters. A standard
convolution network consisting of repeated use of convolutions, each followed
by a rectified linear unit (ReLU) and a max pooling
process, is the contracting part. The spatial information is decreased during
the contraction, while feature information is increased. Via a series of
up-convolutions and concatenations with high-resolution characteristics from
the contracting path, the expansive path incorporates the function and spatial
details.
Results
During the initial run of 5 epochs, u-net model showed promising results
with mean IOU of 0.88, while loss goes up and gradually decreases, the accuracy
of the model seems to take a downfall with the training. The results for the
initial run are shown in the graphs below. The drawback of this model is its
training time is very long nearly 50mins per epoch on GPU.
DENSENET 121
We have an input image in a typical Convolutional Neural Network, which
is then passed through the network to get a projected output mark in a way
where the forward pass is pretty straightforward. In a DenseNet each layer is
connected to every other layer, hence the name Densely Connected Convolutional
Network.
Approach
L(L+1)/2 direct connections exist for L layers. The feature maps of all
the previous layers are used as inputs for each layer, and their own feature
maps are used as inputs for each subsequent layer. The concatenation of feature maps from previous layers is the input of a
layer within DenseNet.
Network
There are four Dense Blocks with varying layer numbers in each
architecture. For instance, in the four dense blocks, DenseNet-121 has
[6,12,24,16] layers. We can see that a 7x7 stage 2 Conv Layer followed by a 3x3
stride-2 MaxPooling layer consists of the first part
of the DenseNet architecture. And a Classification Layer that accepts the
feature maps of all layers of the network to perform the classification follows
the fourth dense block.
Down sampling and upsampling is added to the
dense layers to learn the mask implementation the given input images of 224*224
with three channels (RGB). This network has 6million parameters.
Results
During the initial run of the model, it gave better results than U-net,
here accuracy and loss is better accompanied with 0.88 mean IOU. Training time
takes longer than other models but less than u-net around 37mins for each
epoch. The results from the initial training run is shown in the graph below.
Mask RCNN
The Mask R-CNN is the Faster R-CNN extension which adds an output model
for each detected object to predict a mask. Mask R-CNN, especially as compared
to a simple or even state-of-the-art deep convolutional neural network model,
is a sophisticated model to implement.
Approach
Matterport’s Mask R-CNN is adapted for the
problem at hand. This model generates bounding boxes and
segmentation masks for each instance of an object in the image. It's based on
Feature Pyramid Network (FPN) and a ResNet101 backbone.
Network
The first step is to
install the library. Installation involves cloning the GitHub repository and
running the installation script on the workstation. Coco dataset pretrained
weights are loaded to use for transfer learning.
Mask RCNN architecture
consists of two stages,
Stage 1: The first stage
consists of two networks, a backbone network (ResNet,
VGG, Inception, etc.) and a network of regional proposals. To offer a set of
region proposals, these networks run once per picture. Proposals for a region
are regions in the function map that contain the object.
Stage 2: In the second stage,
the network predicts bounding boxes and object class for each of the proposed
region obtained in stage1. Each proposed region can be of different size
whereas fully connected layers in the networks always require fixed size vector
to make predictions. Size of these proposed regions is fixed by using either RoI pool (which is very similar to MaxPooling)
or RoIAlign method. The output from RoIAlign layer is then fed into Mask head, which consists
of two convolution layers. It generates mask for each RoI,
thus segmenting an image in pixel-to-pixel manner.
Results:
After the initial run of
5 epochs of training loss is reducing gradually along with the rpn_class_loss, rpn_bbox_loss, mrcnn_class_loss, mrcnn_bbox_loss
and mrcnn_mask_loss. This model train little faster
than the above models.
POTENTIAL
CHANCES TO IMPROVE THE MODEL
There are some parts of the model, data and hyperparameters in the models
can be used to improve the performance so far,
1.
Depth of the models can be
increased along with the optimizers and learning rate.
2.
Subset of the data can be
trained using the above models for a greater number of epochs to achieve the
convergence which may give better results.


Before you begin
This is a cross-platform class which primarily focuses on Xamarin.Android and Xamarin.iOS. To fully complete the coding exercises, you will need both development environments with either a simulator/emulator or devices to run the exercise on. Please see the setup page if you need help installing the Xamarin development environment.
Overview
In this class, we will look at specific techniques to identify memory issues in our managed applications and then turn to specific Xamarin.iOS and Xamarin.Android issues that many applications encounter.
Objectives
- Identify and fix memory leaks in your code
- Recognize and fix Xamarin.iOS specific memory problems
- Recognize and fix Xamarin.Android specific memory problems
Lecture
XAM370 - Diagnosing Memory Management Issues.
Exercises
Exercise materials are available from GitHub. The code can be cloned through a desktop Git client or downloaded directly as a ZIP file.
- Using the Xamarin Profiler to monitor allocationsDemonstration
In this demonstration, we will examine an application and watch it's memory allocation to identify some potential improvements we can make in the code. - Finding and fixing delegate reference leaksExercise
In this exercise, we will track down a memory leak in a Xamarin.Forms application which is caused by an event handler. - Identifying and breaking strong reference cyclesExercise
In this group exercise, we will troubleshoot and fix a Xamarin.iOS application which has a reference cycle that causes a memory leak. - Watch out for peer promotionsExercise
In this group exercise, we will fix a case where Xamarin.iOS holds onto a view reference due to a framework peer promotion. - Show ListView memory and performance with a custom adapterDemonstration
In this final demonstration, we will troubleshoot and fix some performance issues with an Android application which utilizes aListView
.


Delighters.JS
Add CSS animations to delight users as they scroll down.
A tiny javascript library by Q42
https://github.com/Q42/delighters
1. Include the script
2. Add data-delighter attributes
3. Write your own CSS delighters
Features
- Declarative
- Flexible
- Light footprint
- Framework-agnostic
- Supports desktop, mobile & tablets
- Degrades gracefully to your default styling
Usage
1. Include the script
<script type="text/javascript" src="delighters.js">
2. Add delighter attributes
<div class="foo" data-delighter>
3. Style the delighter (or its children) using built-in classes
.started
and .ended
/* when the library loads, each [data-delighter] gets the .delighter class */ .foo.delighter { transition: all .3s ease-out; transform: translateX(-100%); opacity: 0; } /* the .started class is set when the top of [data-delighter] is at 0.75 of the viewport (where 0 is top and 1 is bottom) */ .foo.delighter.started { transform: none; opacity: 1; } /* an extra .ended state is set when the bottom of [data-delighter] is at 0.75 of the viewport (where 0 is top and 1 is bottom) */ .foo.delighter.started.ended { border: solid red 10px; }
How it works
- Delighters.js toggles classes when you scroll down. You do the rest!
- Each delighter gets a
.started
class when its top raises above 75% of the browser's viewport height - When the bottom of the delighter is at 75%, an extra class
.ended
is added - You can change any of these like so:
data-delighter="start:0.5;end:0.95;
- Remember: 0 = top, 1 = bottom
- Values outside the viewport are allowed, such as
start:1.2;end:-0.3
Debugging
- Set the
data-delighter="debug"
flag to enable debugging for that delighter - This will give the delighter a red outline
- Also, a dotted red hint line is shown when the delighter is within the viewport
- The hint line is positioned at the defined start, which by default is
0.75
- The line is removed when the bottom of the delighter is above the end position, by default also
0.75
Calculating your own scroll position
If you need to get your scroll position manually, then override the getScrollPosition
method:
Delighters.getScrollPosition = function() { return $(document).scrollTop(); }


By clicking on sign up, you agree to terms & conditions and privacy policy
Already have an account? Sign in


I had my first week of work experience in the village veterinary
I learned many skills during this week such as the importance of clear communication and the basics of running a sole trader business
In my time at bord gais I was given many tasks to fufill.
Here i learned how to coordinate as a team and how to use technology within a business, such as microsoft excel


Foreign Minister to celebrate Rights of the Child in Brussels
The Minister of Foreign Affairs and Regional Integration, Hon. Shirley Ayorkor Botchwey, will participate in a High-Level Conference to celebrate the 30th anniversary of the Convention on the Rights of the Child (CRC).
The celebration is slated for Wednesday, 20th November, 2019 in Brussels, Belgium.
The Hon. Foreign Minister was invited by the Chair of the European Parliament’s Subcommittee on Human Rights, Maria Arena, to participate in the celebration.
She is expected to arrive in Brussels, Belgium on Tuesday night, November 19, 2019.
Expected to serve as the Guest of Honour for the Brussels ceremony is the Queen of the Kingdom of Belgium and Honorary President of UNICEF-Belgium, Queen Mathilde.
Other dignitaries expected to grace the celebration are the President of the European Parliament, David Sassoli, and the President of the European Commission, Ursula Van der Layen.
Hon. Ayorkor Botchwey will be part of a high-level panel discussion on the topic “Every child has the right to dream”.
Among the issues to be discussed during the session are: protecting the rights of the child in an ever-changing digital world: threats and opportunities; addressing the changing nature of armed conflict and its impact on children's rights and future, as well as mainstreaming of a child- rights approach in all development planning and implementation globally.
During the discussion, the Hon. Ayorkor Botchwey is expected to point out Ghana’s commitment to institutionalize the Rights of the Child, which was further demonstrated when the country’s Legislature passed the Children’s Act into law in 1998.
The Children's Act, among others, provides for the rights of the child and protects children from exploitative labour and child marriages.
Ghana made history by becoming the first country in the world to sign and ratify the Convention on the Rights of the Child in 1990.


We're sorry but this doesn't work properly without JavaScript enabled. Please enable it to continue.


_Mercy_Streets_ (PG-13) * 1/2 (out of ****)
_Mercy_Streets_ is the latest feature film project from Providence Entertainment, the makers of last year's abysmal Christian-themed thriller _The_Omega_Code_--and, as that fact suggests, there is an aggressive pro-faith agenda at work in this drama. For devout viewers of the Trinity Broadcasting Network, that element will be enough to not only send them flocking to theatres, but also spread enthusiastic word-of-mouth (as was the case with _Omega_). For everyone else, however, that angle is the only thing that separates this plodding melodrama from most cheap direct-to-video fare.
The not-ready-for-the-big-screen indications come early, when we see that the top-billed star is none other than straight-to-tape stalwart Eric Roberts. Roberts, in fact, only has a supporting role in _Mercy_Streets_, taking a back seat to the real lead, a justified unknown by the name of David White (who also produced). White plays John, a recently released convict who quickly falls back under the wing of mentor Rome (Roberts) and into the criminal life. John tries to double cross Rome, but when the plan unravels, John seeks out estranged brother Jeremiah, a gentle guy studying to become an Episcopal priest. The twist? Jeremiah and John are twins, setting the stage for laughably primitive camera tricks (the brothers never face the camera at the same time; composite shots have an obvious dividing line; etc). When Rome inadvertently kidnaps Jeremiah, John must assume his brother's identity, and Jeremiah has his darker instincts brought out by Rome's persuasive ways.
While not especially fresh, there's nothing inherently wrong with the basic premise of _Mercy_Streets_. But such a twin-switch scenario sinks or swims with the actor tackling the dual role, and White isn't up to the task. He is completely overwrought and unconvincing as the tough John (an early scene that's designed to establish the character's mean side is especially embarrassing), and while he fares better as the nice Jeremiah, White isn't able to convey what should be the conflicted anguish of that character. The air of realism that director Jon Gunn so clearly strives for is also ruined by Roberts' scenery chewing theatrics.
Then there's the matter of the religious agenda. Don't get me wrong; I have no problem with a film that tries to push a personal belief as long as it goes about it in a compelling way (e.g. _The_Contender_). Gunn fails to do so; despite some arbitrary visual flourishes (slow motion and freeze frames), the film is slowly, lazily paced, and he and co-writer John W. Mann clunkily incorporate the Gospel message--somewhat baffling considering one of the main characters is a minister-in-the-making. As such, when the film suddenly shifts to talk of God and His word, the moments stick out and feel even more preachy than they otherwise would have been.
The softhearted spiritual talk also feels less than sincere considering the amount of violent content in _Mercy_Streets_. Bloodshed is fairly minimal, but there are some brutal moments, in particular a couple of fistfighting scenes and one unexpectedly intense beating scene. The positive message behind _Mercy_Streets_ is good for the entire family, but it seems like wasted effort when the vessel for the message isn't entirely appropriate for all audiences.
©2000 Michael Dequina
Michael Dequina<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>Mr. Brown's Movie Site: http://www.mrbrownmovies.com CinemaReview Magazine: http://www.CinemaReview.com on ICQ: #25289934 | on AOL Instant Messenger: MrBrown23
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


This part is inside a .container class.
The .container class provides a responsive fixed width container.


Meneame sentiments
Main function. Connects to a database and reads a CSV with the arousal and valence. Uses the sentiment library to compute the sentiment of a new.
param input_file: the ANEW file param dbname:the name of the database
scraper package
sentiments package
Enter search terms or a module, class or function name.


I like to make things that work and that other people use and like. My developer 'way of life' started a long time ago when I was still into computer games, trying to hack my way through making websites and servers, when I first discovered a passion for computers and making things in the digital world. From then on I got into linux, shell, web design, and now I aspire to become a professional application developer/project manager and much more! Below are some technologies I am familiar with (some of many more).


Create a Game Setting
Use this form to create a game setting. A starter template will be displayed to help you get going.
Cypher Character Generator
New GameUse this form to create a game setting. A starter template will be displayed to help you get going.


Tap to read description
Reach via WhatApp
+917019856923
+919844994785
home Acharya Institutes, Dr. Sarvepalli Radhakrishnan Rd, 560090
Tap anywhere to dismiss


[[Downloading log file|Log file download dialog title.]]
[[Please wait until download has finished.|Log file download dialog info.]]
[[Downloaded: |Log file download dialog download status info.]] {{ $ctrl.loaded | kdMemory }}
[[Save|Log file download dialog 'Save' button.]]
[[Abort|Log file download dialog 'Abort' button.]]
[[Forbidden (403)|Error title displayed on log file download dialog.]]
{{$ctrl.kdLocalizerErrors.MSG_FORBIDDEN_RESOURCE_ERROR}}
[[Close|Log file download dialog 'Close' button.]]


ReactJS Lunch @ CHILI lab, EPFL
May 29th, 2017
⟶ GET board/123/cards
⟵ 200 OK [{
"content": "Move static assets to CDN",
"collaborators": [{...}],
"labels": [{...}, {...}],
"board": {...},
"checklists": [{...}, {...}],
"createdAt": {...},
"updatedAt": {...},
"expiresAt": {...},
"dueDate": {...},
"author": {...},
"attachments": [{...}, {...}],
"activity": [{...}, {...}],
"webhooks": [{...}, {...}],
]}
⟶ GET board/123/cards
⟵ 200 OK [{
"content": "Move static assets to CDN",
"collaboratorsIds": [1308]
]}
⟶ GET collaborator/1308
⟵ 200 OK [{
"name": "Manu",
"avatar": "https://..."
]}
⟶ GET board/123/cards?include=content,labels&expand=collaborators
⟵ 200 OK [{
"content": "Move static assets to CDN",
"labelsIds": [99, 101],
"collaborators": [{...}, {...}]
]}
⟶ GET board/123/cards
⟵ 200 OK [{
...
"collaborators": [{
"name": "Manu",
"avatar": "https://...",
"type": "premium",
"cards": [...],
}],
...
]}
#
# Welcome to the MiniTwitter GraphQL API. It was built by James Nolan as a
# demonstration for the May 29th React Lunch about GrapHQL and Apollo client
#
# Users can write tweets. Users have IDs that have the format of a twitter handle
type User {
# The ID of the user. It is in the Twitter handle format, such as @johnDoe
id: ID
# The name of the user. Usually first name + last name
name: String
# The list of users that follow that user
followers: [User]
# The list of tweets the user wrote
tweets(limit: Int): [Tweet]
}
# A tweet typically consists in a small text and the number of people that liked it
type Tweet {
# The ID of a tweet. Typically a unique integer
id: ID
# the actual content of the tweet. Max 144 in length!
content: String
# the number of times the tweet has been liked
likes: Int
# the user that wrote the tweet
author: User
}
# Queries allows the client to retrieve data from the API. GraphQL queries can be
# compared to GET requests in REST APIs
type Query {
# Returns a list of all the tweets. You can optionally pass a limit parameter to
# specify the max number of tweets the API can return
tweets(limit: Int): [Tweet]
# Returns a single tweet by its ID
tweet(id: ID!): Tweet
}
# Mutations are similar to Queries, except that they will probably change something
# in the data. GraphQL Mutations can be compared to POST requests in REST APIs
type Mutation {
# Updates the "like" count of a given tweet. You should pass the ID of the tweet
# to update
likeTweet(id: ID!): Tweet
}
`
(view in editor)
Int
: a 32-bit signed integerFloat
: A signed double-precision floating-point valueString
: A UTF‐8 character sequenceBoolean
: true or falseID
: A unique identifier (alias of String)
enum CoffeeSize {
Short
Tall
Grande
Venti
}
mutation ($type: String, $size: CoffeeSize) {
orderCoffee (type: $type, size: $size) {
timeToWait
}
}
# variables
{ type: "Americano", CoffeeSize: "Short" }
type User {
id: ID!
name: String!
followers: [User!]
}
Connecting a simple UI to a GraphQL server
git clone git@github.com:j-nolan/react-lunch-graphql.git
cd react-lunch-graphql
cd server && npm install && npm start
cd example-apps/01-pure-ui && npm install && npm start
cd example-apps/02-query-tweet && npm install && npm start
cd example-apps/03-mutate-tweet && npm install && npm start
cd example-apps/04-mutate-tweet-optimistic && npm install && npm start
cd example-apps/05-polling && npm install && npm start
refetchQueries
export default graphql(createTweetMutation, {
props: ({ mutate }) => ({
createTweet: (content, authorId) => mutate({
variables: { content, authorId },
refetchQueries: [{
query: listTweetsQuery
}],
})
})
})
update
export default graphql(createTweetMutation, {
props: ({ mutate }) => ({
createTweet: (content, authorId) => mutate({
variables: { content, authorId },
update: (store, { data: { createTweet } }) => {
const data = store.readQuery({ query: listTweets });
data.tweets.push(createTweet);
store.writeQuery({ query: listTweets, data });
},
})
})
})
<App>
graphql(closestTweets)(<Map />)
</App>
Geolocation.getCurrentPosition()
<App>
withApollo(<Map />)
</App>
/* Map.js */
export default class Map extends Component {
/* Get location, then manually trigger query, then render query result */
}
loading
and error
states
<App>
withLocation(graphql(closestTweets)(<Map />))
</App>
withLocation
Higher Order Component (HOC)