-*- mode: outline -*- [10/15/00] Sun 8:45PM - learning: 1. - Rabbi Zidni 'Ilma. 2. - bismillah. 3. - 10-15 min chunks of lots of subjects? * so that you have to take one look at your digested output and you'll will know what to do. * knowledge comes from God. (you can play with wires and potentials for years but coming up with Del E = Grad V/t comes from God.) Wisedom is guidance. You can know about the splitting of the nucleus but giving it to idiots is wrong. Wisedom is knowing what the best thing to do is with the vector of life. - Software Engineering: * write clean code. * but that doesnt help if your code looks clean but is very hard to figure out or is not very easy to make changes to. * so write clean code, document intent as you write, write self documenting easy to modify code. * Only in the rarest cases is the first attempt at writing a program unit free of errors. syntax errors and run-time errors (such as division by zero) are easy to detect because of system-generated error messages, not so logic errors, where the program executes but does not produce the correct results. * black-box testing only checks inputs and their outputs, white-box testing examines the internals of the code segment and sees how inputs are digested. * Experienced programmers know, however, that special cases must always be considered when selecting test data, since it is often these cases that cause a program unit to malfunction. * 'desk checking' manually an algorithm * Attempting to fix a program unit with "quick and dirty" patches is almost always a bad idea, because it fails to address the real source of the problem and thus makes the program unnecessarily complicated and "messy". - some random thoughts: - v1.1 - write "clean" code - document intent as you write. - A. - developing a project you are an architect of that thing that people see on their computer screen with which they interact with various levels of frustration. * building blocks upon intelligent building blocks. * to become a W. Richard Stevens. * "intelligence". (of the causal kind). * time. * quantized sentencular thoughts.2001 Jul 11 Wed [ 6:44PM] - Test First Design * the Goal * user stories * take a simple one. flesh it out? (what are the input and outputs for this story) * acceptance test for the user story? * "Shall we come up with a design for the system?" * "I wouldn't mind a UML diagram showing the problem domain concepts ... that will give us some candidate objects that we can explore further in code." * "Well, pick a class ... any class. Shall we start at the end of the dependency chain and work backwords?" * This will make testing easier. * Lets create a test case for the Throw class. * what is the behavior fo a Throw object? * behavior class rather than data store (more than just setters and getters) * Refactor mercilessly. - Design Patterns: It's a book of 'design patterns' that describes simle and elegant solutions to specific problems in object oriented software design. * All can be implemented in standard object-oriented languages, thogh they might take a little more work than ad hoc sllutions. But the extra effort invariably pays dividends in increased flexibility and reusability. Once you understand the design patterns and have had an "Aha!" (and not just a "Huh?") experience with them, you won't ever think about object-oriented design in the same way. You'll have insights that can make your own designs more flexible, modular, reusable, and understandable - which is why you're interested in object-oriented technology in the first place, right? * the pattern provides an abstract description of a design problem and how a general arrangement of elements (classes and objects in our case) solves it. * Though consequences are often unvoiced when we describe design decisions, they are critical for evaluating design alternatives and for understanding the costs and benfits of applying the pattern. Since reuse is often a factor in object-oriented design, the consequences of a pattern include its impact on a system's flexibility, extensibility, or portability. Listing these consequences explicitly helps you understand and evaluate them. * The design pattern identifies the participating classes and instances, their roles and collaborations, and the distribution of responsibilities. * Object-oriented programs are made up of objects. An 'object' packages both data and the procedures that operate on that data. An object performs an operation when it receives a 'request' ( or 'message' ) from a 'client'. * The hard part about object-oriented design is decomposing a system into objects. The task is difficult because many factors come into play: encapsulation, granularity, dependency, flexibility, performance, evolution, reusability, and on and on. They all influence the decomposition, often in conflicting ways. * Object-oriented design methodologies favor many different approaches. You can write a problem statement, single out the nouns and verbs, and create corresponding classes and operations. Or you can focus on the collaboratoins and responsibilities in your system. Or you can model the real world and translate the objects found during analysis into design. There will always be disagreement on which approach is best. * Many objects in a design come from the analysis model. But object-oriented designs often end up with classes that have no counterparts in the real world. Some of these are low-level classes like arrays. Others are much higher-level. For example, the Composite pattern introduces an abstraction for treating objects uniformly that doesn't have a physical counterpart. Strict modeling of the real world leads to a system that reflects today's realities but not necessarily tomorrow's. The abstractions that emerge during design are key to making a design flexible. * Design patterns help you identify less-obvious abstractions and the objects that can capture them. For example, objects that represent a process or algorithm don't occur in nature, yet they are a crucial part of flexible designs. The Strategy pattern describes how to implement interchangeable families of algorithms. The State pattern represents each state of an entity as an object. These objects are seldom found during analysis or even the early stages of design; they're discovered later in the course of making a design more flexible and reusable. * Polymorphism, lets a client object make few assumptions about other objects beyond supporting a particular interface. Polymorphism simplifies the definitions of clients, decouples objects from each other, and lets them vary their relationships to each other at run-time. * An abstract class is one whose main purpose is to define a common interface for its subclasses. An abstract class will defer some or all of its implementation to operations defined in subclasses; hence an abstract class cannot be instantiated. ---------------------------------------------- - Refactoring - 1. Frameworkers know that a framework won't be right the first time around it must evolve as they gain experience. - 2. They also know that code will be read and modified more frequently than it will be written. - 3. The key to keeping code readable and modifiable is refactoring, for frameworks, in particular, but also for software in general. - 4. To avoid digging your own grave, refactoring must be done systematically. - 5. when and where you should starting diggging in your code to improve it. - 6. The refactorings in this book will help you change your code one small step at a time, thus reducing the risks of evolving your design. - 7. Even so the program works. Is this not just an aesthetic judgement, a dislike of ugly code? It is until we want to change the system. The compiler doesn't care whether the code is ugly or clean. But when we change the system, there is a human involved, and humans do care. A poorly designed system is hard to change. Hard because it is hard to figure out where the changes are needed. If it is hard to figure out what to change, there is a strong chance that the programmer will make a mistake and introduce bugs. - 8. When you find you have to add a feature to a program, and the program's code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature. - 9. Whenever I do refactoring, the first step is always the same. I need to build a solid set of tests for that section of code. The tests are essential because even though I follow refactorings structured to avoid most of the opportunties for introducing bugs, I'm still human and still make mistakes. Thus I need solid tests. - 10. On testing methodology: Because the statement produces a string, * I create a few customers, * give each customer a few rentals of various kinds of films, and * generate the statement strings. * I then do a comparison between the new string and some reference strings that I have hand checked. * I setup all these tests so I can run them from one Java command on the command line. These tests take only a few seconds to run. It is vital to make self checking tests, otherwise you waste time. - 11. It is essential for refactoring that you have good tests. Its worth spending the time to build the tests, because the tests give you the security you need to change the program later. - 12. Refactoring changes the programs in small steps. If you make a mistake, it is easy to find the bug!!! ... small steps are the best - 13. Code that communicates its purpose is very important. I often refactor just when I'm reading some code. That way I gain understanding about the program, I embed that understanding into the code for later so I don't forget what I learned. - 14. Never be afraid to change the names of things to improve clarity. - "Replace Temp with Query" double getPrice() { int basePrice = _quantity * _itemPrice; double discountFactor; if (basePrice > 1000) { discountFactor = 0.95; } else { discountFactor = 0.98; } return basePrice * discountFactor; } should become: double getPrice() { return basePrice() * discountFactor(); } private int basePrice() { return _quantity * _itemPrice; } private double discountFactor() { if (basePrice() > 1000) { return 0.95; } else { return 0.98; } } the advantage being other places can now make use of these methods. Still don't fully comprehend how this is useful. - "Self Encapsulate Field" class IntRange { private int _low, _high; boolean includes (int arg) { return arg >= _low && arg <= _high; } .-. => becomes class IntRange { private int _low, _high; int getHigh() { return _high } boolean includes (int arg) { return arg >= getLow && arg <= getHigh; } * if you want to override the field in a subclass. * When you are using self-encapsulation, you have to be careful about using the setting method in the constructor. Often it is assumed that you use the setting method for changes after the object is created, so you may have different behavior in the setter than you have when initializing. In cases like this I prefer using either direct access from the constructor or a separate initilization method. * The value in doing all this comes when you have a subclass: class CappedRange { .-. int getHigh() { return Math.min( super.getHigh(), getCap() ) } } - CGI Programming: a
sends information via HTTP to a cgi script on some server. The server makes something of the information and then responds in some way. browsers actually encode form information in the Internet Mediat Type format named 'application/x-www-form-urlencoded', the other optional encodying formats are 'multipart/form-data' and 'text/plain', for file uploading and sending data to an email address instead of a server. thought. form elements. * text * select # sends somthing.cgi?foo=spiderman&foo=gargoyle&Fooey+Upon+You=foobar * textarea - style stuff
your data here. ~/public_html/dev/cgi_dot_pm$ telnet localhost 80 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET /~mehryar/dev/cgi_dot_pm/b5-cookies.cgi HTTP/1.0 HTTP/1.1 200 OK Date: Fri, 20 Jul 2001 07:26:06 GMT Server: Apache/1.3.19 (Unix) mod_perl/1.25 Set-Cookie: foobar=xyzzy; path=/~mehryar/dev/cgi_dot_pm; expires=Fri, 20-Jul-2001 08:26:07 GMT Connection: close Content-Type: text/html; charset=ISO-8859-1 Hello Im setting a cookie Connection closed by foreign host. ~/public_html/dev/cgi_dot_pm$ telnet localhost 80 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET /~mehryar/dev/cgi_dot_pm/b6-cookies.cgi HTTP/1.0 Cookie: foobar=xyzzy; path=/~mehryar/dev/cgi_dot_pm; expires=Fri, 20-Jul-2001 08:26:07 GMT HTTP/1.1 200 OK Date: Fri, 20 Jul 2001 07:27:15 GMT Server: Apache/1.3.19 (Unix) mod_perl/1.25 Connection: close Content-Type: text/html; charset=ISO-8859-1 Untitled Documenttesting cookies
cookie returned =
$VAR1 = 'xyzzy';
Connection closed by foreign host. - escape stuff html escaping is converting back and forth from text to html codes. and i guess that means only certain specical characters are converted, like '<' and '&', ' ', get converted to %3C http escaping converts some non alphabet characters to their hex versions. So ' ' is ord 32, - css - Apache: ./httpd -f my_httpd.conf ./httpd -V # show compile settings 1. stuff in cgi-bin is not chmoded by default - Apache/mod_perl: installation: remember the make install, creates an httpd in the apache source directory. you have to do a make install in there for the mod_purled httpd to get installed. last phase before the cleanup is the logging phase. * type checking phase * fixup phase * response phase (content handler phase?) Access Control.(you are not allowed here, whoever you are) Authentication.(who are you?) Authorization. (I know who you are but are you authorized to see this?) A Simple Access Control Module: Apache::GateKeeper -- .htaccess PerlAccessHandler Apache::GateKeeper PerlSetVar Gate open require valid-user AuthUserFile /home/mehryar/htpasswd AuthGroupFile /dev/null AuthName ByPassword AuthType Basic mod_access order deny,allow deny from all allow from 192.168.2 installed first gets first shot. its usually mod_access first then Apache::GateKeeper. Any of them have veto power. or they can DECLINE and pass off decision to next access handler. $allowed_day = $r->dir_config('Allowed_Day'); # reads PerlSetVar Allowed_Day \ Tue # "\" Tue to note $ua = $r->header_in('User-Agent'); $day = (qw(sun mon tue wed thr fri sat))[localtime->wday]; # use Time::localtime my ($result, $sent_pwd) = $r->get_basic_auth_pw; my $user = $r->connection->user; $r->note_basic_auth_failure; $r->log_reason; $r->filename; # request notes, (as in my notes), $r->notes(foo => bar); - linear algebra: * basic variables * free variables * general solution * parametric description of solution sets * existence of a solution set * uniqueness of a solution set * space of a vector * zero vector * linear combination of V1 and V2. * set of all possible linear combinations of V1 and V2 in R^N is called "the subset of R^N spanned by {V1, V2}" denoted by "Span {V1,V2}". V1 = 1.V1 + 0.V2 (hence V1 is also in Span {V1,V2}. (more generally Span {V1, ..., Vp} - logarithms - bits & stuff: a bit. [0/1] a bit can represent only 2 things. or two numbers. or A and B. two bits [0/1,0/1]:[00][01][10][11],can represent 2x2=4 things.[A,B,C,D],[0,1,2,3] three bits can represent 2^3=8 things. four bits can represent 2^4=16 things. five bits can represent 2^5=32 things. now since the english alphabet has 26 things in it, you need atleast 5 bits to represent all of the alphabet. or (4.8), but thats another story. 8 bits can represent 2^8=256 things. so a byte can represent 256 things. a 64 bit value can represent 2^64= 18,446,744,073,709,551,616 (18 pentillion). little_women.txt ls -l little_women.txt # -rw-rw-r-- 1 mehryar mehryar 1020558 Dec 16 12:00 little_women.txt That says there are 1,020,558 bytes in the Gutenberg little_women.txt file. Since a character is represented by a byte on my machine, thats 1.020558 million characters. A kilobyte is usually 1024bytes. So little women =~ 996.638671875 kB or 997kB ls -ls little_woment.txt 1002 -rw-rw-r-- 1 mehryar mehryar 1020558 Dec 16 12:00 little_women.txt says 1002kB are used to store little_women.txt (thats because a total block is used up and not partially written to). a baud is a bit per second. modem : speed : theoretical time to send little_women.txt 9800 9,800 9.8kbs 104s (1:44 min) 14.4k 14,400 14.4kbs 70s 28.8k 28,800 28.8kbs 35s 36k 36,000 36.0kbs 28s 56k 56,000 56.0kbs 18s ISDN 112,000 112.0kbs 9s DSL ?? Cable 1,500,000 1.5 Mbs 0.68s T1 (1.544Mbs) 1.544Mbs 0.66s ethernet 10M 10.000Mbs 0.10s T3 (44.736Mbs) 44.736Mbs 0.02s ethernet 100M 100.000Mbs 0.01s 10205 microseconds. gigbit ethernet 1.000Gbs 0.001s 1020 microseconds. umask bits # --x 1 # -w- 2 # -wx 3 # r-- 4 # r-x 5 # rw- 6 # rwx 7 so umask(0444); and sysopen(FH,"foo.txt",O_WRONLY|O_CREAT,0777); => -wx-wx-wx what that means is 777 or 111 111 111 and-ed with 100 100 100 => 100 100 100 umask(0777) and sysopen(FH,"foo.txt",O_WRONLY|O_CREAT,0777); ands the mask with the permissions, you get 0777. and those are the bits turned off for the newly created file. - unix: ### rcp stuff rcp spiderman.txt lepew:/usr/test/mehryar/. ### tar stuff tar czvf foo.tar.gz mfister.dbs tar xzvf foo.tar.gz ( to untar ) tar tzvf foo.tar.gz ( to list but not untar ) #### using cut nice top | cut -c7-14, 57-100 (or -b bytes -d delimiter -f fields -s? ) cut -d\ -f 1 #### using sort file * | sort -b -f -t: +1 # -b ignore leading blanks when finding sort keys, # -f fold lower case into upper so 'a' is same as 'A' # -t separator is ':' # +1 sort by field 1 (starting with zero). to sort this numerically HTML static hello.html 1148.1 50000 hits 43.55 sec 0.000871 311 bytes HTML::Embperl v1.3.0 2000 h2000.epl 107.7 6463 hits 60.02 sec 0.009287 28840 byte HTML::Embperl v1.3.0 hello.epl 466.4 27996 hits 60.02 sec 0.002144 220 bytes sort -r -n -k1.59,1.64 foo.txt HTML static hello.html 1148.1 50000 hits 43.55 sec 0.000871 311 bytes HTML::Embperl v1.3.0 hello.epl 466.4 27996 hits 60.02 sec 0.002144 220 bytes HTML::Embperl v1.3.0 2000 h2000.epl 107.7 6463 hits 60.02 sec 0.009287 28840 byte - bash: * pattern matching in bash (primitive) a='http://www.mehryar.com/cgi-bin/sal?foo=bar' echo ${a#http*/} # '#' match from the beginning and strip http followed by anything upto a slash # nongreedy kills only the first slash # prints = /www.mehryar.com/cgi-bin/sal?foo=bar echo ${a##http*/} # greedy kills upto the last slash # prints = sal?foo=bar echo ${a%/*} # '%' matches from the back # prints = http://www.mehryar.com/cgi-bin # strips everything after the last / echo ${a%%/*} # greedy matches from the back and kills everything upto the first slash # prints = http: # substitutions with bash echo ${a/\/*\//URL} # substitutes everything between two slashes with URL # prints = http:URLsal?foo=bar echo ${a/\/*\//} # substitute everything between two slashes with ... nothing given so with nothing # http:sal?foo=bar - variables: $* and $@ - I don't know the difference but they are the arguments provided to a bash script $0 is script name, $1, $2, etc are the rest. beyond $9 you have to do something special - don't know what - sed's regex's suck foo='mehryar mansoor'; echo $foo | sed -n -e 's/^.* //p'; prints 'mehryar' - read a junk; will read the first word into a, and the rest into junk. - if [ "$1" = "foobar" ]; then echo "yup its a foobarity alright"; else echo "nope not it"; fi; - file test operators. # -e file: True if file exists. # -d file: True if file exists and is a directory. # # -a file: True if file exists. # -b file: True if file exists and is a block special file. # -c file: True if file exists and is a character special file. # -f file: True if file exists and is a regular file. # -g file: True if file exists and is set-group-id. # -h file: True if file exists and is a symbolic link. # -k file: True if file exists and its ``sticky'' bit is set. # -p file: True if file exists and is a named pipe (FIFO). # -r file: True if file exists and is readable. # -s file: True if file exists and has a size greater than zero. # -t fd: True if file descriptor fd is open and refers to a terminal. # -u file: True if file exists and its set-user-id bit is set. # -w file: True if file exists and is writable. # -x file: True if file exists and is executable. # -O file: True if file exists and is owned by the effective user id. # -G file: True if file exists and is owned by the effective group id. # -L file: True if file exists and is a symbolic link. # -S file: True if file exists and is a socket. # -N file: True if file exists and has been modified since it was last read. # file1 -nt file2 True if file1 is newer (according to modification date) than file2. # file1 -ot file2 True if file1 is older than file2. # file1 -ef file2 True if file1 and file2 have the same device and inode numbers. # -z string: True if the length of string is zero. # -n string: True if the length of string is non-zero. # -o optname: True if shell option optname is enabled. See the list of options under the # description of the -o option to the set builtin below. -- testing exit status of last command exit_status=$? if [ "$exit_status" != "0" ]; then echo "you died unnaturally" fi - lynx: ====== v - view bookmarks a - add bookmark p - print or save page E - edit current URL V - view current URL z - cancel transfer \ - show source = - info - Perl: ====== - here documents # finally I always forget here documents my $foo =<<'EOT' Hello $a Buddy Boy EOT - finally what the s and m stand for in perlre $s = "Batman\nSuperman"; s treat string as single line. in this case dot(.) will match even a new line which it wont do by default so m/(.+)man/; prints "Batman\nSuper" m treat string as multiple lines. so ^ and $ match multiple times in the string and not just once. - finally for the last time, what the hell is the matter with grep and map? * $n = grep /b/, qw( superman batman robin ); # 2, # number of true matches * @foo = grep /b/, qw( superman batman robin ); # batman, robin # true matches * $n = map /b/, qw( superman batman robin ); # number of list elements # produced by BLOCK or EXPR * @foo = map /[aeiou]./g, qw( superman batman robin ); # list elements produced # by BLOCK or EXPR - file locking flock() implements a cooperative system of locking that must be used by all programs attempting to access a given file if it is to be effective. This includes read-only scripts, which can use flock() to test whether or not it is safe to attempt a read on the database. flock() allows locking in two modes: exclusive and shared see my semaphores example implements MJDs stuff what it basically says is FILE_EX flock a file other than the data file. and dont let go off that EXclusive lock until you're done with your business. my $FILE = 'hitcounter.txt'; my $SEMAPHORE = $FILE . '.lck'; # 1. open the SEMAPHORE file and open(S,"> $SEMAPHORE") || die "couldnt open semaphore lock file\n"; # 2. get a shared lock flock S, LOCK_EX; # 3. open the data file open(FH, $FILE) || die "couldnt open for reading\n"; # 4. read it. my $count = ; ++$count; # 5. write info print "count = $count\n"; # 6. close data filehandle close FH; # # 7. close SEMAPHORE filehandle # close S; # # open(S,"> $SEMAPHORE") || die "couldnt open semaphore lock file\n"; # flock S, LOCK_EX; # write open(OUT,">$FILE") || die "couldnt WRITE\n"; print OUT $count; close OUT; close S; __END__ - do/require/use/import and memory #!/usr/local/bin/perl use strict; use warnings; sleep 5; if (1) { require Date::Calc; Date::Calc->import(qw(:all)); } sleep 5; __END__ 3288K plain perl process 3644K if (0) and use (); 3766K if (0) and use (:all); 3644K if (1) and use (); 3766K if (1) and use (:all); 3292K if (0) and require; 3292K and then 3644K if (1) and require; 3292K if (0) and require and import(:all); 3292K and then 3766K if (1) and require and import(:all); - Data::Dumper Data::Dumper::Indent = 0,1,2 or 3 my $dumper = Data::Dumper->new(ARRAYREF,[ARRAYREF]); my $dumped_value = $dumper->Dump; and later eval $dumper_value * . perl -mFoo is 'use Foo ()'; . -MFoo is 'use Foo'; . -M-Foo is 'no Foo'; . -M'Cwd qw(abs_path fast_abs_path)' is 'use Cwd qw(abs_path fast_abs_path);' . -MCwd=abs_path,fast_abs_path same as above * hex, treats its argument as a hex value and returns its decimal value. hex 9 => 9 hex a => 10 hex b => 11 hex 10 => 16 (hex 10 is decimal 16) (hex a is decimal 10) oct 7 => 7 oct 8 => 10 (oct 8 is decimal 10) * oct('0x10'); # treats its argument as a hex converts it into decimal 16 * oct('010'); # treats its argument as an oct converts it into decimal 8 * oct('0b10'); # treats its argument as a binary converts it into decimal 2 * printf("%#x",10); # does the opposite so this prints 16, takes its argument as a decimal # and converts it into a hex * printf("%#o",10); # prints 8 * printf("%#b",4); # print 0b100 or 100 hex 10; # returns 16, i.e. treats its arg as a hex and converts it into a dec. hex '010'; # returns 16; hex '0x10'; # returns 16; oct 10; # returns 8; oct '010'; # returns 8; oct '0x10'; # returns 16; treats it as a hex oct '0b10'; # should treat it as a binary but its not working printf "%s\n",join '', map chr, map hex, qw(0x31 0x39 0x38 0x34); # prints 1984; perl -e 'printf "%s\n", join"", map chr, map hex, qw(0x6a 0x75 0x73 0x74 0x20 0x61 0x6e 0x6f 0x74 0x68 0x65 0x72 0x20 0x70 0x65 0x72 0x6c 0x20 0x68 0x61 0x63 0x6b 0x65 0x72)' # my very first 'just another perl hacker' sig. ord(a) = 97; %#x 97 = 0x611; %#o 97 = 0141; $s = 'mehryar'; $s =~ s/\141/A/; prints mehryAr printf("%#b\n",0b101 & 0b110); # prints 0b100 printf("%#o\n",04 & 05); # prints 04 thats 100 & 101 => 100 => 04 $a = "\n"; $o = ord $a; # 10 $oct = printf("%#o",$o); # 012; $line =~ s/\015\012//; same as $line =~ s/\r\n//; * ### forgot about this. little tidbits perl -pi.bak -e '~s/man/woman/' foo.txt perl -pi -e 's|^.*[^\000-\172].+||g' 2001.txt > foreign_movies_2001.txt perl -pi -e 's|\015|\012|g' stupid_ms_files.txt perl -MO=Terse/Deparse Devel::Peek::dump($scalar); - time(); # Thinking about time in Perl. 1. First there is the builtin time() function. returns the number of non-leap seconds since the epoch which for unix systems is 1970, Jan 1st, 00:00:00 UTC. it can be fed to localtime() or gmtime(). so print scalar gmtime(1) = Thu Jan 1 00:00:01 1970 there are = 60 seconds in 1 min. there are 60 * 60 = 360 seconds in 1 hour. there are 24 * 360 = 86,000 seconds in 1 day. there are 7 * 86400 = 600,000 seconds in 1 week. there are 30 * 86400 =~ 2,500,000 seconds in 1 month. there are 365 * 86400 =~ 30,000,000 seconds in 1 year. now is 1,037,304,514 =~ 1,000 million seconds =~ 1000/30 =~ 33 years =~ since 1970 + 33 = 2003 900000000 = Thu Jul 9 09:00:00 1998 900000001 = Thu Jul 9 09:00:01 1998 # 1. 1 sec 900000010 = Thu Jul 9 09:00:10 1998 # 2. 10 sec 900000100 = Thu Jul 9 09:01:40 1998 # 3. 1 min 40 sec 900001000 = Thu Jul 9 09:16:40 1998 # 4. 16 min 40 sec 900010000 = Thu Jul 9 11:46:40 1998 # 5. 2 hr 46 min 46 sec 900100000 = Fri Jul 10 12:46:40 1998 # 6. 1 day 1 hr 46 min 46 sec 901000000 = Mon Jul 20 22:46:40 1998 # 7. 11 days 1 hr 46 min 46 sec 910000000 = Mon Nov 2 01:46:40 1998 # 8. 3 months 1000000000 = Sat Sep 8 18:46:40 2001 # 9. 2 years -- regular expressions: ====================== $s = 'mehryar mansoor'; $s =~ /(.{5})/; # Match exactly n times # prints |mehry| $s =~ /(.{5,})/; # Match at least n times, more if possible # prints |mehryar mansoor| $s =~ /(.{5,10})/; # Match at least n times, but no more than m # prints |mehryar ma| -- type globs: ============= *b = *a; # now all b symbol table entries point to a. *b = \$c; # now only $b has been modified to point to $c. a reference to a datatype # effects only that datatype. glob magic. my $ref = \*a; # ref is a reference to the glob of a. print ${*$ref}; # prints $a; dereferencing a reference to a typeglob. and asking for its scalar slot my $ref_to_scalar_slot = \${*$ref}; # is one way my $ref_to_scalar_slot = *$ref{SCALAR}; # is another the foo{THING} way. local *b = \&a; # receipe for local changes. - Perl Modules: - writing your own # # MyModule - some succinct description # # $Id: file.txt,v 1.5 2004/10/28 15:03:19 mehryar Exp $ # package MailFolder; use warnings; use strict; use vars qw($VERSION $DEBUG); sub new { } sub foo { } 1; __END__ =head1 NAME MailFolder - Describes a unix mail folder =head1 SYNOPSIS use MailFolder; # create a new MailFolder object my $m = MailFolder->new($file_name); # get emails my $emails = $m->get_messages($sort_criteria); =head1 DESCRIPTION Some very nice description. =head1 AUTHOR Mehryar Mansoor Emehryar@mehryar.com L =head1 COPYRIGHT Copyright (C) 2001 Mehryar Mansoor. All Rights Reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO Message =cut - DBI stuff: These extensions all associate a DBM file on disk with a Perl hash variable in memory. The simple look like a hash programming interface lets programmers store data in operating system files wihtout having to consider how its done. It stores the data according to a hash value computed from the string specified as the key itself. Hashtables are generally extremely fast, in that by simply applying the hash function to any given key value, the data associated with that key can be located in a single operation. This is much faster than sequential scanning. use the tie mechanism to associate the actual Berkeley DB with the Perl variables, which will automatically perform the appropriate operations on the Berkeley DB files instead of us having to manually program the Berkeley DB API ourselves. - use Carp; carp - warn of errors (from perspective of caller) croak - die of errors (from perspective of caller) cluck - warn of errors with stack backtrace (not exported by default) confess - die of errors with stack backtrace - use Chart::Bars; my $g = Chart::Bars->new; $g->add_dataset('Berlin', 'Paris', 'Rome', 'London', 'Munich'); $g->add_dataset(14, 5, 4, 5, 11); $g->add_dataset(12, 4, 6, 7, 12); $g->add_dataset(18, 2, 3, 3, 9); my %hash = ( precision => 0, # 1. number of numerals after decimal point, mostly affects y axis. x_ticks => 'vertical', # 2. 'normal','staggered','vertical' grid_lines => 'true', spaced_bars => 0, # should there be spaces between the bars or not (default:true) colors => { dataset1 => 'blue', dataset1_7 => 'red', } ); $g->set(%hash); $g->png("bars.png"); - use Compress::Zlib; my $D = deflateInit() or die "cannot create a deflation stream\n"; my $I = inflateInit() or die "cannot create an inflation stream\n"; while($line=) { ($output,$status) = $D->deflate($line); die "deflation failed $status\n" unless $status == Z_OK; $compressed_output .= $output; } ($output,$status) = $D->flush(); die "deflation failed $status\n" unless $status == Z_OK; $compressed_output .= $output; print "$compressed_output\n"; ($output,$status) = $I->inflate($compressed_output); die "inflation failed $status\n" unless $status == Z_OK or $status == Z_STREAM_END; print $output; - use Date::Manip qw( yesterday ); perl -I/usr/local/lib/perl5/site_perl -MDate::Manip -e 'print &UnixDate("yesterda y","%y%m%d")'` $date = ParseDate('some type of date'); - use File::Basename; basename ('/usr/le/lib/LE/Object.pm'); # prints Object.pm dirname ('/usr/le/lib/LE/Object.pm'); # prints /usr/le/lib/LE fileparse('/usr/le/lib/LE/Object.pm'); # returns $base,$path,$type. havent played with type - use File::Find; find(\&do_something,'/home/mehryar/tmp','/tmp'); sub do_something { print "dir is $File::Find::dir, file is $_, full path is $File::Find::name"; } dir is ./new_perlref, file is a2-Find.pl, full path is ./new_perlref/a2-Find.pl - use File::Path; mkpath('/foo/bar/moo', 1, 0711); # 1 here is a booleans says to print dir name if created mkpath(['/foo/bar/baz', 'bin/foo'], 1, 0711); # numeric mode defaults to 0777 rmtree(['/foo/bar/baz', 'bin/foo'], 1, 1); - use Getopt::Std; use vars qw( $opt_a $opt_b ); getopts("ab:"); # 'a' is a binary switch, 'b' requires an argument print "option b was $opt_b" if $opt_b; or my %args; getopts("ab",\%args); or use Getopt::Long; my ($foo,$file,$bar); GetOptions("foo" => \$foo, "file=s" => \$file, "bar:s" => \$bar); print "foo is true $foo\n" if $foo; print "file is true $file\n" if $file; print "bar is true and has the optional value $bar\n"; my $r = getopts("ab"); # if no options $r=1 # if unknown option $r=undef # if known option $r=1 - use HTML::Template: my $t = HTML::Template->new(filename => 'formletter.tmpl') || die $!; $t->param( HOME => $ENV{HOME} ); # variable interpolation my @loop_data; foreach my $dir (split(/:/,$ENV{PATH})) { # loops push @loop_data, { dir => $dir }; } $t->param(DIRECTORIES_LOOP => \@loop_data); print "Content-Type: text/html\n\n"; print $t->output; #------------------------------------------------------------- <TMPL_VAR NAME=TITLE> using HTML::Template


#------------------------------------------------------------- - use LWP::Simple; $c = get("http://www.fooey.com"); perl -MLWP::Simple -e 'getprint "http://www.fooey.com"'; - use Storable; store \%table, 'file'; $hashref = retrieve 'file'; $seralized = freeze \%table; %table_clone = %{ thaw($serialized) }; - use Test::Harness; perl -MTest::Harness -e 'runtests(@test_scripts)' - use Test; use Time; BEGIN { plan_test => 32, todo => [3,6,13,23] }; ok(add_delta($time,'+1'),'2:00'); BEGIN { open(FH,$0) or die; my $count; while () { $count++ if /\#\s*\d/ } plan test => $count } - use Text::Template: my $t = Text::Template->new(SOURCE => 'formletter.tmpl') || die "wha? $Text::Template::ERROR"; my %vars = ( title => 'Mr', lastname => "Mansoor", day => (qw/ Sun Mon Tue Wed Thr Fri Sat /)[ (localtime)[6] ] ); my $filled_in_template = $t->fill_in( HASH => \%vars ); (defined $filled_in_template) ? print $filled_in_template : die "couldnt fill it"; - use Template; my $config = { EVAL_PERL => 1 }; my $tt = Template->new($config); # 1. Template.pm my $data = get_data(); $tt->process('some_template.ttml',$data) || die $tt->error(), "\n"; #directives [% list_of_foo = [ 1, 2, 3 ] %] [% FOREACH foo = list_of_foo %] And the foo is [% foo %] [% END %] [% PERL %] $stash->set('surah_no', sprintf("%03d", $stash->get('verses.surah'))); [% END %] - use URI; - Perl Networking: ================= A pipe is a filehandle that connects the curent script to the standard input or standard output of another process. open(READ, "who |") or die "cant open who:$!"; open(WRITE," | wc -l ") or die; perl -MMIME::Base64 -ne 'print decode_base64($_)' < sep_25 > mail.tar.gz - passing around filehandles $fh = *FH; $fh = \*FH; # a little better die "invalid file handle\n" unless defined fileno( $fh ); - sex: ===== * we'll think about sex after we are with Sarah. * it will be an interesting educational class to take. (remember mapping). - understanding: ================ the "molecules" of understanding. building up on them and building a better world from them. Soriya has no ideals about what is happening in Israel/Palestine. The Israeli propoganda. - modern algebra: ================ * We think of a set as a collection of objects about which it is possible to determine whether or not a particular object is a member of the set. * set-builder notation, uses braces to enclose a property that is the qualification for membership in the set. B = { x|x is a nonnegative integer }. | => such that. x E A, x is an element of the set A. x !E A => x is not a member of A * Cartesian Product For two nonempty sets A and B, the Cartesian product A X B is the set of all orderered pairs (a,b) of elements where a E A and b E B. That is A X B = { (a,b)|a E A and b E B }. * mapping ( or an image ) For two nonempty sets A and B, a subset C of A X B is a 'mapping' from A to B iff foreach a E A, there is a unique (that is one and only one) element b E B, such that all (a,b) E C. But traditionally C is represented as f. so f: A -> B (indicates that f is a mapping from A to B) f(a) = a^2 - linux: ======= nice top , M sort by resident memory usage find . -type f - -amin -n - file was last [a]ccessed less than n minutes ago. -atime -n - file was last [a]ccessed less than n days ago. -cmin -n - file's status was last [c]hanged less than n minutes ago. -ctime -n - file's status was last [c]hanged less than n days ago. -mmin -n - file was last [m]odified less than n minutes ago. -mtime -n - file was last [m]odified less than n days ago. find . -type f -mmin -360 -exec 'cp' {} /home/mehryar/upload/ ';' find . -type f -exec 'chmod' {} 'u+' ';' ^ the current file, arguments to the command, end cmd find . -path './[12][0-9][0-9][0-9]/*' -type f -regex '.*[^.][^c][^t]$' find . -path './[12][0-9][0-9][0-9]/*' -type f | xargs perl -I/home/mehryar/lib -MMailFolder -e 'foreach (@ARGV) { $f = MailFolder->new($_); print "$_: ", $f->name, " ", $f->count,"\n" }' find . -name "*.png" -or -name "*.gif" find . ! -path "./pages*" ! -path "*CVS*" ! -path "*~" -setting the clock hwclock --set --date="4/18/01 13:22" hwclock --hctosys - ssh: your public key is placed on the server where you want to go. The server uses your public key to check against the private key from where you are trying to login. (or something like that). - man updatedb | col -b > updatedb.txt - ps -opid,lstart,command (to find out how long one of your processes has been running) * rsync dev/ /backup/dev/ # will move all the files in dev/ to /backup/dev/ * rsync -vrn --size-only dev /backup # will move dev to /backup/dev -n means dry run -v vebose -r recursively -- Advanced Unix Programming ============================ * ioctl for functions that cant be handled by read/write/lseek * fd = dup(0); to duplicate filedescriptor 0 with same mode cant be overridden * /dev/fd/0 is a step toward uniformity and cleanliness as opposed to '-' for specifying STDIN to programs. * permissions and how they apply when creating and reading files and directories. * the 'access' function determines file permissions based on not the effective ids but the real ids. So if you're root but your program wants to check that the real user can read the file use this function. - UML: ====== use cases. functional view of a system. non-temporal. A <|--- <> B when A always entails B. (deleting an order always deletes sub-items.) A ---|> <> B when A conditionally entails B. (Adding an order might require adding the orderee as a new customer). - XML: ====== -- XML::DOM: ============ use XML::DOM; $p = XML::DOM::Parser->new; $doc = $p->parsefile('some_xml_file.xml'); $root = $doc->getDocumentElement; $children = $root->getChildNodes; # hasChildNodes for (my $i=0; $i < $children->getLength; $i++) { my $child = $children->item($i); } $element->getNodeName; address_book * NODELIST->getLength; * NODELIST->item($i); -- XSLT: ======== * stylesheet program and stylesheet modules * first example * second example * XPath - Upkeep: ========= * convenient in the little book. * MUST sync with file.txt - Life: ======= * / )) \ (you need resonance). * OS: * salat and most important things earliest, this is my solution to avoid being stung by this snake again. * must sleep by 10:30 for Api, Abu, Ami, Sarah. - Work: ====== * come early in the morning, as early as conveniently possible. * then do your work. (saabiru wa raabitu). - CVS: ===== In CVS parlance, a "module" is a directory hierarchy... * Putting an existing project into CVS Let's say you've been working on the Frobozz Magic C Compiler (fmcc) and you want to put it under version control. If it lives in a directory called project_dir_name, you could: $ cd project_dir_name $ cvs import -m "initial comment" project_dir_name silly_putty V_6 CVS will create a project_dir_name directory in the CVSROOT and import the current directory and it's children into revision control. The last two arguments are the vendor and release tags. They don't have to have any special meaning. You can make sure that this worked by saving the old directory and checking the project out of the CVS repository: $ cd .. $ mv project_dir_name project_dir_name.orig $ cvs checkout project_dir_name $ cd project_dir_name ; ls * that stupid variable is "$Revision: 1.5 $" the other one is # $Id: file.txt,v 1.5 2004/10/28 15:03:19 mehryar Exp $ $VERSION = substr q$Revision: 1.5 $, 10; cvs commit -F foo.msg filename[s] Tagging. cvs -q tag Release-1995_01_04 cvs checkout -r Release-1995_01_04 filename or myproj cvs tag V_1_2 cvs tag -d V_1_2 Branching. see that link that you have: cvs rtag -b branchname my_module cvs tag -b branchname file cvs checkout -r branchname my_module cvs update -j branchname file # to merge - Documents: ============ save them under a proper directory name in public_html/docs/ this way you can cut them up and still retain persistency. tar it up and ncvs it. - Xemacs: ========= - narrow window: C-x n-n widen window: C-n n-w - M-C/ (indent-region) * C-q key prints the ^ctrl key for that key. like C-q M will print ^M * C-x x-1 copy to register 1 C-x g-1 copy from register 1 - set-variable: outline-regex "[ \t]*\\-+ " - outline mode C-c C-a show-all C-c C-q hide-sublevels C-c C-t hide-bodies C-c C-d hide-subtree C-c C-s show-subtree C-c C-l hide-leaves C-c C-c hide-entry C-c C-e show-entry C-c C-i show-children C-c C-k show-branches C-c C-o hide-other C-c C-u outline-up-heading C-c C-b outline-backward-same-level C-c C-f outline-forward-same-level C-c C-p outline-previous-visible-heading C-c C-n outline-next-visible-heading - ediff mode `wa' Saves buffer A, if it was modified. `wb' Saves buffer B, if it was modified. `a' take changes from a to b `b' take changes from b to a - learning * using CPAN.pm; running as su; downloading bundles * creating a log f by piping perl -MCPAN -e shell | tee -a /home/mehryar/.cpan/log - Scheme ======== this stuff is going into the wiki now. - Lisp ====== ; this here be a comment ; setting a variable (set 'foobar "Superman") ; evaluating the variable foobar ; a list '(superman batman robin) ; setting a variable to a list (set 'superheroes '(superman batman robin)) superheroes ; a convenience special form setq set quote the first expression (setq superheroes '(superman batman robin)) (setq superheroes '(superman batman robin) villians '(drdoom magneto "lex luthor")) villians ; defining functions "defun" (defun foo ()) (foo) (defun foo () (message "Hello")) (foo) ; concat (concat "Hello " "World") ; (message (concat "Hello " "World")) ; (defun foo (arg) (message (concat "Hello " arg))) (foo "Mehryar") - Java ====== - javac com/mehryar/SimpleTest.java && java com/mehryar/SimpleTest - simple inheritance public class Surgeon extends Doctor { public void getSalary { super.getSalary() + $100K; } } * object construction Wolf w = new Wolf(); w.makeNoise(); * to know if you have designed your types correctly, ask, "Does it make sense to say type X ISA type Y?" If it doesn't you know there's something wrong with the design,... * Do not use inheritance just so that you can reuse code from another class, if the relationship between the superclass and subclass violate either of the above two rules. (1: when one class is a more specific type of a superclass, 2: when you have behaviour that should be shared among multiple classes of the same general type). * private instance variables and private methods are not inherited * polymorphism is "good" because you get to refer to a subclass object using a reference *declared* as the supertype. Animal an_animal = new Wolf(); * overriding a method: arguments and return types must be the same. method can't be less accessible (can't be private if super-method is public) - SQL: ===== * MySQL: * show databases; * show tables from database_name; * show columns from table_name; * mysqldump --opt ebay > ebay-backup.sql * if you forget the mysqladmin password then search for 'forget password' on the www.mysql.com site and you'll find the steps to recover it. * safe_mysqld --log & * open MYSQL, "|mysql -h $DB_HOST -f $DB_NAME" or die $!; * GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host'; # done by root print MYSQL < 5; - JOIN: ======= INNER ----- SELECT a.id, a.name, b.address FROM people AS a JOIN homes AS b WHERE a.id = b.id; LEFT ---- SELECT a.id, a.name, b.address FROM people AS a LEFT JOIN homes AS b ON a.id = b.id; 1, Superman, Metropolis 2, Batman, Gotham 3, Spiderman, Null RIGHT is just the opposite of that not supported in old MySQL so reverse it. 1, Superman, Metropolis 2, Batman, Gotham NULL, NULL, New York ( there is no person with the id matched to NY). - INSERT: ========= INSERT INTO foo (id,blah) VALUES (3,'fooey'); - CREATE: ========= * CREATE TABLE Users ( user_id MEDIUMINT AUTO_INCREMENT, username VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL, password VARCHAR(20) NOT NULL, password_hint VARCHAR(60) NOT NULL, PRIMARY KEY(user_id), UNIQUE(username), UNIQUE(email), INDEX username_ind (username(5)), ); CREATE TABLE time_test ( stock VARCHAR(4), datetime DATETIME, date DATE, price FLOAT(4) ); mysql> desc time_test; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | stock | varchar(4) | YES | | NULL | | | datetime | datetime | YES | | NULL | | | date | date | YES | | NULL | | | price | float(10,2) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 4 rows in set (0.05 sec) - INDEX: ======== * SHOW INDEX FROM login; * CREATE INDEX login_index ON login (login); * DROP INDEX email ON email_update; - ALTER: ======== ALTER TABLE time_test ADD COLUMN foo_id SMALLINT PRIMARY KEY AUTO_INCREMENT; mysql> select * from time_test; +-------+---------------------+------+-------+--------+ | stock | datetime | date | price | foo_id | +-------+---------------------+------+-------+--------+ | MSFT | 0000-00-00 00:00:00 | NULL | NULL | 1 | +-------+---------------------+------+-------+--------+ 1 row in set (0.00 sec) * ALTER TABLE table_name CHANGE COLUMN old_name new_name CHAR(30); ALTER TABLE contact ADD COLUMN fax varchar(32); ALTER TABLE foo RENAME employee_old; ALTER TABLE supplier CHANGE req_ref_num_for_po req_ref_num_for_po enum('Y','N') NOT NULL DEFAULT 'Y'; - UPDATE: ========= UPDATE stocks SET ticker = 'CVX', foo = 'bar' WHERE ticker = 'CHV' - MySQL functions: - CONCAT SELECT CONCAT('My', 'S', 'QL'); - mysqldump --tables table_name or mysqldump database table_name