text:
My flagship 32+ hour C# course takes you far beyond the other C# courses I created for Microsoft.
You'll learn C# using ASP.NET to create dynamic web applications.
Many people learn a programming language but never learned how to decompose problems into solutions using code. This course focuses on using the language to solve real business problems by building your problem solving muscles one coding challenge at a time.
Learn the skills you need to know to build enterprise scale applications for employers and clients.
Take your first steps into ASP.NET MVC Core to build fast-performing, cloud-ready web apps on any platform. Over 3 hours of easy to understand explanations of key concepts, how-to and workflow examples. You'll build a Help Desk Ticketing system and a solid foundation for more in-depth courses.
The fastest, most gentle introduction to SQL Server 2016 available. Less than 4 hours, with several challenges to help you learn database development and T-SQL quickly.
Object Oriented Programming is more than just learning about Classes, Objects, Properties, Methods and so on. It's a programming philosophy, a "religion" filled with tenets, idioms, best practices, patterns. This course makes it simple to learn.
This 2+ hour course gets you quickly up to speed with foundational .NET Core concepts. It covers installation considerations, using the Command Line Interface Tooling to scaffold new projects, adding dependencies, compilation, packages, and much more!
Get a jump on the new and advanced features of Bootstrap 4. No experience required. Bob demonstrates all the classes and components in this important new version of Bootstrap.
This 20 lesson course (in progress) mixes hands-on code & lectures covering Entity Models, work flows, ORMs, architecture, DbContexts, DbSets, Code First Workflow, Migrations, LINQ queries, conventions, and more.
"I still feel the lifetime membership is the best investment I have made. I spent months doing Pluralsight courses but the skill based challenge approach you offer is much better IMHO."by member: Haider in a blog comment
I wanted to say that I've watched your on .Net via Channel 9 for the past few months and am exceedingly impressed. I actually cancelled my Pluralsight subscription due to the fact that their videos were NO where near as concise and user-based as yours. You are without a doubt one of the most impressive people in the .Net arena and someone I'm pretty glad I started following.by Gavin Dobbs
LI absolutely love the new site. Way to go!!! Your training is what other training companies should aspire to be. I should know, I've paid for plenty of them in my quest to find the best online training company. Your price is small, especially when one looks at the value. Keep it up. I wanted to say thank you for the product and the updates.by David Sandlin
I wanted to say thank you very much for starting learnvisualstudio.net. I am VB.NET web forms application developer and now the market has been shifting quite some time to C#.NET MVC.
This is a radical change for me and I am still fighting with it, but your tutorials have helped me so much. The work that you do is amazing and I greatly and sincerely appreciate it.
The lifetime membership I purchased, years back has paid off in such a big way. I hope you continue to develop more videos.
I have been offered a Senior C# MVC development position at [the largest hobby retailer in the USA – edited].
Crazy thing is during my interview I told them I did not know MVC nor was I a C# guru as my background was VB.NET and web forms. I merely let them know the steps I have been taking to learn it, I dropped your name and learnvisualstudio.net in the interview.
So I am utilizing your courses nightly and diving deep and making myself struggle with it.
I simply wanted to say thank you!
Artie Catalano
Just to say thanks for such easy to understand lessons (even for a 49 year old). I spent more money on just one book which just confused me more.
I just wanted to tell you how invaluable your tutorials have been to me in conjunction with my college programming courses … Best money EVER spent. I've since gone from being a single mother working as a factory grunt to being hired by that same company to design and maintain an in-house product/inventory tracking and control program. I don't think I could have progressed so rapidly without your help. Thanks so much for being such a big part of my current and future success!!!
Lori Soete


text:
- Yield
- Makes 6 first-course servings
- Active Time
- 45 min
- Total Time
- 45 min
- 6 large eggs (in shells)
- 2 tablespoons heavy cream
- 5 tablespoons unsalted butter
- 1/4 teaspoon salt
- 1/4 teaspoon black pepper
- 3 (1/2-inch-thick) slices firm white bread such as pain de mie or Pullman loaf, crusts discarded
- 50 g caviar (preferably osetra)
- Special Equipment
- an egg topper or a sharp paring knife; 6 eggcups; 6 demitasse spoons
- Holding 1 egg narrow end up, remove top half inch of shell with egg topper or knife and discard. Pour egg into a bowl and reserve shell. Repeat with remaining eggs.
- Rinse eggshells gently in water, then submerge in a 2-quart saucepan of water and bring to a boil, covered. Remove from heat, leaving shells in water to keep warm.
- While shells come to a boil, add cream to eggs and whisk until well combined.
- Melt 4 tablespoons butter in a double boiler or in a metal bowl set over a saucepan of barely simmering water, then cook egg mixture, gently whisking constantly, until the consistency of pudding (thick enough to mound), 15 to 20 minutes. Remove from heat and whisk in salt, pepper, and remaining tablespoon butter. Transfer to a 2-cup glass measure and keep warm, covered.
- Toast bread and cut into long 1/2-inch-thick sticks.
- While bread toasts, drain eggshells upside down on paper towels.
- Put shells in eggcups, then pour egg mixture into shells, guiding flow with a small spoon. (Alternatively, put shells in an empty egg carton to stabilize while filling, then wipe shells clean before transferring to eggcups.) Spoon some caviar on top of each and serve with toast fingers.
Related Video
Nutritional Info
- Calories245
- Carbohydrates8 g(3%)
- Fat19 g(29%)
- Protein11 g(22%)
- Saturated Fat9 g(47%)
- Sodium283 mg(12%)
- Polyunsaturated Fat2 g
- Fiber1 g(2%)
- Monounsaturated Fat6 g
- Cholesterol294 mg(98%)

subset: commoncrawl


text:
20722 Surnames | 136047 Records | 2773 Reunions
Dead Fred asks:Are you a Desperate Genealogist?
Click the e-book above for details!
Dead Fred's Genealogy Photo Archive, a free, fun photo genealogy research web site devoted to helping you visualize your heritage!
Photo Thumbnail
Click image for
larger view.
Order The Desperate Genealogist's Idea Book: Creative Ways to Outsmart Your Elusive Ancestors (eBook).You can also order The Desperate Genealogist's Idea Book in hardcopy format by clicking here.
Photo #1002
Last Name: LANE
First Name : DOLLY
Middle Name:
Subject's City:
Subject's State: IA
Subject's County: Polk
Subject's Country: UNITED STATES
Date: c1880
Photographer: SUSONG
Photographer's City: DES MOINES
Photographer's State: IA
Type** : CC
Comments: DOLLY LANE (Nee: ) | IA UNITED STATES | c1880 | Comments: SISTER DOLLIE
Found 4/3/2001 Janalee Garn:I found 2 Uncles, Virgil and Ward Davidson, 1 Aunt, Ruth Davidson, and 1 Great Grandaunt, Dolly Lane, among your photos. I'm wonderinig where you might have gotten them from. The two uncles along with another uncle whose picture you didn't have (Orville Davidson) died within a couple weeks of each others as small children. The aunt was their sister who just died a few years ago. The great grandaunt was their mother's sister. The great grandaunt also died young at the age of 18. They all lived in Polk Co., IA when the pictures were taken. I will give you the numbers and perhaps you could give me some insight as to how they got on your website of which I am greatful. They are photos #939, #1000, #1001, and #1002. My Mom is still alive at age 87 and I had her take a look at the pictures. She thinks the one of Ruth Davidson may actually be Ruth's sister Mae Davidson
Digital Image Only?
Everyone Listed In This Photo:
To view all records posted by this submitter, click here:
Search Photos | Post Photos | Surnames | Mysteries | Annuals
Meet Fred | Testimonials | Media | Archivists | FAQs
Contact Us | Groups | Links | Your Own Search Box | Marketplace
Privacy Policy | Terms of Service
Free genealogy searches for those looking into their family history.
© 2001-2019 DeadFred.com Genealogy Photo Archive
P.O. Box 6937 | Springdale, AR | 72766-6937 | (479) 750-0082
Search Photos
Post Photos
Meet Fred
Media Center
Contact Us
Facebook Group
Your Own Search Box


text:
grape jelly addition
Reactions to and impressions of commercial and home made beers and beverages. Travelling and experiencing beers from around the world.
Moderator: slothrob
2 posts • Page 1 of 1
grape jelly addition
has anyone added grape jelly to a peanut butter ale ? I'm looking for some tips and advice.
Thanks in advance for any suggestions.
Thanks in advance for any suggestions.
- deano1602
- Posts: 2
- Joined: Sat Feb 18, 2017 4:05 pm
Re: grape jelly addition
Well, that sounds rather original... Let us know if you try it.
- uzicarl
2 posts • Page 1 of 1
Return to Tasting & Experiencing
Who is online
Users browsing this forum: No registered users and 21 guests


text:
Board index » Racer X » Racer X Discussion
All times are UTC
Moderators: Pao, Lamer, TheSurgeon
Last edited by KenHower on Sun Apr 20, 2008 9:12 am, edited 1 time in total.
Last edited by inhe on Sun Apr 20, 2008 9:48 am, edited 1 time in total.
Users browsing this forum: No registered users and 4 guests


text:
Women Chopping Wood — Morning Eyegasm [PICTURES]
There is nothing sexier than a woman that can swing an axe and split some lumber. Women chopping trees and slicing them into kindling with high powered saws gives gets us as hard as…well you think about the word that would fit best in that sentence.
While you're pondering, enjoy this gallery of women mincing some oak and cedar.
Click here for the 'Morning Eyegasm' archive.


text:
Your boyfriend Idris Elba is in Vogue, sounding too charming and talented to deal with. The article covers a wide variety of topics all huddled around the basic concept "Idris Elba is insanely good at everything."
He discusses his burgeoning DJ career (he's working on a full-length album called Mi Mandela: "Each song is about some sort of feeling, some sort of transitional moment, while I was playing [Mandela]. I took some musicians down to South Africa, and I created this soundscape."), the challenges of playing Mandela before predominantly South African extras ("I stood up and talked to these extras. I'm looking them in the eye, and I know what they're thinking: 'You're not South African. You don't look like Mandela. Show me something.' " By the time the film wrapped, the article states, the extras were calling him Madiba.), and his plans for the future (he wants to create a "really fantastic musical... Original music, original story—that would be a cherry on the cake for me.")
Read it in full here.


text:
Wish there was a Congressional Net Worth graph somewhere? There is, on this very page! Using data compiled from one of our favorite sites Open Secrets, we took the average United States Congressional Net Worth (that data comes as a range, so the average will fall between the low and the high point) and used IBM's Many Eyes to show their net worth to you, our curious readers. (If reading this in a reader or email click through to play with this awesome tool)
Congressional Net Worth Visualization
All of my data is available at IBM's Many Eyes. Feel free to play with it and I'll link to you if you come up with any derivative work!
To make every point the same size, you can change the size in the lower left once you click to interact. The slider on the right is interactive so you can color only members with higher than a certain net worth. If you hover over a box you can look at the data compiled for each politician.
Problems with the Congressional Net Worth Graph
I mentioned one problem with this graph – it lists the 'average' Net Worth reported per member of Congress. It may be closer to the lower or the upper bound, but it's a decent starting point. Also note that member of Congress can play with the reporting when their spouses are independently wealthy, like Teresa Heinz (D – MA: John Kerry's Wife. Kerry has much more resources than this graph implies.).
Also there are 435 members in a full House of Representatives (usually it's a bit less due to retirements, deaths, and scandals) and 100 in the Senate. There are 638 data points in this graph since it includes members of Congress elected in 2008 and 2010.
How Many Members of Congress are in the One Percent?
The Economic Policy Institute reported in a 2011 briefing paper that being in the top 1% of net worth in 2007 would put you at $19,167,600 in 2009 adjusted dollars. Basically, by average net worth, 6.11% of Congress would be in the top 1%. Not bad!
On the other hand, the bottom 40% of households had a net worth of $2,300 in 2009 dollars according to that same study. By average net worth, that would put 5.49% of Congress in the bottom 40%. Also, the following member of Congress have an average net worth which is negative
- Keith Ellison (D-Minn)
- Steve Scalise (R-La)
- Tim Griffin (R-Ark)
- Andre Carson (D-Ind)
- Debbie Wasserman Schultz (D-Fla)
- Raul Labrador (R-Idaho)
- Mario Diaz-Balart (R-Fla)
- Deborah Ann Stabenow (D-Mich)
- John Shadegg (R-Ariz)
- Steve Israel (D-NY)
- Artur Davis (D-Ala)
- Marlin A. Stutzman (R-Ind)
- Renee Ellmers (R-NC)
- Kevin W. Yoder (R-Kan)
- Grace Napolitano (D-Calif)
- Dan Maffei (D-NY)
- Kristi Lynn Noem (R-SD)
- John Conyers Jr (D-Mich)
- Nydia M. Velazquez (D-NY)
- Louis B. Gohmert Jr (R-Texas)
- Patrick J. Murphy (D-Pa)
- Sanford D. Bishop Jr (D-Ga)
- Sean P. Duffy (R-Wis)
- Terri Sewell (D-Ala)
- Bart Stupak (D-Mich)
- Laura Richardson (D-Calif)
- John Salazar (D-Colo)
- Ruben Hinojosa (D-Texas)
- Steve Fincher (R-Tenn)
- Alcee L. Hastings (D-Fla)
So it would certainly affect some members of Congress more than others if they are forced to take a pay cut.
I'm sure not all members on that list are still in Congress (read: I'm too lazy to check) – but note that Congress is in charge of our budget, including the 12 Republicans and 18 Democrats with an average negative net worth. Ironic, huh?
So you've got two Personal Finance takeaways from this… pick one. If you're rich, joining Congress is a nice feather in your cap OR if you want to make money join Congress. I don't know which one is more disturbing… let me know in the comments!


text:
Difference between revisions of "GNOME"
m (→Introduction)
|Line 23:
|Line 23:
== Introduction ==
== Introduction ==
GNOME3 comes with two interfaces, gnome-shell(standard) and fallback mode. gnome-session will automatically detect if your computer is capable to run gnome-shell and it would start the fallback mode if not.
GNOME3 comes with twointerfaces, gnome-shell(standard ) and fallbackmode. gnome-session will automatically detect if your computer is capable to run gnome-shell and it would start the fallback mode if not.
Fallback mode is the
Fallbackmode is the layout using gnome-panel )
fallback mode you can still change the window manager with your preferred one.
== Upgrade from the current gnome 2.32 ==
== Upgrade from the current gnome 2.32 ==
Revision as of 23:32, 8 April 2011
Template:Article summary start Template:Article summary text Template:Article summary heading Template:Article summary text Template:Article summary end
For GNOME 3, the GNOME Project has started from scratch and created a completely new, modern desktop designed for today's users and technologies. In GNOME 3:
- There is a new default modern visual theme and font
- The Activities view which provides an easy way to access all your windows and applications
- Built-in (integrated) messaging desktop services
- A more subtle notifications' system and a more discreet panel
- A fast Activities' search feature
- A new System Settings application
- ... and more features like: window tiling (Aero Snap like), an improved Nautilus etc.
[more details on the GNOME3 website]
- 1 Introduction
- 2 Upgrade from the current gnome 2.32
- 3 Installing to a new system
- 4 Using the shell
- 5 Customization
- 6 Enabling fallback mode
- 7 Enabling hidden features
- 8 How to shutdown through the Status menu
- 9 Enabling integrated messaging
- 10 Enabling extensions
GNOME3 comes with two interfaces, gnome-shell (the new, standard layout) and fallback mode. gnome-session will automatically detect if your computer is capable to run gnome-shell and it would start the fallback mode if not.
Fallback mode is very much alike the GNOME 2.x layout (while using gnome-panel and metacity, instead of gnome-shell and Mutter).
If you are on fallback mode you can still change the window manager with your preferred one.
Upgrade from the current gnome 2.32
Enable testing repo. Edit /etc/pacman.conf and uncomment testing.
#testing uncommented [testing] Include = /etc/pacman.d/mirrorlist
# pacman -Syu
You will end up with a system that has gnome 3.0 fallback mode. To install the new shell:
# pacman -S gnome-shell
Installing to a new system
Enable testing in the same way as above.
# pacman -Syu testing/gnome
For additional applications
# pacman -Syu testing/gnome-extra
Daemons and modules needed by GNOME
The GNOME desktop requires one daemon, DBUS for proper operation.
To start the DBUS daemon:
# /etc/rc.d/dbus start
Or add these daemons to the DAEMONS array in Template:Filename so they will start on boot up, e.g.:
DAEMONS=(syslog-ng dbus network crond)
GVFS allows the mounting of virtual file systems (e.g. file systems over FTP or SMB) to be used by other applications, including the GNOME file manager Nautilus. This is done with the use of FUSE: a user space virtual file system layer kernel module.
To load the FUSE kernel module:
# modprobe fuse
Or add the module to the MODULES array in Template:Filename so they will load at boot up, e.g.:
MODULES=(fuse usblp)
Running GNOME
For a better desktop integration is recommended GDM.
# pacman -S gdm
Check out Display_Manager to learn how to start it correctly.
If you prefer to start it from console, add the following line to your Template:Filename file, making sure it's the last line and the only one that starts with exec (see xinitrc):
exec ck-launch-session gnome-session
Now GNOME will start when you enter the following command:
$ startx
Using the shell
See https://live.gnome.org/GnomeShell/CheatSheet
Using Gnome-tweak-tool
# pacman -S gnome-tweak-tool
This tool can customize fonts, themes and some other useful settings like action when lid is closed.
Changing the GTK3 theme using settings.ini
You can change the GTK3 (Gnome 3 ) theme through the ${XDG_CONFIG_HOME}/gtk-3.0/settings.ini (it's like the ~/.gtkrc-2.0 for GTK2+).
For example, you may insert:
[Settings] gtk-theme-name = Adwaita gtk-fallback-icon-theme = gnome
in there. The defined theme will then be used when logging in another DE or WM.
Enabling fallback mode
Your session would start automatically to fallback mode if gnome-shell is not present. If you want to enable it while having gnome-shell installed, open gnome-control-center. Open System Info > Graphics. Change Forced Fallback Mode to ON.
Gnome 3.0 hides a lot of useful options and you have to use dconf-editor to customize them.
For now, the Shutdown option seems to be hidden if the user presses the Status menu on the upper right. If you want to shutdown your system through the Status menu, click on it and then press the Alt button. The "Suspend" option will instantly turn into "Power off...", as long as you press the Alt button, which will allow you to properly shutdown your system.
Enabling integrated messaging
Empathy, the engine behind the integrated messaging, and all of the system settings based on your messaging accounts will not show up unless the telepathy group of packages or at least one of the backends (telepathy-gabble, or telepathy-haze, for example) is installed. These are not included in the default Arch GNOME installs and the Empathy interface doesn't give a nice error message, it just fails to work silently. You can install them:
# pacman -S telepathy
Enabling extensions
Gnome Shell can be customised to an extent with extensions that have been written by others. These provide functionality like having a dock that is always present, and being able to change the shell theme. More details on the functionality of currently available extensions is given here You can use the gnome-shell-extensions-git package in the AUR to install them. Restart Gnome to enable them.
If installing the extensions causes Gnome to stop working then you must remove the user-theme extension and and the auto-move-windows extension from their installation directory (could be in ~/.local/share/gnome-shell/extensions or /usr/share/gnome-shell/extensions or /usr/local/share/gnome-shell/extensions). Removing or adding extensions to these directories will remove or install them form the system. More details on Gnome Shell extensions are available here.


text:
Derek Jeter Suffers a Broken Ankle in Yankees' ALCS Loss
New York Yankees' shortstop Derek Jeter was helped off the field after fracturing his left ankle in the top of 12th inning of his team's 6-4 loss to the Detroit Tigers in Saturday's Game 1 of the American League Championship Series at Yankee Stadium. The injury will sideline Jeter for the remainder of the postseason, Yankees' manager Joe Girardi said after the game.
One batter after Delmon Young's run-scoring double put the Tigers ahead 5-4, Detroit shortstop Jhonny Peralta hit a ground ball to Jeter's left. The Yankee captain fell to the infield while grabbing the grounder, but he stayed down in obvious pain after flipping the ball toward second baseman Robinson Cano before time was called.
Girardi and trainer Steve Donohue attended to Jeter, carrying him off the field without allowing any weight on his left leg. Jayson Nix replaced Jeter at shortstop. Infielder Eduardo Nunez, who was left off the ALCS roster, could take Jeter's spot.
Earlier in the game, Jeter recorded his 200th postseason hit. New York trailed 4-0 heading to the last of the ninth, but Yankee Raul Ibanez hit a two-run homer off Detroit closer Jose Valverde to tie the game. Ichiro Suzuki had hit a two-run homer off Valverde earlier in the inning to close the gap.
[Via ESPN]


text:
Forms Jobs
Ardmore Area |Elledge Plant |Landfill |Saving Energy |Sewage Treatment | Sewer Collection | Water Distribution |Water Leak
The original Thomas Water Plant served us for almost a hundred years. As the plant aged, it was less able to meet modern water quality requirements. That's why Utilities replaced it with a modern plant that will serve us for another hundred years. I'm Kenny Atkins with City/County Utilities, and I'm working for you.
Receive E-Mail Notification When New Information is Posted on this PageAs a member, enjoy the benefits of MyCityofWS, including your choice of newsletters, and notifications about events and site updates. Login and Manage Your Subscriptions Now.


text:
Monday, March 21, 2011
Papers signed this afternoon! Now I can finally have a little time to blog! We won't move until June, to give the family a little time to finish out the school year and move. I am a little relieved ... it gives me plenty of time to pick out colors for re-painting a few rooms, find some furniture, and take time organizing and de-junking before we move! Since the house isn't ours, I will wait to post pictures of the inside when we are in and settled!
We're a little nervous, a LOT excited, and can't WAIT to move in!
6 comments:
- Brandi said...
Yay, congrats Douglass family! Your new home is beautiful :)
- March 21, 2011 at 9:22 PM
- KristynG said...
Congrats! We are currently in negotiations with a buyer for our home and excitedly anticipating the signing of our Build Contract on our new home. Nerve racking to say the least!! Yay for yall!
- March 22, 2011 at 6:19 AM
- Jennifer DeWolfe said...
Congratulations! This is always my favorite part ... moving in and making it my own. Best of luck to you and your family during this exciting (and sometimes scary) time :)
- March 22, 2011 at 7:21 AM
- amyp said...
Congrats to you and your family! We have been in our new home for almost 2 years now and I remember how fun and exciting and fun it was to move into our new home. And you are right, now is the perfect time to declutter! Hey, a wonderful way to "spring clean"!
- March 22, 2011 at 9:47 AM
- Eric & Jodi Eames said...
Congrats Duds!!! I hope that cute house is close to South Jordan!! I miss you tonz. Lmk when you paint I did all 2300 sq feet of our home on my own and learned what to do and what not to do. I am seriously a pro...at least I know if I get board of Radiology I have a back up job if I want it :)
Congratulations I'm so excited for your cute little family!!
- March 23, 2011 at 4:10 PM
- Wendy said...
Very exciting! have a fun time making your new home "yours"!
- March 24, 2011 at 6:12 PM


text:
Like...I don't even know where to start with people. The ignorance is starting to give me horrible headaches. I know like four people who are atheist. I'm in a deep sea of water and sometimes it feels like I'm drowning. My Facebook...So much fighting.
Views: 667
Well, I'm sure we theists (and men in general) can be annoying! I'm not sure there's much of a correlation with intelligence one way or the other, but then I might just be stupid. ;-)
Now please don't take this the wrong way, and feel free to dismiss me as another unintelligent theist if you like. It's meant only for reflection.
There are lots of people who will only date people like themselves. Only date people the same race, only date people who are Catholics, or Muslims, ... or atheists, I suppose. I will grant that working out cultural, religious, or philosophical differences in a long-term or married relationship requires some effort, and one should be thoughtful and open about such things up front. People all over the place live wonderful mixed marriages, though. It's very doable, and can be very rich and beautiful.
Besides, we're just talking about dating, not marriage. I'd gently suggest that starting from a position of exclusion isn't going to be all that healthy, and really is something that reflects the worst of religious practice that you seem to be against. Shunning others and all that just because of the groups to which they belong. People can turn religion, or a philosophy like atheism, into a sort of idol, and lose site of good things, and good people, and even the God or philosophy they claim to follow.
I left comment directly on the FB thread. I'm just confirming my identity here.
I don't think anyone cares about your relationship status. They are merely responding to your inflammatory post condemning everyone of faith to be unintelligent..
@adam I wouldn't say hostile, post after post on that FB 'discussion' is about calling xians unintelligent which Elizibeth didn't do. They all focus on their hurt feelings that someone else would find them less attractive because they believe in invisible friends. Stay strong and remind them that this is only your opinion and it can't possibly harm them. :)
If you want to have a fairly large, diverse group of friendly acquaintances, then saying things that alienate people who don't think the same way you do isn't going to make that easy. It does sound like you're calling religious people unintelligent, even if you didn't mean for it to sound that way. If you want to say what you want sans filter, you should probably be prepared to not make or keep many friends as easily. That's generally true in most any circumstance, not just where differing religious views are concerned. I don't think either alternative is wrong, but it's something to keep in mind, because it's damn near impossible to have it both ways.
Who would have thought so many people would be interested in what I look for in relationships! LOL :)
I know how that feels. Don't worry about these people. Life is too short. I tend to do a cost-benefit analysis when I'm about to debate or argue with someone. Ask yourself is there anything to gain by debating idiots online? Really is there? Sometimes the mental drain is just too exhausting and time consuming. Look at it this way, you can't save the world and as Bob Dylan said, you can only do your best and do it well.
I silently deleted my facebook and have not looked back. Spending 6 hours or more on facebook ever day. Now that I look back, it really took a toll on me.
I went to your link and I automatically closed it at the first few few sentences of pain. The only thing I can do to help you is shoot you a friend invite on TA. : )
An interesting study:
Sure. It doesn't make generalizing all religious people with a broad stroke of "you must be dumber than me" any more acceptable though.


text:
Task: Redesign Pig logical plan structure and execution engine
- Address current inefficiencies.
- Open up new opportunities for optimization.
- Support arbitrary operator DAGs (which may arise in a single pig program, or when jointly executing groups of interrelated programs).
Logical Plan Structure
Current Problems:
- We use operators to manipulate the outermost dataset, but eval specs to manipulate the nested data, which reduces code reuse and increases complexity.
- Eval specs are assumed to be a linear chain. Thus it makes doing splits and general DAGs difficult.
- Get rid of eval specs, make everything operators
Since Pig deals with nested data models and allows manipulation of nested data, it is only natural for the logical plan structure to be fully nestable, e.g. the foreach operator can have a nested query plan that it uses to process each input tuple.
- Execute the outermost operators using their map-reduce implementations if any (see table below). Execute all nested query plans using local execution mode.
- Add a split operator that replicates input data along multiple outgoing branches. This will help us to support multiple outputs and DAGs.
Advantages of a nested query plan:
- Same operator set used for processing both the outermost, as well as nested data; no code duplication, easier to understand.
- Can reuse the local execution mode to process the nested query plans
Can allow for generalization of Pig Latin in the future where the language within FOREACH can be the same as that outside it.
Here is a list of proposed operators:
Number of inputs in query plan
Implementation (M-R vs local)
file names, load function
Loads the contents of the files using the given load function into a bag
Same (with file system abstraction layer
file name, store function, in future a hierarchy of fields to partition by
Stores the input bag into the given file (in future, partitioned by the given field hierarchy)
Same (with file system abstraction layer)
nested query plan
Applies the nested query plan to each item of the input bag to produce an output bag
Computes the output(s) of its child query plan(s), and concatenates them together into output tuple(s). This will typically be the topmost operator in the nested query plan within the FOREACH operator
nested query plan for condition
Applies the nested query plan to each item of the input bag. If the plan returns true, the item is put in the output bag, otherwise not.
nested query plans, one for the grouping criteria of each input
Applies the appropriate nested query plan to each item of each input to determine its group. Items within the same group are grouped together into bags
Different: M-R will use map-reduce, Local will use our new SortedBag to sort and collect data into bags
list of columns on which to sort, ASC, DESC flags for each column
Orders the input bag to produce an output bag
Different: M-R will use quantiles and map-reduce to do a parallel sort, local will use SortedBag.
DISTINCT (Blocking)
Eliminates duplicates in the input bag to produce an output bag
Different: M-R will rewrite into group/foreach, local will use DistinctBag.
list of column numbers or schema names
Selects the specified columns of the input tuple into the output tuple
a list of keys to lookup
Selects the contents of the specified keys into an output tuple
3 nested query plans: 1 specifying condition, 1 specifying what to ouptut when condition is true, and 1 specifying what to output when condition is false
Same as conditional expression in C++/Java (a>b?c:d)
COMPARISON (<, <=, >, >=, matches, ==, !=)
Computes the output(s) of its child query plan(s), and compares them according to the specified logical operator, outputs a boolean
Computes the (boolean) output(s) of its child query plan(s), and combines them according to the specified logical operator, outputs a boolean
constant value
Outputs a constant value
UDF to apply
Computes the output(s) of its child query plans, assembles the results together into a tuple, and applies the UDF using that tuple as the argument. The result is passed on as output.
program to invoke
>=1 (may have multiple outputs as well)
streams the input to the external program without waiting for output. The output arrives at some later point in time
1 (only operator to have multiple outputs apart from STREAM)
replicates input along both output branches
different (depends on our choice of push vs pull model). If pull, M-R buffers to DFS, local buffers in memory (spilling to disk if necessary).
union of child query plans
Different (Map-side union will be no-op, reduce side will cause break in pipeline) In local mode, straightforward.
Plan Execution
Each of the above logical operators will translate to a physical operator (in many cases, the physical operator will be shared between backends, as shown in the above table).
One physical operators have been linked together into a query plan, they must be executed. There is a choice of mainly 2 models for execution (assume that data flows downwards in an execution plan):
Push: Operator A pushes data to B that operates on it, and pushes the result to C.
Pull: Operator C asks B for its next data item. If B has nothing pending to return, it asks A. When A returns a data item, B operates on it, and finally returns the result to C.
Pull API
public interface Pull<T> { /* * T is the return type. In the most general case * it can be Object, so we might omit T altogether. */ public void open(); public T getNext(); public void close(); }
Push API:
public interface Push<T> { /* * T is the output type. In the most general case * it can be Object, so we might omit T altogether. */ public void open(); public putNext(T); public void close(); }
Each model has its own unique advantages and disadvantages. Pull is more natural when there are multiple inputs, push is natural when there are multiple outputs. In the context of our operators, there are several places where one of the models is a natural fit, and is hard to replace.
Pull - Natural use in:
- UDFs already pull data by using an iterator.
- FILTER, GROUP/COGROUP, BINCOND : Evaluate their nested query plans using pull (can be converted to push, though unnatural).
- COMPARISON, AND/OR/NOT: Pull data because they have multiple inputs
Push - Natual use in:
EvalFunc<Bag>: Eval functions push data (through bag.add()). If we go with a pull model, have to hold in memory any bag output by a function (seems reasonable).
- SPLIT: Multiple outputs are most naturally supported through the push model.
- Requires buffering whenever there are multiple outputs.
- Requires multiple passes over the data if multiple aggregates are to be computed.
- No convenient API to push data to UDFs that have multiple inputs.
- Single-threaded execution.
No API changes to UDFs in the short term. In the long term, we might introduce an aggregation function API that is push-based along the lines of the Postgres user-defined aggregation function API.
Make the model entirely push-based. Reasons:
- Accomodates multiple outputs more naturally.
- Accomodates possible future change of having special aggregate function API to iterate over data only once.
- Functions can still pull data; we will push an entire iterator to them, instead of pushing tuple by tuple.
- Implement hadoop iterator cloning/rewind so that we don't have to do our own disk writes.
- Before hadoop iterator cloning becomes available, we could even materialize bags in memory, as today and this model works.
- When multiple iterators become available (either by reduce-side extension of hadoop), or when doing a map-side cogroup, it will fit nicely into this model.
Use Cases
To be written
Related Reading
- Fjords paper
- Stream Programming Model / MIT Stream-It
official page for stream-it: http://www.cag.csail.mit.edu/streamit/ (Articles on the compiler might be useful)
Logical and Physical Plans
A criterion we are adopting in the redesign of the logical and physical layer in Pig is to promote what used to be EvalSpec's and Cond's to operators.
- Such approach provides: 1.) a clearer definition of the language; 2.) better identification of possibility for optimizations of various form
- Logical operators are such that they provide the logical representation of a Pig computation and type checking.
- The aspects that pertain to carrying out the actual computations on a given dataset belong to physical operators. Exploitation of type information should enable efficient computations.
- The mapping from logical operators to physical operators aims at preserving isomorphism of computation trees. Hence, most logical operators have their counterpart in physical operators. For instance, a logical FILTER will be translated into a physical FILTER. See translation scheme below.
- These are the following exceptions:
Logical Cogroup to be translated into a Physical LocalRearrange and GlobalRearrange.
- Chris mentioned that even Algebraic Functions are exceptions to this.
Logical Plan
The logical plan will consist of a directed acyclic graph (DAG) of with logical operators as the nodes, and data flow between the operators as the edges.
The focus of the logical operators is post parse stage checking (such as type checking), optimization, and translation to a physical plan. The logical operators will contain information that facilitates these objectives.
A list of the classes used to model the logical plan follows, with a description of the classes, and the interfaces defined for major classes, or in some cases one interface defined to give an example of a set of classes.
The class LogicalPlan will contain the collection of logical operators. It will not contain the edges between the operators. To see why, consider the following simple pig script:
a = load 'myfile'; b = filter a by $0 > 5; store b into 'myfilteredfile';
This will generate a logical plan that looks something like this:
Notice that the graph edges represent data flow between relational operators (LOAD, FILTER, STORE, PROJECT) and between expression operators (greater than, CONSTANT), and between the two types. This means that edges in the graph have meaning beyond simply input and output for a node. For example, the filter node has two inputs, the load node and its condition (in this case, the greater than node). These inputs however have different semantics, as tuples coming from the load input are evaluated based on the boolean result coming from the conditional input and then possibly passed on to the store node. Given the differing semantics of different inputs, it seems better to encode the edges of the graph in the logical operators themselves, rather than in a generic graph contain object.
In addition to containing the collection of logical operators, LogicalPlan will provide methods for callers to insert logical operators into the graph, and connect the inputs and outputs of operators. These connections will only be for data flow inputs and outputs, not contextual inputs such as the condition on a filter node. This strains the model described above somewhat, but it allows for generic manipulation of inputs and outpus of the operators without every visitor to the tree needing to understand all the different operator types.
The interface for LogicalPlan is:
public class LogicalPlan { private static final long serialVersionUID = 2L; protected PigContext mContext = null; protected Map<LogicalOperator, OperatorKey> mOps; protected Map<OperatorKey, LogicalOperator> mKeys; private List<LogicalOperator> mRoots; public LogicalPlan(PigContext pigContext) { ... } public LogicalOperator getRoots() { ... } public PigContext getPigContext() { return mContext; } public byte getOutputType(){ return root.getOutputType(); } /** * Given an operator, find its OperatorKey. * @param op Logical operator. * @return associated OperatorKey */ public OperatorKey getOperatorKey(LogicalOperator op) { return mOps.get(op); } /** * Given an OperatorKey, find the associated operator. * @param opKey OperatorKey * @return associated operator. */ public LogicalOperator getOperator(OperatorKey opKey) { return mKeys.get(opKey); } /** * Insert an operator into the plan. This only inserts it as a node in * the graph, it does not connect it to any other operators. That should * be done as a separate step using makeSuccessor or addSuccessor. * @param op Logical Operator to add to the plan. */ public void add(LogicalOperator op) { ... } /** * Make one operator the sole input of another. If that operator * already has an input, that operator will become the passed in * operator's input. So, for example, if the plan current contains * three nodes: a, b, c. And a is currently c's input, and this * function is called makeInput(b, c), then a will become b's input * and b will become c's input. * @param op Operator to make input of another operator. * @param inputOf Operator to make op an input of. * @throws IOException if op or inputOf are not in the plan. */ public void makeInput(LogicalOperator op, LogicalOperator inputOf) throws IOException { ... } /** * Make one operator an additional input of another. This can only * legally be called on operators that can have multiple inputs, such as * Cogroup, Generate, or BinaryExpression. * @param op Operator to make input of another operator. * @param inputOf Operator to make op an input of. * @throws IOException if op or inputOf are not in the plan. */ public void addInput(LogicalOperator op, LogicalOperator inputOf) throws IOException { ... } /** * Remove an operator from the plan. Connections in the graph will be * reconnected after the operator is removed. So if a is b's input and b * is c's input, and b is removed, then a will become c's input. * @param op Operator to revmove. * @throws IOException if op or inputOf are not in the plan. */ public void remove(LogicalOperator op) throws IOException { ... } }
All logical operators will be a subclass of LogicalOperator. LogicalOperator itself will contain lists of the inputs and outputs of the operator, the schema for the operator, and the data type of the operator.
abstract public class LogicalOperator { private static final long serialVersionUID = 2L; /** * Schema associated with this logical operator. */ protected Schema mSchema; /** * OperatorKey associated with this operator. This key is used to find the * operator in the LogicalPlan. */ protected OperatorKey mKey; /** * Datatype of this output of this operator. Operators start out with data type * set to UNKNOWN, and have it set for them by the type checker. */ protected byte mType = DataType.UNKNOWN; /** * Requested level of parallelism for this operation. */ protected int mRequestedParallelism; /** * References to an operators inputs */ protected List<LogicalOperator> mInputs; /** * Back pointers so that the logical plan can be navigated in either direction. */ protected List<LogicalOperator> mOutputs; /** * Equivalent to LogicalOperator(k, 0). * @param - k Operator key to assign to this node. */ public LogicalOperator(OperatorKey k) { this(k, 0); } /** * @param - k Operator key to assign to this node. * @param = rp degree of requested parallelism with which to execute this node. */ public LogicalOperator(OperatorKey k, int rp) { ... } /** * Get the operator key for this operator. */ public OperatorKey getOperatorKey() { return mKey; } /** * Set the schema for this oeprator. * @param schema Schema to set. */ public void setSchema(Schema schema) { mSchema = schema; } /** * Get a copy of the schema for the output of this operator. */ public Schema getSchema() { return mSchema; } /** * Set the type of this operator. This should only be called by the type * checking routines. * @param type - Type to set this operator to. */ final public void setType(byte t) { mType = t; } /** * Get the type of this operator. */ public byte getType() { return mType; } /** * Get a list of all inputs to the operator. */ public List<LogicalOperator> getInputs() { return mInputs; } /** * Get a list of all outputs to the operator. */ public List<LogicalOperator> getOutputs() { return mOutputs; } public abstract void visit(LOVisitor v) throws ParseException; public abstract String name(); @Override public String toString() { ... } }
Each of the relational operators will be modeled as a logical operator. There will be a class ExpressionOperator that extends LogicalOperator and represents all types of expression operators. The class hierarchy will look like:
Extenders of LogicalOperator:
- LOLoad
- LOStore
- LOGenerate
- LOFilter
- LOSort
- LODistinct
- LOProject
- LOStream
- LOSplit
- LOUnion
ExpressionOperator (abstract, represents all expression types)
Extenders of ExpressionOperator
BinaryExpressionOperator (abstract, represents all binary expressions)
UnaryExpressionOperator (abstract, represents all unary expressions)
- LOConst (constant values)
LO!UserFunc (invocation of user defined function)
- LOParend
- LOCast
Extenders of BinaryExpressionOperator
- LOAnd
- LOOr
- LOEqual
- LOAdd
- LOSubstract
- LOMultiply
- LODivide
- LOMod
Extenders of UnaryExpressionOperator
- LONot
- LONegative
Logical Plan Visitors
The method for accessing the logical plan will be a visitor class, !LOVisitor. This class will contain the logic for traversing logical plans. Any class that needs to operate on the plan should extend this class. The extending class need not provide logic to navigate the logical plan (unless it needs to navigate it in some non-standard way). It just needs to provide logic for the specific operations it wants to do on the tree.
abstract public class LOVisitor { /** * Extenders of this class should implement this to either call * depthFirst() dependencyOrder(). If order is not important, * depthFirst() should be called, as it's faster. If it is important * that your nodes only be visited after all the nodes they depend on * have been visited than you should call dependencyOrder() instead. */ public abstract void visit(); /** * Only LOFilter.visit() and subclass implementations of this function * should ever call this method. */ void visitFilter(LOFilter f) throws ParseException { f.getCondition().visit(this); f.getInput().visit(this); } // And so on with other LO operators /** * Visit the graph in a depth first traversal. */ private void depthFirst() { // TODO } /** * Visit the graph in a way that guarantees that no node is visited before * all the nodes it depends on (that is, all those giving it input) have * already been visited. */ private void dependencyOrder() { // TODO } }
Physical Plan Structure
Logical to Physical Translation Scheme
The logical operator co-group would be converted to 3 physical operators the Local Rearrange, Global Rearrange and Package as shown below:
There will be a Local Rearrange operator for each input which will aggregate to a Global Rearrange followed by a Package as shown below:
The Local Rearrange takes the input tuple and outputs a key, value pair with the group field as the key and the tuple as the value. For eg., (1,R) will be converted to {1,(1,R)}. Also the tuple is tagged with the input index it originated from. In our case, if (1,R) came from A it would be tagged 1 and if it was from B it would be tagged 2.
The Global Rearrange converts the kev-value pairs of keys belonging to a partition into a set of (key, list of values). The partition is decided by which reducer the Global Rearrange is catering to. This need not be implemented by us as this is the intermediate step that happens between mapper and reducer.
The Package just takes each key, list of values and puts it in appropriate format as required by the co-group. So lets say we have (1,R),(2,G) in A and (1,B), (2,Y) in B. If there are two reducers, Global Rearrange catering to reducer 1 will have {1,{(1,R),(1,B)}} as the key, list of values which should be converted into an output tuple for co-group based on the tagged index of the tuples in the list. So this would be converted to {1,{(1,R)},{(1,B)}}. Similarly, {2,{(2,G),(2,Y)}} will be converted to {2,{(2,G)},{(2,Y)}} by reducer 2.
Logical to Physical Stubs and API's
Below are code samples that define possible APIs for the physical pipeline implementation. The fragments aim at validating how pull model and splitting can be used in the generation of a physical plan from a logical plan.
The sample code does not take advantage of type information at this point. Actual implementation would use type information as made available from the logical plan.
The example focuses on the case of the FILTER operator, pull model (via iterators), and splitting.
package org.apache.pig.optimization; import java.util.Iterator; import java.util.Vector; public abstract class PhysicalOperator { public Vector<PhysicalOperator> inputs; public PhysicalOperator() { inputs = new Vector<PhysicalOperator>(); } public abstract Iterator<Object> iterator(); }
package org.apache.pig.optimization; import java.util.Iterator; public class POFilter extends PhysicalOperator { public PhysicalOperator input; public PhysicalOperator condition; public POFilter(PhysicalOperator input, PhysicalOperator condition) { this.input = input; this.condition = condition; } private class POFilterIterator implements Iterator<Object> { private Iterator<Object> inputIter; private Iterator<Object> condIter; public POFilterIterator(Iterator<Object> inputIter, Iterator<Object> condIter) { this.inputIter = inputIter; this.condIter = condIter; } public Object next() { Object nextVal = null; while(inputIter.hasNext()) { if (((Boolean)condIter.next()).booleanValue() == true) { nextVal = inputIter.next(); break; } else { // skip val inputIter.next(); } } return nextVal; } public boolean hasNext() { assert(inputIter.hasNext() == condIter.hasNext()); return inputIter.hasNext(); } public void remove() { throw new RuntimeException("Not supported"); } } public Iterator<Object> iterator() { return new POFilterIterator(input.iterator(), condition.iterator()); } }
package org.apache.pig.optimization; import java.util.Iterator; import java.util.Vector; import java.util.Map; import java.util.HashMap; public class POSplit extends PhysicalOperator { // most naive implementation: // all is cached, saving comes from sharing the same // values without recomputing them from the split input // Vector<Object> buffer; // key = split reader // val = position in buffer that reader key is at // Map<POSplitReader, Integer> readerMap; Iterator<Object> iter; public POSplit(PhysicalOperator input) { super(); inputs.add(input); buffer = new Vector<Object>(); readerMap = new HashMap<POSplitReader, Integer>(); iter = null; } public PhysicalOperator[] addReaders(int num) { PhysicalOperator[] result = new PhysicalOperator[num]; for (int i = 0; i < num; ++i) { result[i] = new POSplitReader(this); readerMap.put((POSplitReader)result[i], new Integer(-1)); } return result; } private class POSplitIterator implements Iterator<Object> { private POSplitReader reader; private POSplit source; public POSplitIterator(POSplitReader reader, POSplit source) { this.reader = reader; this.source = source; } public boolean hasNext() { int readerPos = source.readerMap.get(reader).intValue(); int bufferSize = source.buffer.size(); if (readerPos + 1 == bufferSize) { // need to bring one value in if possible // if (source.iter.hasNext()) { return true; //there is more stuff, not cached yet } else { return false; // reached the end } } else { return true; // next value is cached already } } public Object next() { int readerPos = source.readerMap.get(reader).intValue(); int bufferSize = source.buffer.size(); if (readerPos + 1 == bufferSize) { Object nextVal = source.iter.next(); if (nextVal == null) { return null; } else { source.buffer.add(nextVal); } } ++readerPos; source.readerMap.put(reader, new Integer(readerPos)); return source.buffer.elementAt(readerPos); } public void remove() { throw new RuntimeException("Unsupported"); } } public Iterator<Object> iterator(POSplitReader reader) { iter = inputs.get(0).iterator(); return new POSplitIterator(reader, this); } public Iterator<Object> iterator() { throw new RuntimeException("Do not Iterate directly but Use a Split Reader"); } }
package org.apache.pig.optimization; import java.util.Iterator; public class POSplitReader extends PhysicalOperator { public POSplit source; public POSplitReader(POSplit source) { super(); this.source = source; } public Iterator<Object> iterator() { return source.iterator(this); } }
package org.apache.pig.optimization; public class PhysicalCompiler { public static PhysicalOperator compile(LogicalOperator lo) { IR ir = new IR(lo); return ir.compile(); } } --- package org.apache.pig.optimization; import java.util.HashMap; import java.util.Map; import java.util.Vector; /** * In some cases we may need some pre-processing... * */ class IR { LogicalOperator root; // key = logical node // val = vector of nodes under root that match key // Map<LogicalOperator, Vector<LogicalOperator>> nodeMap; // key = logical node // val = vector of physical operators to use in the translation // process // Map<LogicalOperator, Vector<PhysicalOperator>> translationMap; IR(LogicalOperator root) { this.root = root; this.nodeMap = new HashMap<LogicalOperator, Vector<LogicalOperator>>(); this.translationMap = new HashMap<LogicalOperator, Vector<PhysicalOperator>>(); } private void doMapNode(LogicalOperator root, LogicalOperator nodeToMap) { if (root.equals(nodeToMap)) { Vector<LogicalOperator> map = nodeMap.get(nodeToMap); map.add(root); } else { for (LogicalOperator newRoot : root.inputs) { doMapNode(newRoot, nodeToMap); } } } public void mapNode(LogicalOperator nodeToMap) { if (nodeMap.get(nodeToMap) == null) { nodeMap.put(nodeToMap, new Vector<LogicalOperator>()); doMapNode(root, nodeToMap); } } public int getNodeMapOccurence(LogicalOperator mapNode) { mapNode(mapNode); Vector<LogicalOperator> map = nodeMap.get(mapNode); if (map != null) { return map.size(); } else { return 0; } } public void translateNodeTo(LogicalOperator nodeToTranslate, PhysicalOperator[] translation) { Vector<PhysicalOperator> vec = new Vector<PhysicalOperator>(); for (PhysicalOperator po : translation) { vec.add(po); } translateNodeTo(nodeToTranslate, vec); } public void translateNodeTo(LogicalOperator nodeToTranslate, Vector<PhysicalOperator> translation) { mapNode(nodeToTranslate); Vector<LogicalOperator> map = nodeMap.get(nodeToTranslate); if (map.size() != translation.size()) { throw new RuntimeException("Mismatch!"); } translationMap.put(nodeToTranslate, translation); } private POFilter compileLOFilter(LOFilter filter) { assert(filter.condition.type == LogicalOperator.PIG_TYPE.BOOLEAN); PhysicalOperator physicalInput = (new IR(filter.input)).compile(); IR booleanCondIR = new IR(filter.condition); POSplit split = new POSplit(physicalInput); PhysicalOperator splitReads[] = split.addReaders(1 + booleanCondIR.getNodeMapOccurence(filter.input)); booleanCondIR.translateNodeTo(filter.input, splitReads); PhysicalOperator booleanCond = booleanCondIR.compile(); POFilter result = new POFilter(physicalInput, booleanCond); return result; } public PhysicalOperator compile() { if (root instanceof LOFilter) { return compileLOFilter((LOFilter) root); } else { throw new RuntimeException("Unsupported Logical Operator"); } } }
Stubs for LocalRearrange and Package No need to provide an implementation for GlobalRearragnge as its taken care of by the shuffle phas. However, for performance improvements, we can add an identity combiner so that the local rearrange outputs a <groupKey,list of tuples>. In this case, we would have to slightly change the part where input is provided to POPackage as we need to merge the list of lists into a flattened Bag or Bag of Bags. If we have a bag of bags, then there will be a slight improvement in performance as all Tuples inside the inner bag will belong to the same input and we just need to put this bag into its appropriate place.
package org.apache.pig.optimization; import java.io.IOException; import java.util.Iterator; import org.apache.pig.data.Tuple; import org.apache.pig.impl.physicalLayer.PhysicalOperator; public class POLocalRearrange extends PhysicalOperator { public PhysicalOperator input; public PhysicalOperator groupCondition; //The input index public int index; public POLocalRearrange(PhysicalOperator groupCondition, int index) { this.input = super.inputs[0]; this.groupCondition = groupCondition; this.index = index; } private class POLRIterator implements Iterator<Object> { private Iterator<Object> inputIter; private Iterator<Object> gcIter; public POLRIterator(Iterator<Object> inputIter, Iterator<Object> gcIter) { this.inputIter = inputIter; this.gcIter = gcIter; } public Tuple next() { if(!inputIter.hasNext()) return null; //create a tuple(groupKey,Tuple) tagged with input index Tuple res = new IndexedTuple(index,gcIter.next(),inputIter.next()); return res; } public boolean hasNext() { assert(inputIter.hasNext() == gcIter.hasNext()); return inputIter.hasNext(); } public void remove() { throw new RuntimeException("Not supported"); } } public Iterator<Object> iterator() { return new POLRIterator(input.iterator(), groupCondition.iterator()); } }
package org.apache.pig.optimization; import java.util.Iterator; import org.apache.pig.data.Tuple; import org.apache.pig.impl.physicalLayer.PhysicalOperator; public class POPackage extends PhysicalOperator{ //Assuming the input is appropriately set to load from //<key,list of vals> passed to the reducer by Hadoop PhysicalOperator input; public POPackage(PhysicalOperator input){ this.input = input; } private class POPkgIterator implements Iterator<Object>{ Iterator<Object> inputIter; public POPkgIterator(Iterator<Object> inputIter){ this.inputIter = inputIter; } public Tuple next(){ if(!inputIter.hasNext()) return null; //Assuming the input Tuples will be of the form <groupKey, Bag of Tuples> Tuple t = inputIter.next(); Tuple res = new Tuple(); res.addField(t.getField(0)); for(IndexedTuple bt : t.getField(1)){ //Add the tuple value at the appropriate index res.addField(bt.getIndex(),bt.getField(0)); } return res; } public boolean hasNext(){ return inputIter.hasNext(); } } public Iterator<Object> iterator(){ return new POPkgIterator(input.iterator()); } }
There is a problem with the above model when it is working on a nested bag. For example consider the following script:
A = load 'a'; B = group A by $1; C = foreach B { D = filter A by $0<=2; generate D; }
For each tuple in B the filter in the above script works on the bag nested inside the tuple. Since this is an explicit bag, and in the above model, a project operator would not be able to handle an explicit bag. It would just pass the bag instead of streaming its contents. Hence the project inside the condition of the filter will fail. As a solution, we want to propose overloading the Project operator to check if its input is a bag of tuples and if so stream its contents instead of passing the entire bag.
As can be seen from the above figure, the overloaded Project operator indicated in the figure works even with the nested bag.
[PipelineImpl Pipeline Implementation]: Plan and Issues


text:
When a death occurs, there are many decisions that must be made at that time. It's hard enough simply dealing with the loss without having to also try to make the right decisions. By preplanning these decisions now, one can lift the emotional and financial decisions from your family. It won't be time consuming or difficult for you. But the real beneficiaries will be the loved ones that are relieved of having to make these difficult decisions. Preplanning gives your family a detailed road map of what type of service you want. It gives you the opportunity to make important decisions on your own timetable.
Making funeral arrangements for a loved one can be a very stressful process. By preplanning, you help relieve that unwanted stress. Preplanning is truly one of the most thoughtful and loving things you can do for your family.
You also have the option of prepaying your funeral costs if you wish. You do not have to prepay in order to preplan. But, by prepaying, you lift the financial burden from your family. Prepaying allows you to lock in at a guaranteed price and you receive a lifetime guarantee that this is all you will ever have to pay for.
There are state laws regulating the funding process. Therefore, it is important to work with a licensed funeral professional when making plans to prepay funeral costs in advance.
Families often mark relevant changes in their lives with elaborate ceremonies, such as graduation, weddings, baptisms, etc. A funeral service is a time to reflect on the past while looking toward the future, and to celebrate our loved ones' lives and reflect upon their accomplishments. A service at a church or in the chapel of Bismarck Funeral Home would be followed by burial in a cemetery. A time for fellowship, viewing and visitation are key elements of this type of service. Musical selections, musicians and casketbearers are all variable aspects for this type of service.
Because we are a locally-owned firm, we know the community well enough to understand the importance of quality of service and costs. We want the people we deal with to be comfortable with their decision.
A casket service includes the following services:
* Professional services of funeral director and staff.
* Embalming and other care of the body to allow open casket viewing.
* Visitation and funeral service conducted at Bismarck Funeral Home or in your church or facility.
* Removal from place of death.
* Hearse and car for clergy provided at funeral.
* Filing of permits and documentation.
* All transportation within a 100-mile radius of Bismarck.
* Casket selection from one of the four casket categories.
* Folders, register book, and acknowledgement cards.
There are some outside charges that a family usually incurs related to the funeral service. These include certified copies of the death certificate, obituary notice, clergy honorarium, musician fees, flowers, cemetery expenses and vault. These costs are usually taken care of at the time of need.
Today, many people are considering cremation as an alternative to the traditional burial service. The planning of a cremation comes down to a matter of personal choice. Once can choose from having a casket service with a public viewing followed by a cremation, a cremation followed by a memorial service held at your church or at the funeral home or direct cremation with no service.
Bismarck Funeral Home and Crematory has its own crematory right in the funeral home, so we can personally see to the quality of the cremation and guarantee you that when the urn is presented to your family, that those are the remains of your loved one. Following the cremation process, families may choose to inter the cremated remains at a cemetery, scatter the cremated remains, keep them in their home or any combination thereof.
The following are the choices of cremation services and their costs:
Traditional Funeral Service with Cremation – Consists of a traditional funeral service including embalming, preparation of the body, professional services of the funeral director, cremation casket, visitation, funeral service at the funeral home or church and the cremation process. These services are similar to those of a traditional service with the exception that following the funeral service, the casket is taken to the crematory and not the cemetery.
Cremation with a Memorial Service – Consists of the removal of the body from the place of death, the professional service of the funeral director, the cremation process and a memorial service held at the funeral home or church.
Direct Cremation – Consists of the removal of the body from the place of death, the professional service of the funeral director and the cremation process. There are no services.


text:
Over 40 years after the fact, William Roache was arrested and charged with two counts of rape on Wednesday, May 1, BBC reports. The 81-year-old Coronation Street actor is accused of raping a 15-year-old girl in Haslingden, England back in spring to summer 1967, when he was 35 years old.
"Having completed our review, we have concluded that there is sufficient evidence and it is in the public interest for Mr Roache to be charged with two offenses of rape relating to a girl, aged 15, in 1967," Chief Crown Prosecutor, Nazir Afzal, said in a statement. CPS and Lancashire Police began reviewing evidence in March.
Roache, who set a Guinness World Record for being the longest-serving soap actor, has denied the charges against him.
"I am astounded and deeply horrified by the extraordinary events of the last 24 hours," Roache said in a statement through his lawyers to the BBC. "I strenuously deny the allegations and will now focus my full attention on fighting to preserve my innocence in the challenging times ahead. I would like to offer my sincere thanks to all those people who have offered me their support and good wishes at this difficult time."
Roache continues to play the character of Ken Barlow on the British soap opera Coronation Street, which he has starred on since its debut in 1960. He is due to in court on May 14.
Sign up now for the Us Weekly newsletter to get breaking celebrity news, hot pics and more delivered straight to your inbox!
Want stories like these delivered straight to your phone? Download the Us Weekly iPhone app now!


text:
Scavenger: Velvet Flocked MidCentury Love Seat - $75
It's large, gold, black and certainly will make one heckuva an impression in the right setting. Described as straight out of "That 70's Show", certainly not for everyone, but a perfect match for someone looking for a disco era style seating option...
Apartment Therapy Furniture Classifieds are open for your business in our Shopping Guide.
Apartment Therapy Los Angeles Furniture Classifieds are open for your business in the Los Angeles Shopping Guide. They are local and JUST DECOR. Post a particularly good thing, and we'll highlight you here on the front page.
• Gold/Velvet Flocked MidCentury Love Seat - $75 (LA)
• Turn-of-the-Century Heirloom Bed - $290 (Long Beach)
• Art Deco Vanity - $150 (Fairfax/Melrose)
• Bakelite, Metal and Wood Dental Cabinet - $550 (covina)
• MidCentury Bar/Kitchen Cart - $120 (Beverly Hills)
• Futurama Custom Sofa - $750 (Los Feliz)
• Unique Patio Chairs - $10 (Glendale)
• Case Study Bedframe - Std King - $1600 (Larchmont Village)
• "Pair of chairs" Wesley Allen Louis XVI - $800 (Torrance)
• Mid-Century Canister Set - $80 (Echo Park)
>> The most recent Los Angeles Scavengers
Apartment Therapy is not the seller of these items. This is an edited selection of our favorite offerings from other independent sources. Please check the item's link for the original source.


text:
Soon-to-be first-round NFL draft pick Jadeveon Clowney has already drawn comparisons to some of the game's great defensive ends.
Specifically, the South Carolina junior who is expected to declare is doing his best to emulate Mario Williams lately.
According to WIS-TV in Columbia, S.C., Clowney was pulled over Saturday night by the South Carolina Highway Patrol and cited for doing 110 mph in a 70 mph zone in his Chrysler 300.
It's a dangerous and silly thing to do, and not just because he could put himself and others in peril.
NFL evaluators are going to be going over Clowney's personnel file closely after his production dipped this season, so he shouldn't give them any reason to downgrade his stock, which will only serve to take more money out of his pocket.


text:
PayPal Holdings (PYPL) try to takes its spot in context of active momentum, while shares price plunged -1.28% with the closing value of $91.12 during Tuesday trading session. Along recent down drift, stock price presented -3.66% negative comparing value from it 52-week high point and showed 29.76% upward in value from its 52-week low point. PayPal Holdings traded 6399936 shares at hands versus to its average volume of 8774.91K shares. Mostly all the indicators used in technical analysis are based on pricing data. Volume, though, is an independent variable and can therefore be extremely useful in confirming price action. There are lots of ways of using volume, such as the construction of oscillators, on balance volume lines, and the design of indicators using both volume and price. It is important to understand there is always a perfect balance between buyers and sellers because the amount of a security sold is always identical to that which is purchased. What moves pieces is the relative enthusiasm of buyers or sellers. If sellers are more motivated than buyers the price will decline and vice versa.
Profitability Analysis:
Several salient technical indicators of PayPal Holdings are now starting to make their way into the trading conversation. Every investor and other stake holder of firm are most concerned with its profitability. So to answer this concerns frequently used tools of financial ratio analysis is profitability ratios, which are used to determine the company's bottom line and its return to its investors.
Start focusing on ordinary profitability ratio which covers margins; PYPL has a profit margin of 14.00%. It has gross profit margin ratio of 48.70% for trailing twelve months and operating margin is calculated as 16.30%; these are a better detectors to find consistency or positive/negative trends in a firm's earnings. So upper calculated figures are representing the firm's ability to translate sales dollars into profits at various stages of measurement. To walk around the gross margin figure of firm that looks at how well a company controls the cost of its inventory and the manufacturing of its products and subsequently pass on the costs to its consumers.
Following in trace line of profitability ration analysis; second part is covering returns. The returns on investment amplify the findings, the firm's ROI concludes as 11.20%; it gives idea for personal financial decisions, to compare a firm's profitability or to compare the efficiency of different investments. The returns on assets of firm also on noticeable level, it has ROA of 5.00%, which signifies how profitable a firm is relative to its total assets.
Volatility Analysis:
Taking notice on volatility measures, PayPal Holdings has noticeable recent volatility credentials; price volatility of stock was 2.41% for a recent week and 2.42% for a month. Volatility is a statistical measure of the dispersion of returns for a given security or market index. Volatility can either be measured by using the standard deviation or variance between returns from that same security or market index. Commonly, the higher the volatility, the riskier the security. Volatility refers to the amount of uncertainty or risk about the size of changes in a security's value. A higher volatility means that a security's value can potentially be spread out over a larger range of values. This means that the price of the security can change dramatically over a short time period in either direction. A lower volatility means that a security's value does not fluctuate dramatically, but changes in value at a steady pace over a period of time.
Average true range (ATR) as a Volatility indicator
The average true range (ATR) is a measure of volatility introduced by Welles Wilder in his book, New Concepts in Technical Trading Systems. The true range indicator is the greatest of the following: current high less the current low, the absolute value of the current high less the previous close and the absolute value of the current low less the previous close. The average true range is a moving average, generally 14 days, of the true ranges. Average true range (ATR) is often used as a volatility indicator. It doesn't necessarily predict anything, but extremes in activity can indicate a change in a stock's movement; higher ATRs can mean a stock is trending, and lower ATRs could indicate a consolidation in price. . Its Average True Range (ATR) shows a figure of 2.62.
Simple Moving Average (SMA) Analysis:
The 2.31% positive depiction highlighted by the trends created around 20 day SMA. The established trader's sentiment toward the stock has created a trading environment which can appropriately be designated as optimistic.
There has been positive change grasped around 50 day SMA. The stock price is showing 6.34% distance above 50 SMA. On the surface, it seems as the higher the 50-day moving average goes, the more bullish the market is (and the lower it goes, the more bearish). In practice, however, the reverse is true. The 50-day moving average is perceived to be the dividing line between a stock that is technically healthy and one that is not. Furthermore, the percentage of stocks above their 50-day moving average helps determine the overall health of the market. Many market traders also use moving averages to determine profitable entry and exit points into specific securities.
PayPal Holdings (PYPL) stock price recognized positive trend built on latest movement of 200 SMA with 7.80% during the course of recent market activity. This trend discloses recent direction. The up-to-date direction of 200 SMA is upward. When the price over the last 200 days is moving with increasing trend, look for buy opportunities and when it shows decreasing trend the price is below the last 200 days, look for sell opportunities.
The relative strength index (RSI)'s recent value positioned at 56.82. The RSI's interpretations notify overbought above 70 and oversold below 30. The stock has a beta value of 1.09. When beta is less/more than 1, it can be read that the stock is theoretically less/more volatile than the market.
Analysts assigned consensus rating of 1.8. This rating scale created between 1 and 5. Analyst's suggestion with a score of 3 would be a mark of a Hold views. A rating of 1 or 2 would be indicating a Buy recommendation. A rating of 4 or 5 represents a Sell idea.


text:
Promote our shirts on your own site and make money! $2 Per shirt!
Think you have a good shirt idea? Send it in, you could win $$$
Members only exclusive content and contests. Sign up now, it's free!
Tags: insert titty here baby tee shirt, insert tit here arrow pointing up baby shirt, insert breast here arrow pointing up baby t-shirt, insert booby here baby shirt, insert boob here baby t-shirt


text:
Brain Teasers
Po Folk
Fun: (1.77) Difficulty: (1.07) Puzzle ID: #50256 Submitted By: BadBunnee02
Rebus Rebus brain teasers use words or letters in interesting orientations to represent common phrases.
What common phrase is suggested by the two words below?
do out
do out
HintWhen two things are together we usually add a "connective" word. What is that word?
Answerdo without
"do" is with the word "out"
If you wish to get a definition and an example of usage enter the notation below in any computer search engine:
idiom:do without
Hide Hint Show Hint Hide Answer Show Answer
What Next?
View a Similar Brain Teaser...
Or, get a random brain teaser.
Or, get a random brain teaser.
If you become a registered user you can vote on this brain teaser, keep track of which ones you have seen, and even make your own.


text:
Thanks to a mention of new content at the Joseph Smith Papers Project (h/t BCC) I went and took a look at the website. The JSPP home page mentioned new biographical information, so I looked at John Tanner's entry and saw a reference I hadn't noticed before about his ordination as a priest. Here is the source material, a newspaper account of Orson Pratt's early missions, referencing his journal entry for February 2, 1833.
John Tanner would have been ordained during the four days Orson Pratt and William Snow were in Bolton.
|"History of Orson Pratt," Deseret News, 9 June 1858, 65.
Here are Orson Pratt's travels from November 8, 1832, to February 17, 1833. Bolton shows up at (G) when he spent ten days there in late December 1832, held ten meetings, baptized ten people and (L) when he returned to Bolton at the beginning of February.
Here is a picture of Orson Pratt in his later years. He was the winner of Keepapitchinin's famous Best Beards Contest.


text:
The Bronkies owners requested that we, as we used to do a year or so back, drive up to the house and pay at gate in front of the house. This means that you take the paved road leading to the house which turns off the dirt road (i.e. you pay at the gate in front of the house and NOT at the bottom of the house near the cattle kraal). If you pass through this gate and continue on the paved road (going down the left of the house) you will meet up with the normal dirt road again so it is just as convenient. This measure is re-introduced on request of the owners to make sure that they see the cars and come out to collect the money. This is more convenient for the owners and leaves less room for others to fraudulently collect money.
A new Bronkies access register has also been given to the owners. Please ensure that it is filled in and specifically that the money you pay is recorded (R10 per person). It does seem that money sometimes does not reach the rightful owners when the access register is not filled in. This causes suspicions about climbers and has lead to a few isolated "incidents". There has also been instances where more money is asked for than what is agreed upon. To control this, the access register is checked by the owners and hence this is the best way to ensure that they receive their money and to ensure that the relationship is not soured due to squabbles over the money etc.. Please note that the access register has a MCSA logo, access arrangements and rules are on the cover. The rules are also available on the SA climbing wiki on climb.co.za. Should the access register disappear again, please try and resolve the issue without any confrontation and report it immediately to the JHB / MAG MCSA committee member for climbing / land and access (or phone me on 083 274 1116 or at least post a message here).
We trust you understand the reasons for these access arrangements. This is private property and our continued access to this crag is dependent on maintaining a good relationship with the owners.
Changes in Bronkes access arrangements
For the posting and discussion of Access Issues and Closures for Areas around South Africa.
Post Reply
6 posts • Page 1 of 1
- OneDogClimbing
- Posts: 145
- Joined: Tue Jul 03, 2007 11:00 am
- Posts: 61
- Joined: Tue Jul 31, 2007 7:44 am
- Location: Gauteng, Pretoria
- Posts: 84
- Joined: Tue Feb 26, 2008 9:33 am
- Location: Johannesburg
Post Reply
6 posts • Page 1 of 1


text:
Bob Baffert, the self-proclaimed "Mr. Cal Cup" after his early domination of California Cup races, expressed surprise Thursday at Hollywood Park when informed that he still led the trainer standings with nine wins, three more than anyone else. The 21st running of the Cal Cup is scheduled here Saturday.
"I haven't won one in so long that I can't believe someone hasn't passed me," said Baffert, who entered Queenie Marini in the $75,000 Robert H. Walter Juvenile Fillies at 1 1/16 miles on Cushion Track.
"I was worried about her going that far, so in training up to the race, we were teaching her to rate," recalled Baffert. "The gates opened and Julio Garcia put her on the lead, so all that work went out the window."
"She was a nice filly," said Baffert of Theresa's Pleasure, who lasted around two turns to the relief of Baffert. "I won my first stakes in California with her at Del Mar."
Baffert hopes that Queenie Marini can duplicate the performance of Theresa's Pleasure. The gray/roan daughter of Marino Marini broke her maiden in her fourth and most recent start on October 9 in $40,000 claming company for Cal-bred maidens. She drew post four in a field of eight under Martin Garcia.
Corey Nakatani, who leads Cal Cup jockeys in wins with 17, hopes to add to that total with Pop'shands Are Hot in the $100,000 Mile and Joy Boy in the $75,000 Juvenile.
The 10-race card includes seven California-bred stakes for $700,000 in purses, headed by the $150,000 California Cup Classic Presented by City National Bank.
Turning Top hopes to continue her love affair with the Hollywood Park turf course when she carries high weight of 119 pounds in the $150,000 Las Palmas Handicap Sunday, closing-day feature of the first Oak Tree/Hollywood Park meet.
The Grade II test is for fillies and mares at one mile on grass and serves as a prep for the $250,000 Grade I Matriarch at the same distance here on November 26.
Turning Top finished second in her most recent start here in the Grade I Yellow Ribbon Stakes, one length behind Breeders' Cup-bound Hibaayeb.
During the summer, she strung together three straight victories on this course, including the Redondo Beach Stakes and Grade III Beverly Hills Handicap.
The Irish-bred 4-year-old filly began her career in England before joining the stable of Simon Callahan in California at the end of last year.
A daughter of Pivotal, Turning Top will again be ridden by Brice Blanc for owner Michael Tabor.
Blue Maiden, a 3-year-old filly in the Richard Mandella stable, breezed three furlongs in 36.60 seconds over Cushion Track Thursday for the Las Palmas.
Jockeys Rafael Bejarano and Joel Rosario, who have dominated the Southern California circuit the past three years, are heading for another photo finish at the Oak Tree meet with four days remaining at Hollywood Park.
Bejarano won three races Wednesday to build a 30-28 lead over Rosario. Bejarano edged Rosario last year, 31-30, to win the Oak Tree title and seeks the first three-peat since Laffit Pincay, Jr. from 2000-02. Rosario was one win better than Bejarano in the Del Mar race this summer.
In an equally tight trainer race, Doug O'Neill leads with 10 wins, one ahead of defending champion Bob Baffert and 2008 leader John Sadler. O'Neill previously led the meet in 2003 and 2006. Baffert was the titlist in 1997, '98 and '99.
Twenty-four horses stabled at Hollywood Park and pre-entered for the Breeders' Cup November 5 and 6 at Churchill Downs are scheduled to be flown to Kentucky on Tex Sutton charter flights Sunday and Tuesday.
The Sunday flight is expected to include Blind Luck for the Ladies Classic, Hibaayeb and Éclair de Lune for the Filly & Mare Turf, The Usual Q.T. for the Mile, Kinsale King and Supreme Summit for the Sprint, A.Z. Warrior, Indian Gracey and Izshelegal for the Juvenile Fillies, Romp in
the Marathon, Evening Jewel and Gabby's Golden Gal in the Filly & Mare Sprint, Dakota Phone in the Dirt Mile, and Quick Enough and Waveline in the Turf Sprint.
Booked for Tuesday are Zenyatta and Lookin at Lucky for the Classic, Champ Pegasus for the Turf, Jaycito and J P's Gusto for the Juvenile, Crown of Thorns and Tropic Storm for the Dirt Mile, Awesome Gem for the Marathon, and Unzip Me for the Turf Sprint.
Flights are scheduled to leave Ontario Airport at 5 a.m. Pacific time and arrive in Louisville at 11:30 a.m. Eastern time.
Unzip Me, winner of the Senator Ken Maddy Handicap, and Dakota Phone, third-place finisher in the Goodwood Stakes, worked at Hollywood Park Thursday for Breeders' Cup engagements next week.
Unzip Me worked five furlongs on turf in 1:03.60 breezing under exercise rider Paddy Dalton to the satisfaction of trainer Mart Jones for the Turf Sprint. Dakota Phone drilled six furlongs on Cushion Track in 1:13.80 for the Dirt Mile for the Jerry Hollendorfer stable.
Hollendorfer also blew out U R All That I Am three furlongs on turf in 35.60 for the California Cup Distaff Saturday.
Fluke, winner of the Citation Handicap last year, worked five furlongs in 1:01.20 for trainer Humberto Ascanio.
Zenyatta made one of her final journeys up Zenyatta Way, the 400-yard path along the south border of the track leading to her stable, after galloping 1 ½ miles on Cushion Track under regular exercise rider Steve Willard.
"She's doing grand," said Willard of the unbeaten 6-year-old mare, seeking her 20th victory in the Breeders' Cup Classic at Churchill Downs on November 6.
Subject of a lengthy feature in this week's Sports Illustrated, the star of the racing world will work Saturday before leaving for Kentucky Tuesday, according to trainer John Shirreffs.


text:
Seat Belt Use at Record High, New Report Shows
(WASHINGTON) -- Seatbelt use in the U.S. has reached an all time high, according to a new report released by the National Highway Traffic Safety Administration, or NHTSA.
Through an annual survey, the organization found that 86 percent of Americans use a seat belt when driving a car, a 2 percent increase over the previous year. Researchers also found that seat belt use has been on a consistent incline since 1994, which corresponds with a steady decrease in unrestrained vehicle passenger fatalities in the daytime.
"When it comes to driving safely, one of the most effective ways to protect yourself and your family is to use a seat belt," said Transportation Secretary Ray LaHood.
Officials attribute the trend to the passage of primary seat belt laws in certain states, where authorities can issue tickets solely based on those not wearing a seat belt. A total of 32 states and the District of Columbia have passed primary laws requiring seat belt use.
There have also been rising efforts in seat belt use awareness, such as the "Click It or Ticket" initiative, a national campaign dedicated to heighten awareness among young people to wear a seat belt when in the car.
"We've made steady gains in belt use in recent years," said NHTSA Administrator David Strickland. "Moving forward, it will be critical to build on this success using a multi-faceted approach that combines good laws, effective enforcement, and public education and awareness."
Copyright 2012 ABC News Radio