CAF means CoArray Fortran, an extension to the Fortran-95 standard which provides some simplified parallelization capabilities to Fortran-95 (and later standards, of course).
It’s not totally simple, but it does provide:
The key idea is using specifically identified variables
to exchange data amongst the nodes, and not MPI
primitive routines. The specific nodes are indicated with square
brackets variable[(nodenumber)]
.
While the old joke about “you can write a Fortran program in any language” is sometimes true, you can’t write a CAF program in anything but Fortran. CAF is supported by GCC Fortran and some commercial compilers.
Don’t rely on me for this; I’m terrible at explaining stuff, as you can readily see. Look at the references below for intros to Fortran and CAF.
You need to add a new (as yet unsupported) package for this. This
package is pretty simple, see the link; untar into
/usr/ports/mystuff/lang
and cd to opencoarrays
and issue
a make package
, followed by an install. It requires: bash, openmpi,
cmake, and g95 to be installed.
What you get includes:
a caf
command which wraps gcc and library specifics. It’s
not very reliable and I don’t use it. The --show
option is
very useful to learn how building and linking works, however.
a cafrun
command which wraps the OpenMPI mpirun
command.
static and dynamic runtimes which are needed for executables
opencoarrays.mod
file for accessing some features from
Fortran: reductions, image number, total images.The GCC Fortran compiler includes the -fcoarray=
option,
where the value is either single
or lib
. “Single” uses the
libcaf_single library included with the fortran package. Specifying “lib” uses
whatever you provide which should be -lcaf_mpi provided with
this opencoarrays package.
Here is a sample program. The rnbasis
variable is dimensioned
automatically according to the number of images at runtime:
$ cat coblin.f90 << __end
program coblin
use pcg_basic
implicit none
type(pcg_state_setseq_64) :: rnbasis[*]
if ( this_image() .eq. num_images() ) then
write (*,*) "this_image()", this_image()
write (*,*) "this_image( rnbasis )", this_image( rnbasis )
write (*,*) "lcobound( rnbasis )", lcobound( rnbasis )
write (*,*) "ucobound( rnbasis )", ucobound( rnbasis )
write (*,*) "image_index(ucobound(rnbasis))", &
image_index( rnbasis, ucobound( rnbasis ) )
end if
end program coblin
__end
$ # my pcg lib is in my $HOME directory
$ il="-I$HOME/gcc/include -L$HOME/gcc/lib"
$ OMPI_FC=egfortran mpif90 \
-fcoarray=lib $il coblin.f90 -lpcg -lcaf_mpi
$ ./a.out
this_image() 1
this_image( rnbasis ) 1
lcobound( rnbasis ) 1
ucobound( rnbasis ) 1
image_index(ucobound(rnbasis)) 1
$ mpirun -np 2 -H localhost:2 ./a.out
this_image() 2
this_image( rnbasis ) 2
lcobound( rnbasis ) 1
ucobound( rnbasis ) 2
image_index(ucobound(rnbasis)) 2
This isn’t the prettiest output, but indicates the low bound and
upper bounds of the coarray rnbasis
, when run with 1 or 2 images.
Well, you can run multiple images but if you are doing RNG-based calculations you need to ensure each image get’s it’s own set of pseudo-random numbers. Otherwise their effort is duplicated.
Let’s check to see if we understand how:
use pcg_basic
implicit none
integer, parameter :: veclen = 6
integer :: perImage(veclen)
call pcg32_srandom( 10_8, 3_8 )
perImage=pcg32_random()
sync all
if(this_image() == 1) then
print *,' shallow assignment of pcg32_random()'
print *,perImage
endif
Here, “shallow” assignment means called pcg32_random() once and assign that value throughout all elements of the array perImage. Since this array is local to every image, every image has the same values in this array. This is not too interesting for parallelized programs: they would all do the same thing with identical RNGs.
Here we use a local variable for each image, and set it according to the image number:
type(pcg_state_setseq_64) :: singlebasis
type(pcg_state_setseq_64), allocatable :: rnbasis(:)[:]
allocate( rnbasis(num_images())[*] )
call pcg32_srandom_r( singlebasis, &
10_8, 3_8 * this_image() )
rnbasis(this_image())[1] = singlebasis
sync all
if(this_image() == 1) then
print *,'coarray assignment of rng basis for all images (unbuggy)'
print *, rnbasis(1:num_images())%state
print *, rnbasis(1:num_images())%inc
end if
This is a bit tricky, so let’s walk through one thought at a time:
singlebasis
is local to each image, and is initialized by the
pcg32_srandom_r routine to a value that depends on the image number
this_image().
The rnbasis
array is sized according to the number of images, and the
square bracket declaration [*] indicates it is a coarray used for exchanging
data between images.
The expression rnbasis(this_image())[1] =
will assign a value to
the rnbasis array located on image #1. The subscript this_image()
indicates which element of the array is to receive a value.
The rnbasis array(3) element receives a value from image #3, and so on.
The rnbasis array located on image #1 (rnbasis()[1]) receives the values.
Then image #1 prints the result. The arrays state and inc values will all be different. Right?
$ mpirun -np 3 -H localhost:3 ./co_vec.x
…
coarray assignment of rng basis for all images (unbuggy)
-2490148636861828604 -1198819441200173800<PHONE_NUMBER>1481004
7 13 19
If you feel like I just threw you into the deep end of the Co-Array Fortran swimming pool, you are right. See the links for a gentler introduction to CAF and getting some ordinary things done. Then you might find this RNG article more understandable.
January 2020 (revised November 2020)
Links
Parallel Programming with Fortran 2008 coarrays
Introduction to Fortran 90, Student notes
OpenBSD Numerics Experience - 1 - RNG
OpenBSD Numerics Experience - 2 - RNG floats
OpenBSD Numerics Experience - 3 - FFTW
OpenBSD Numerics Experience - 4 - CAF
OpenBSD Numerics Experience - 5 - MPI Networking
OpenBSD Numerics Experience - 6 - Memory Models
OpenBSD Numerics Experience - 7 - Python Image Display
OpenBSD Numerics Experience - 8 - RNGs, again
OpenBSD Numerics Experience - 9 - Nim
OpenBSD Numerics Experience - A - Graphical Display
OpenBSD Numerics Experience - B - ParaView
OpenBSD Numerics Experience - C - Numerical Debugging
OpenBSD Numerics


Loading . . .
Privacy as Expected : Consent Gateway
settings
Gathering Info
Show all receipts
Current Site Receipts


Fake Bomb Delays Concert at Amsterdam Synagogue
by Hana Levi JulianAmsterdam Police bomb squad units were dispatched to a synagogue in the Dutch city of Delft this weekend after a bomb threat was received outside the building.
Police sealed off the area while sappers examined the alleged bomb, planted before a concert scheduled at the site by the Israeli “Atar” string trio.
The bomb turned out to be a fake after being examined, and police reopened the venue. The concert took place as scheduled.


MarginInterestRate
objects contain the margin interest rate, which is a cost associated with trading on margin. MarginInterestRate
objects have the following properties:
To get the MarginInterestRate
objects in the Slice
, index the MarginInterestRate
property of the Slice
with the Crypto Future Symbol
. The MarginInterestRate
property of the Slice
may not contain data for your Symbol
. To avoid issues, check if the property contains data for your Crypto Future before you index it with the Crypto Future Symbol
.
public override void OnData(Slice slice) { if (slice.MarginInterestRates.ContainsKey(_symbol)) { var interestRate = slice.MarginInterestRates[_symbol].InterestRate; } }
def OnData(self, slice: Slice) -> None: if self.symbol in slice.MarginInterestRates: interest_rate = slice.MarginInterestRates[self.symbol].InterestRate
You can also iterate through the MarginInterestRates
dictionary. The keys of the dictionary are the Symbol
objects and the values are the MarginInterestRate
objects.
public override void OnData(Slice slice) { foreach (var kvp in slice.MarginInterestRates) { var symbol = kvp.Key; var marginInterestRate = kvp.Value; var interestRate = marginInterestRate.InterestRate; } }
def OnData(self, slice: Slice) -> None: for symbol, margin_interest_rate in slice.MarginInterestRates.items(): interest_rate = margin_interest_rate.InterestRate


So it’s almost time to leave for SRS and you’re wondering what’s good to pack? The following is a generic list of stuff most postop persons found useful and neccessary on their journey to anatomial womanhood
Tech Stuff
-
A tablet or a laptop to communicate with folks back home. If traveling light, at least a mobile.
-
Don’t forget to bring the required power socket adapters and voltage transformers so that your tech stays juiced. It is very miserable running out of battery energy when you are down wounded.
-
Some women chose to bring a gaming console, especially if they weren’t traveling alone. I personally enjoyed playing the XBox with my friend from Europe who had brought her own xBox along.
-
WiFi repeater if you are techy and WiFi is free. Configure it in your room before surgery though, it is not that easy focusing or doing things after surgery.
-
A camera if shooting from your mobile phone isn’t your thing. Or get one of those fancy phones with really great cameras built in.
-
A pair of earphones or earbuds to plug in and cancel external noise whether on the plane or in recovery or whenever it gets too stressful
-
A spare mobile phone if traveling overseas and intending to have a local SIM card
Surgery Care Stuff
-
Buy overnight sanitary pads (as long and big as you like) at the location. Buying from home might be unneccsarily heavy or onerous.
-
A diaper changing mat. Diaper mats are easy to clean, which makes it suitable for dilating on, and for sleeping upon, to prevent bedsheet staining (the costs of cleanup most likelt to be borne by you)
-
Neosporin or topical antiseptic which is allowed by your own doctor, to help wound recovery
-
A small spray-bottle capable of being refilled with betadine, for easy, effective and efficient dispensation of Betadine onto site
-
It is a Good Idea to find out the costs of lube back home, for a comparison against prices provided by the surgical facility or by a local pharmacy.
-
Getting a small container around 5 inches wide can help you hold used dilators within especically if they’re icky with lube . This way they won’t get on your bedding or the floor or get dirty.
Clothes
-
Plenty of loose underwear, about 1.5 per day for each day stay.
-
Loose skirts
-
Loose pants (not recommended)
-
Bras, tops, etc
-
Other climate-specific gear suitable for the climate you are entering, including shoes and scarves.
Toiletries
-
Toothbrush and toothpaste
-
Personal grooming kit such as razors , creams, makeup, hairbrushes, etc
-
Spare kitchen towels or toilet paper for just in case
-
wet wipes or baby wipes – lifesaver.
-
Hair ties are useful especially if showering isn’t permitted for the first few days.
Misc Stuff
-
Sunglasses
-
Spare zipper bags
-
Mom/Dad/relative
-
A big cloth-based bag for the donut. It’s less conspicuous and makes it easier to carry and also easier to clean, too.


Astute - I pay attention and research to speedily launch myself forward with any task.
Teamwork - I have respect from my co-workers and assist with all collaborative tasks.
Think Tank - I won't necessarily reinvent the wheel, but I will continue spitballing. I believe there may always be an easier and more cost effective way to work.
Typing - I've taken the courses for proper typing. 100wpm
Negotiator - I believe developing and caring for relationships is important. This is what is needed to make business happen.
Goal Oriented - I plan, make outlines, and execute.
Diverse - I believe that diverse opinions, people, experiences, and ideas lead to an enriched environment.
Delegator - I give and oversee projects/contracts through to the end.
Coding - HTML, CSS, Javascript, jQuery, AJAX, node.js, RESTful APIs, JSON, Git, Express, SQL.
Databases - SQL


RGB to single digit converter. Change RGB colors to 10 set colors labelled 0 - 9 0: black 1: red 2: orange 3: yellow 4: green 5: blue 6: indigo 7: violet 8: brown 9: white


JavaScript vs Ruby: A Refresher
November 1, 2015
JavaScript
Data Types
JavaScript is a loosely typed language, so data types do not have to be declared explicitly. There are several primitive data types - boolean, null, undefined, number, string, and symbol. In addition, JavaScript has the dynamic data type - object. The number data type includes both integers and decimals or floats, and JavaScript will treat all numbers as decimals, regardless of whether or not they are typed as such. JavaScript does support some methods for its primitive data types.
Operators
JavaScript uses the standard operators: = (assignment), >, <, >=, <=, +, -, /, *, %, !=. Of note: JavaScript does not have shovel operators (<< and >>) for addition and subtraction. Also, the comparator operator is a triple equal sign ===, not a double. Also, you cannot use operators on differing data types, e.g. 16 * 'hello'.
Destructive Methods
JavaScript does not use destructive methods in general - a new object is always returned. However, JavaScript will evaluate expressions that modify an object even when it is the condition in an 'if' statement, and even if the result is assigned to a new variable.
Keywords
JavaScript uses standard keywords. Of note: 'var' must be used to declare variables, and will preceed the variable name. Otherwise, the variable will be considered global, and will have global scope. 'new' and 'delete' should also go before the name of the new or deleted object, not following and not using dot notation. Also, for conditions, JavaScript uses the keyword 'else if' and does not have 'unless'.
Variable Naming
JavaScript conventionally uses turtleCase.
String Interpolation
There is no string interpolation in JavaScript. I.e. "this is a string with a #{variable}" is not viable. You must use + signs or another method to include variables in strings.
Return Values
There are no implicit return values for JavaScript functions. If you wish a function to return a particular value, this needs to be explictly coded. Also, the return function will act as a 'break' in the function, and any code past the return statement will not be evaluated. JavaScript may throw a 'not a function' error if there is no return value.
Indexing
You cannot use a negative index number to access values starting at the end of an array, e.g. array[-1]. Unless explictly set, negative index values do not have meaning. Also note: arrays in JavaScript do not have supported methods for first, last or empty.
Object Structures
JavaScript has an object data type, which groups together key-value pairs and which supports prototyping. A key in a JavaScript object is called a property, and all properties are evaluated as strings, regardless of whether or not they are in quotation marks. Property values in a JavaScript object can be any primitive data type, another object, or a function. JavaScript objects can be created anywhere, and are implicitly open to access from another object or function.
Loops
JavaScript supports 'for', 'do', and 'while' loops. The iteration syntax can either be spelled out with start and end points and iteration step, i.e. for (var i = 0; i < object.length; i++) {}, or can be simplified with the assumption of starting at the beginning, iterating until the end, and making one step at a time, using 'for (i in object) {}'. Parentheses are always necessary for the loop conditions, and semicolons are used to separate terms.
Callback Functions
JavaScript supports the use of callback functions, i.e. functions passed to other functions as arguments. They are often used as an effect, commenced when the main function evaluates to a particular value, or detects a certain action (for example, a mouse click).
Ruby
Data Types
Ruby is a pure object-oriented language. Thus, its data types are all defined as objects, including boolean, nil, etc. Ruby has a large standard library of methods for use on its supported object instances - include string, nil, boolean, etc.
Operators
Ruby uses the standard operators: = (assignment), >, <, >=, <=, +, -, /, *, %, !=. The comparator operator is a double equal sign ==, although the triple equal sign exists for strict comparison. Ruby also allows shovel operators (<< and >>) for addition and subtraction, and will try to evaluate the use of operators on mixed data types. Order is important for a valid expression; the term on the right is applied to the term on the left.
Destructive Methods
Ruby has both destructive and non-destructive methods. Although not a hard rule, most destructive methods (unless obviously named to indicate destructiveness) have a 'bang' or ! at the end, e.g. 'map!'
Keywords
Ruby uses the standard keywords. Of note: there is no declarative variable keyword. Also, conditionals use the keyword 'elsif' to designated alternative paths. Ruby also has 'unless' as a loop option.
Variable Naming
Ruby conventionally uses snake_style for variables.
String Interpolation
Ruby allows string interpolation, i.e. "this #{variable} is allowed", and will even evaluate methods used within the curly brackets.
Return Values
Ruby will automatically return the last evaluated expression in a function. If a return statement is used in a function, it will act as a 'break' and the function will not be evaluated past the return.
Indexing
Ruby will evaluate negative index numbers for an array - they will count from the end of the array. I.e. array[-1] will be the last item of an array. Ruby also has methods to access the first and last items in an array, and to check if the array is empty.
Object Structures
As a pure object-oriented language, everything in Ruby is an object, which possesses attributes and supported object methods. These attributes are essentially key value pairs, and can be accessed via method calls. Custom objects can be created in Ruby via the creation of a custom class, and then creating a new instance of that custom class. Every object must be an instance of a class, and classes themselves are instances of the class object.
Loops
Ruby supports 'for', 'do', 'while', and 'unless' loops. The loop conditions are generally simple, e.g. 'for i in object', and do not require the use of parentheses for evaluation. Commas can be used to separate expressions if necessary.
Callback Functions
As a block of code which is passed to a method as an argument, callback functions are generally not necessary in Ruby, as their effects can be acheived otherwise.


VENGO
Reviewed by Harvey Karten Cowboy Booking International Director: Tony Gatlif Writer: Tony Gatlif, David Trueba Cast: Antonio Canales, Orestes Villasan Rodriguez, Antonio Perez Dechent, Bobote, Juan Luis Corrientes, Fernando Geurrero Rebollo
"Vengo" is a tale of death, despair, drunkenness, murder and revenge in the province of Seville in southern Spain. If I had not been to the region of Andalucia--one of the many homes of the world's gypsies for hundreds of years--four times already, I'd have been inspired enough by this movie to be on the next evening's Iberia flight. Why? Because I like to be surrounded by death, despair, drunkenness, murder and revenge? Not quite. What provides the inspiration for this movie, even its motif, is not the plot and not even the characters, but the music. Yep. Some stories are plot driven, some character driven: this is music driven. And my oh my oh my, what music! Do you like flamenco? And have you seen flamenco singers and dancers only in touristic spots like the Meson Flamenco in Madrid rather than in the roadside taverns in Andalucian towns like Moron de la frontera and Utrera and in Daniel Pohren's famed finca espartera? Then you're in for a special treat because watching "Vengo" is like seeing a story that takes place in Rio, except that instead of worrying about the plot and characters, the filmmaker takes you to the Carnival.
But I won't get carried away. The movie is not perfect for the very reasons mentioned: its music is just about everything; it's story is as melodramatic and contrived as director Tony Gatlif's 1998 French-Romanian production "Gadjo Dilo--about a young Frenchman hoping to track down a folk singer who is "adopted" by a village of gypsies. In short, "Vengo" is not just a product placement for southern Spain's most exciting region of Andalucia but a nationalistic cri de coeur for the culture of the gypsies. The tight-family structure, however, is the cause for sadness as well, because the people who inhabit Mr. Gatlif's film (mostly nonprofessional actors but some quite professional-sounding singers, dancers and instrumentalists) are committed to seek personal, family vengeance--forget about going to the courts-- for spilled blood.
The viewer who attends a screening of "Vengo" cold, knowing nothing about the movie, will wonder what the heck is going on, because straight away we're in the company of some passionate looking and fervent people from North Africa who appear to be performing spontaneously before a crowd of people standing by, not necessarily paying to hear a concert. We're eased into the story which centers on handsome Caco (Antonio Canales) who is the leader of his gypsy clan. His brother has for reasons unknown killed a member of the derisive Caravacas clan (who grow their hair even longer than do the members of his own group), and is hiding out somewhere in Morocco to avoid the obligatory vengeance of the Caravacas. Caco has more problems. His own daughter has died. He visits the young woman's shrine daily and spends the rest of his time drinking and partying in an attempt to forget her, and what's more he displaces his love for his daughter onto his brother's mentally challenged son, Diego (Orestes Villasan Rodriguez). He sure loves this unfortunate young man, and Diego loves his uncle. When Caco hears from the grapevine that the scuzzy Caravacas folks, unable to locate the murderer, will settle for killing Diego, Caco becomes even more despondent. Thankfully for the audience, instead of showing his despair by crying, he parties all the more, and we're treated to more Flamenco! Guitars, beautiful women singing their hearts out and dancing up a storm, and a bevy of soldiers and citizens clapping their hands in the required convention of palmas fill the Cinemascope screen lensed by Thierry Pouget, who casts all of the Andalucian scenes with an appropriate sepia tint.
Take the melodrama in stride (pretend this is an opera, the kind of thing that would be pure soap were it not for the glorious music), and you'll dig "Vengo."
Not Rated. Running time: 90 minutes. (C)2001, Harvey Karten<EMAIL_ADDRESS>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


---
layout: default
---
{% include header.html %}
{% include coach.html %}
{% include gallery1.html %}
{% include programs.html %}
{% include results.html %}
{% include gallery2.html %}
{% include testimonials.html %}
{% include gallery3.html %}
{% include location.html %}


Golpe Global
| Home
| Contact
| About Us
Business Analytics
Workflow Analysis
Procedures Development
Paperless Record Keeping
Accounting Services
Payroll
Year-end planning
Full service bookkeeping
Advertising
Craigslist Posting
Social Media
Direct Mail Advertizing
Design and Implementation


Note
Looking for Intert This?I just wanted to look at Eunuchs -- I don't even know if I care about this package at this point, I just want to see what its scope is.
Unfortunately, it appears like it only has a BitKeeper repository as its homepage. OK, looks prettier than ViewCVS, I'll just browse around... except all I can find are changesets, not the actual complete files. Am I missing something? OK, so I go to the download page, which tells me to download it via the bk tool. Well, of course, bk is not packaged as part of Debian, because it's very un-free.

 Only now do I realize there's a Debian package python-eunuchs, even if it is a little out of date.
I didn't read the license very well. I think for good measure I'm going to delete the thing, which hopefully gets rid of any obligations in the license.
All but the "turn over your first born child" obligation, yes.
Yeah, I went to look at it to see what it was about, and was immediately turned off by the complete lack of *any* information about the package. The PyPI record has some info though, as a teaser:
http://python.org/pypi?:action=display=python-eunuchs=0.0.0
OK, granted, this is a 0.0.0 release, which I guess could be taken as an annoucement of intention, I guess ;)
Hmm. Must migrate PyPI to postgres soon.
Hmm. comment display code mangled the URL. Here 'tis as a "proper URL" :)
python-eunuchs v0.0.0 PyPI record


-
140%
Qubit's top customers annual growth rate. -
$20bn
Online sales generated by our customers -
364
Ecommerce stores are growing faster with Qubit.
-
9.5m
Personalized experiences annual growth rate. -
4.4m
Shoppers influenced by our customers in 2020. -
$1.6bn
Incremental revenue generated by our customers


This is similar to the original recipe that began the red velvet craze. It was developed by the Adams Extract company in Gonzales, Tex. The original recipe, popularized in the 1940s, called for butter flavoring and shortening and is usually iced with boiled milk, or ermine, frosting.Red velvet cake, once a reasonably tender, softly flavored culinary gimmick, has become a national commercial obsession, its cocoa undertones and cream-cheese tang recreated in chemical flavor laboratories and infused into all manner of places cake should not exist.
Read MoreHave you ever encountered a chocolate cake recipe that used neither eggs nor butter, but relied on vinegar and baking soda for leavening? Apparently, the recipe has been around for ages. We first discovered a version of it in a magazine called Cuisine at Home, but you can find other versions at Epicurious and other places online. The thing about this cake recipe is not only is it incredibly easy to make, with ingredients that you likely already have in your pantry, but it produces a surprisingly moist and delicious cake (and cupcakes). Read more: http://www.simplyrecipes.com/recipes/super_easy_super_moist_chocolate_cupcakes/#ixzz4P0ICH5mk.
Read MoreThis month we’re sharing our recipe for Honey Lemon Cupcakes.They are pretty simple.  We cut the top off of the center piece and placed it over the pudding as a top, then frosted the cupcake with a vanilla buttercream. To finish it we drizzled honey over it and topped it with a lemon drop candy.The lemon pudding gave it a great flavor and it kept the cupcakes moist for days. The kids and adults loved them, but if you want to make them a little bit fancier, you can substitute lemon curd for lemon pudding.
Read More


DB settings
Default settings
Host
Port
http
https
Protocol
User
Password
Password confirm
DB Name
Round real to
Buffer Datapoints
(
use 0 to not buffer at all
)
Buffer Flush Interval
(
Seconds
)
wifi_tethering
Test connection
report
Reset DB
debounce
log changes interval(s)
(
0 = disable
)
log changes minimal delta
(
0 = disable delta check
)
keep forever
2 years
1 year
6 months
3 months
1 months
2 weeks
1 week
5 days
3 days
1 day
retention


Back to Home | Is Your Device not Included?
Kind
Location
Device
Service
Assignment
© 2020 - EpicRepare. All rights reserved.


You're doing great here at Epicodus! But what track is the right one for you? Check out Epicodus' blog on which language to choose here and take the quiz below to help you decide!
Prev Question 1/7 Next
Prev Question 2/7 Next
Prev Question 3/7 Next
Prev Question 4/7 Next
Prev Question 5/7 Next
Prev Question 6/7 Next
Prev Question 7/7 Submit
Track Suggester 3000 says:
Beep... Boop... Calculating... , looks like you're a good match for


NSFW YouTube is an addon that let you watch the age restricted content on YouTube without creating an account.


Mode
Note Mode
Colour Mode
Colouring
White
Green
Blue
Red
Amber
Alignment
Centre
Top-Left
Layout
QWERTY
AZERTY
QWERTZ
Dvorak
Colemak
Save
Save as PNG
Save as JPG (80%)
Contribute
MegaApplePi/keyboard


bool ftp_site ( resource $ftp_stream , string $command )
ftp_site() sends the given SITE command to the FTP server. SITE commands are not standardized, and vary from server to server. They are useful for handling such things as file permissions and group membership.
Returns TRUE on success or FALSE on failure.


Cosmopolitan Foodies
Recipes from Around the World
Got recipe recommendations? Questions? Please feel free to get in contact with us... Follow us on social media!
Got recipe recommendations? Questions? Please feel free to get in contact with us... Follow us on social media!


Incomplete conversion of an FA to a grammar
To add the productions for an object, click on an object that corresponds to a production in the FA. If a grammar production is selected, the object in the automaton that it was generated by will be highlighted. Eventually all productions will be added, and the grammar may be exported. For an FA, there will be exactly one production for every transition and final state. For a PDA, there will be productions for only transitions, though there may be many of them. Specialized notes for these two operations are written below.
The tool bar has some helpful controls:
This operation converts a FA to a regular (specifically right linear) edu.duke.cs.jflap.grammar. This operation is featured in the window above. Each state in the FA corresponds to a variable in the grammar, which is shown slung beneath each state. The terminals for the grammar are the symbols on the transitions.
Each transition and each final state correspond to a production in the grammar, with finals states correspond to lambda productions, and for a transition of a between two states labeled A to B, the production A aB is added.
The conversion from PDA to Context-Free Grammar requires that the PDA have a certain form before the conversion begins:
only one final state
accepts only if stack is empty
each transition has the form: a,A; or a,A;BC
In the PDA transformation, all variables in the resulting Context Free Grammar (CFG) will be formed from two states and a symbol from the alphabet. In other words, one variable is represented in the form qiAqj where i and j are numbers corresponding to states in the PDA and A is a symbol in the alphabet of the PDA.
The actual rule generating begins with the starting rule. The variable for the starting rule is found by concatenating the initial state with the end of stack character(Z) and the beginning state.
For example, if an automata had an initial state q0 and a final state q3, the starting rule would be Sq0Zq3.
Once the starting state is established, the transitions must be processed.
Transitions of the form a, A; from state qi to state qj are converted to qiAqja
Transitions of the form a, A; BC from state qi to state qj are converted to the set of rules:
{ qiAqx a (qjBqy) (qyCqx) | qx and qy are states in the automaton}.
When exporting, each of the qiAqj symbols has a single character variable substituted in its place.


Yachts should anchor in the inner harbour flying the Q flag and await Customs, Immigration and Port Health officials. Port officials usually work 07:00-17:00.
Afterwards it is possible to anchor off the Dar es Salaam Yacht Club in Msasani Bay, six miles north of the main harbour.


ASP.Net Core Security
Nuget packages
- Microsoft.AspNetCore.Authorization
- Microsoft.AspNetCore.Authentication.Cookies
Startup Configuration
- In ConfigureServices, services.AddAuthorization();
- In Configure, app.UseCookieAuthentication(options => { options.AuthenticationScheme = "Cookie"; ...
- For login page, set the options.LoginPath = new PathString("/Account/Login/"); //unauthenticated/ 401
- For "not authorized" page, set the options.AccessDeniedPath = new PathString("/Account/Forbidden/"); //unauthorized/ 403
- See docs for Bearer (js)/Cookie (html) schemes - you have to set options.AutomaticAuthenticate = false when you have two schemes
Policy
Policy is a richer than simple Role-based authorization.
Configure in Startup.ConfigureServices
services.AddAuthorization(opts => opts.AddPolicy("PolicyName", policy => policy.RequireRole("Administrator") );
You can have several named policies, which your Authorize attribute can add together.
Policies can be more complex:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
//a role
options.AddPolicy("AdministratorOnly", policy => policy.RequireRole("Administrator"));
//a specific claim with paramarray of acceptible values
options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
//a custom requirement
options.AddPolicy("Over21Only", policy => policy.Requirements.Add(new MinimumAgeRequirement(21)));
});
services.AddMvc(config =>
{
//For MVC config, build a policy (here, must be authenticated)
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
//Add a global filter
config.Filters.Add(new AuthorizeFilter(policy));
});
//register the custom handlers that know what to do with custom requirements
services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>();
}
Custom Requirements
Custom requirements have the IAuthorizationRequirement marker interface
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public MinimumAgeRequirement(int age)
{
MinimumAge = age;
}
public int MinimumAge { get; set; }
}
And an handler (which must be registered in ConfigureServices). If there are 2 handlers for the same requirement, the request is authorized if either succeeds ("or").
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
protected override void Handle(AuthorizationContext context, MinimumAgeRequirement requirement)
{
//check the claim (and issuer).
if (!context.User.HasClaim(
c => c.Type == ClaimTypes.Age &&
c.Issuer == "http://contoso.com"))
{
return;
}
//find the claim
var age = Convert.ToInt32(context.User.FindFirst(
c => c.Type == ClaimTypes.Age &&
c.Issuer == "http://contoso.com").Value);
//test the claim
if (age >= requirement.MinimumAge)
{
context.Succeed(requirement);
}
//if fails, don't do anything
}
}
Controllers
Old-style [Authorize] attribute and [AllowAnonymous] are still used (there's no Authorize(Users=...) though)
[Authorize(Roles = "Admin,Reader")] //classic style
[Authorize(Policy = "AdminPolicy")]
[Authorize(AuthenticationSchemes = "Cookie,Bearer")]
For login, create a ClaimsPrincipal and await HttpContext.Authentication.SignInAsync("Cookie", userPrincipal,new AuthenticationProperties...
Resource authorisation
docs.asp.net. Conditional authorisation (for instance, user is only able to see their own files)
Controller/Service:
- take an IAuthorizationService argument in DI
- call await _authorizationService.AuthorizeAsync(User, document, "policyName")
public class FileController : Controller
{
private readonly IAuthorizationService _authorizationService;
private readonly IFileService _fileService;
public FileController(IAuthorizationService authorizationService, IFileService fileService)
{
_authorizationService = authorizationService;
_fileService = fileService;
}
public async Task<IActionResult> Edit(int id)
{
var document = _fileService.Find(id);
if (await _authorizationService.AuthorizeAsync(User, document, "EditPolicy"))
{
return View(document);
}
return new ChallengeResult();
}
}


Before you get work done on your home
Follow these steps before you get building work, renovations or repairs done on your home. They’ll help you save time, money and stress. They’ll also help you avoid problems with builders, decorators or other contractors, eg plumbers and electricians.
- Check if you need permission or approval
Avoid costly penalties by checking if you need building regulations approval for home improvements, planning permission for building work, or permission as a leaseholder. - Find good builders or contractors
Don’t just rely on what it says on contractors’ websites. Get personal recommendations or references and do the proper checks to find someone you can trust to do a good job. - Get quotes before you decide who to use
Check you’re getting a fair price by getting at least 3 quotes before you decide. Get a quote not an estimate - a quote gives you a fixed price, so you know exactly how much you’ll pay. - Check there’s insurance in place
Check the contractor’s insurance to make sure you don’t face big costs if things go wrong. Then check that your home insurance still covers you while the work’s being done. - Get a written contract
Avoid disputes later by getting agreement in writing on details like start and finish dates, tidying up and how you’ll pay. - Be prepared to deal with problems
Speak to contractors as soon as problems come up, and get them to agree to put them right.
Step 1: Check if you need permission or approval
You may have to get more than one kind of permission or approval before you go ahead with work on your home.
Always check if you need:
- building regulations approval - you may need this even for small improvements, eg replacing windows or doors
- planning permission - you usually need this to build something new or make a major change, eg an extension
You don’t have to apply for building regulations approval yourself if you hire a contractor from a ‘competent person scheme’.
If you have to get approval or permission
You may need to hire a surveyor or architect to help you apply for building regulations approval or planning permission. If you’d struggle to pay for this, ask the Chartered Surveyor's Voluntary Scheme for advice about applying.
If you’re in a conservation area
You must also check with your local council before doing work on your home if it’s in conservation area.
If you’re a leaseholder
Check your lease if you own the leasehold (not the freehold) on your home. You may have to get permission from the freeholder before work starts. If the lease says you can’t make changes, you can still ask the freeholder for permission. You may have to pay some costs.
If you don’t get the permission or approval you need, you could be fined, prosecuted or made to pay to put things right.
Step 2: Find good builders or contractors
Recommendations and references are good ways to find reliable contractors who do a good job.
If you can’t get personal recommendations from people you know, ask contractors for references. It’s best to get:
- 2 or 3 recent examples of similar work they’ve done
- contact details for the people they did the work for - it’s best to get in touch because written references aren’t always genuine
Avoid contractors who won’t give references - it’s a sign they could be dishonest.
Do the proper checks
It’s dangerous to use someone who doesn’t know what they’re doing, especially for anything involving gas or electrics.
It’s important to check that you’re using:
- a registered gas engineer for gas work, eg installing a boiler or cooker
- a registered electrician for electrical work, eg installing new lighting or rewiring
- someone in a competent person scheme for work that needs building regulations approval (unless you got approval yourself)
You could be breaking the law if you don’t do these checks.
You should also do the following checks to help you find a contractor you can trust.
Check for approved contractors
Contractors can sign up for schemes that list them as ‘approved’. This means they’ve agreed to meet professional standards. The scheme may also have checked they’re trustworthy and do a good job - check the scheme’s website to find out how they approve contractors.
These are good places to search for approved contractors:
- TrustMark - check the type of work you need is listed in the contractor’s ‘licensed trades’ (they’ll have passed checks proving that they’re qualified for that trade)
- Buy With Confidence for contractors approved by Trading Standards
- your local council’s approved trader scheme, if they have one
Check what a contractor says
It’s good idea to check what a contractor or their website tells you - especially if they’ve knocked on your door or telephoned you to offer their services. For instance, you can:
- ask to see a business card or letterhead, or get full contact details, then ring the business to check it exists and the contractor works for them
- ask to see proof of qualifications - eg an NVQ in construction for builders or a card from the Construction Skills Certification Scheme (trade associations can tell you about qualifications for particular types of work)
- search trade association websites to check they’re a member if they say they are
Avoid contractors who just give a mobile number. They may be hard to contact if problems come up. It could also be a sign they’re unreliable or dishonest.
Interview contractors in person
It’s a good idea to speak with contractors in person before you hire them, eg when they come to your home to give a quote.
Trust your instincts and make sure you can communicate with them easily - this will help you sort out any problems that come up later.
Before you meet them, it’s a good idea to write down:
- a clear and detailed description of exactly what you want done
- a list of questions to help you get all the information you need to compare and choose between contractors - Trustmark has questions you can use as a checklist
When you meet them, write down what they say they’ll do - if they don’t end up doing it, having it in writing can help you hold them to their word or get some of your money back.
Step 3: Get quotes before you decide who to use
A quote is a promise from the contractor to do the work at a fixed price.
It’s a good idea to get at least 3 written quotes before you decide on a contractor. Comparing quotes will help you decide if you’re getting a fair price.
Don’t rely on a verbal quote - get it in writing. After you say yes to a quote, it’s a binding agreement between you and the contractor, whether it’s written down or not. But having it in writing means you can check what you agreed and prove it if there’s a dispute later.
Some contractors charge for quotes - ask about this first.
Make sure you get a quote, not an estimate. An estimate is just a rough guess of the price, and you could end up having to pay more.
The contractor can’t charge you more than the price on their quote unless:
- you ask for extra work that’s not included in the quote
- they let you know they have to do extra work and you agree to pay more for it
- they made a genuine mistake when writing down or calculating the price - they have the legal right to charge you what it should have been
Avoid contractors who won’t put a quote in writing. It’s a sign they could be unreliable.
Also be cautious if their price is a lot lower than other quotes you get. It could mean they don’t have the right skills or experience, or they’re not being honest.
What a quote should include
Be very clear about the work you want done - this will help you get the most accurate price and save misunderstandings later.
A quote should include:
- a fixed total price - not a daily rate
- a breakdown of all the work to be done and the materials needed
- separate costs for each material and part of the work
- how long the price is valid for
- if the price includes VAT
- when the price can go up, eg only if you agree to extra work
If you get a daily rate instead of a fixed total price there’s a risk the contractor could string out the work to get more money. Avoid this by getting them to put in writing:
- how many days the work will take
- how many hours of work counts as a day
- when they need your go-ahead to work more days
Before saying yes to a quote, you should check there’s insurance in place and try to get a written contract.
See a sample quote
You can download a PDF of a sample quote.
Step 4: Check there’s insurance in place
Contractors’ insurance - what to check
Ask to see insurance policies and check they don’t run out before the work will be finished. If it’s insurance they must have, they have to let you see the policy.
Insurance they must have
Public liability insurance - contractors are breaking the law if they don’t have this. It covers you and them if someone’s hurt or property is damaged (eg your home or your neighbour’s).
Employers’ liability insurance - contractors who work through a company are breaking the law if they don’t have this. It doesn’t matter if it’s their own company or not. It covers you and the company if they’re hurt on the job.
If a contractor doesn’t have the right insurance, and things go wrong or someone’s hurt, you could be forced to pay to fix things, or go to court and pay damages and legal fees.
Other insurance to check for
Other types of insurance are optional, but they’re worth looking for.
Contractors’ all-risk cover - this cover the cost of replacing work that’s destroyed before it’s completed, and before your insurance covers it.
Insurance-backed warranties or guarantees - you can buy one of these as part of the cost of the work, if the contractor offers it. Check exactly what’s covered before you decide to buy one - it should cover the cost of finishing or fixing the work if the contractor does a bad job or goes out of business.
Your insurance - what to check
If you have home or contents insurance, contact your insurer to check you will be covered during the work. You may have to pay more for your insurance during and after the work.
Your insurer will probably want to know what contractor you’re using and what insurance they have. They might suggest that you take out joint insurance with the contractor.
If you don’t have home and contents insurance, it’s worth getting some before the work starts - there’s a bigger risk your home will be damaged or your things stolen while work’s going on.
Step 5: Get a written contract
As soon as you give a contractor the go-ahead, you’ve made a contract with them, even if it’s not written down.
But you should always try to get a contract in writing before you give the go-ahead. If the contractor doesn’t do what you agreed, a written contract can help you get what you paid for at least get some of your money back.
Avoid contractors who won’t put anything in writing - it’s a sign they could be dishonest.
If the contractor gives you a contract, check if covers everything you agreed. If they don’t you can write your own.
Written contracts don’t need to be in legal language - they just need to outline:
- exactly what you’re paying for (they can refer back to the quote for this)
- everything you’ve agreed on, eg timings, tidying up and payments
Timings
Make sure the contract covers:
- start and finish dates
- if you’ve agreed on a daily rate, the number of days the work will take and how many working hours are in a day
- delays - why they might happen, and what the contractor will do about them
Tidying up
Make sure the contract covers:
- how and when the contractors will remove rubbish and clear up after themselves
- who pays for delivery and collection of any skips
Materials, equipment and subcontractors
Make sure the contract covers:
- who pays to buy or hire materials and equipment
- for things the contractor buys, how they’ll give you receipts and paperwork
- if and when they’ll use subcontractors
Payments
Make sure the contract covers how and when you’ll pay. Aim to:
- pay by card not cash
- pay in stages
- avoid deposits or upfront payments
- get some protection for your money
Avoid contractors who only accept cash or want you to pay everything upfront - it’s a sign they could be dishonest or unreliable.
Paying by card not cash
If you pay by credit or debit card, you may be able to get your money back through your bank if something goes wrong, eg the contractor doesn’t turn up but refuses to pay back your deposit.
If this happens, you can contact your bank and say you want to use the ‘chargeback’ scheme. Many bank staff don’t know about the scheme, so you may need to talk to a manager.
If you pay more than £100 by credit card, it may be easier to tell your bank you want to ‘make a section 75 claim’. It’s another way to get your money back.
Paying in stages
This is a good idea, particularly if it’s a big job, because it means problems can be put right before you make the final payment. Be clear about the point in the work when payments are due.
Avoiding deposits
Don’t agree to pay everything up front, in case something goes wrong or the contractor doesn’t turn up.
If they ask for a deposit to pay for materials, offer to buy them yourself instead of paying a deposit - that way, at least you own the materials if something goes wrong.
If the work will take a long time, you may not be able to avoid a deposit. Aim to push it down as much as possible, and don’t agree to more than 25%.
Always get a receipt for a deposit, as well as receipts for any materials it covers.
Getting protection
You can protect your deposit or staged payments until the work’s complete, eg with a:
- deposit protection scheme - your money will be stored in a secure account until you and the builder are happy with the work
- insurance-backed warranty or guarantee - you can buy one of these from some contractors to cover the cost of finishing or fixing work if they do a bad job or go out of business
Help writing your own contract
It can help to look at example contracts, or create a contract using a template - eg for:
- home repairs or maintenance - you can download a free contract template
- building work - you can download an example contract or buy a contract template
You have 14 days to cancel the contract after giving the go-ahead or signing a written contract. This is known as the cooling-off period.
Further help
Contact the Citizens Advice consumer helpline if you need more help - a trained adviser can give you advice over the phone or by email. Contact the Consumerline if you're in Northern Ireland.
Step 6: Be prepared to deal with problems
Get the contractor’s full contact details before work starts. If you know how to get in touch, it’s easier to deal with any problems that come up.
As soon as something happens that you’re not happy with:
- ask the builder or contractor to put it right
- come to an agreement about how they’ll fix it, and ask them to put it in writing
Next steps
If a contractor does a bad job or doesn’t do what you agreed, you should be entitled to get it fixed or get some money back. Find out what you can do about problems with building work, decorating and home repairs.


I had the opportunity today to see the long awaited Lethal Weapon 4, being this it's release date. Let me first mention that I am a very big fan of this classic action series. The series has changed since it was first established. It has gone from a hard edged action drama to a more comedic style adventure series. To some this is bad news, to some this is good news. I personally enjoy the entire series. Lethal Weapon 4 is similar in essence to Lethal Weapon 3. It is a highly charged action adventure/comedy drama.
The plot begins simple but throws many curves. Riggs (Mel Gibson) and Murtagh (Danny Glover) are fishing with Leo (Joe Pesci) in Murtagh's boat. Leo catches a shark and is trying to determine what to do with it. Suddenly a massive tanker appears and begins firing on our heroes. They discover the boat is full of illegal Chinese immigrants sold into slave labor. A family takes refuge in Murtagh's boat and Murtagh takes them into his home. They are soon begin an investigation which leads them to a triad boss played by Jet Li. I don't want to reveal more of the plot so all I will say is this ends up in the usual bang- bang method with some subplots thrown in involving Lorna (Rene Russo), Riggs's girlfriend being pregnant with Riggs's baby and Murtagh's daughter being pregnant by Chris Rock. Riggs's also confronts feelings of marriage and his dead wife. The first hour of the movie is basically a comedy, and the second hour is non stop action with some dramatic moments thrown in.
I thought the movie was fun and exciting, and that it raised interesting questions about our two middle-aged heroes getting older. The sole fault in this movie is it's sappy ending that seems to belong on Family Matters. Joe Pesci even has a monologue about his pet frog (named froggy) that he had as a child. Besides that the movie is riveting and the final incredible shootout and fight in the factory must be seen to be believed. Jet Li easily steals the picture as the villain. His martial arts powers are amazing. In the final fight you even may find yourselves thinking our heroes are done for!
9.5/10 (It would be 10 if it weren't for the aforementioned sappy ending)
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


{% include 'header.html' %}
This program is the product of a project done by Master forensic students in the UvA.
This site gives an overview of the data gather from discord. The data is also gathered in the output
folder that is given when running this program. Please remember to only use this knowledge and
forensic power for good. In essence, we have collected all collectable artifacts from discord
and present it here in a user friendly overview. On the right hand side you can find links about us and
about the project. To restart the project use:
export FLASK_APP=serv.py ; flask run
where serv.py is the hard link to the serv.py file.


| Event type | {{ news.event.event_type }} |
| Event date | {{ news.event.event_date|date:"l, F d, o f a"}} |
| Outage start | {{ news.outage.start_date|date:"l, F d, o f a" }} |
| Expected end | {{ news.outage.end_date|date:"l, F d, o f a" }} |
| Event type | {{ news.event.event_type }} |
| Event date | {{ news.event.event_date|date:"l, F d, o f a"}} |
| Outage start | {{ news.outage.start_date|date:"l, F d, o f a" }} |
| Expected end | {{ news.outage.end_date|date:"l, F d, o f a" }} |


bugreport
Dependency
# of open issues
# of open PRs
Avg. age of open issues
Avg. age of open PRs
Age of oldest open issue
Age of newest open issue
mockery/mockery
41
9
624 days
333 days
1998 days
7 days
humbug/humbug
35
10
419 days
148 days
865 days
10 days


Conway's Game of Life
Play Step Randomize Reset
Indicate cell age Fast Off-screen
Generation: 1 Population: 0 FPS: 0.0


Train Time Schedule
Current Train Schedule
Train Name
Destination
Frequency(min)
Next Arrival
Minutes Away
Add Train
Train Name
Destination
First Train Time (HH:mm - military time)
Frequency
Add Train


{% extends 'base.html' %} {% block content %} {% if results %} {% for report in results %}
Year: {{report.year}}
Author: {{report.author}}
Degree Program: {{report.degreeProgram}}
{%if report.date_range_of_reported_data%}Date Range of Reported Data: {{report.date_range_of_reported_data}}
{%endif%} {% endfor %}| SLO Number | Goal | Bloom's Taxonomy Level | {% for slo in slos %}
|---|---|---|
| SLO {{slo.1.number}} | {{slo.1.goalText}} | {{slo.0}} |
{{resultCommunicate.text}}
{% endif %}| SLO {{assessmentM.0}} | |
|---|---|
| Describe How the Measure aligns to the SLO | {{assessmentM.1.description}} |
| Domains: | {%if assessmentM.2.domainExamination %}Examination{%endif%} {%if assessmentM.2.domainProduct %}Product{%endif%} {%if assessmentM.2.domainPerformance %}Performance{%endif%} |
| Type | {%if assessmentM.2.directMeasure %}Direct Measure {%else%} Indirect Measure {%endif%} |
| Point in Program Assessment is Administered | {%if assessmentM.1.finalTerm %}Final Term {%else%} Not Final Term {%endif%}
Where does the assessment occur: {{assessmentM.1.where}} |
| Population Measured | {%if assessmentM.1.allStudents %}All Students{%else%} Sample of students - {%endif%}
{{assessmentM.1.sampleDescription}} |
| Frequency of Data Collection | {{assessmentM.1.frequencyChoice}} {{assessmentM.1.frequency}} |
| Proficiency Threshold | {{assessmentM.1.threshold}} |
| Program Proficiency Target | {{assessmentM.1.target}} |
| Data Collection Date Range | Number of Students Assessed | Percentage of Students who met/Eceeded Threshold Proficiency | |
|---|---|---|---|
| SLO {{assessmentD.0}} - Measure | {{assessmentD.1.dataRange}} | {{assessmentD.1.numberStudents}} | {{assessmentD.1.overallProficient}} |
| SLO Number | Description | {% for decisionAction in decisionActions%}
|---|---|
| SLO {{decisionAction.0}} | {{decisionAction.1.text}} |


Casual user persona:
- Site: Thatswhatcheesesaid.io
- Name: Raymond Jones
- Gender: Male
- Age: 32
- Technology: Raymond has a IPhone 8 from AT&T, he doesn't keep up with the newest phones, because his IPhone 8 still works fine. He is running the latest OS on his phone. He also has a HP Pavilion, which his work provided him. When not using his work laptop he has an older MSI gaming laptop which he plays Overwatch on. Both of his laptops are running Windows 10.
- Attitudes: Raymond's favorite food is mac and cheese, he usually reads yelp reviews while determining which restaurant he wants to try next.
- Needs, Goals and Features:Raymond, wants to be able to upload his favorite mac and cheese restaurant and up-fork it.
- Frustrations: Can’t see written reviews compared to a site like yelp.
Use case:
- Title:Uploading a restaurant and up-forking a restaurant
- Description:Raymond wants to add a picture of the mac and cheese from his favorite restaurant for users to vote on. He would also like to up-fork that restaurant once uploaded.
- Name of user and role: Raymond’s favorite food is mac and cheese and has found a new favorite mac and cheese restaurant.
- Preconditions: Raymond already has an account and is signed in.
- Postconditions: Raymond uploaded a picture of the his favorite mac and cheese and has up-forked it, increasing the total number by 1.
Interaction flow:
- 1. Raymond clicks upload button on site
- 2. The site brings up a page asking to upload a picture and name of the restaurant
- 3. Raymond selects a picture of the mac and cheese from his saved pictures
- 4. The site loads Raymond's picture and displays it
- 5. Raymond enters the restaurants name and hits done.
- 6. The site takes the information Raymond entered and uploads it the the mac and cheese ranker list and redirects Raymond back to the home page.
- 7. Raymond sees the restaurant he uploaded on the ranker list and clicks the up-fork button
- 8. The site recognizes the button click and increases the total up-fork number by 1
- 9. Raymonds up-fork is displayed on the total for users to see
Frequency of use:
2-3 times a week (Raymond wants to make sure his favorite restaurant is the best).


Global BGP Network
Through Our AS 54600, Peered Directly With Tier 1 Network Providers Like China Telecom, China Unicom, China Mobile, Telia, NTT, SoftBank, PCCW, GTT and Cogent Across Multiple Global Network Exchanges, Our Network Provides Optimized Routes To Reach Your Customers With Lightning Fast Speed
Our Network Footprint
portland
San Jose
Los Angeles
Korea
Japan
Taiwan
India
Thailand
Vietnam
Cambodia
the Philippines
Singapore
London
Frankfurt
Amsterdam
Speed Test
| Network name | Distribution of operators | Test IP | Download test |
|---|---|---|---|
| {$vo.w_name|default=''} | {$vo.w_operator_name|default=''} | {$vo.w_ip|default=''} | START DOWNLOAD |


Score:
0
Question:
Questions Will Appear Here.
Game Over
Play Again?
Green Zone
Yellow Zone
Orange Zone
Red Zone
Grey Zone
×
Modal body text goes here.


Kelly Priede is
a life long resident of
Berrien County,
a 1988 graduate from
Loyola University,
Chicago, Il, with a
Bachelor’s of Arts,
Political Science.
Kelly Priede is married
30 years to Andre,
where together they have a
daughter graduating from college this spring.
A small business owner
for more than 10 years
of a property management company specializing in
The Harbor Country
Second Home Market.
Kelly Priede
Is looking to become
A
Conservative,
Exemplary Public Servant
Representing The People of
Southwest Michigan’s
78th district.


About Me
Academics
Work
Activities
Projects
Contact Us
Projects
Below are some of the links to my Github projects.
Sleek Millenial Website
Kazi.Search Website


The Context-User-Item Object Model
The Elko Context Server supports applications build around the Context-User-Item object model.
A Context is a rendezvous and coordination point for communications among multiple parties. A context is hosted on a Context Server. Within a context may be found users and items.
A User represents a human being sitting at a client application, typically implemented as Javascript code in a web browser. At any given time, a user is in some context. Multiple users may be in the same context together, enabling them to engage in multiparty interactions of various kinds.
An Item is an object that embodies some aspect of the application. An item is always in some container, which may be a context, a user, or another item.
Contexts, users and items are all examples of unums, world objects in a distributed instantiation object pattern. Each of these objects has a representation, called a presence, that exists in the Context Server and in each of the clients. Each unum has a reference string (or ref for short) by which it may be named in JSON messages. When a client sends a message over a connection to a server and the server receives it, the message is delivered to the server presence of the object named by the message as its target. Similarly, a server may send a message over a connection to a client, addressing the message to the client presence of some object. Additionally, code running in the server may send a single message to all client presences of some object; the server message system will fan out that message to all the clients that hold presences of that object, using those clients' respective connections. This will be explained in more detail in the section on server programming below.
Additional objects may exist only on the server or on some particular
client. These objects may be addressed as the targets of messages
individually. For example, when a client first connects to the server, the
only server object that is immediately in scope for that client is the
communications session itself, which may be addressed as
"session"
. In particular, the client may send a message to the
session object requesting that the client's associated user be granted
admission to some particular context.
Most of the logic that is specific to particular applications is embodied in objects known as Mods (short, variously, for "module" or "modification", depending on your perspective). A mod is simply a bundle of behavior and state that is attached to some particular context, user, or item. The mod augments the object to which it is attached with additional message protocols specific to whatever functionality it is that the mod provides. Mods are most frequently attached to items, since the main thing that distiguishes one item from another (aside from its identity) is what mods it has that customize its behavior.


@@include('../00.global/include-header.html')
@@include('../00.global/include-loader.html') @@include('../00.global/include-toggle-trigger.html')Transform, agency working families thinkers who make change happen communities.
Read MoreFrontline respond, visionary collaborative cities advancement overcome injustice, UNHCR public-private partnerships cause. Giving, country educate rights-based approach; leverage disrupt solution.
Read MoreSustainability involvement fundraising campaign connect carbon rights, collaborative cities convener truth.
Read More


--- title: "Steps to Make Perfect Olive Oil Lemon Cake Tasty" slug: olive-oil-lemon-cake description: "Olive Oil Lemon Cake Recipe - A moist and delicious, light, lemon-flavored cake; perfect for tea parties or dessert. Recipe of Favorite Olive Oil Lemon Cake Delicious" date: 2021-05-23T00:02:26Z image: https://cdn.statically.io/img/images.media-allrecipes.com/userphotos/2276445.jpg thumbnail: https://cdn.statically.io/img/images.media-allrecipes.com/userphotos/2276445.jpg cover: https://cdn.statically.io/img/images.media-allrecipes.com/userphotos/2276445.jpg author: Mardhiyah ratingvalue: 4.5 reviewcount: 754 recipeingredient: - "cooking spray" - "1 cup fat free milk" - "1 tablespoon lemon juice" - "6 egg whites" - "2 cups sucanat" - "1 cup light olive oil" - "1 cup whole wheat flour" - "1 cup all-purpose flour" - "1 tablespoon lemon zest" - "1 teaspoon baking soda" - "1 teaspoon salt" - "1 teaspoon vanilla extract" recipeinstructions: - "Preheat oven to 350 degrees F (175 degrees C). Spray a 9-inch fluted tube pan (such as Bundt®) with cooking spray and dust with flour." - "Mix milk and lemon juice together in a bowl." - "Beat egg whites together in a bowl using an electric mixer until stiff peaks form; beat in sucanat until fluffy. Mix olive oil into beaten egg whites mixture until smooth." - "Mix whole wheat flour, all-purpose flour, lemon zest, baking soda, salt, and vanilla extract together in a separate bowl." - "Stir egg white mixture, alternating with milk mixture, into the flour mixture until batter is smooth; pour into the prepared pan." - "Bake in the preheated oven until a knife inserted in the center of the cake comes out clean, about 1 hour." categories: - "Desserts" - "Fruit Dessert Recipes" - "Lemon Dessert Recipes" - "Recipes" tags: - "desserts" - "fruit dessert recipes" - "lemon dessert recipes" katakunci: olive oil lemon cake, desserts, fruit dessert recipes, lemon dessert recipes, . nutrition: 369.1 calories recipecuisine: Western preptime: "P0DT0H15M" cooktime: "P0DT1H0M" totaltime: "P0DT1H15M" recipeyield: "12 servings" recipecategory: - Desserts - Fruit Dessert Recipes - Lemon Dessert Recipes quotes: Food shared is happiness multiplied. ---
Olive Oil Lemon Cake - Hey everyone, hope youre having an amazing day today. It is me again Mardhiyah , welcome to my recipe website. Today, Im gonna show you how to prepare a distinctive dish, Olive Oil Lemon Cake. It is one of my favorites food recipes. For mine, I will make it a little bit tasty. This is gonna smell and look delicious.
Olive Oil Lemon Cake is A moist and delicious, light, lemon-flavored cake; perfect for tea parties or dessert.
Olive Oil Lemon Cake is one of the most well liked of recent trending meals on earth. its easy, its quick, it tastes yummy. It is appreciated by millions daily. its easy, it is fast, it tastes delicious. Olive Oil Lemon Cake is something that I have loved my whole life. They re nice and they look wonderful. They are nice and they look wonderful. Olive Oil Lemon Cake is something that I ve loved my entire life.
To begin with this particular recipe, we must first prepare a few ingredients. You can have Olive Oil Lemon Cake using 12 ingredients and 6 steps. Here is how you can achieve that.
So that is going to wrap this up for this exceptional food Olive Oil Lemon Cake recipe. Thank you very much for your time. Im sure that you will make this at home. Theres gonna be more interesting food at home recipes coming up. Remember to bookmark this page on your browser, and share it to your family, colleague and friends. Thanks again for reading. Go on get cooking!


{{ page.title }}
def main():
I = boy('MO Huansheng ')
I.born = "19901019GuiLinGuangXiChina"
I.undergraduteUniversity = USTC
I.graduateUniversity = ICT.CAS
I.email =<EMAIL_ADDRESS>I.github = http://github.com/pathfinder007
I.weibo = http://weibo.com/mushsen
I.interests = CyclingHikingSoccerReadingProgrammingAlgorithms
I.skills = C++CPythonObjective-CMySQLiOSLinux KernelData Mining
# Finally, I found this place to record my life and what I learn in every single day.
# Live, love and Laugh!
while True:
I.Effort += 1
if __name__ == '__main__':
main()


B&P Gallery
Gallery of independent artists
Home
Sign Up
Shop
Gallery
Blog
Recent
Popular
About
Contact
Sign UP
Register


Extracting the essential
Reading large texts takes time. Sometimes it would be useful to extract essential sentences of a text to get a first impression of the whole. Therefore we will scrap a text from the web, do some string manipulation, tokenize it and finally extract the most important sentences by using Google Pagerank algorithm.
To do so I will use the following R packages
rvest
stringr
udpipe
textrank
In our example, we will use a text of the The Bureau of investegative journalism by Madlen Davies and Ben Stockton from July 22 2019. The article describes the ban of a antibioticum in Indian farms to fatten up animals. Fatten up animals is - according to the WHO - a major cause of the world’s growing antibiotic resistance crisis.
You can find the full article here.
To scrape the text from the website we will use the rvest package which makes it easy to get all the data we want. It also provides assistance to use pipes from the magrittr package which is always a good choice. :)
library(rvest)
Scraping the data we simply define the relevant URL and a node which indicates a corresponding CSS selector. Because we only want the text of our article, we choose p
as our relevant node. The p element is used to identify blocks of paragraph text in HTML.
There is a wide variety of nodes we can define but do not need in this context. For exmaple we could scrape tables, rating, pictures and so on.
url <- 'https://www.thebureauinvestigates.com/stories/2019-07-22/india-bans-use-of-last-hope-antibiotic-colistin-on-farms'
webpage <- read_html(url)
text <- webpage %>%
html_nodes("p") %>%
html_text()
In the next step we will do a little string manipulation to
split our text in sentences (
str_split
)get rid of some symbols we do not wanna have (
str_trim
) and whitespace at the begin and ending (str_trim
)
library(stringr)
text <- unlist(strsplit(text, "\\. ")) %>%
str_replace_all(pattern = "\n", replacement = " ") %>%
str_replace_all(pattern = "[\\^]", replacement = " ") %>%
str_replace_all(pattern = "\"", replacement = " ") %>%
str_replace_all(pattern = "\\s+", replacement = " ") %>%
str_trim(side = "both")
Our text has now a total number of 776 words.
Next thing we wanna do is tokenizing and tagging our text. Therefore we use the udpipe package.
library(udpipe)
To do so we need a udpipe-model in english language.
udmodel <- udpipe_download_model("english")
udmodel <- udpipe_load_model(udmodel$file_model)
Once we loaded the model we can annotate our sentences by calling udpipe_annotate()
and transforming it to a dataframe.
df_text <- udpipe_annotate(udmodel, text) %>%
as.data.frame(text)
head(df_text)
## doc_id paragraph_id sentence_id sentence token_id
## 1 doc1 1 1 We tell the stories that matter 1
## 2 doc1 1 1 We tell the stories that matter 2
## 3 doc1 1 1 We tell the stories that matter 3
## 4 doc1 1 1 We tell the stories that matter 4
## 5 doc1 1 1 We tell the stories that matter 5
## 6 doc1 1 1 We tell the stories that matter 6
## token lemma upos xpos feats
## 1 We we PRON PRP Case=Nom|Number=Plur|Person=1|PronType=Prs
## 2 tell tell VERB VBP Mood=Ind|Tense=Pres|VerbForm=Fin
## 3 the the DET DT Definite=Def|PronType=Art
## 4 stories story NOUN NNS Number=Plur
## 5 that that PRON WDT PronType=Rel
## 6 matter matter ADV RB <NA>
## head_token_id dep_rel deps misc
## 1 2 nsubj <NA> <NA>
## 2 0 root <NA> <NA>
## 3 4 det <NA> <NA>
## 4 2 obj <NA> <NA>
## 5 6 nsubj <NA> <NA>
## 6 4 acl:relcl <NA> SpacesAfter=\\n
To find the most important senteces we will use a graph based ranking model by using an unsupervised method.
Textrank constructs a graph where “the verticles of a the graph represent each sentence in our text and the edges between sentences are based on content overlap, namely by calculating the number of words that two sentences have in common.”
Textrank then uses PageRank to identify the most important sentences of a text. PageRank is also used by Google Search to rank web pages.
If you are interested in more details please read the paper.
library(textrank)
Textrank needs a dataframe with sentences and a dataframe with words which are part of these sentences.
Here we only take nouns and adjectives for finding overlaps between sentences.
df_text$textrank_id <- unique_identifier(df_text, c("doc_id", "paragraph_id", "sentence_id"))
sentences <- unique(df_text[, c("textrank_id", "sentence")])
terminology <- subset(df_text, upos %in% c("NOUN", "ADJ"))
terminology <- terminology[, c("textrank_id", "lemma")]
head(terminology)
## textrank_id lemma
## 4 1 story
## 9 12 defend
## 10 12 quality
## 13 12 spark
## 14 12 change
## 34 37 story
By applying our sentences and terminology into textrank_sentences()
they will be applied to Google’s Pagerank.
textrank <- textrank_sentences(data = sentences, terminology = terminology)
We can now extract the top n most relevant sentences where n defines the number of sentences which should be mentioned.
important_sentences <- summary(textrank,
n = 4,
keep.sentence.order = TRUE)
cat(important_sentences, sep = "\n")
## The Indian government has banned the use of a “last hope” antibiotic on farms to try to halt the spread of some of the world’s most deadly superbugs, after a Bureau investigation revealed it was being widely used to fatten livestock.
## The use of antibiotics to fatten up animals — known as “growth promotion” — is a major cause of the world's growing antibiotic resistance crisis
## He said the ban indicates that “the Indian government is convinced that colistin is a last resort antibiotic, colistin resistance is increasing in clinical practice and colistin is extensively used in poultry and aqua farming as a growth promoting agent” and such practice should stop.
## The discovery of a colistin-resistant gene that can pass between bacteria, conferring resistance to bugs never exposed to the drug, sent shockwaves through the medical world in 2015
We redouced our text from 776 to 139 words by using natural language processing in combination with Google Pagerank.
Do you understand the core message of the text by reading only the summary?


- Judging will be blind. No names or other indicators are allowed in or on the entry that could indicate who is the author of the entry.
- Each entry will be uploaded on Facebook as contestant number and will be judged on the basis of likes.
- The judging process is as follows:
LEVEL 1
The entries with the top 10 highest number of likes till 12th March, 2016 midnight will be taken to level 2 and others will be disqualified.
LEVEL 2
The top 10 entries from the LEVEL 1 will be uploaded freshly on Facebook and have to score fresh likes.
The entries with the top 5 highest number of likes till 16th March, 2016 midnight will be taken to the final level and others will be disqualified.
FINAL LEVEL
The top 5 entries will be scored by separate judges.
The entry with the top 2 highest final score will be declared and awarded with prizes and certificates as first and second , and will be notified through emails and phones.


Event passing is the means by which components communicate with each other. Components broadcast events, and the underlying framework delivers the events to the components that are to be notified. The notified components usually perform some action based on the event that took place.
The event model was designed to accommodate the JavaBeans™ architecture. To understand how events and event handling work in the JavaBeans component model, you must understand the concepts of events, listeners, and sources. To refresh your knowledge in these areas, read the Writing Event Listeners lesson of the Swing tutorial.
The event model that is used by the JavaBeans architecture is a delegation model. This model is composed of three main parts: sources, events, and listeners.
The source of an event is the object that originates or fires the event. The source must define the events it will fire, as well as the methods for registering listeners of those events. A listener is an object that indicates that it is to be notified of events of a particular type. Listeners register for events using the methods defined by the sources of those events.
From the Properties lesson you discovered two event listeners. The
PropertyChangeListener
(in the API reference documentation) interface provides a notification whenever a
bound property value is changed and the
VetoableChangeListener
(in the API reference documentation) creates a notification whenever a bean changes
a constrained property value.
ActionEvent
(in the API reference documentation).
Listeners of events of this type must register for these events using the
addActionListener
method.
Therefore, the addActionListener
method is used to register
the ButtonHandler
object as a listener of the ActionEvent
event that is fired by the button.
In addition, according to the requirements of the ActionListener
class, you must define an actionPerformed
method, which is the
method that is called when the button is clicked.
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JTextArea; import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; public class ButtonHandler implements ActionListener { /** * Component that will contain messages about * events generated. */ private JTextArea output; /** * Creates an ActionListener that will put messages in * JTextArea everytime event received. */ public ButtonHandler( JTextArea output ) { this.output = output; } /** * When receives action event notification, appends * message to the JTextArea passed into the constructor. */ public void actionPerformed( ActionEvent event ) { this.output.append( "Action occurred: " + event + '\n' ); } } class ActionTester { public static void main(String args[]) { JFrame frame = new JFrame( "Button Handler" ); JTextArea area = new JTextArea( 6, 80 ); JButton button = new JButton( "Fire Event" ); button.addActionListener( new ButtonHandler( area ) ); frame.add( button, BorderLayout.NORTH ); frame.add( area, BorderLayout.CENTER ); frame.pack(); frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); frame.setLocationRelativeTo( null ); frame.setVisible( true ); } }
The JavaBeans API provides event-oriented design patterns to give introspecting tools the ability to discover what events a bean can fire. For a bean to be the source of an event, it must implement methods that add and remove listener objects for that type of event. The design patterns for these methods are the following:
public void add<EventListenerType>(<EventListenerType> a) public void remove<EventListenerType>(<EventListenerType> a)
ActionListener
objects, it will fire events at those objects by calling the
actionPerformed
method on those listeners.
package java.awt.event; import java.util.EventListener; public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent e); }
In the lesson "Using the NetBeans GUI Builder," you learned how to create a
MyBean
component, add the yourName
property, and design a simple form.
Now you will set an event by which a value entered in the JTextField
component
is stored in the yourName
property.
Use the GUI Builder as follows to set such an event:
jButton1
).
Notice that the button is highlighted in red when it is selected.
myBean1
component.
jButton1ActionPerformed1
] event by expanding the event type directory nodes,
as represented in the following figure.
yourName
property in the MyBean
component,
and click the Next button.
jTextField
component
from the Component combobox and choose the text property from the list
that is presented, as shown on the following figure.
The Source Editor window is now displayed. Since the GUI Builder automatically
generates the code to connect the form's components, the following code
will be added to the MyForm
class:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { myBean1.setYourName(jTextField1.getText()); }


Hong Kong riot police fire tear gas near university campus
HONG KONG (Reuters) - Hong Kong riot police fired volleys of tear gas at protesters emerging from a university campus on Sunday, according to a Reuters witness, as overnight violence restarted.
Hours earlier, police tear gas forced hundreds of protesters, some lobbing petrol bombs, to retreat behind make-shift fortifications at the Hong Kong Polytechnic University in some of the most dramatic scenes since protests began more than five months ago.


--- title: "Authors" layout: default permalink: "/authors.html" --- {% for auth in site.authors %} {% assign author=auth[1] %} {{ author.display_name }}


Internal Server Error
Sorry an error has occurred, please try refreshing the page or navigate back to
home
.


Toggle navigation
Dashboard Starter UI
Home
Team
Source
Community
Technical Support
Pageviews by browser (past 24 hours)
This is a sample text region to describe this chart.
Pageviews by browser (past 5 days)
Notes go down here
Enter Your Email Here
Submit


--- layout: post title: Make a Zombie date: '2009-12-18T12:51:00.000-08:00' author: Daniel Hilst blogger: true tags: modified_time: '2009-12-18T12:52:26.023-08:00' blogger_id: tag:blogger.com,1999:blog-8785437776394405849.post-5354923053113236404 blogger_orig_url: http://gkos-hw.blogspot.com/2009/12/make-zombie.html ---
/*
* file: make-zombie.c
* compiling: gcc -o make-zombie make-zombie.c
* This will make a Zombie Process that will endure
* for 1 minute, or at least up to you press Ctrl-c
*/
#include <stdio.h>
#include <unistd.h>
int
main (void)
{
int child_return, child_pid = fork();
if (child_pid != 0)
/*
* I'm the parent process
*/
sleep (60);
wait (&child_return);
return 0;
}


Overview
Building reliable software is hard. The scale and complexity of
modern systems, the number of people involved in building them,
and the range of demands placed on them make it extremely
difficult to build software that is even more-or-less correct,
much less 100% correct. At the same time, the increasing degree
to which information processing is woven into every aspect of
society greatly amplifies the cost of bugs and insecurities.
Computer scientists and software engineers have responded to these
challenges by developing a whole host of techniques for improving
software reliability, ranging from recommendations about managing
software projects teams (e.g., extreme programming) to design
philosophies for libraries (e.g., model-view-controller,
publish-subscribe, etc.) and programming languages (e.g.,
object-oriented programming, aspect-oriented programming,
functional programming, ...) to mathematical techniques for
specifying and reasoning about properties of software and tools
for helping validate these properties. The present course is
focused on this last set of techniques.
The text weaves together five conceptual threads:
(1) basic tools from
logic for making and justifying precise
claims about programs;
(2) the use of
proof assistants to construct rigorous logical
arguments;
(3)
functional programming, both as a method of programming that
simplifies reasoning about programs and as a bridge between
programming and logic;
(4) formal techniques for
reasoning about the properties of
specific programs (e.g., the fact that a sorting function or
a compiler obeys some formal specification); and
(5) the use of
type systems for establishing well-behavedness
guarantees for
all programs in a given programming
language (e.g., the fact that well-typed Java programs cannot
be subverted at runtime).
Each of these is easily rich enough to fill a whole course in its
own right, and tackling all of them together naturally means that
much will be left unsaid. Nevertheless, we hope readers will find
that these themes illuminate and amplify each other and that
bringing them together creates a good foundation for digging into
any of them more deeply. Some suggestions for further reading can
be found in the
Postscript chapter. Bibliographic
information for all cited works can be found in the file
Bib.
Logic
Logic is the field of study whose subject matter is
proofs —
unassailable arguments for the truth of particular propositions.
Volumes have been written about the central role of logic in
computer science. Manna and Waldinger called it "the calculus of
computer science," while Halpern et al.'s paper
On the Unusual
Effectiveness of Logic in Computer Science catalogs scores of
ways in which logic offers critical tools and insights. Indeed,
they observe that, "As a matter of fact, logic has turned out to
be significiantly more effective in computer science than it has
been in mathematics. This is quite remarkable, especially since
much of the impetus for the development of logic during the past
one hundred years came from mathematics."
In particular, the fundamental tools of
inductive proof are
ubiquitous in all of computer science. You have surely seen them
before, perhaps in a course on discrete math or analysis of
algorithms, but in this course we will examine them much more
deeply than you have probably done so far.
Proof Assistants
The flow of ideas between logic and computer science has not been
unidirectional: CS has also made important contributions to logic.
One of these has been the development of software tools for
helping construct proofs of logical propositions. These tools
fall into two broad categories:
- Automated theorem provers provide "push-button" operation:
you give them a proposition and they return either true or
false (or, sometimes, don't know: ran out of time).
Although their capabilities are still limited to specific
domains, they have matured tremendously in recent years and
are used now in a multitude of settings. Examples of such
tools include SAT solvers, SMT solvers, and model checkers.
- Proof assistants are hybrid tools that automate the more
routine aspects of building proofs while depending on human
guidance for more difficult aspects. Widely used proof
assistants include Isabelle, Agda, Twelf, ACL2, PVS, and Coq,
among many others.
This course is based around Coq, a proof assistant that has been
under development since 1983 and that in recent years has
attracted a large community of users in both research and
industry. Coq provides a rich environment for interactive
development of machine-checked formal reasoning. The kernel of
the Coq system is a simple proof-checker, which guarantees that
only correct deduction steps are ever performed. On top of this
kernel, the Coq environment provides high-level facilities for
proof development, including a large library of common definitions
and lemmas, powerful tactics for constructing complex proofs
semi-automatically, and a special-purpose programming language for
defining new proof-automation tactics for specific situations.
Coq has been a critical enabler for a huge variety of work across
computer science and mathematics:
- As a platform for modeling programming languages, it has
become a standard tool for researchers who need to describe and
reason about complex language definitions. It has been used,
for example, to check the security of the JavaCard platform,
obtaining the highest level of common criteria certification,
and for formal specifications of the x86 and LLVM instruction
sets and programming languages such as C.
- As an environment for developing formally certified software
and hardware, Coq has been used, for example, to build
CompCert, a fully-verified optimizing compiler for C, and
CertiKos, a fully verified hypervisor, for proving the
correctness of subtle algorithms involving floating point
numbers, and as the basis for CertiCrypt, an environment for
reasoning about the security of cryptographic algorithms. It is
also being used to build verified implementations of the
open-source RISC-V processor.
- As a realistic environment for functional programming with
dependent types, it has inspired numerous innovations. For
example, the Ynot system embeds "relational Hoare reasoning" (an
extension of the Hoare Logic we will see later in this course)
in Coq.
- As a proof assistant for higher-order logic, it has been used
to validate a number of important results in mathematics. For
example, its ability to include complex computations inside
proofs made it possible to develop the first formally verified
proof of the 4-color theorem. This proof had previously been
controversial among mathematicians because part of it included
checking a large number of configurations using a program. In
the Coq formalization, everything is checked, including the
correctness of the computational part. More recently, an even
more massive effort led to a Coq formalization of the
Feit-Thompson Theorem — the first major step in the
classification of finite simple groups.
By the way, in case you're wondering about the name, here's what
the official Coq web site at INRIA (the French national research
lab where Coq has mostly been developed) says about it: "Some
French computer scientists have a tradition of naming their
software as animal species: Caml, Elan, Foc or Phox are examples of
this tacit convention. In French, 'coq' means rooster, and it
sounds like the initials of the Calculus of Constructions (CoC) on
which it is based." The rooster is also the national symbol of
France, and C-o-q are the first three letters of the name of
Thierry Coquand, one of Coq's early developers.
Functional Programming
The term
functional programming refers both to a collection of
programming idioms that can be used in almost any programming
language and to a family of programming languages designed to
emphasize these idioms, including Haskell, OCaml, Standard ML,
F#, Scala, Scheme, Racket, Common Lisp, Clojure, Erlang, and Coq.
Functional programming has been developed over many decades —
indeed, its roots go back to Church's lambda-calculus, which was
invented in the 1930s, well before the first computers (at least
the first electronic ones)! But since the early '90s it has
enjoyed a surge of interest among industrial engineers and
language designers, playing a key role in high-value systems at
companies like Jane St. Capital, Microsoft, Facebook, and
Ericsson.
The most basic tenet of functional programming is that, as much as
possible, computation should be
pure, in the sense that the only
effect of execution should be to produce a result: it should be
free from
side effects such as I/O, assignments to mutable
variables, redirecting pointers, etc. For example, whereas an
imperative sorting function might take a list of numbers and
rearrange its pointers to put the list in order, a pure sorting
function would take the original list and return a
new list
containing the same numbers in sorted order.
A significant benefit of this style of programming is that it
makes programs easier to understand and reason about. If every
operation on a data structure yields a new data structure, leaving
the old one intact, then there is no need to worry about how that
structure is being shared and whether a change by one part of the
program might break an invariant that another part of the program
relies on. These considerations are particularly critical in
concurrent systems, where every piece of mutable state that is
shared between threads is a potential source of pernicious bugs.
Indeed, a large part of the recent interest in functional
programming in industry is due to its simpler behavior in the
presence of concurrency.
Another reason for the current excitement about functional
programming is related to the first: functional programs are often
much easier to parallelize than their imperative counterparts. If
running a computation has no effect other than producing a result,
then it does not matter
where it is run. Similarly, if a data
structure is never modified destructively, then it can be copied
freely, across cores or across the network. Indeed, the
"Map-Reduce" idiom, which lies at the heart of massively
distributed query processors like Hadoop and is used by Google to
index the entire web is a classic example of functional
programming.
For purposes of this course, functional programming has yet
another significant attraction: it serves as a bridge between
logic and computer science. Indeed, Coq itself can be viewed as a
combination of a small but extremely expressive functional
programming language plus a set of tools for stating and proving
logical assertions. Moreover, when we come to look more closely,
we find that these two sides of Coq are actually aspects of the
very same underlying machinery — i.e.,
proofs are programs.
Program Verification
Approximately the first third of
Software Foundations is devoted
to developing the conceptual framework of logic and functional
programming and gaining enough fluency with Coq to use it for
modeling and reasoning about nontrivial artifacts. In the middle
third, we turn our attention to two broad topics of critical
importance in building reliable software (and hardware):
techniques for proving specific properties of particular
programs and for proving general properties of whole programming
languages.
For both of these, the first thing we need is a way of
representing programs as mathematical objects, so we can talk
about them precisely, plus ways of describing their behavior in
terms of mathematical functions or relations. Our main tools for
these tasks are
abstract syntax and
operational semantics, a
method of specifying programming languages by writing abstract
interpreters. At the beginning, we work with operational
semantics in the so-called "big-step" style, which leads to simple
and readable definitions when it is applicable. Later on, we
switch to a lower-level "small-step" style, which helps make some
useful distinctions (e.g., between different sorts of
nonterminating program behaviors) and which is applicable to a
broader range of language features, including concurrency.
The first programming language we consider in detail is
Imp, a
tiny toy language capturing the core features of conventional
imperative programming: variables, assignment, conditionals, and
loops.
We study two different ways of reasoning about the properties of
Imp programs. First, we consider what it means to say that two
Imp programs are
equivalent in the intuitive sense that they
exhibit the same behavior when started in any initial memory
state. This notion of equivalence then becomes a criterion for
judging the correctness of
metaprograms — programs that
manipulate other programs, such as compilers and optimizers. We
build a simple optimizer for Imp and prove that it is correct.
Second, we develop a methodology for proving that a given Imp
program satisfies some formal specifications of its behavior. We
introduce the notion of
Hoare triples — Imp programs annotated
with pre- and post-conditions describing what they expect to be
true about the memory in which they are started and what they
promise to make true about the memory in which they terminate —
and the reasoning principles of
Hoare Logic, a domain-specific
logic specialized for convenient compositional reasoning about
imperative programs, with concepts like "loop invariant" built in.
This part of the course is intended to give readers a taste of the
key ideas and mathematical tools used in a wide variety of
real-world software and hardware verification tasks.
Type Systems
Our final major topic, covering approximately the last third of
the course, is
type systems, which are powerful tools for
establishing properties of
all programs in a given language.
Type systems are the best established and most popular example of
a highly successful class of formal verification techniques known
as
lightweight formal methods. These are reasoning techniques
of modest power — modest enough that automatic checkers can be
built into compilers, linkers, or program analyzers and thus be
applied even by programmers unfamiliar with the underlying
theories. Other examples of lightweight formal methods include
hardware and software model checkers, contract checkers, and
run-time monitoring techniques.
This also completes a full circle with the beginning of the book:
the language whose properties we study in this part, the
simply
typed lambda-calculus, is essentially a simplified model of the
core of Coq itself!