My
Front-End
developer
Journey
Hello,
My name is Tatyana Olvera and I am a Web Content Editor based in Dallas, TX. I am currently in the process of becoming a Front-End Developer. If I'm not working on a website you might find me painting.
My Skills: HTML/CSS and Javascript/Jquery
My goal is to write clean, well
-formatted, semantic HTML5 by hand
to make sure that the content is easy
to read, easy to collaborate,
trouble-shoot and accessible.
I want to pride myself on writing CSS
that is easy to read and build on. I
focus on keeping my CSS lean and
fast to load, and I make it a habit
to stay up to date on current
best practices.
I want you to trust me to take a designer's
PSD and quickly & accurately convert
it into a webpage that is pixel-perfect
match.
Samsung S9 Life
This website was created to be a personal portfolio for photographs I have take with my Samsung S9
Unplugged
The Unplugged website was a SkillCrush class asignment that focused on creating a responsive website with a mobile first approach usin gonly HTML and CSS


Home
Map
(current)
Find a School
(current)
Filter Search by City
Filter Search by State
Filter Search by Type
Filter Table
School Name
City
State
Rank
Enrollment
Tuition
Average GPA
Average ACT Score
Average SAT Score
Type


Toggle navigation
Getmii Admin
Map
Change Location
Change Location
Logout
Getmii...
Change Location
Post the Need


I think it is an useful contribution to the R community. But first of all, the title:
RStudio for R Statistical Computing Cookbook
The book is a concentrated of recipes targeted to the average R user to get him from being in the mean to the become an outlier. Aside from statistical analogies, this book provides recipes to perform relevant activities within all phases of data analysis projects, and literally:
data acquisition;
data cleansing;
data visualisation;
specific domain application (not actually a phase, I know…);
results sharing.
data acquisition
you find here all you need to get data from around the word into R, using social networks API but also developing custom functions to access specific APIs you need. Data import from nearly every kind of file is also covered, giving you hints on how to streamline your analyses.
data cleansing
within this section you discover how to give your data a tidy structure, which is a structure where each row is an observations and every column host and attribute (yeah yeah, we are talking about tidy data framework by hadley whickam).
data visualisation
no matter if you are within the exploratory data analysis phase or production stage, data visualisation is a core step of your work (I know you already know this, but let me make it a bit more commercial, come on…), that’s why a whole section is devoted to show you basic and advanced visualisation techniques, like great Sankey diagrams and 3D animated plots.
domain specific application
domain specific applications is were R really shines, and you find here nearly a dozens of great R language applications, from text analytics on PDFs to benford analysis on ecommerce data and reccomandation engine modelling.
results sharing
We could have named this section “Rmarkdown is everywhere”, since within this chapters the reader is introduced to all possible flavours of this powerful tool provided by Rstudio guys. One of my favourite recipe is the one which shows you how to publish and curate a blog directly from Rstudio.
free chapter
Packt publishing provided for your convenience a free chapter which will let you get a first sense of how the book is structured and conceived. you cane easily find it on slideshare.
final ad
Summing it all up: If you are looking for a way to get from good to great with R this book is going to be a good companion to your journey, or at least this was my objective 😅. And if you are thinking if it is worthing to spend a sum of money for me, well,** don’t forget I am now dad of three voracious babies** :).


My Library
Welcome to your Library!
All the status of your current books
Add New Book
Add book details
Your book has been added to the library!
Book Title
Author's Name
Book Cover
https://
We'll use a default image if you can't find one.
Number of pages
Read
Not read yet
Add


Sort By Tag :
We are a dedicated team of game developers, designers, artists and programmers. Our passion is making fun, meaningful and enjoyable experiences. We believe in the power of games to entertain and immerse players in its unique and fun worlds.
Sort By Tag :
Sky Striders
Sky Striders is an online multiplayer game that focuses on movement mechanics whether on the ground or in the air. Sky Striders will have many game modes that utilizes a dynamic set of movement abilities to push and challenge our players into moving fast with precision. Sky striders will have many characters that will differ in shape, and movement stats.
That Just Happend
That just happend is a serious VR game about blue collars workplace safety, the purpose of the player is to help his/her co-workers by giving them safety equipments to save their lives from deadly accidents.
Skull Switch
Skull Switch is a Hyper-Casual game where you try to save the skulls on screen from incoming danger by clicking on the lane which contains a skull to make it invisible before obstacles can destroy it.
Scriptable System
Scriptable System was made to make managing/creating scriptable variables and events an easy organized process.
Sky Strider
Description
Sky Striders is an online multiplayer game that focuses on movement mechanics whether on the ground or in the air. Sky Striders will have many game modes that utilizes a dynamic set of movement abilities to push and challenge our players into moving fast with precision. Sky striders will have many characters that will differ in shape, and movement stats.
Gameplay
Multiplayer
That Just Happend
Description
That just happend is a serious VR game about blue collars workplace safety, the purpose of the player is to help his/her co-workers by giving them safety equipments to save their lives from deadly accidents.
Gameplay
Skull Switch
Description
Skull Switch is a Hyper-Casual game where you try to save the skulls on screen from incoming danger by clicking on the lane which contains a skull to make it invisible before obstacles can destroy it.
Gameplay
Scriptable System
Description
Scriptable System was made to make managing/creating scriptable variables and events an easy organized process.
Tutorial
Features


This Privacy Policy governs the manner in which Emprovise collects, uses, maintains and discloses information collected from users (each, a "User") of the emprovise.x10.mx website ("Site"). This privacy policy applies to the Site and all products and services offered by Emprovise.
Personal identification information
We may collect personal identification information from Users in a variety of ways, including, but not limited to, when Users visit our site, respond to a survey, and in connection with other activities, services, features or resources we make available on our Site. Users may be asked for, as appropriate, name, email address. Users may, however, visit our Site anonymously. We will collect personal identification information from Users only if they voluntarily submit such information to us. Users can always refuse to supply personally identification information, except that it may prevent them from engaging in certain Site related activities.
Non-personal identification information
We may collect non-personal identification information about Users whenever they interact with our Site. Non-personal identification information may include the browser name, the type of computer and technical information about Users means of connection to our Site, such as the operating system and the Internet service providers utilized and other similar information.
Web browser cookies
Our Site may use "cookies" to enhance User experience. User's web browser places cookies on their hard drive for record-keeping purposes and sometimes to track information about them. User may choose to set their web browser to refuse cookies, or to alert you when cookies are being sent. If they do so, note that some parts of the Site may not function properly .
How we use collected information
Emprovise may collect and use Users personal information for the following purposes:
i. To improve customer service:
Information you provide helps us respond to your customer service requests and support needs more efficiently.
ii. To improve our Site:
We may use feedback you provide to improve our products and services.
Iii. To send periodic emails:
We may use the email address to respond to their inquiries, questions, and/or other requests. If User decides to opt-in to our mailing list, they will receive emails that may include company news, updates, related product or service information, etc. If at any time the User would like to unsubscribe from receiving future emails, we include detailed unsubscribe instructions at the bottom of each email or User may contact us via our Site.
How we protect your information
We adopt appropriate data collection, storage and processing practices and security measures to protect against unauthorized access, alteration, disclosure or destruction of your personal information, username, password, transaction information and data stored on our Site.
Sharing your personal information
We do not sell, trade, or rent Users personal identification information to others. We may share generic aggregated demographic information not linked to any personal identification information regarding visitors and users with our business partners, trusted affiliates and advertisers for the purposes outlined above.
Third party websites
Users may find advertising or other content on our Site that link to the sites and services of our partners, suppliers, advertisers, sponsors, licensors and other third parties. We do not control the content or links that appear on these sites and are not responsible for the practices employed by websites linked to or from our Site. In addition, these sites or services, including their content and links, may be constantly changing. These sites and services may have their own privacy policies and customer service policies. Browsing and interaction on any other website, including websites which have a link to our Site, is subject to that website's own terms and policies.
Google Adsense
Some of the ads may be served by Google. Google's use of the DART cookie enables it to serve ads to Users based on their visit to our Site and other sites on the Internet. DART uses "non personally identifiable information" and does NOT track personal information about you, such as your name, email address, physical address, etc. You may opt out of the use of the DART cookie by visiting the Google ad and content network privacy policy at Google Advertising Privacy.
Changes to this privacy policy
Emprovise has the discretion to update this privacy policy at any time. When we do, we will post a notification on the main page of our Site, revise the updated date at the bottom of this page. We encourage Users to frequently check this page for any changes to stay informed about how we are helping to protect the personal information we collect. You acknowledge and agree that it is your responsibility to review this privacy policy periodically and become aware of modifications.
Your acceptance of these terms
By using this Site, you signify your acceptance of this policy. If you do not agree to this policy, please do not use our Site. Your continued use of the Site following the posting of changes to this policy will be deemed your acceptance of those changes.
Contact Information
If you have any questions about this Privacy Policy, the practices of this site, or your dealings with this site, please contact us at:
Emprovise Inc
<EMAIL_ADDRESS>34th St
Moline, IL 61265
USA


- warn(String) - Method in class com.github.mathiewz.slick.util.DefaultLogSystem
-
Log a warning
- warn(String, Throwable) - Method in class com.github.mathiewz.slick.util.DefaultLogSystem
-
Log a warning with an exception that caused it
- warn(Object) - Static method in class com.github.mathiewz.slick.util.Log
-
Log a warning
- warn(Object, Throwable) - Static method in class com.github.mathiewz.slick.util.Log
-
Log a warning
- warn(String) - Method in interface com.github.mathiewz.slick.util.LogSystem
-
Log a warning
- warn(String, Throwable) - Method in interface com.github.mathiewz.slick.util.LogSystem
-
Log a warning
- WAV - Static variable in class com.github.mathiewz.slick.openal.DeferredSound
-
Indicate a WAV to be loaded
- WaveData - Class in com.github.mathiewz.slick.openal
-
Utitlity class for loading wavefiles.
- WebstartMuffin - Class in com.github.mathiewz.slick.muffin
-
A muffin load/save implementation based on using Webstart Muffins (a bit like cookies only
for webstart)
- WebstartMuffin() - Constructor for class com.github.mathiewz.slick.muffin.WebstartMuffin
-
- white - Static variable in class com.github.mathiewz.slick.Color
-
The fixed colour white
- width - Variable in class com.github.mathiewz.slick.tiled.Layer
-
The width of this layer
- width - Variable in class com.github.mathiewz.slick.UnicodeFont.DisplayList
-
The width of rendered text in the list
- windFactor - Variable in class com.github.mathiewz.slick.particles.ConfigurableEmitter
-
The factor of wind to apply
- wrapUp() - Method in class com.github.mathiewz.slick.particles.ConfigurableEmitter
-
- wrapUp() - Method in class com.github.mathiewz.slick.particles.effects.FireEmitter
-
- wrapUp() - Method in interface com.github.mathiewz.slick.particles.ParticleEmitter
-
Wrap up the particle emitter.
- write(Image, String, OutputStream) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a specified output stream
- write(Image, String, OutputStream, boolean) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a specified output stream
- write(Image, String) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a file on the local file system.
- write(Image, String, boolean) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a file on the local file system.
- write(Image, String, String) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a file on the local file system.
- write(Image, String, String, boolean) - Static method in class com.github.mathiewz.slick.imageout.ImageOut
-
Write an image out to a file on the local file system.


DNS Problems! - Better Battlelog Forums #117808
Sitemap
09. May 2014 13:04
Topicstarter
BrainFooLong
Administrator
My hosting provider have done a wrong domaintransfer and now the DNS is misconfigured.
Maybe some people will not be able to visit getbblog.com sites.
I hope it will work as soon as possible.


| Figure 1 |
The bud break stages used for scoring the spring phenology w ... |
| Figure 2 |
Average score values of apical stages of intact and bud‐remo ... |
| Figure 3 |
Average score values of apical stages of intact and bud‐remo ... |
| Figure 4 |
Ambient daily average temperature at the experimental site f ... |


North Korea turns down invite for Kim to attend South Korea ASEAN summit
by Hyonhee ShinNorth Korea rejected an invitation for leader Kim Jong Un to attend a planned summit in Seoul with Southeast Asian nations next week, saying “now is not the time” due to strained ties, North Korean state media reported on Thursday.
South Korean President Moon Jae-in sent a letter of invitation to Kim on Nov. 5, with an offer for an envoy to attend if he was unable to participate in the event, the official KCNA news agency said.
Moon will host leaders of the Association of Southeast Asian Nations (ASEAN) in the South Korean port city of Busan next week to celebrate the 30th anniversary of their partnership, and has said Kim might join them.
While thanking Seoul for the invitation, North Korea requested the South’s “understanding that we could not find any legitimate reason” for Kim to participate, KCNA said.
The statement accused South Korea of harming relations by depending on the United States in resolving inter-Korean issues.
“It is perplexing that they proposed discussing inter-Korean relations at such an unfitting multilateral venue, even after experiencing failures by relying so much on the United States,” KCNA said.
The two Koreas undertook a flurry of diplomacy including three summits last year, during which Moon and Kim agreed to improve ties and restart stalled business initiatives.
But there has been no significant progress amid tightening sanctions aimed at the North’s nuclear and missile programmes, and lacklustre denuclearisation talks between Pyongyang and Washington.


| Jump to DART Documentation Main Index |
This short description of the SEALEVEL_GLO_SLA_L3_REP_OBSERVATIONS_008_018 product is repeated from the INFORMATION tab from the Copernicus Marine Environment Monitoring Service online catalogue (in April 2017).
For the Global Ocean- Mono altimeter satellite along-track sea surface heights computed with respect to a twenty-year mean. Previously distributed by Aviso+, no change in the scientific content. All the missions are homogenized with respect to a reference mission which is currently Jason-2. This product is computed with an optimal and centered computation time window (6 weeks before and after the date). Two kinds of datasets are proposed: filtered (nominal dataset) and unfiltered.The convert_aviso.f90 program is designed to read a netCDF file containing the (Level 3) sea surface anomalies from any of the following platforms: "Jason-1", "Envisat", or "Geosat Follow On". One of those platforms must be listed in the netCDF file global attribute: platform
After creating a large number of output observation sequence files, it is usually
necessary to consolidate the files and subset them into files containing just the
timeframe required for a single assimilation. NOTE:
the obs_sequence_tool is constructed for just this purpose.
The shell_scripts/makedaily.sh script attempts to
consolidate all the SLA observations and those that may have been (separately)
converted from the World Ocean Database into 24-hour segments centered at midnight GMT.
You will have to modify the makedaily.sh script to suit your
filesystem and naming convention. It is provided as a starting point.
Reminder: (according to the data providers): In order to compute Absolute Dynamic Topography, the Mean Dynamic Topography (MDT) can be added. It is distributed by Aviso+ ( http://www.aviso.altimetry.fr/en/data/products/auxiliary-products/mdt.html ). Fred was using this product in assimilations with POP, so he chose a different source for MDT - consistent with POP's behavior.
The Copernicus Marine and Environment Monitoring Service (CMEMS) has taken over the processing and distribution of the Ssalto/Duacs multimission altimeter products formerly administered by Aviso+. After a registration process, the along-track sea level anomalies (SLA) may be downloaded from http://marine.copernicus.eu/services-portfolio/access-to-products/ - search for the SEALEVEL_GLO_SLA_L3_REP_OBSERVATIONS_008_018 if it does not come up directly.
| convert_aviso.f90 | does the actual conversion from netCDF to a DART observation sequence file, which may be ASCII or binary. |
| shell_scripts/convert_aviso.py | python script to convert a series of input files and datestamp the output files. |
| shell_scripts/makedaily.sh | shell script to repeatedly call obs_sequence_tool to consolidate multiple observation sequence files into an observation sequence file that has ALL the observations from ALL platforms in a single file. makedaily.sh is capable of looping over time ranges and creating observation sequences for each time range. |
There is no namelist for convert_aviso, but other namelists control aspects of the execution, namely &obs_sequence_nml:write_binary_obs_sequence. see obs_sequence_mod.html.
assimilation_code/location/threed_sphere/location_mod.f90 assimilation_code/modules/assimilation/assim_model_mod.f90 assimilation_code/modules/io/dart_time_io_mod.f90 assimilation_code/modules/observations/obs_kind_mod.f90 assimilation_code/modules/observations/obs_sequence_mod.f90 assimilation_code/modules/utilities/ensemble_manager_mod.f90 assimilation_code/modules/utilities/null_mpi_utilities_mod.f90 assimilation_code/modules/utilities/random_seq_mod.f90 assimilation_code/modules/utilities/sort_mod.f90 assimilation_code/modules/utilities/time_manager_mod.f90 assimilation_code/modules/utilities/types_mod.f90 assimilation_code/modules/utilities/utilities_mod.f90 models/template/model_mod.f90 observations/forward_operators/obs_def_mod.f90 observations/obs_converters/AVISO/convert_aviso.f90 observations/obs_converters/utilities/obs_utilities_mod.f90
none
none
DART software - Copyright UCAR. This open source software is provided by UCAR, "as is", without charge, subject to all terms of use at http://www.image.ucar.edu/DAReS/DART/DART_download


EASTER 6 SATURDAY
Entrance Antiphon
O chosen people, proclaim the mighty works of him, who called you out of darkness into his wonderful light, alleluia.
Collect
O God, whose Son, at his Ascension to the heavens, was pleased to promise the Holy Spirit to the Apostles, grant, we pray, that just as they received manifold gifts of heavenly teaching, so on us, too, you may bestow spiritual gifts Through our Lord...
FIRST READING Acts 18:23-28
A reading from the Acts of the Apostles
After spending some time in
The word of the Lord.
RESPONSORIAL PSALM Psalm 47:2-3.8-9.10 (R. 8a)
R. God is king of all the earth.
R. God is king of all the earth.
Or Alleluia!
All peoples, clap your
hands. Cry to God with shouts of joy! For the LORD, the Most High, is awesome,
the great king over all the earth.
R. God is king of all the earth.
God is king of all the earth. Sing praise with all
your skill. God reigns over the nations. God sits upon his holy throne.
R. God is king of all the earth.
The princes of the peoples are assembled with the
people of the God of Abraham. The rulers of the earth belong to God, who is
greatly exalted.
R. God is king of all the earth.
ALLELUIA
Before the Ascension:
R. Alleluia. If
then you have been raised with Christ, seek the things that are above, where
Christ is seated at the right hand of God. R. Alleluia.
After the Ascension
R. Alleluia. I came from the Father and have come into the world; again, I am leaving the world and going to the Father. R. Alleluia.
GOSPEL John 16:23-28
A reading from the holy Gospel according to John
At that time: Jesus said to his disciples, “Truly, truly, I say to you, if you ask anything of the Father, he will give it to you in my name. Until now you have asked nothing in my name; ask, and you will receive, that your joy may be full. "I have said this to you in figures; the hour is coming when I shall no longer speak to you in figures but tell you plainly of the Father. In that day you will ask in my name; and I do not say to you that I shall pray the Father for you; for the Father himself loves you, because you have loved me and have believed that I came from the Father. I came from the Father and have come into the world; again, I am leaving the world and going to the Father."
The Gospel of the Lord.
Prayer over the Offerings
Sanctify graciously these gifts, O Lord, we pray, and,
accepting the oblation of this spiritual sacrifice, make of us an eternal offering to you. Through Christ our Lord.
Communion Antiphon
Father, I wish that where I am, those you gave me may also be with me,
that they may see the glory that you gave me, alleluia.
Prayer after Communion
We have partaken of the gifts of this sacred mystery, humbly imploring, O Lord,
that what your Son commanded us to do in mem-ory of him may bring us growth in charity. Through Christ our Lord.


Starting commands
When you start your game you may want to customize the behavior of the game
.
Also setting the spawn point will help so the players don't get teleported after joining
Turning off the weather as well as setting the time of day will help make the game stable
Execute Server Command is located in World, Server
You will need to change the spawnpoint X Y Z values to match your game start location


Customer Profile
1,507 / Customer Profile
1,507 / Outstanding Invoice
Invoice
Hello, Stanley Jones
Thanks a lot because you keep purchasing our products. Our company promises to provide high quality products for you as well as outstanding customer service for every transaction.
Order Date: Jan 17, 2016
Order Status: Paid
Order ID: #123456
Billing Address
Stanley Jones795 Folsom Ave, Suite 600
San Francisco, CA 94107
P:<PHONE_NUMBER>
Shipping Address
Stanley Jones795 Folsom Ave, Suite 600
San Francisco, CA 94107
P:<PHONE_NUMBER>
| # | Item | Quantity | Unit Cost | Total |
|---|---|---|---|---|
| 1 |
Laptop Brand Model VGN-TXN27N/B 11.1" Notebook PC |
1 | $1799 | $1799 |
| 2 |
Warranty Two Year Extended Warranty - Parts and Labor |
3 | $499 | $1497 |
| 3 |
LED 80cm (32) HD Ready LED TV |
2 | $412 | $824 |
| Sub-total: $4120.00 |
||||
VAT (12.5): $515 |
||||
| $4635.00 USD |
Signature
llslslsls dikslsl


'Kanto' guy Fran Yu delivers Finals MVP clapback
Once a fodder for online bashers, Letran's Fran Yu saves his best retort on the hardcourt
by JR IsagaSubscribe
Email Address
Newsletters
- Glenda Gloria's Take this Tuesday
- Huddle by Miriam Grace Go
- The Newsbreak Agenda by Chay Hofileña
- Sometimes, all you need is video by Lilibeth Frondoso


In this interactive tutorial, we'll cover many essential Python idioms and techniques in depth, adding immediately useful tools to your belt.
There are 3 versions of this presentation:
©2006-2008, licensed under a Creative Commons Attribution/Share-Alike (BY-SA) license.
My credentials: I am
In the tutorial I presented at PyCon 2006 (called Text & Data Processing), I was surprised at the reaction to some techniques I used that I had thought were common knowledge. But many of the attendees were unaware of these tools that experienced Python programmers use without thinking.
Many of you will have seen some of these techniques and idioms before. Hopefully you'll learn a few techniques that you haven't seen before and maybe something new about the ones you have already seen.
These are the guiding principles of Python, but are open to interpretation. A sense of humor is required for their proper interpretation.
If you're using a programming language named after a sketch comedy troupe, you had better have a sense of humor.
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced....
In the face of ambiguity, refuse the temptation to guess.There should be one—and preferably only one—obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than right now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea—let's do more of those!—Tim Peters
This particular "poem" began as a kind of a joke, but it really embeds a lot of truth about the philosophy behind Python. The Zen of Python has been formalized in PEP 20, where the abstract reads:
Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.
You can decide for yourself if you're a "Pythoneer" or a "Pythonista". The terms have somewhat different connotations.
When in doubt:
import this
Try it in a Python interactive interpreter:
>>> import this
Here's another easter egg:
>>> from __future__ import braces File "<stdin>", line 1 SyntaxError: not a chance
What a bunch of comedians! :-)
Programs must be written for people to read, and only incidentally for machines to execute.
—Abelson & Sussman, Structure and Interpretation of Computer Programs
Worthwhile reading:
http://www.python.org/dev/peps/pep-0008/
PEP = Python Enhancement Proposal
A PEP is a design document providing information to the Python community, or describing a new feature for Python or its processes or environment.
The Python community has its own standards for what source code should look like, codified in PEP 8. These standards are different from those of other communities, like C, C++, C#, Java, VisualBasic, etc.
Because indentation and whitespace are so important in Python, the Style Guide for Python Code approaches a standard. It would be wise to adhere to the guide! Most open-source projects and (hopefully) in-house projects follow the style guide quite closely.
4 spaces per indentation level.
No hard tabs.
Never mix tabs and spaces.
This is exactly what IDLE and the Emacs Python mode support. Other editors may also provide this support.
One blank line between functions.
Two blank lines between classes.
def make_squares(key, value=0): """Return a dictionary and a list...""" d = {key: value} l = [key, value] return d, l
joined_lower for functions, methods, attributes
joined_lower or ALL_CAPS for constants
StudlyCaps for classes
camelCase only to conform to pre-existing conventions
Attributes: interface, _internal, __private
But try to avoid the __private form. I never use it. Trust me. If you use it, you WILL regret it later.
Explanation:
People coming from a C++/Java background are especially prone to overusing/misusing this "feature". But __private names don't work the same way as in Java or C++. They just trigger a name mangling whose purpose is to prevent accidental namespace collisions in subclasses: MyClass.__private just becomes MyClass._MyClass__private. (Note that even this breaks down for subclasses with the same name as the superclass, e.g. subclasses in different modules.) It is possible to access __private names from outside their class, just inconvenient and fragile (it adds a dependency on the exact name of the superclass).
The problem is that the author of a class may legitimately think "this attribute/method name should be private, only accessible from within this class definition" and use the __private convention. But later on, a user of that class may make a subclass that legitimately needs access to that name. So either the superclass has to be modified (which may be difficult or impossible), or the subclass code has to use manually mangled names (which is ugly and fragile at best).
There's a concept in Python: "we're all consenting adults here". If you use the __private form, who are you protecting the attribute from? It's the responsibility of subclasses to use attributes from superclasses properly, and it's the responsibility of superclasses to document their attributes properly.
It's better to use the single-leading-underscore convention, _internal. This isn't name mangled at all; it just indicates to others to "be careful with this, it's an internal implementation detail; don't touch it if you don't fully understand it". It's only a convention though.
There are some good explanations in the answers here:
Keep lines below 80 characters in length.
Use implied line continuation inside parentheses/brackets/braces:
def __init__(self, first, second, third, fourth, fifth, sixth): output = (first + second + third + fourth + fifth + sixth)
Use backslashes as a last resort:
VeryLong.left_hand_side \ = even_longer.right_hand_side()
>>> print 'o' 'n' "e" one
The spaces between literals are not required, but help with readability. Any type of quoting can be used:
>>> print 't' r'\/\/' """o""" t\/\/o
The string prefixed with an "r" is a "raw" string. Backslashes are not evaluated as escapes in raw strings. They're useful for regular expressions and Windows filesystem paths.
Note named string objects are not concatenated:
>>> a = 'three' >>> b = 'four' >>> a b File "<stdin>", line 1 a b ^ SyntaxError: invalid syntax
That's because this automatic concatenation is a feature of the Python parser/compiler, not the interpreter. You must use the "+" operator to concatenate strings at run time.
text = ('Long strings can be made up ' 'of several shorter strings.')
The parentheses allow implicit line continuation.
Multiline strings use triple quotes:
"""Triple double quotes"""
'''\ Triple single quotes\ '''
Good:
if foo == 'blah': do_something() do_one() do_two() do_three()
Bad:
if foo == 'blah': do_something() do_one(); do_two(); do_three()
Whitespace & indentations are useful visual indicators of the program flow. The indentation of the second "Good" line above shows the reader that something's going on, whereas the lack of indentation in "Bad" hides the "if" statement.
Multiple statements on one line are a cardinal sin. In Python, readability counts.
Docstrings = How to use code
Comments = Why (rationale) & how code works
Docstrings explain how to use code, and are for the users of your code. Uses of docstrings:
Comments explain why, and are for the maintainers of your code. Examples include notes to yourself, like:
# !!! BUG: ... # !!! FIX: This is a hack # ??? Why is this here?
Both of these groups include you, so write good docstrings and comments!
Docstrings are useful in interactive use (help()) and for auto-documentation systems.
False comments & docstrings are worse than none at all. So keep them up to date! When you make changes, make sure the comments & docstrings are consistent with the code, and don't contradict it.

—Ralph Waldo Emerson
(hobgoblin: Something causing superstitious fear; a bogy.)
There are always exceptions. From PEP 8:
But most importantly: know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!
Two good reasons to break a particular rule:
- When applying the rule would make the code less readable, even for someone who is used to reading code that follows the rules.
- To be consistent with surrounding code that also breaks it (maybe for historic reasons) -- although this is also an opportunity to clean up someone else's mess (in true XP style).
... but practicality shouldn't beat purity to a pulp!
A selection of small, useful idioms.
Now we move on to the meat of the tutorial: lots of idioms.
We'll start with some easy ones and work our way up.
In other languages:
temp = a a = b b = temp
In Python:
b, a = a, b
The right-hand side is unpacked into the names in the tuple on the left-hand side.
Further examples of unpacking:
>>> l =['David', 'Pythonista', '+1-514-555-1234'] >>> name, title, phone = l >>> name 'David' >>> title 'Pythonista' >>> phone '+1-514-555-1234'
Useful in loops over structured data:
l (L) above is the list we just made (David's info). So people is a list containing two items, each a 3-item list.
>>> people = [l, ['Guido', 'BDFL', 'unlisted']] >>> for (name, title, phone) in people: ... print name, phone ... David +1-514-555-1234 Guido unlisted
Each item in people is being unpacked into the (name, title, phone) tuple.
Arbitrarily nestable (just be sure to match the structure on the left & right!):
>>> david, (gname, gtitle, gphone) = people >>> gname 'Guido' >>> gtitle 'BDFL' >>> gphone 'unlisted' >>> david ['David', 'Pythonista', '+1-514-555-1234']
>>> 1, (1,)
>>> (1,) (1,)
>>> (1) 1
>>> () ()
>>> tuple() ()
>>> value = 1, >>> value (1,)
This is a really useful feature that surprisingly few people know.
In the interactive interpreter, whenever you evaluate an expression or call a function, the result is bound to a temporary name, _ (an underscore):
>>> 1 + 1 2 >>> _ 2
_ stores the last printed expression.
When a result is None, nothing is printed, so _ doesn't change. That's convenient!
This only works in the interactive interpreter, not within a module.
It is especially useful when you're working out a problem interactively, and you want to store the result for a later step:
>>> import math >>> math.pi / 3 1.0471975511965976 >>> angle = _ >>> math.cos(angle) 0.50000000000000011 >>> _ 0.50000000000000011
colors = ['red', 'blue', 'green', 'yellow']
Don't do this:
result = '' for s in colors: result += s
This is very inefficient.
It has terrible memory usage and performance patterns. The "summation" will compute, store, and then throw away each intermediate step.
Instead, do this:
result = ''.join(colors)
The join() string method does all the copying in one pass.
When you're only dealing with a few dozen or hundred strings, it won't make much difference. But get in the habit of building strings efficiently, because with thousands or with loops, it will make a difference.
If you want spaces between your substrings:
result = ' '.join(colors)
Or commas and spaces:
result = ', '.join(colors)
Here's a common case:
colors = ['red', 'blue', 'green', 'yellow'] print 'Choose', ', '.join(colors[:-1]), \ 'or', colors[-1]
To make a nicely grammatical sentence, we want commas between all but the last pair of values, where we want the word "or". The slice syntax does the job. The "slice until -1" ([:-1]) gives all but the last value, which we join with comma-space.
Of course, this code wouldn't work with corner cases, lists of length 0 or 1.
Choose red, blue, green or yellow
If you need to apply a function to generate the substrings:
result = ''.join(fn(i) for i in items)
If you need to compute the substrings incrementally, accumulate them in a list first:
items = [] ... items.append(item) # many times ... # items is now complete result = ''.join(fn(i) for i in items)
Good:
for key in d: print key
Bad:
for key in d.keys(): print key
But .keys() is necessary when mutating the dictionary:
for key in d.keys(): d[str(key)] = d[key]
For consistency, use key in dict, not dict.has_key():
# do this: if key in d: ...do something with d[key] # not this: if d.has_key(key): ...do something with d[key]
We often have to initialize dictionary entries before use:
navs = {} for (portfolio, equity, position) in data: if portfolio not in navs: navs[portfolio] = 0 navs[portfolio] += position * prices[equity]
dict.get(key, default) removes the need for the test:
navs = {} for (portfolio, equity, position) in data: navs[portfolio] = (navs.get(portfolio, 0) + position * prices[equity])
Initializing mutable dictionary values:
equities = {} for (portfolio, equity) in data: if portfolio in equities: equities[portfolio].append(equity) else: equities[portfolio] = [equity]
dict.setdefault(key, default) does the job much more efficiently:
equities = {} for (portfolio, equity) in data: equities.setdefault(portfolio, []).append( equity)
dict.setdefault() is equivalent to "get, or set & get". Or "set if necessary, then get". It's especially efficient if your dictionary key is expensive to compute or long to type.
The only problem with dict.setdefault() is that the default value is always evaluated, whether needed or not. That only matters if the default value is expensive to compute.
If the default value is expensive to compute, you may want to use the defaultdict class, which we'll cover shortly.
setdefault can also be used as a stand-alone statement:
navs = {} for (portfolio, equity, position) in data: navs.setdefault(portfolio, 0) navs[portfolio] += position * prices[equity]
New in Python 2.5.
defaultdict is new in Python 2.5, part of the collections module. defaultdict is identical to regular dictionaries, except for two things:
There are two ways to get defaultdict:
import the collections module and reference it via the module,
➔
or import the defaultdict name directly:
➔
import collections d = collections.defaultdict(...)
from collections import defaultdict d = defaultdict(...)
from collections import defaultdict equities = defaultdict(list) for (portfolio, equity) in data: equities[portfolio].append(equity)
There's no fumbling around at all now. In this case, the default factory function is list, which returns an empty list.
This is how to get a dictionary with default values of 0: use int as a default factory function:
navs = defaultdict(int) for (portfolio, equity, position) in data: navs[portfolio] += position * prices[equity]
given = ['John', 'Eric', 'Terry', 'Michael'] family = ['Cleese', 'Idle', 'Gilliam', 'Palin']
pythons = dict(zip(given, family))
>>> pprint.pprint(pythons) {'John': 'Cleese', 'Michael': 'Palin', 'Eric': 'Idle', 'Terry': 'Gilliam'}
>>> pythons.keys() ['John', 'Michael', 'Eric', 'Terry'] >>> pythons.values() ['Cleese', 'Palin', 'Idle', 'Gilliam']
# do this: # not this: if x: if x == True: pass pass
Testing a list:
# do this: # not this: if items: if len(items) != 0: pass pass # and definitely not this: if items != []: pass
| False | True |
|---|---|
| False (== 0) | True (== 1) |
| "" (empty string) | any string but "" (" ", "anything") |
| 0, 0.0 | any number but 0 (1, 0.1, -1, 3.14) |
| [], (), {}, set() | any non-empty container ([0], (None,), ['']) |
| None | almost any object that's not explicitly False |
Example of an object's truth value:
>>> class C: ... pass ... >>> o = C() >>> bool(o) True >>> bool(C) True
(Examples: execute truth.py.)
To control the truth value of instances of a user-defined class, use the __nonzero__ or __len__ special methods. Use __len__ if your class is a container which has a length:
class MyContainer(object): def __init__(self, data): self.data = data def __len__(self): """Return my length.""" return len(self.data)
If your class is not a container, use __nonzero__:
class MyClass(object): def __init__(self, value): self.value = value def __nonzero__(self): """Return my truth value (True or False).""" # This could be arbitrarily complex: return bool(self.value)
In Python 3.0, __nonzero__ has been renamed to __bool__ for consistency with the bool built-in type. For compatibility, add this to the class definition:
__bool__ = __nonzero__
>>> items = 'zero one two three'.split() >>> print items ['zero', 'one', 'two', 'three']
Say we want to iterate over the items, and we need both the item's index and the item itself:
- or - i = 0 for item in items: for i in range(len(items)): print i, item print i, items[i] i += 1
The enumerate function takes a list and returns (index, item) pairs:
>>> print list(enumerate(items)) [(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')]
Our loop becomes much simpler:
for (index, item) in enumerate(items): print index, item
# compare: # compare: index = 0 for i in range(len(items)): for item in items: print i, items[i] print index, item index += 1
The enumerate version is much shorter and simpler than the version on the left, and much easier to read and understand than either.
An example showing how the enumerate function actually returns an iterator (a generator is a kind of iterator):
>>> enumerate(items) <enumerate object at 0x011EA1C0> >>> e = enumerate(items) >>> e.next() (0, 'zero') >>> e.next() (1, 'one') >>> e.next() (2, 'two') >>> e.next() (3, 'three') >>> e.next() Traceback (most recent call last): File "<stdin>", line 1, in ? StopIteration
int a = 1; |
Box "a" now contains an integer 1.
Assigning another value to the same variable replaces the contents of the box:
a = 2; |
Now box "a" contains an integer 2.
Assigning one variable to another makes a copy of the value and puts it in the new box:
int b = a; |
a = 1 |
Here, an integer 1 object has a tag labelled "a".
If we reassign to "a", we just move the tag to another object:
a = 2 |
Now the name "a" is attached to an integer 2 object.
The original integer 1 object no longer has a tag "a". It may live on, but we can't get to it through the name "a". (When an object has no more references or tags, it is removed from memory.)
If we assign one name to another, we're just attaching another nametag to an existing object:
b = a |
Although we commonly refer to "variables" even in Python (because it's common terminology), we really mean "names" or "identifiers". In Python, "variables" are nametags for values, not labelled boxes.
If you get nothing else out of this tutorial, I hope you understand how Python names work. A good understanding is certain to pay dividends, helping you to avoid cases like this:
def bad_append(new_item, a_list=[]): a_list.append(new_item) return a_list
>>> print bad_append('one') ['one']
>>> print bad_append('two') ['one', 'two']
def good_append(new_item, a_list=None): if a_list is None: a_list = [] a_list.append(new_item) return a_list
Although if you don't know C, that's not very helpful. Basically, you provide a template or format and interpolation values.
In this example, the template contains two conversion specifications: "%s" means "insert a string here", and "%i" means "convert an integer to a string and insert here". "%s" is particularly useful because it uses Python's built-in str() function to to convert any object to a string.
The interpolation values must match the template; we have two values here, a tuple.
name = 'David' messages = 3 text = ('Hello %s, you have %i messages' % (name, messages)) print text
Output:
Hello David, you have 3 messages
By name with a dictionary:
values = {'name': name, 'messages': messages} print ('Hello %(name)s, you have %(messages)i ' 'messages' % values)
Here we specify the names of interpolation values, which are looked up in the supplied dictionary.
Notice any redundancy? The names "name" and "messages" are already defined in the local namespace. We can take advantage of this.
By name using the local namespace:
print ('Hello %(name)s, you have %(messages)i ' 'messages' % locals())
The locals() function returns a dictionary of all locally-available names.
This is very powerful. With this, you can do all the string formatting you want without having to worry about matching the interpolation values to the template.
But power can be dangerous. ("With great power comes great responsibility.") If you use the locals() form with an externally-supplied template string, you expose your entire local namespace to the caller. This is just something to keep in mind.
To examine your local namespace:
>>> from pprint import pprint >>> pprint(locals())
By name using the instance namespace:
print ("We found %(error_count)d errors" % self.__dict__)
Equivalent to, but more flexible than:
print ("We found %d errors" % self.error_count)
The traditional way, with for and if statements:
new_list = [] for item in a_list: if condition(item): new_list.append(fn(item))
As a list comprehension:
new_list = [fn(item) for item in a_list if condition(item)]
For example, a list of the squares of 0–9:
>>> [n ** 2 for n in range(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
A list of the squares of odd 0–9:
>>> [n ** 2 for n in range(10) if n % 2] [1, 9, 25, 49, 81]
As a loop:
total = 0 for num in range(1, 101): total += num * num
As a list comprehension:
total = sum([num * num for num in range(1, 101)])
As a generator expression:
total = sum(num * num for num in xrange(1, 101))
Generator expressions ("genexps") are just like list comprehensions, except that where listcomps are greedy, generator expressions are lazy. Listcomps compute the entire result list all at once, as a list. Generator expressions compute one value at a time, when needed, as individual values. This is especially useful for long sequences where the computed list is just an intermediate step and not the final result.
In this case, we're only interested in the sum; we don't need the intermediate list of squares. We use xrange for the same reason: it lazily produces values, one at a time.
total = sum(num * num for num in xrange(1,<PHONE_NUMBER>))
Rule of thumb:
Here's a recent example I saw at work.
We needed a dictionary mapping month numbers (both as string and as integers) to month codes for futures contracts. It can be done in one logical line of code.
The way this works is as follows:
Recent example:
month_codes = dict((fn(i+1), code) for i, code in enumerate('FGHJKMNQUVXZ') for fn in (int, str))
month_codes result:
{ 1: 'F', 2: 'G', 3: 'H', 4: 'J', ... '1': 'F', '2': 'G', '3': 'H', '4': 'J', ...}
a_list.sort()
(Note that the list is sorted in-place: the original list is sorted, and the sort method does not return the list or a copy.)
But what if you have a list of data that you need to sort, but it doesn't sort naturally (i.e., sort on the first column, then the second column, etc.)? You may need to sort on the second column first, then the fourth column.
We can use list's built-in sort method with a custom function:
def custom_cmp(item1, item2): return cmp((item1[1], item1[3]), (item2[1], item2[3])) a_list.sort(custom_cmp)
DSU = Decorate-Sort-Undecorate
* Note: DSU is often no longer necessary. See the next section, Sorting With Keys for the new approach.
# Decorate: to_sort = [(item[1], item[3], item) for item in a_list] # Sort: to_sort.sort() # Undecorate: a_list = [item[-1] for item in to_sort]
The first line creates a list containing tuples: copies of the sort terms in priority order, followed by the complete data record.
The second line does a native Python sort, which is very fast and efficient.
The third line retrieves the last value from the sorted list. Remember, this last value is the complete data record. We're throwing away the sort terms, which have done their job and are no longer needed.
def my_key(item): return (item[1], item[3]) to_sort.sort(key=my_key)
The function my_key will be called once for each item in the to_sort list.
You can make your own key function, or use any existing one-argument function if applicable:
def my_range_generator(stop): value = 0 while value < stop: yield value value += 1 for i in my_range_generator(10): do_something(i)
The yield keyword turns a function into a generator. When you call a generator function, instead of running the code immediately Python returns a generator object, which is an iterator; it has a next method. for loops just call the next method on the iterator, until a StopIteration exception is raised. You can raise StopIteration explicitly, or implicitly by falling off the end of the generator code as above.
Generators can simplify sequence/iterator handling, because we don't need to build concrete lists; just compute one value at a time. The generator function maintains state.
This is how a for loop really works. Python looks at the sequence supplied after the in keyword. If it's a simple container (such as a list, tuple, dictionary, set, or user-defined container) Python converts it into an iterator. If it's already an iterator, Python uses it directly.
Then Python repeatedly calls the iterator's next method, assigns the return value to the loop counter (i in this case), and executes the indented code. This is repeated over and over, until StopIteration is raised, or a break statement is executed in the code.
A for loop can have an else clause, whose code is executed after the iterator runs dry, but not after a break statement is executed. This distinction allows for some elegant uses. else clauses are not always or often used on for loops, but they can come in handy. Sometimes an else clause perfectly expresses the logic you need.
For example, if we need to check that a condition holds on some item, any item, in a sequence:
for item in sequence: if condition(item): break else: raise Exception('Condition not satisfied.')
Filter out blank rows from a CSV reader (or items from a list):
def filter_rows(row_iterator): for row in row_iterator: if row: yield row data_file = open(path, 'rb') irows = filter_rows(csv.reader(data_file))
datafile = open('datafile') for line in datafile: do_something(line)
This is possible because files support a next method, as do other iterators: lists, tuples, dictionaries (for their keys), generators.
There is a caveat here: because of the way the buffering is done, you cannot mix .next & .read* methods unless you're using Python 2.5+.
It's easier to ask forgiveness than permission
Look before you leap
Duck typing
If it walks like a duck, and talks like a duck, and looks like a duck: it's a duck. (Goose? Close enough.)
Exceptions
Use coercion if an object must be a particular type. If x must be a string for your code to work, why not call
str(x)
instead of trying something like
isinstance(x, str)
try: return str(x) except TypeError: ...
from module import *
You've probably seen this "wild card" form of the import statement. You may even like it. Don't use it.
To adapt a well-known exchange:
(Exterior Dagobah, jungle, swamp, and mist.)
LUKE: Is from module import * better than explicit imports?
YODA: No, not better. Quicker, easier, more seductive.
LUKE: But how will I know why explicit imports are better than the wild-card form?
YODA: Know you will when your code you try to read six months from now.
Wild-card imports are from the dark side of Python.
Never!
The from module import * wild-card style leads to namespace pollution. You'll get things in your local namespace that you didn't expect to get. You may see imported names obscuring module-defined local names. You won't be able to figure out where certain names come from. Although a convenient shortcut, this should not be in production code.
Moral: don't use wild-card imports!
It's much better to:
reference names through their module (fully qualified identifiers),
➔
import a long module using a shorter name (alias; recommended),
➔
or explicitly import just the names you need.
➔
Instead,
import module module.name
import long_module_name as mod mod.name
from module import name name
To make a simultaneously importable module and executable script:
if __name__ == '__main__': # script code here
When imported, a module's __name__ attribute is set to the module's file name, without ".py". So the code guarded by the if statement above will not run when imported. When executed as a script though, the __name__ attribute is set to "__main__", and the script code will run.
Except for special cases, you shouldn't put any major executable code at the top-level. Put code in functions, classes, methods, and guard it with if __name__ == '__main__'.
"""module docstring""" # imports # constants # exception classes # interface functions # classes # internal functions & classes def main(...): ... if __name__ == '__main__': status = main() sys.exit(status)
Example: cmdline.py:
#!/usr/bin/env python """ Module docstring. """ import sys import optparse def process_command_line(argv): """ Return a 2-tuple: (settings object, args list). `argv` is a list of arguments, or `None` for ``sys.argv[1:]``. """ if argv is None: argv = sys.argv[1:] # initialize the parser object: parser = optparse.OptionParser( formatter=optparse.TitledHelpFormatter(width=78), add_help_option=None) # define options here: parser.add_option( # customized description; put --help last '-h', '--help', action='help', help='Show this help message and exit.') settings, args = parser.parse_args(argv) # check number of arguments, verify values, etc.: if args: parser.error('program takes no command-line arguments; ' '"%s" ignored.' % (args,)) # further process settings & args if necessary return settings, args def main(argv=None): settings, args = process_command_line(argv) # application code here, like: # run(settings, args) return 0 # success if __name__ == '__main__': status = main() sys.exit(status)
package/ __init__.py module1.py subpackage/ __init__.py module2.py
Example:
import package.module1 from package.subpackage import module2 from package.subpackage.module2 import name
In Python 2.5 we now have absolute and relative imports via a future import:
from __future__ import absolute_import
I haven't delved into these myself yet, so we'll conveniently cut this discussion short.
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
—Brian W. Kernighan, co-author of The C Programming Language and the "K" in "AWK"
Check Python's standard library.
Check the Python Package Index (the "Cheese Shop"):
Search the web. Google is your friend.


Routing
The Mako router lets you map URL patterns to class methods and closures.
Routes are registered in the app/routing/routes.php
file and there are three variables avaiable in the scope, $routes
(the route collection) and $app
(the application instance) and $container
(the IoC container instance).
Basics
The following route will forward all GET
requests to the /
route to the welcome
method of the app\controllers\Home
controller class.
$routes->get('/', 'app\controllers\Home::welcome');
If you want the route to respond to POST
requests instead then you'll have to use the post
method.
$routes->post('/', 'app\controllers\Home::welcome');
The available methods are get
, post
, put
, patch
, and delete
.
You can also make a route respond to all request methods using the all
method.
$routes->all('/', 'app\controllers\Home::welcome');
All routes will by default respond to requests made using the
OPTIONS
method.GET
routes will also respond toHEAD
requests.
If you only want to allow a specific set of methods then you can use the methods
method.
$routes->methods(['GET', 'POST'], '/', 'app\controllers\Home::welcome');
Routes can also execute closures instead of class methods.
$routes->get('/hello-world', function()
{
return 'Hello, world!';
});
Route parameters
You'll often want to send parameters to your route actions. This is easy and can be done like this.
$routes->get('/articles/{id}', function($id)
{
return $id;
});
If you need to make a parameter optional then you can do so by adding the ?
suffix.
$routes->get('/articles/{id}/{slug}?', function($id, $slug = null)
{
return $id . ' ' . $slug;
});
You can also impose constraints on your parameters using the when
method. The route will not be matched unless all constraints are satisfied.
$routes->get('/articles/{id}', function($id)
{
return 'article ' . $id;
})
->when(['id' => '[0-9]+']);
Closure actions get executed by the Container::call()
method so all dependecies are automatically injected.
$routes->get('/article/{id}', function(ViewFactory $view, $id)
{
return $view->render('article', ['id' => $id]);
})
->when(['id' => '[0-9]+']);
Route filters
Defining filters
You can define filters that will get executed before and after your route actions.
Filters are registered in the app/routing/filters.php
file. There are three variables avaiable in the scope, $filters
(the filter collection) and $app
(the application instance) and $container
(the IoC container instance).
Closure filters get executed by the Container::call()
method so all dependecies are automatically injected.
The route filters (both class filters and closures) are executed using the Container::call()
method. This means that you typehint dependencies just like you can with route actions.
Note that a route action and its after filters will not be executed if a before filter returns data.
This filter will return cached version of route response if it's available.
$filters->register('cache.get', function(Request $request, CacheManager $cache)
{
if($cache->has('route.' . $request->path()))
{
return $cache->get('route.' . $request->path());
}
});
This filter will cache route responses for 10 minutes:
$filters->register('cache.put', function(Request $request, Response $response, CacheManager $cache, $minutes = 10)
{
$cache->put('route.' . $request->path(), $response->getBody(), 60 * $minutes);
});
The cache example above is very basic and should probably not be used in a production environment.
You can also create a filter classes instead of closures. The class will be instantiated through the dependency injection container so you can easily inject your dependencies through the constructor.
<?php
namespace app\routing\filters;
use mako\http\Request;
use mako\http\Response;
class MyFilter
{
public function construct(Request $request, Response $response)
{
$this->request = $request;
$this->response = $response;
}
public function filter()
{
// Do your filtering here
}
}
Registering a filter class is just as easy as registering a closure.
$filters->register('my_filter', 'app\routing\filters\MyFilter');
Assigning filters
Assigning filters to a route is done using the before
and after
methods. You can also pass an array of filters if your route has multiple filters. The filters get executed in the order that they are assigned.
$routes->get('/articles/{id}', 'app\controllers\Articles::view')
->when(['id' => '[0-9]+'])
->before('cache.read')
->after('cache.write');
You can also pass parameters to your filters. In the example below we're telling the filter to cache the response for 60 minutes instead of the default 10.
$routes->get('/articles/{id}', 'app\controllers\Articles::view')
->when(['id' => '[0-9]+'])
->before('cache.read')
->after('cache.write:{"minutes":60}');
Anything after the first colon symbol (
:
) will be parsed as JSON. In the example above we're telling the dispatcher that the value60
should be passed to the$minutes
parameter of the filter.
Route groups
Route groups are usefull when you have a set of groups with the same constraints and filters.
$options =
[
'before' => 'cache.read',
'after' => 'cache.write',
'when' => ['id' => '[0-9]+'],
'namespace' => 'app\controllers',
];
$routes->group($options, function($routes)
{
$routes->get('/articles/{id}', 'Articles::view');
$routes->get('/photos/{id}', 'Photos::view');
});
All routes within the group will now have the same filters and constraints. You can also nest groups if needed.
The following options are available when creating a route group. They are also available as chainable methods on individual routes.
| Option | Method | Description |
|---|---|---|
| before | before | A before filter or an array of before filters |
| after | after | An after filter or an array of aflter filters |
| when | when | An array of parameter constraints |
| prefix | prefix | Route prefix |
| namespace | setNamespace | The controller namespace (closures will not be affected) |
Reverse routing
You can assign names to your routes when you define them. This will allow you to perform reverse routing, thus removing the need of hardcoding URLs in your views.
$routes->get('/', 'Home::Welcome', 'home');
The route in the example above has been named home
and we can now create a URL to the route using the toRoute
method of the URLBuilder
class.
toRoute('home')}}">Home
You can also pass parameters to your route URLs.
toRoute('articles.view', ['id' => 1])">Article
Faking request methods
Most browsers only support sending GET
and POST
requests. You can get around this limitation by performing a POST
request including a REQUEST_METHOD_OVERRIDE
field where you specify the request method you want to use.
<input type="hidden" name="REQUEST_METHOD_OVERRIDE" value="DELETE">
Another solution is to send a X_HTTP_METHOD_OVERRIDE
header.


I have to confess that I know little about Selena when I watch the show, and 2.5 hours later, I felt what thousands felt when she passed away in 1995, sadness and grief.
This movie was bypassed from the big screens here as the targetted audience might be small, but what a mistake it is. It is one of the most moving show I have seen this year.
We are given a visual treat from the very beginning of the show, it would be hard not to be shakened by the enormous reception Selena got from her fans at the concert. You might be mistaken that she must be Madonna. A song later, we are transported back to the time where her father was still in his teens, trying to make it as a pop group, only to fail because of language barrier.
A few decades on, he discovered that his daughter and his other 2 children had the potential to fulfil his long time dream, to become famous ie. So, his three children exchanged their stones and footballs for the mic, drum sticks and the guitar. A typical journey for any pop star, it has to start of from humble settings, get recognised and then move on to big things. That is what we will get to see. What we are constantly reminded of is, it is important to keep your dreams alive and see it happen.
Jennifer Lopez gave an outstanding performance as Selena, she does deserve the Oscar nomination last year. She oozes the charm and energy that Selena had. Edward James Olmos who plays her father, Abraham, also gave a strong performance a concerned father and manager of his daughter. Sad to say, Jon Seda's (Chris Perez) role as Selena's husband was not exploited, the same can also be said for her brother and sister.
What probably spoiled the mood of the show is that you know what is you know what is going to happen next. A colourful and happy journey for the audience (and most importantly, for Selena herself) turned sour towards the end, no thanks to her mistrust towards her employee.
One will feel what a waste of talent that was, she had the looks, she had the voice and she had the fashion tastes, at the time where she was on the verge of bigger times, she had to go. She was only 23.
Selena Quintanilla Perez (1971 - 1995)
-- Boon Wee -- Nothing is ever done for the right reason. (icq 1268007)
MY HOME! <:> http://www.iscs.nus.sg/~limboonw Man Utd Page <:> http://www.iscs.nus.sg/~limboonw/mufc.html UK Chart Page <:> http://www.iscs.nus.sg/~limboonw/Ukchart/
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


UI/UX Challenge
Interaction Flow
To Keith's delight, BRCC has a Coffee Quiz on their website that will help him decide if he'll take a liking to the magical bean brew.
In bold letters, it reads:
"TAKE THE BRCC COFFEE QUIZ TO GET MATCHED TO YOUR PERFECT ROAST. CLICK HERE!"
Keith clicks there.
The first question the quiz asks is:
"How do you brew your coffee?"
The choices presented to Keith are: Coffee Maker | Single-Serve Pods | Pour Over | Espresso | French Press | Aero Press | Cold Brew
Keith chooses single-serve pods.
The next question the quiz asks is:
"How do you take your coffee?"
Keith is asked to choose between: Black | Cream | Sugar | Cream & Sugar | Flavored | Other
Keith chooses cream & sugar. That's how his wife likes it, and she's smarter than him.
The next question on the quiz is:
"What do you want your coffee to taste like? (Select all that apply)"
The choices presented to Keith are: Chocolate | Earthy | Nutty | Smoke | Floral | Fruit | Sweet/Sugary | Just coffee
Keith selects chocolate and nutty.
The next question the quiz asks is:
"How dark do you like your coffee?"
Keith is presented with a spectrum, from light to medium to extra dark, with a slider button.
Keith isn't sure about this one, so he leaves the slider on medium.
The next question Keith is asked is:
"How much caffeine should your coffee have?"
Keith is presented with three options: None | An average amount | As much as possible
He chooses an average amount.
Finally, Keith gets a form that prompts him to enter his email address to get his results, and to sign up for offers and promotions.
Keith rolls his eyes and curses under his breath. "That's how they get ya."
He decides to stop being a whiner and enters his email address and sends the form...
Immediately, a page is served with the recommended products based on his quiz answers. He also receives an email with the same information.
Three options are presented to Keith for consideration: Freedom Roast Coffee Rounds, AK-47 Espresso Blend Coffee Rounds, and Freedom Fuel Coffee Rounds.
Keith now has a place to start on his journey toward coffee appreciation.
HOME


Home
Organizations
{{org.name}}
{{heading}}
Title
Short Description
Save
Cancel
You must be signed in to create or edit an idea!


Typing game!
Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!
Start


Times Table Tester
Which times table do you want to practice
Start
Answer this sum and press enter...
0%
Time result for this practice run shown here
The curent record time for this practice shown here
Try again?


Distributed systems (SSH documentation)¶
VIKI allows you to run nodes on several computers, it does not even be installed on the other systems. Since VIKI builds on top of ROS, the distributed functionality of ROS can be used. For this to work, there are some network requirements that can be tedious to setup. This guide helps you in setting up these requirements in order for the network to work. Below there is one way to set up your distributed system, there are however more possibilities (if you are an advanced user).
Setting up the network¶
ROS works by running a ros master, or roscore, on one system. All other systems connect to it via it’s location that is saved in the ROS_MASTER_URI environment variable. Other computers on the network are found by using their name. Furthermore all ports need to be open as ROS opens a new connection for every topic on a random port.
First we make sure we can communicate bidirectionally between systems. As an example take a computer named Ash and a computer named Pikachu. Ash will be the main computer where we run VIKI. Pikachu will be the remote computer (with ROS, but possibly without VIKI). There can be more computers like Pikachu (with different names!) but in this guide we will describe just one.
Network connection¶
Make sure your computers are connected to the same network. This can be done by connecting to the same wireless or wired network. If you’re running ROS in a VM, like VirtualBox, this can be achieved by adding an extra ‘internal’ network adapter.
Finding computer names¶
Find the name of your computers. In this case we know that they are Ash and Pikachu. If you are unsure of your computer name you can find it by typing
hostname
in a terminal. It will return the name of your computer.
Finding IP adresses¶
Now we need to find the IP adresses of both computers. Open a terminal and run
ifconfig
You will get some feedback on the network connections that you have open. Find the adapter that is connected to the network you are going to use and look for inet addr:. Behind it will be a number that looks like <IP_ADDRESS>. Keep these values in mind, since we will need them for configuration later on.
Note: IP addressses of computers are usually dynamic, meaning they will change over time. To keep yourself from reconfiguring this all the time, you might also want to make both systems have a static IP address. For ubuntu, some more information can be found here.
Setting hostnames¶
To make sure the computers can find each other, they need to be able to resolve the hostname to an IP address. When there is a DNS running on your network, you might use this to resolve the hostnames. If not, you will have to add records to the hosts file of each computer. To do this:
Open a new terminal and start editing the hosts file, e.g. run
sudo gedit /etc/hosts
to edit the file with gedit.
The top line of this file says something like
<IP_ADDRESS> localhost
This line resolves the ‘localhost’ to <IP_ADDRESS>. For every computer, we will need such an entry as well. For each computer in the network that you want to use, add a line that has the IP address of the computer, some space separation, and it’s hostname. In our case the first three lines of the file will look like this
<IP_ADDRESS> localhost
<IP_ADDRESS> Ash
<IP_ADDRESS> Pikachu
Testing¶
When these steps are defined, the computers should be able to find each other. You can test if you found the right IP adress and if communication is possible by running
ping <IP_ADDRESS>
with <IP_ADDRESS> replaced by the IP adress of the computer you want to reach. You can test if your changes to /etc/hosts has worked by running
ping Pikachu
from Ash, or the other way around. Both should give you information about succesfully sent packages. If not, recheck your network and make sure you have the right IP’s.
Setting up SSH¶
ROS uses the SSH protocol to run things on other systems. For it we need a username and password on the machine on which we want to run things. These are the username and password you would normally use to log in on the computer.
If it is not yet previously installed you need to install openssh-client on the main PC (Ash) and openssh-server on the remote. You can do this by running one of the following two lines and accepting the questions
sudo apt-get install openssh-client
sudo apt-get install openssh-server
Testing SSH¶
Now test if you can make an SSH connection to the other machine. Open a terminal on Ash and run
ssh username@Pikachu
where you replace username by the username you would normally use to log in on Pikachu. The terminal asks you if you want to connect, reply yes and fill in your password when asked.  This means you are now ‘in’ Pikachu. You can exit by typing
exit
and you will return to the normal terminal (on Ash).
Adding to known_hosts¶
Your computer keeps a list of computers you can connect to called known_hosts. To make ROS able to connect to another computer you need to add it to the list. Open a terminal and run
ssh-keygen -R [hostname]
ssh-keygen -R [ip_address]
ssh-keygen -R [hostname],[ip_address]
ssh-keyscan -H [hostname],[ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [hostname] >> ~/.ssh/known_hosts
This will add both the username and the ip adress and the combination ot the known_hosts file, so that you can acces it either way.
At this point you should be able to run anything you want on the remote computer by using VIKI. However by default SSH session are not ‘visible’ on the remote PC. They just run in the background. To for instance open a screen on the remote machine you need to run nodes in it’s X server. VIKI uses an environment loader for this.
Creating the environment file¶
On Pikachu create a file called .viki_env in the home folder for instance via
gedit ~/.viki_env
and add to it the following:
#!/bin/bash
. /opt/ros/jade/setup.sh
DISPLAY=:0; export DISPLAY
exec "$@"
replace jade by the ros distribution on Pikachu, then save and exit.
Testing the setup (tutorial)¶
Everything should now be set up. We can test the setup with a simple configuration of VIKI. For instance:
- Start VIKI
- Add a turtle sim node
- Add a turtle teleop node
- Connect them
- Click the ‘machin list’ icon (top of screen in VIKI)
- change the localhost to the name of the computer running VIKI (Ash in above example)
- add a machine, give it a name and fill in the adresses/username and password. In our case: name Pikachu, adress Pikachu
- Save and close
- Click the turtlesim node, and in the properties screen (right side) use select screen to make it run on Pikachu rather then default (local)
- Select the teleop node and add a prefix xterm -e to make it open in a new terminal
- Click run
This setup will open a roscore on the current machine, a turtlesim node on Pikachu, and a teleop node on Ash. Run RQT to see everything works (remember to refresh after the you have sent a few messages) or just run around with your turtle trying to draw a Pikachu.


Preparation time
less than 30 mins
Cooking time
30 mins to 1 hour
Serves
Serves 8
Dietary
Making soufflés is easy when you have Mary to guide you - and this huge chocolate version is a sure fire hit.
Preheat the oven to 190C/170C Fan/Gas 5. Place a heavy baking tray on the middle shelf of the oven.
Grease a 14x8cm (1.2 litre/2 pint) soufflé dish with butter and dust with caster sugar. Make a collar for the soufflé dish by folding a 50x30cm/20x12in piece of baking parchment 4 times lengthways (to make a 7½cm/3in deep collar). Wrap it around the top of the dish and secure with string.
For the crème pâtissière chocolat, melt the chocolate in a bowl set over a pan of simmering water. Remove from the heat and leave to cool slightly.
Pour the milk and cocoa powder into a heavy-based pan and bring gradually to the boil. Remove from the heat and leave to cool for 30 seconds. Meanwhile, in a medium bowl, whisk together the egg yolks and caster sugar until pale, then whisk in the plain flour. Pour the chocolate milk onto the eggs, whisking continuously, then pour back into the pan.
Bring back to the boil, whisking continuously over a medium heat and cook for 1 minute until thickened. Remove from the heat and whisk in the melted chocolate. Spoon the crème pâtissière chocolat into a bowl, cover the surface with cling film to prevent a skin forming and leave to cool to room temperature.
In a clean bowl whisk the egg whites to soft peaks. Add the sugar and continue whisking to a stiff and glossy meringue.
Whisk one third of the meringue mixture into the crème patissiere chocolat, then fold in the remaining two-thirds using a large metal spoon. The mixture should be fairly loose.
Pour the mixture into the souffle dish. Run your thumb around the interior rim of the dish to ensure a good rise. Bake on the preheated baking tray for 40-50 minutes, or until well risen and springy to touch.
You need JavaScript to view this clip.
Folding
You need JavaScript to view this clip.
Melting chocolate
You need JavaScript to view this clip.
Whisking egg whites


A time I got blocked on a simple problem
A problem that was too common for me as I was doing the kata was simple syntax errors. These were errors that should have been able to be fixed with a simple look at the documentation but instead, took ages to find.
I often used console logging to isolate the problem, for example, by logging the results of functions to see if they had worked as expected. However, once I had the problem isolated, which was fairly quick, I spent too long just blindly trying solutions without checking to see whether the most basic aspect of the code - the syntax - was correct. Had I checked the documentation immediately after isolating the dysfunctional code, I might have saved an hour or so of blind and incredibly frustrating experimentation.
I will remember to make absolutely sure that my syntax is correct before trying other, more complex types of problem solving, because syntax errors are - at least for me - the most common, and most easily fixed problems i encounter while coding.
A time I solved a problem in an elegant way
When solving the ‘where are you’ kata, I decided to use the array.find method. I wasn’t super familiar with the method syntax so after having a look at some examples in the documentation (I love examples) I copied and pasted an example into my code, replacing their variables with mine and paying attention to how this translated between the two contexts.
This was a very fast and satisfying way of gaining a just-in-time understanding of the syntax. I think it’s important to realise that for most programming problems, especially the most fundamental ones like the basic syntax of a method, there’s almost always information readily available through google. Instead of trying to know everything, we should accept that we are practically cyborgs, with a large part of our “knowledge” stored online and ready at hand at a moment’s notice.
I will continue to shamelessly consult google with my programming problems, embracing the concept of just-in-time learning.
Reflect on how confident you feel using the problem solving techniques and process:
Pseudocode
I don’t do enough pseudocode. I tend to rush into problems without first creating a solid plan. That’s worked fine in the easier problems, but won’t work so well for more complex ones in the future.
Trying something
I do this a lot, probably too much
Rubber ducky method
I explain things to myself often but I think it would make a difference if I did it more out loud, in a clear, logical, first principles based fashion, instead of my usual quiet muttering.
Reading error messages
I pay close attention to error messages. They’re really helpful.
Console.logging
This is one of my main tools. I use console logging to get an look into how the code is running step by step. I will console log the results of functions or the values of variables etc. at different points throughout the code to make sure it’s working as planned.
Googling
I do a lot of googling, it’s invaluable.
Asking your peers for help
I try to rely more on myself and google but after a long enough struggle, i will sometimes ask my peers. I think it’s because I view this strategy as too slow, and perhaps it’s a bit of an ego thing.
Asking coaches for help
I do this if i really need to
Improving your process with reflection
I find reflection very useful, this post in particular has been very helpful in gaining insight into my own problem solving process


When the sine function is plotted on a Cartesian axis it “looks like” a wave.
Move the circle radius to draw the sine wave.
A form of this wave is found in many physical phenomena, but it often needs to be compressed, stretched or shifted to properly model the phenomena.
It is therefore useful to know how to change the equation to achieve these transformations.
To shift the plot in \(y\), we add our desired offset \(B\) to the sine function.
\[\bbox[20px, border: 2px solid red]{y = \sin\left(\theta\right) + B}\]
To stretch or compress a sine function in \(y\), the function can be scaled with an amplitude \(A\).
\[\bbox[20px, border: 2px solid red]{y=A\sin\left(\theta\right)}\]
Drag the trace up and down to change the amplitude.
We have seen previously that a function \(f(x)\) can be shifted in \(x\) by subtracting the shift from \(x\). So, a shift of \(+d\) results in:
\[y=f\left(x-d\right)\]
And a shift of \(-d\) results in:
\[y=f\left(x-(-d)\right) = f\left(x + d\right)\]
Therefore we can shift a sine function by an angle \(\phi\):
\[\bbox[20px, border: 2px solid red]{y=\sin\left(\theta - \phi\right)}\]
A horizontal shift in a sine function is often called a phase shift.
The sine function repeats every time the input value \(\theta\) changes by \(2\pi\) radians.
What happens if we multiply the input value by \(2\pi\)?
\[y=\sin(2\pi\theta)\]
Now, every time the value \(\theta\) changes by 1 radian, the input to the sine function changes by \(2\pi\).
Instead of 1, if we want the function to repeat every change of \(r\) radians we can:
\[y=\sin\left(2\pi{\theta \over r}\right)\]
Now every time \(\theta\) changes by \(r\), the input to the sine function changes by \(2\pi\).
Let's rewrite this as:
\[\bbox[20px, border: 2px solid red]{y=\sin\left({2\pi \over r}\theta\right)} \ \ \ \ \ \ \ \ \ (1)\]
Drag the trace left and right to change how often it repeats.
The name and nomenclature for \(r\) changes depending on where the sine wave is being used.
If the sine wave is modeling a phenomena in time, then the \(r\) term in equation (1) represents the period of time over which the function repeats. As such, it is usually referred to as period or \(T\).
\[y=\sin\left({2\pi \over T}t\right)\]
If the sine function repeats every \(T\) seconds, then the frequency it repeats is:
\[f={1 \over T}\]
Therefore we have:
\[y=\sin\left(2\pi f t\right)\]
\(2\pi f\) is the number of times \(2\pi\) radians is cycled through per second, and therefore is often called the angular frequency \(\omega\).
\[\bbox[20px, border: 2px solid red]{y=\sin\left(\omega t\right)}\]
On the other hand if the sine wave is modeling a phenomena in space, then \(r\) in equation (1) represents the distance over which the function repeats. As such, it is usually referred to as wavelength or \(\lambda\).
\[y=\sin\left({2\pi \over \lambda}x\right)\]
The \({2\pi \over \lambda}\) term describes how many radians per unit distance the sine wave progresses through, and is often called the wave number \(k\):
\[\bbox[20px, border: 2px solid red]{y=\sin\left(kx\right)}\]
Both \(k\) and \(\omega\) serve the same function for space and time respectively. Both give the number of times the sine function repeats per unit length or unit time.
The general equation to shift and scale a sine function is:
\[\bbox[20px, border: 2px solid red]{y=A\sin\left({2\pi \over r} -\phi\right) + B}\]
Touch the amplitude, wavelength, phase or y offset terms of the equation and then move the trace in the direction of the arrows.


Apache Kafka includes new java clients (in the org.apache.kafka.clients package). These are meant to supplant the older Scala clients, but for compatability they will co-exist for some time. These clients are available in a seperate jar with minimal dependencies, while the old Scala clients remain packaged with the server.
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version><IP_ADDRESS></version> </dependency>Examples showing how to use the producer are given in the javadocs.
For those interested in the legacy Scala producer api, information can be found here.
class Consumer { /** * Create a ConsumerConnector * * @param config at the minimum, need to specify the groupid of the consumer and the zookeeper * connection string zookeeper.connect. */ public static kafka.javaapi.consumer.ConsumerConnector createJavaConsumerConnector(ConsumerConfig config); } /** * V: type of the message * K: type of the optional key assciated with the message */ public interface kafka.javaapi.consumer.ConsumerConnector { /** * Create a list of message streams of type T for each topic. * * @param topicCountMap a map of (topic, #streams) pair * @param decoder a decoder that converts from Message to T * @return a map of (topic, list of KafkaStream) pairs. * The number of items in the list is #streams. Each stream supports * an iterator over message/metadata pairs. */ public <K,V> Map<String, List<KafkaStream<K,V>>> createMessageStreams(Map<String, Integer> topicCountMap, Decoder<K> keyDecoder, Decoder<V> valueDecoder); /** * Create a list of message streams of type T for each topic, using the default decoder. */ public Map<String, List<KafkaStream<byte[], byte[]>>> createMessageStreams(Map<String, Integer> topicCountMap); /** * Create a list of message streams for topics matching a wildcard. * * @param topicFilter a TopicFilter that specifies which topics to * subscribe to (encapsulates a whitelist or a blacklist). * @param numStreams the number of message streams to return. * @param keyDecoder a decoder that decodes the message key * @param valueDecoder a decoder that decodes the message itself * @return a list of KafkaStream. Each stream supports an * iterator over its MessageAndMetadata elements. */ public <K,V> List<KafkaStream<K,V>> createMessageStreamsByFilter(TopicFilter topicFilter, int numStreams, Decoder<K> keyDecoder, Decoder<V> valueDecoder); /** * Create a list of message streams for topics matching a wildcard, using the default decoder. */ public List<KafkaStream<byte[], byte[]>> createMessageStreamsByFilter(TopicFilter topicFilter, int numStreams); /** * Create a list of message streams for topics matching a wildcard, using the default decoder, with one stream. */ public List<KafkaStream<byte[], byte[]>> createMessageStreamsByFilter(TopicFilter topicFilter); /** * Commit the offsets of all topic/partitions connected by this connector. */ public void commitOffsets(); /** * Shut down the connector */ public void shutdown(); }You can follow this example to learn how to use the high level consumer api.
class kafka.javaapi.consumer.SimpleConsumer { /** * Fetch a set of messages from a topic. * * @param request specifies the topic name, topic partition, starting byte offset, maximum bytes to be fetched. * @return a set of fetched messages */ public FetchResponse fetch(kafka.javaapi.FetchRequest request); /** * Fetch metadata for a sequence of topics. * * @param request specifies the versionId, clientId, sequence of topics. * @return metadata for each topic in the request. */ public kafka.javaapi.TopicMetadataResponse send(kafka.javaapi.TopicMetadataRequest request); /** * Get a list of valid offsets (up to maxSize) before the given time. * * @param request a [[kafka.javaapi.OffsetRequest]] object. * @return a [[kafka.javaapi.OffsetResponse]] object. */ public kafka.javaapi.OffsetResponse getOffsetsBefore(OffsetRequest request); /** * Close the SimpleConsumer. */ public void close(); }For most applications, the high level consumer Api is good enough. Some applications want features not exposed to the high level consumer yet (e.g., set initial offset when restarting the consumer). They can instead use our low level SimpleConsumer Api. The logic will be a bit more complicated and you can follow the example in here.
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version><IP_ADDRESS></version> </dependency>Examples showing how to use the producer are given in the javadocs.


GitHub API rate limiter makes it impossible to collect stargazer data on repos with more than 3000 stars without GitHub authentication.
If you'd like to view stargazer data for this repo, please provide your GitHub auth details.
Please note these credentials aren't sent to any server. This application is based on pure javascript so the credentials are only used to send authenticated requests to GitHub API.


Explore the galaxies as Nyan Cat!!!
Eat the sushi!


This demo only works in Chrome or Safari, with WebGL enabled.
This is the face hidden in the Aphex Twin track Equation, revealed on a logarithmic spectrogram.
Source
·
Shaders