Friend shuffles his pack for Connacht team to face Toulouse
The province are looking to back up a brilliant win against Montpellier last week.
by Ciarán KennedyANDY FRIEND HAD made a number of changes to the Connacht team that pulled off a thrilling defeat of Montpellier as they prepare to visit French giants Toulouse on Saturday [KO 1pm, BT Sport].
With a number of players recovering from injury, the Connacht head coach has been able to inject some fresh faces into his side ahead of a massive challenge at the Stade Ernest Wallon, as well as reshuffling his backline.
Quinn Roux returns to the second row to partner Ultan Dillane and captains the side in place of Jarrad Butler. There are also two changes in the front row, with Dominic Robertson-McCoy keeping his place at tighthead, as Dave Heffernan comes in at hooker and Peter McCabe at loosehead.
In the back row, Eoghan Masterson comes in at blindside with Colby Fainga’a at openside and Robin Copeland remaining number eight.
The changes continue in the backline. Matt Healy is named at full back, with wings Kyle Godwin and John Porch completing the back three, while Tom Farrell comes into the midfield to line out alongside Tom Daly.
Caolin Blade makes his 100th appearance for his home province at scrum-half, with Conor Fitzgerald starting at out-half.
“We were happy with the character shown against Montpellier but we know we will need to improve as we travel away to Toulouse,” said Friend.
“We have seen the quality they have in the past few seasons in this competition and winning the Top 14 in France. However we are travelling with a squad that has a huge sense of belief that we can win the game on Saturday”.
“We are boosted this week with a number of players returning from injury and the real positive for us is that with a six day turnaround from the Montpellier game we have players coming in fresh into the squad. Saturday is another challenge for us but one we are really looking forward to.”
Connacht:
15. Matt Healy
14. John Porch
13. Tom Farrell
12. Tom Daly
11. Kyle Godwin
10. Conor Fitzgerald
9. Caolin Blade
1. Peter McCabe
2. Dave Heffernan
3. Dominic Robertson-McCoy
4. Ultan Dillane
5. Quinn Roux
6. Eoghan Masterson
7. Colby Fainga’a
8. Robin Copeland
Replacements:
16. Shane Delahunt
17. Matthew Burke
18. Finlay Bealham
19. Joe Maksymiw
20. Paul Boyle
21. Angus Lloyd
22. Jack Carty
23. Peter Robb
Toulouse:
15. Thomas Ramos
14. Yoann Huget
13. Sofiane Guitoune
12. Lucas Tauzin
11. Maxime Médard
10. Romain Ntamack
9. Sébastien Bézy
1. Cyril Baille
2. Peato Mauvaka
3. Charlie Faumuina
4. Richie Gray
5. Joe Tekori
6. Alban Placines
7. Rynhardt Elstadt
8. Jerome Kaine (captain)
Replacements:
16. Julien Marchand
17. Thomas du Toi
18. Dorian Aldegheri
19. Rory Arnold
20. Selevasio Tolofua
21. Francois Cros
22. Pita Ahki
23. Pierre Pages
Referee: Karl Dickson (England)
Murray Kinsella and Bernard Jackman join Gavan Casey in studio to preview the second weekend of Champions Cup action


Cowthink!


|
QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.30
|
#include <ql/math/matrixutilities/sparseilupreconditioner.hpp>
Public Member Functions | |
| SparseILUPreconditioner (const SparseMatrix &A, Integer lfil=1) | |
| const SparseMatrix & | L () const |
| const SparseMatrix & | U () const |
| Array | apply (const Array &b) const |
Private Member Functions | |
| Array | forwardSolve (const Array &b) const |
| Array | backwardSolve (const Array &y) const |
Private Attributes | |
| SparseMatrix | L_ |
| SparseMatrix | U_ |
| std::vector< Size > | lBands_ |
| std::vector< Size > | uBands_ |
References: Saad, Yousef. 1996, Iterative methods for sparse linear systems, http://www-users.cs.umn.edu/~saad/books.html
Definition at line 36 of file sparseilupreconditioner.hpp.
|
explicit |
Definition at line 29 of file sparseilupreconditioner.cpp.
| const SparseMatrix & L | ( | ) | const |
Definition at line 148 of file sparseilupreconditioner.cpp.
| const SparseMatrix & U | ( | ) | const |
Definition at line 152 of file sparseilupreconditioner.cpp.
Definition at line 156 of file sparseilupreconditioner.cpp.
Definition at line 160 of file sparseilupreconditioner.cpp.
Definition at line 176 of file sparseilupreconditioner.cpp.
|
private |
Definition at line 46 of file sparseilupreconditioner.hpp.
|
private |
Definition at line 46 of file sparseilupreconditioner.hpp.
|
private |
Definition at line 47 of file sparseilupreconditioner.hpp.
|
private |
Definition at line 47 of file sparseilupreconditioner.hpp.


Person hit by train between Whifflet and Cumbernauld
The incident happened at 6pm on Wednesday evening.
by Record ReporterA person has been struck by a train between Cumbernauld and Whifflet.
ScotRail revealed the news with a social media post just after 6pm on Wednesday evening.
The line between both stations was closed following the incident, but re-opened after emergency services cleared the line.
ScotRail warns that there may still be ongoing delays and disruption.
The condition of the person is unknown.
British Transport Police has been contacted for comment.


The Helicopter Company flies high at Dubai Airshow
RIYADH: LuLu Hypermarket has kicked off its 10th anniversary promotion “LuLu Super Fest 2019” across its stores in the Kingdom. Along with the “One Million Riyal Grand Raffle” giveaway, there are many chances for customers to win prizes worth half a million riyals, which include gold coins, iPhone 11Pro, PS4 and shopping vouchers.
Another main highlight of the promotion is the daily #LiveDeals in store, which feature an on-the-spot “Guess & Win” contest for shoppers to guess the correct price of a specific product and win prizes for every correct answer given.
LuLu KSA Director Shehim Mohammed said: “We have always been committed to offering the highest quality products from around the world, along with a great shopping experience through monthly festivals and special events. ‘LuLu Super Fest’ is one such event that will not only showcase the amazing product offers and exciting in-store activities but is also the perfect time to give something extra special to our loyal customer base coinciding with our 10th year celebration of serving the people of Saudi Arabia as a conducive shopping destination.”
The promo offers are valid from Nov. 24 to Dec. 7.


Draw something amazing in the grid below and we will print it out with microbial ink - real living bacteria that produce vivid colors! We'll email a photo of your living work of art back to you.
{% if announcement %}{{announcement}}
{% endif %}| {% endfor %} |


| DevIL Documentation | Home | Previous | Next |
The ilRegisterMipNum function registers the current image's number of "next" images.
ILboolean ilRegisterNumImages(
ILuint Num
);
ilRegisterNumImages tells OpenIL the number of images in the current image's animation chain. The "next" images can then be chosen and modified via ilActiveImage. This function is to be used from within functions that have been registered via ilRegisterLoad.
None
ilActiveImage, ilRegisterMipNum, ilRegisterLoad


Exam 1 Study Guide
Logistics
Date:
Thursday, September 26, 2019
Time: 8:45pm-10:15pm ET - (it is a 1.5 hour exam)
Location: Your exam location is posted on UBlearns.
What to Bring: You should bring multiple pens / pencils, your approved calculator, and a photo ID.
Calculator: You are allowed to use only the Texas Instruments TI-30XIIS calculator on the exam. All other calculators are prohibited. See the Calculator and Reference Policy in the syllabus for more details.
Photo ID: You must bring a photo ID with you to your test site (either a UB student ID or a state-issued ID like a driver's licencse).
What Not to Bring: Do not bring any bags, books, notes, formula sheets, or other loose items.
- No Formula Sheets: You are not allowed any outside references (e.g., cheat sheets, formula sheets, note cards, or textbooks). See the Calculator and Reference Policy in the syllabus for more details.
Material
Learning Outcomes Being Tested
Below is the list of potential exam questions for each section covered in lecture.
Section 0.1
Additional Practice Textbook problems: 0.1 #13, 15, 17, 21, 23, 25, 27, 53
- Evaluate a function at some given \(x\) value.
- Evaluate a piecewise function at some given \(x\) value.
- Determine the domain of a function.
- Use a graph to evaluate a function at some given \(x\) value.
- Sketch the graph of a function by plotting points.
Section 0.2
Additional Practice Textbook problems: 0.2 #1, 3, 9, 9, 31, 33, 35
- Sketch the graph of a linear function.
- Sketch the graph of a quadratic function.
- Sketch the graph of a piecewise function that has pieces involving linear and/or quadratic functions.
Section 0.3
Additional Practice Textbook problems: 0.3 #7, 9, 31, 33
- Express the sum or difference of two rational functions as a rational function.
- Express the product or quotient of two rational functions as a rational function.
- Calculate the composition of two functions.
Section 0.4
Additional Practice Textbook problems: 0.4 #1, 3, 5, 7, 31, 33, 39
- State the definition of the zero of a function.
- State the Quadratic Formula.
- Use the Quadratic Formula to solve a quadratic equation.
- Use the Quadratic Formula to find the zeros of a quadratic function.
- Use the Quadratic Formula to find the intersection points of two curves.
- Use the Quadratic Formula to solve an equation involving a rational expression.
- Factor a polynomial of the form \(x^{2}+bx+c\).
- Factor a polynomial of the form \(ax^{2}+bx+c\).
- Factor a polynomial of the form \(ax^{3}+bx^{2}+cx\).
- Factor a polynomial using one of the 5 special case formulae.
Section 0.5
Additional Practice Textbook problems: 0.5 #33, 35, 39, 41, 43, 45, 89, 91
- Identify the different exponential rules.
- Simplify an exponential expression using the exponent rules.
Section 1.1
Additional Practice Textbook problems: 1.1 #1, 3, 7, 11, 15, 27, 29
- State the slope formula.
- State the point-slope formula for the equation of a line.
- Determine the slope and \(y\)-intercept of a line given the following:
- An equation of the form \(y=mx+b\).
- An equation of the form \(ax+cy=d\).
- Sketch an example of a line with positive slope. Similarly for negative slope.
- Give an equation that describes a Vertical Line. Similarly for a Horizontal Line.
- Calculate the slope of a line given the following information:
- Its graph or
- Two points on the line.
- Find an equation of the line given the following information:
- Slope and a point on the line or
- Two points on the line
- Given a line of the form \(y=mx+b\)
- Find the slope of a parallel line.
- Find the slope of a perpendicular line.
Section 1.2
Additional Practice Textbook problems: 1.2 #1, 3, 17, 19, 21
- Estimate the slope of the curve at designated point given:
- A graph of the function and a sketch of the tangent line or
- A graph of the function.
Section 1.3
Additional Practice Textbook problems: 1.3 #3, 5, 7, 9, 11, 15, 17, 19, 25, 33, 35, 71, 73
- Differentiate functions of the form \(f(x)=mx+b\).
- Differentiate functions of the form \(f(x)=b\).
- Differentiate functions of the form \(f(x)=x^{n}\) using the Power Rule.
- Be able to rewrite root functions \(\sqrt[n]{x}=x^{1/n}\)
- Be able to rewrite fractions \(1/x^{n}=x^{-n}\)
- Use the derivative to find the slope of the curve at a given point.
- Use the derivative to find the slope of the curve at a given \(x\)-value.
- Use the derivative to find the equation of the tangent line at a given \(x\)-value.
Section 1.4a
Additional Practice Textbook problems: 1.4 #1, 3, 5, 7, 9, 13, 15, 17, 19, 21
- Numerical Methods
- Find the limit of a function given a table of values.
- Fill in a table of function values to help find the limit of a function.
- Graphical Methods
- Find the limit of a function given its graph.
- State the limit laws.
- Find the limit of a function using the limit laws.
- Find the limit of a polynomial or rational function.
- Calculate a limit using the Factor and Cancel Method.
Section 1.4b
Additional Practice Textbook problems: 1.4 #29, 33, 41
- State the definition of the derivative of a function \(f(x)\).
- Use the limit definition of the derivative to calculate the derivative of:
- A polynomial of degree 2 or less (multiply out).
- A rational function (common denominator).
- A root function (conjugate method).
Section 1.5
Additional Practice Textbook problems: 1.5 #1, 3, 5, 9, 11, 13, 15
- Given the graph of a function \(f(x)\):
- Determine if the function is continuous at a designated number.
- Determine if the function is differentiable at a designated number.
- Determine the \(x\)-values where a function is discontinuous.
- Determine the \(x\)-values where a function is non-differentiable.
- State the definition of continuous at a number \(a\).
- Determine whether a piecewise function is continuous and/or differentiable at a designated number (not given the graph of the function).
Section 1.6
Additional Practice Textbook problems: 1.6 #1, 5, 9, 11, 13, 17, 19, 29, 41
- State the Constant Multiple Rule.
- Differentiate functions of the form \(f(x)=kx^{r}\).
- State the Sum Rule.
- Differentiate various functions using the constant multiple, sum, and power rules.
- Differentiate a general power function using the General Power Rule.
Section 1.7
Additional Practice Textbook problems: 1.7 #1, 3, 7, 13, 19
- Compute derivatives of functions with variables other than \(x\).
- Compute the second derivative of a function (without needing the General Power Rule).
- Compute the second derivative of a function (requiring the General Power Rule).
- Evaluate the second derivative at a given \(x\)-value.
Section 1.8
Additional Practice Textbook problems: 1.8 #1, 3, 7, 9, 13, 17
- Calculate the average rate of change of a function \(f(x)\) over a given interval \([a,b]\).
- Compute the instantaneous rate of change of a function \(f(x)\) at a given \(x\)-value.
- Given a position function \(s(t)\) that represents the position of an object moving in a straight line:
- Calculate the average velocity over a given time interval \([a,b]\).
- Find the velocity function \(v(t)\).
- Find the acceleration function \(a(t)\).
- Solve problems involving the position, velocity, and acceleration (determine when the position, velocity, or acceleration is a certain value).


Transforming Calvin Klein commercials into interactive experiences, writing coverage for Fox 2000’s blockbuster The Monuments Men, producing a documentary on the broken lives of wildfire survivors; my passion for production is comprehensive. Some stories need to be told.
Testing computer vision algorithms, innovating systems construction, writing and improvising code, and working with brilliant people compels me towards steady and rapid ingenuity.
With a Management Consulting/Film Production BBA from the University of Notre Dame, I strive to optimize pipelines, solve problems, and exceed clients' expectations.
As the Executive Interactive Producer of Fuisz Video, I am responsible for the execution of all interactive videos. I have created interactive experiences for clients such as Ford, Dell, Walmart, Showtime, Activision, Annheuser Busch, McDonald's, Calvin Klein, and Nestle. Our videos have gathered millions of impressions. I work with the engineering and design teams to perfect our production software with a filmmaker's perspective.
As the sole Executive Production and Development intern of Fox 2000 Pictures, I provided coverage for scripts in Production or being considered for Production. I assisted in maintaining Production Books for the President and Vice President of Production, researched production and acting talent for upcoming films, and supported the office with administrative tasks. I provided coverage for The Fault in Our Stars, The Monuments Men, Poltergeist (2015),The Book Thief, The Counselor, and many more. I couldn't have been happier.
As the summer IT technician, I repaired and cleaned PCs and Macs, installed two computer labs by myself, imaged PCs via Windows Server, removed viruses, and aided in updating domain credentials.
At Luxion, I worked as a Business Administration and Software Tester intern. As a Business Administration intern, I generated reports from Salesforce.com, researched potential leads, and participated in a webinar with clients. As a Software Tester, I analyzed and assessed new implementations of bumpmapping rendering and tested new product features. I also assisted in anti-piracy efforts.
At the University of Notre Dame, I double majored in Business Management Consulting and Film Production. The Mendoza College of Business (rated #1 in the country by Bloomberg 2010-2014) taught me Lean Six Sigma, Agile Scrum, and Quantitative Decision Modeling. As an Advanced film student, I produced three short films including a horror film, a slap-stick comedy, and a documentary about wildfire victims. In the advanced film track, I became competent with RED cameras, Premiere, Audition, Photoshop, After Effects, Avid Media Composer, Final Cut, dollies, jibs, lighting, directing, acting, editing, audio production, and sound design.
Executive Interactive Producer
<EMAIL_ADDRESS>(949) 292-9765


| read.pubmed | read pubmed data table files |
| image_fly | |
| query.external | query of the pathways, taxonomy and reaction |
| CID | query cid from pubchem database |
| pubchem_url | Generate the url for get pubchem pugviews data object |
| query.knowlegde_graph | |
| query | query of the pubchem database |
| pugView | query pubchem data via a given cid value |
| SID_map | parse the pubchem sid map data file |
| read.pugView | read xml text and then parse as pugview record data object |
| metadata.pugView | extract the compound annotation data |
| read.mesh_tree | |
| mesh_background | create MeSH ontology gsea background based on the mesh tree |
| mesh_level1 |


#include <ThRingBuffer.h>
Public Member Functions | |
| ThRingBuffer (unsigned int regionSize, unsigned int regionCount, unsigned int alignment=16) | |
| class header. | |
| ~ThRingBuffer () | |
| unsigned int | GetRegionSize () const |
| region info. | |
| unsigned int | GetRegionCount () const |
| unsigned int | GetCurrentUsage () |
| public methods | |
| void * | GetWriteRegion (bool wait=true) |
| returns the current write region. | |
| const void * | GetReadRegion (bool wait=true) |
| void * | NextWriteRegion (bool wait=true) |
| region access. | |
| const void * | NextReadRegion (bool wait=true) |
| const ThSignal & | GetReadSignal () const |
| signal access. | |
| const ThSignal & | GetWriteSignal () const |
File: ThRingBuffer.h Author: Kevin Bray Created: 09-01-08 Copyright © 2004 Bootstrap Studios. All rights reserved. base class includes. project includes. class ThRingBuffer
Definition at line 22 of file ThRingBuffer.h.
| ThRingBuffer::ThRingBuffer | ( | unsigned int | regionSize, | |
| unsigned int | regionCount, | |||
| unsigned int | alignment = 16 | |||
| ) |
class header.
File: ThRingBuffer.cpp Author: Kevin Bray Created: 09-01-08 Copyright © 2004 Bootstrap Studios. All rights reserved. class ThRingBuffer ctor & dtor
Definition at line 21 of file ThRingBuffer.cpp.
| ThRingBuffer::~ThRingBuffer | ( | ) |
Definition at line 33 of file ThRingBuffer.cpp.
| unsigned int ThRingBuffer::GetCurrentUsage | ( | ) |
public methods
returns how many regions are currently in use between the read and write locations.
calculate the total number of regions in use.
Definition at line 45 of file ThRingBuffer.cpp.
| const void * ThRingBuffer::GetReadRegion | ( | bool | wait = true |
) | [virtual] |
wait for data to become available.
calculate the region's starting address.
return the starting address to indicate success.
Implements ThPipe.
Definition at line 72 of file ThRingBuffer.cpp.
| const ThSignal& ThRingBuffer::GetReadSignal | ( | ) | const [inline, virtual] |
| unsigned int ThRingBuffer::GetRegionCount | ( | ) | const [inline] |
Definition at line 30 of file ThRingBuffer.h.
| unsigned int ThRingBuffer::GetRegionSize | ( | ) | const [inline, virtual] |
| void * ThRingBuffer::GetWriteRegion | ( | bool | wait = true |
) | [virtual] |
returns the current write region.
wait for a write region to become available.
calculate the region's starting address.
return the starting address to indicate success.
Implements ThPipe.
Definition at line 56 of file ThRingBuffer.cpp.
| const ThSignal& ThRingBuffer::GetWriteSignal | ( | ) | const [inline, virtual] |
| const void * ThRingBuffer::NextReadRegion | ( | bool | wait = true |
) | [virtual] |
determine if we can allow the read region to advance.
advance the read region.
calculate the region's starting address.
check to see if we need to raise the write signal.
check to see if we need to lower the read signal.
wait if necessary.
return the buffer.
Implements ThPipe.
Definition at line 136 of file ThRingBuffer.cpp.
| void * ThRingBuffer::NextWriteRegion | ( | bool | wait = true |
) | [virtual] |
region access.
wait if necessary.
enter the region.
determine if there is room to advance.
if the read signal is lowered, raise it.
increment the current write region and the usage count.
calculate the region's starting address.
if we're in the last writable region, lower the write signal. Otherwise, return the start of the current region.
wait if need be.
return the buffer.
Implements ThPipe.
Definition at line 88 of file ThRingBuffer.cpp.


What Is GrizzHacks 2?
GrizzHacks 2 is the secound hackathon held at Oakland University. A hackathon is an opportunity for students to create incredible hardware and software projects from the bottom up in one weekend. A team of passionate sponsors and mentors is brought in to help students achieve their goals. Come join almost 300 students and local industry professionals for 24 hours of learning and technological passion.
Who Can Participate?
GrizzHacks is open for all undergraduate students and those who have graduated within the last calendar year. You don’t need to be an engineering major; If you have a passion for technology and the drive to change the world, you belong at GrizzHacks. If you are still in high school, contact us for information on how to attend the event.
What If I'm New To This?
While it can be helpful, no previous programming/engineering experience is required at GrizzHacks. We will have presentations from sponsors, and mentors available to help you with your project. Every student who attends a hackathon leaves with a wealth of new knowledge, regardless of what they came with. Bring an open mind and be ready to learn, we’ll help you through the rest.
How Much Will GrizzHacks Cost Me?
GrizzHacks is absolutely free! There is no charge for attending GrizzHacks. Food will also be supplied throughout the event. Contact us and stay tuned to this page for information on transportation costs.
How Do I Get To GrizzHacks?
GrizzHacks will be held at Oakland University in Rochester, Michigan. If you need help getting from your location to our new Engineering Center, contact us for support. There is an updated map at oakland.edu/map. Stay tuned to this page, or email us for information regarding potential travel reimbursements. More details coming soon!
I Don't Have A Team Or An Idea!
Just like having previous knowledge, having a team or an idea is not a requirement either! We will have an opportunity for team building and allow you to meet new people to work with. There will be a number of presentations to help inspire you with an idea, we know you’ll build something great!
How Many People Can Be On My Team?
Teams can range from one to four people. You can work with your best friends from class, or with someone you just met during the opening ceremony! Working alone is allowed, but in our experience, a hackathon is always more fun collaborating with someone else.
What Should I Bring
The most important items to bring are your laptop, charger, and student ID. If you plan to work on a hardware project, bring any necessary parts as well. GrizzHacks is only 24 hours, but you may want to bring toiletries and a change of clothes. We’ll try to get you anything else!
What About Hardware?
GrizzHacks will try our best to give you the hardware to bring your dream to life. If you have your own hardware, we encourage you to bring it with you as well. For more information about hardware that will be available at the event, please contact us.
Can I Start On My Hack Before The Event?
Students are not allowed to begin progress on their hack before GrizzHacks. However, the use of third-party APIs and libraries is allowed and encouraged. We also encourage you to be familiar with the tools you plan to use at the event, such as a specific programming language, as long as it is not a part of your hack.
How Does Judging Work?
A panel of to-be-determined judges will assess your hacks creativity, difficulty, design, and potential. Ten hacks will be selected for a demo in front of the entire GrizzHacks audience for a final round of judging. Stay tuned to see who our judges are!
I Have More Questions!
Feel free to reach out to us on the contact form, Twitter, Facebook or email.


Ex-Galway defender Treacy to coach Clare senior hurlers
Ex-Galway defender Seán Treacy is to coach Brian Lohan’s Clare senior hurlers.
Clare’s panel met for the first time under Lohan on Sunday and completed a morning training session.
Treacy’s Clare role is his highest-profile to date and comes off the back of guiding Kiladangan to the Tipperary county final earlier this year.
A two-time All-Star, Treacy replaces fellow Tribesman Gavin Keary in the post. Keary is now linked with a role with Dublin.
During his playing career, the Portumna man represented the Galway seniors between 1989 and 1996.
Lohan also went to Galway to secure his strength and conditioning coach. Keith Carr succeeds Kelvin Harold in the role. Ex-Tipperary minor Ken Ralph and Limerick’s James Moran were ratified as the two-time All-Ireland winner’s selectors in October.
Elsewhere, Tipperary native Brian Coffey has begun preparations with the Clare minor hurlers for the 2020 campaign. He has added National League winners Oisin O’Brien and Paul Flanagan to his management team, along with James Carrig, Niall O’Connor, Alphie Rodgers, and Terence Chaplin.


One important special case for a pressure loss is the friction at the wall of a pipe under the assumption of quasi steady state flow (i.e., the mass flow rate varies only slowly). In this section it is explained how this case is handled in the Modelica.Fluid library for pipes with nonuniform roughness, including the smooth pipe as a special case (see Pipes.BaseClasses.WallFriction). The treatment is non-standard in order to get a numerically well-posed description.
For pipes with circular cross section the pressure drop is computed as:
dp = λ(Re,D)*(L/D)*ρ*v*|v|/2 = λ(Re,D)*8*L/(π^2*D^5*ρ)*m_flow*|m_flow| = λ2(Re,D)*k2*sign(m_flow); with Re = |v|*D*ρ/μ = |m_flow|*4/(π*D*μ) m_flow = A*v*ρ A = π*(D/2)^2 λ2 = λ*Re^2 k2 = L*μ^2/(2*D^3*ρ)
where
The first form with λ is used and presented in textbooks, see "blue" curve in the next figure:
This form is not suited for a simulation program since λ = 64/Re if Re < 2000, i.e., a division by zero occurs for zero mass flow rate because Re = 0 in this case. More useful for a simulation model is the friction coefficient λ2 = λ*Re^2, because λ2 = 64*Re if Re < 2000 and therefore no problems for zero mass flow rate occur. The characteristic of λ2 is shown in the next figure and is used in Modelica.Fluid:
The pressure loss characteristic is divided into three regions:
dp = 128*μ*L/(π*D^4*ρ)*m_flow
1/sqrt(λ) = -2*lg( 2.51/(Re*sqrt(λ)) + 0.27*D)gives an implicit relationship between Re and λ. Inserting λ2 = λ*Re^2 allows to solve this equation analytically for Re:
Re = -2*sqrt(λ2)*lg(2.51/sqrt(λ2) + 0.27*D)Finally, the mass flow rate m_flow is computed from Re via m_flow = Re*π*D*μ/4*sign(dp). These are the red curves in the diagrams above.
λ2 = 0.25*(Re/lg(D/3.7 + 5.74/Re^0.9))^2The pressure drop is then computed as dp = k2*λ2*sign(m_flow). These are the blue curves in the diagrams above.
Re1 = 745*e^(if D ≤ 0.0065 then 1 else 0.0065/D)These are the blue curves in the diagrams above.
The absolute roughness d has usually to be estimated. In [Idelchik 1994, pp. 105-109, Table 2-5; Miller 1990, p. 190, Table 8-1] many examples are given. As a short summary:
| Smooth pipes | Drawn brass, copper, aluminium, glass, etc. | d = 0.0025 mm |
| Steel pipes | New smooth pipes | d = 0.025 mm |
| Mortar lined, average finish | d = 0.1 mm | |
| Heavy rust | d = 1 mm | |
| Concrete pipes | Steel forms, first class workmanship | d = 0.025 mm |
| Steel forms, average workmanship | d = 0.1 mm | |
| Block linings | d = 1 mm |
The equations above are valid for incompressible flow. They can also be applied for compressible flow up to about Ma = 0.6 (Ma is the Mach number) with a maximum error in λ of about 3 %. The effect of gas compressibility in a wide region can be taken into account by the following formula derived by Voronin [Voronin 1959; Idelchik 1994, p. 97, sect. 2.1.81]:
λ_comp = λ*(1 + (κ-1)/2 * Ma^2)^(-0.47)
where κ is the isentropic coefficient (for ideal gases, κ is the ratio of specific heat capacities cp/cv). An appreciable decrease in the coefficient "λ_comp" is observed only in a narrow transonic region and also at supersonic flow velocities by about 15% [Idelchik 1994, p. 97, sect. 2.1.81]. This effect is not yet included in Modelica.Fluid. Another restriction is that the pressure drop model is valid only for steady state or slowly changing mass flow rate. For large fluid acceleration, the pressure drop depends additionally on the frequency of the changing mass flow rate.
In the "Advanced menu" it is possible via parameter "from_dp" to define in which form the pressure drop equation is actually evaluated (default is from_dp = true):
from_dp = true: m_flow = f1(dp) = false: dp = f2(m_flow)
"from_dp" can be useful to avoid nonlinear systems of equations in cases where the inverse pressure loss function is needed.
A detailed pressure drop model for pipe wall friction is provided in the form m_flow = f1(dp, D) or dp = f2(m_flow, D). These functions are continuous and differentiable, are provided in an explicit form without solving non-linear equations, and do behave well also at small mass flow rates. This pressure drop model can be used stand-alone in a static momentum balance and in a dynamic momentum balance as the friction pressure drop term. It is valid for incompressible and compressible flow up to a Mach number of 0.6.


Command Line Options
Command-line options
You can customize test runs from the command-line thanks to SeleniumBase's pytest plugin, which adds command-line options for setting/enabling the browser type, headless mode, mobile mode, multithreading mode, demo mode, proxy config, user agent config, browser extensions, and more.
Here are some examples of configuring tests, which can be run from the examples/ folder:
# Run a test in Chrome (default browser)
pytest test_swag_labs.py
# Run a test in Firefox
pytest test_swag_labs.py --browser=firefox
# Run a test in Demo Mode (highlight assertions)
pytest my_first_test.py --demo
# Run another test in Demo Mode
pytest test_demo_site.py --demo
# Run a test in Headless Mode (invisible browser)
pytest my_first_test.py --headless
# Run tests multi-threaded using [n] threads
pytest test_suite.py -n=4
# Create a pytest html report after tests are done
pytest test_suite.py --html=report.html
# Enter Debug Mode on failures
pytest test_fail.py --pdb
# Rerun failing tests more times
pytest test_suite.py --reruns=1
# Pass extra data into tests (retrieve by calling self.data)
pytest my_first_test.py --data="ABC,DEF"
# Run tests on a local Selenium Grid
pytest test_suite.py --server="<IP_ADDRESS>"
# Run tests on a remote Selenium Grid
pytest test_suite.py --server=IP_ADDRESS --port=4444
# Run tests on a remote Selenium Grid with authentication
pytest test_suite.py --server=USERNAME:KEY@IP_ADDRESS --port=80
# Reuse the same browser session for all tests being run
pytest test_suite.py --reuse-session
# Reuse the same browser session, but empty cookies between tests
pytest test_suite.py --reuse-session --crumbs
# Run tests through a proxy server
pytest proxy_test.py --proxy=IP_ADDRESS:PORT
# Run tests through a proxy server with authentication
pytest proxy_test.py --proxy=USERNAME:PASSWORD@IP_ADDRESS:PORT
# Run tests while setting the web browser's User Agent
pytest user_agent_test.py --agent="USER-AGENT-STRING"
# Run tests using Chrome's mobile device emulator (default settings)
pytest test_swag_labs.py --mobile
# Run mobile tests specifying CSS Width, CSS Height, and Pixel-Ratio
pytest test_swag_labs.py --mobile --metrics="411,731,3"
# Run tests while changing SeleniumBase default settings
pytest my_first_test.py --settings-file=custom_settings.py
You can interchange pytest
with nosetests
for most tests, but using pytest
is recommended. (chrome
is the default browser if not specified.)
If you're using pytest
for running tests outside of the SeleniumBase repo, you'll want a copy of pytest.ini at the base of the new folder structure. If using nosetests
, the same applies for setup.cfg.
Here are some useful command-line options that come with pytest
:
-v # Verbose mode. Prints the full name of each test run.
-q # Quiet mode. Print fewer details in the console output when running tests.
-x # Stop running the tests after the first failure is reached.
--html=report.html # Creates a detailed pytest-html report after tests finish.
--collect-only # Show what tests would get run without actually running them.
-n=NUM # Multithread the tests using that many threads. (Speed up test runs!)
-s # See print statements. (Should be on by default with pytest.ini present.)
--junit-xml=report.xml # Creates a junit-xml report after tests finish.
--pdb # If a test fails, pause run and enter debug mode. (Don't use with CI!)
-m=MARKER # Run tests with the specified pytest marker.
SeleniumBase provides additional pytest
command-line options for tests:
--browser=BROWSER # (The web browser to use. Default: "chrome".)
--cap-file=FILE # (The web browser's desired capabilities to use.)
--cap-string=STRING # (The web browser's desired capabilities to use.)
--settings-file=FILE # (Override default SeleniumBase settings.)
--env=ENV # (Set a test environment. Use "self.env" to use this in tests.)
--data=DATA # (Extra test data. Access with "self.data" in tests.)
--var1=DATA # (Extra test data. Access with "self.var1" in tests.)
--var2=DATA # (Extra test data. Access with "self.var2" in tests.)
--var3=DATA # (Extra test data. Access with "self.var3" in tests.)
--user-data-dir=DIR # (Set the Chrome user data directory to use.)
--server=SERVER # (The Selenium Grid server/IP used for tests.)
--port=PORT # (The Selenium Grid port used by the test server.)
--proxy=SERVER:PORT # (Connect to a proxy server:port for tests.)
--proxy=USERNAME:PASSWORD@SERVER:PORT # (Use authenticated proxy server.)
--mobile # (Use the mobile device emulator while running tests.)
--metrics=STRING # (Set mobile "CSSWidth,CSSHeight,PixelRatio".)
--extension-zip=ZIP # (Load a Chrome Extension .zip|.crx, comma-separated.)
--extension-dir=DIR # (Load a Chrome Extension directory, comma-separated.)
--headless # (Run tests headlessly. Default mode on Linux OS.)
--headed # (Run tests with a GUI on Linux OS.)
--locale=LOCALE_CODE # (Set the Language Locale Code for the web browser.)
--start-page=URL # (The starting URL for the web browser when tests begin.)
--archive-logs # (Archive old log files instead of deleting them.)
--time-limit=SECONDS # (Safely fail any test that exceeds the limit limit.)
--slow # (Slow down the automation. Faster than using Demo Mode.)
--demo # (Slow down and visually see test actions as they occur.)
--demo-sleep=SECONDS # (Set the wait time after Demo Mode actions.)
--highlights=NUM # (Number of highlight animations for Demo Mode actions.)
--message-duration=SECONDS # (The time length for Messenger alerts.)
--check-js # (Check for JavaScript errors after page loads.)
--ad-block # (Block some types of display ads after page loads.)
--block-images # (Block images from loading during tests.)
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
--disable-csp # (This disables the Content Security Policy of websites.)
--enable-ws # (Enable Web Security on Chrome.)
--enable-sync # (Enable "Chrome Sync".)
--use-auto-ext # (Use Chrome's automation extension.)
--swiftshader # (Use Chrome's "--use-gl=swiftshader" feature.)
--incognito # (Enable Chrome's Incognito mode.)
--guest # (Enable Chrome's Guest mode.)
--devtools # (Open Chrome's DevTools when the browser opens.)
--reuse-session # (Reuse the browser session between tests.)
--crumbs # (Delete all cookies between tests reusing a session.)
--maximize-window # (Start tests with the web browser window maximized.)
--save-screenshot # (Save a screenshot at the end of each test.)
--visual-baseline # (Set the visual baseline for Visual/Layout tests.)
--timeout-multiplier=MULTIPLIER # (Multiplies the default timeout values.)
(For more details, see the full list of command-line options here.)
You can also view a list of popular pytest
options for SeleniumBase by typing:
seleniumbase options
Or the short form:
sbase options
Customizing default settings¶
An easy way to override seleniumbase/config/settings.py is by using a custom settings file.
Here's the command-line option to add to tests: (See examples/custom_settings.py)
--settings-file=custom_settings.py
(Settings include default timeout values, a two-factor auth key, DB credentials, S3 credentials, and other important settings used by tests.)
Running tests on a remote Selenium Grid¶
SeleniumBase lets you run tests on remote Selenium Grids such as BrowserStack's Selenium Grid, Sauce Labs's Selenium Grid, TestingBot's Selenium Grid, other Grids, and even your own Grid:
(For setting browser desired capabilities while running Selenium remotely, see the ReadMe located here: https://github.com/seleniumbase/SeleniumBase/tree/master/examples/capabilities)
Here's how to connect to a BrowserStack Selenium Grid server for running tests:
pytest my_first_test.py<EMAIL_ADDRESS>--port=80
Here's how to connect to a Sauce Labs Selenium Grid server for running tests:
pytest my_first_test.py<EMAIL_ADDRESS>--port=80
Here's how to connect to a TestingBot Selenium Grid server for running tests:
pytest my_first_test.py<EMAIL_ADDRESS>--port=80
Here's how to connect to a CrossBrowserTesting Selenium Grid server for running tests:
pytest my_first_test.py<EMAIL_ADDRESS>--port=80
Here's how to connect to a LambdaTest Selenium Grid server for running tests:
pytest my_first_test.py<EMAIL_ADDRESS>--port=80
Or you can create your own Selenium Grid for test distribution. (See this ReadMe for details)
Example tests using Logging¶
pytest test_suite.py --browser=chrome
(During test failures, logs and screenshots from the most recent test run will get saved to the latest_logs/
folder. Those logs will get moved to archived_logs/
if you have ARCHIVE_EXISTING_LOGS set to True in settings.py, otherwise log files with be cleaned up at the start of the next test run.)
Demo Mode¶
If any test is moving too fast for your eyes to see what's going on, you can run it in Demo Mode by adding --demo
on the command line, which pauses the browser briefly between actions, highlights page elements being acted on, and lets you know what test assertions are happening in real time:
pytest my_first_test.py --demo
You can override the default wait time by either updating settings.py or by using --demo-sleep={NUM}
when using Demo Mode. (NOTE: If you use --demo-sleep={NUM}
without using --demo
, nothing will happen.)
pytest my_first_test.py --demo --demo-sleep=1.2
Passing additional data to tests¶
If you want to pass additional data from the command line to your tests, you can use --data=STRING
. Now inside your tests, you can use self.data
to access that.
Running tests multithreaded¶
To run Pytest multithreaded on multiple CPUs at the same time, add -n=NUM
or -n NUM
on the command line, where NUM is the number of CPUs you want to use.
Retrying failing tests automatically¶
You can use --reruns=NUM
to retry failing tests that many times. Use --reruns-delay=SECONDS
to wait that many seconds between retries. Example:
pytest --reruns=2 --reruns-delay=1
Debugging tests¶
You can use the following calls in your scripts to help you debug issues:
import time; time.sleep(5) # Makes the test wait and do nothing for 5 seconds.
import ipdb; ipdb.set_trace() # Enter debugging mode. n = next, c = continue, s = step.
import pytest; pytest.set_trace() # Enter debugging mode. n = next, c = continue, s = step.
To pause an active test that throws an exception or error, add --pdb -s
:
pytest my_first_test.py --pdb -s
The code above will leave your browser window open in case there's a failure. (ipdb commands: 'c', 's', 'n' => continue, step, next).
Pytest Reports¶
Using --html=report.html
gives you a fancy report of the name specified after your test suite completes.
pytest test_suite.py --html=report.html
Nosetest Reports¶
The --report
option gives you a fancy report after your test suite completes.
nosetests test_suite.py --report
(NOTE: You can add --show_report
to immediately display Nosetest reports after the test suite completes. Only use --show_report
when running tests locally because it pauses the test run.)
Using a Proxy Server¶
If you wish to use a proxy server for your browser tests (Chrome and Firefox only), you can add --proxy=IP_ADDRESS:PORT
as an argument on the command line.
pytest proxy_test.py --proxy=IP_ADDRESS:PORT
If the proxy server that you wish to use requires authentication, you can do the following (Chrome only):
pytest proxy_test.py --proxy=USERNAME:PASSWORD@IP_ADDRESS:PORT
To make things easier, you can add your frequently-used proxies to PROXY_LIST in proxy_list.py, and then use --proxy=KEY_FROM_PROXY_LIST
to use the IP_ADDRESS:PORT of that key.
pytest proxy_test.py --proxy=proxy1
Changing the User-Agent¶
If you wish to change the User-Agent for your browser tests (Chrome and Firefox only), you can add --agent="USER-AGENT-STRING"
as an argument on the command line.
pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU"
Mobile Device Testing¶
Use --mobile
to quickly run your tests using Chrome's mobile device emulator with default values for device metrics (CSS Width, CSS Height, Pixel-Ratio) and a default value set for the user agent. To configure the mobile device metrics, use --metrics="CSS_Width,CSS_Height,Pixel_Ratio"
to set those values. You'll also be able to set the user agent with --agent="USER-AGENT-STRING"
(a default user agent will be used if not specified). To find real values for device metrics, see this GitHub Gist. For a list of available user agent strings, check out this page.
# Run tests using Chrome's mobile device emulator (default settings)
pytest test_swag_labs.py --mobile
# Run mobile tests specifying CSS Width, CSS Height, and Pixel-Ratio
pytest test_swag_labs.py --mobile --metrics="411,731,3"
# Run mobile tests specifying the user agent
pytest test_swag_labs.py --mobile --agent="Mozilla/5.0 (Linux; Android 9; Pixel 3 XL)"


?0
1
2
3'
4
5
cm
6
7
s
9
io
™“v
.
,
The
New
York
copyright
reserved
botanical
Garden
Plants
of
Trinidad.
So.
lf*0.
Legit.
A.
FeNDLER,
]
S77-80
'y?t£c
<**/***$
Plant®
Cubenses
Wrishtianĺ.
No.
3oo
*2~
/fyrnUL.
L^Cuu-C^C^^
Coll.
C.
WRIGHT,
1865.
01334630
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


Sign in with the same password you use for Meetup.com to create a review, post comments or pictures. Join us on Monday nights at a different microbrew every week in the Boulder, CO area.


@(repairs:List[RepairModels.RepairsCompletedOnTime],customs:List[CustomsModels.CustomsCompletedOnTime])
Title
@bootstrap.render
@navbar.render
@sidebar.render
Completed Repairs
This chart represents time from start to finish of repair.
Completed Custom Jobs
This chart represents time from start to finish of job.
Previous
Next


--- layout: post title: Development Setup of B-Translator date: 2013-07-08 summary: I describe the development setup that I use for B-Translator. Most of the the tips are project specific, however some of them can be used on any Drupal project. tags: [B-Translator, Development] ---
B-Translator helps to get feedback about l10n (translations of the programs). It tries to collect very small translation contributions from a wide crowd of people and to dilute them into something useful. It is developed as a Drupal7 profile and the code is hosted on GitHub. Here I describe the development setup and process that I use for this project. Most of the the tips are project specific, however some of them can be used on any Drupal project.
Installation for development is the same as the installation for a production server, inside a chroot. The steps are like this:
mkdir /var/chroot cd /var/chroot/ git clone https://github.com/dashohoxha/B-Translator.git nohup nice B-Translator/install/install.sh btr & tail -f nohup.out chroot btr/ /tmp/install/config.sh chroot btr/ rm -rf /tmp/install reboot ## it is advisable to reboot the host after this installation
The webserver that is used for production is NGINX because it is more responsive in high load, has build in cache, etc. The configuration of NGINX is also tweaked for production (has DoS protection, short timeout, etc.) For development Apache2 can be more suitable. It can be started and stopped like this:
chroot /var/chroot/btr/ /var/www/btranslator/profiles/btranslator/dev/apache2.sh start /var/www/btranslator/profiles/btranslator/dev/apache2.sh stop
Important: When apache2 is started, the services nginx,
memcached and php5-fpm are stopped. Don't forget to modify the
init script /etc/init.d/chroot-btr
like this:
#CHROOT_SERVICES="cron php5-fpm memcached mysql nginx" CHROOT_SERVICES="cron mysql apache2"
The script apache2.sh
cannot make this modification automatically
because it runs inside the chroot, and the init script is outside
the chroot (on the host system). So it has to be done manually.
I also add something like this on /etc/hosts, so that I can access it on the browser with a domain name:
<IP_ADDRESS> l10n.org.xx dev.l10n.org.xx
This modification has to be done manually as well.
It can be done with the script dev/install.sh
:
chroot /var/chroot/btr/ /var/www/btranslator/profiles/btranslator/dev/reinstall.sh
It will rebuild the Drupal directory with drush make and install the btranslator profile with drush site-install, and then do all the rest of configurations just like they are done during installation.
Normally there is no need to reinstall the application, unless we want to test the installation profile and the installation scripts.
Another kind of re-installation, which touches only the database of
Drupal (btranslator) and nothing else, can be done with the script
dev/install.sh
:
chroot /var/chroot/btr/ /var/www/btranslator/profiles/btranslator/dev/reinstall-db.sh
It is useful for testing the features. Usually, when features are un-installed, things are not undone properly. In order to leave out a feature, it should not be installed since the beginning. So, it is important to test different combinations of them to see which one works better for us.
Inside the chroot I make a clone for development like this:
chroot /var/chroot/btr/ cd /var/www/btranslator/profiles/btranslator/ dev/clone.sh dev
It creates a new application with root var/www/btranslator_dev and with DB named btranslator_dev. It also creates the drush alias @dev, and modifies the configuration of the webserver so that the cloned application can be accessed at dev.l10n.org.xx.
Caution: The root directory and the DB of the clone will be erased, if they exist.
Other clones like this can be created for testing etc. To cleanup (remove/erase) a clone, we can use clone_rm.sh like this:
chroot /var/chroot/btr/ cd /var/www/btranslator/profiles/btranslator/ dev/clone_rm.sh dev
By the way, we can also modify a little bit the configuration of a
development copy of the application (in order to help us not confuse
a development copy with a live or testing one), with the script dev/config.php
:
chroot /var/chroot/btr/ cd /var/www/ drush php-script btranslator/profiles/btranslator/config.php dev1 drush @dev php-script btranslator/profiles/btranslator/config.php dev2
It will set site_name to 'B-Translator (dev1)', will make site email something like<EMAIL_ADDRESS>will enable email re-routing, display the devel menu on the footer region, etc. It is not required, but sometimes may be useful.
Sometimes, when testing things on Drupal (installing/uninstalling modules etc.) things get messy and it is not possible anymore to revert to the state that you were before starting the test. In this case the only way to get safely to a previous stable state is by restoring a backup (or installing from the scratch and repeating all the configurations).
A snapshot of the application is just like a full backup with a time stamp. It saves the state of the application at a certain time, both the code (the whole Drupal directory) and the database. It can be done like this:
chroot /var/chroot/btr/ cd /var/www/ ln -s btranslator_dev/profiles/btranslator/ B-Translator B-Translator/dev/snapshot.sh make B-Translator/dev/snapshot.sh make @dev
These will create the files snapshot-btranslator-20130602.tgz
and snapshot-btranslator_dev-20130602.tgz
. They can be restored
like this:
B-Translator/dev/snapshot.sh restore --file=snapshot-btranslator-20130602.tgz B-Translator/dev/snapshot.sh restore --file=snapshot-btranslator_dev-20130602.tgz B-Translator/dev/snapshot.sh restore @dev --file=snapshot-btranslator-20130602.tgz B-Translator/dev/snapshot.sh restore @dev --file=snapshot-btranslator_dev-20130602.tgz
As you may notice, a snapshot of @dev can also be restored on the main application, and the other way around.
However, in many cases a backup/restore of the database is all that is needed, and it is more efficient. It can be done with drush sql-dump and drush sql-query like this:
drush sql-dump > btranslator.sql drush sql-dump @dev > btranslator_dev.sql drush sql-query --file=$(pwd)/btranslator.sql drush sql-query --file=$(pwd)/btranslator_dev.sql drush @dev sql-query --file=$(pwd)/btranslator.sql drush @dev sql-query --file=$(pwd)/btranslator_dev.sql
In order to access easily the code of the application from outside chroot, I create a symbolic link like this:
cd /var/chroot/ ln -s btr/var/www/btranslator_dev/profiles/btranslator/ \ dev
Now I can go to var/chroot/dev and start emacs or any other tools. This way I don't have to install emacs or any other development tools inside the chroot and can use the best of development tools that my host environment can offer me.
The copy of the application on
/var/www/btranslator_dev/profiles/btranslator/
(as well as the one
on /var/www/btranslator/profiles/btranslator/
) are actually clones
of the git repository at https://github.com/dashohoxha/B-Translator
so we can pull from it and push to it. Pulling (to get
up-to-date) can be done by everybody, however pushing requires a
username and password (the ones that are used to access the account
at GitHub).
For small or straight-forward changes I can also work directly on the master branch, then commit, and then push to github.
However I usually use a bit more complicated workflow. First I create and checkout a dev branch. When the work is done I merge this branch to master and then delete it. Finally push the commit(s) to github.
git checkout -d dev ### create a branch and switch to it [work-commit-work-comit] git checkout master ### switch back to master git pull ### get any latest commits from github git merge dev [--squash] git push ### send commits to github git branch -D dev ### erase the branch
Usually there are no commits comming from github, since I am the only developper (unless I have worked and commited from some other location). So, when I merge without –squash this usually results in fast-forward merge, which means that all the commits that I have done on the branch dev are automatically transferred to the branch master.
However sometimes there may be dirty commits on the dev branch, which means that there may be incomplete commits, or commits that reverse what was done on the previous commits etc. When I wish to reorganise commits and make them cleaner, I use the –squash option, which collects all the changes on the dev branch and leaves them on the master sandbox as local modifications (uncommitted). Then I can redo the commits on a cleaner or more logical way. Afterwards the dev branch will be deleted and the old commits will be lost.
Sometimes it is not easy or suitable to test modifications on the
@dev application (/var/www/btranslator_dev
). For example this is
the case when I have to test install/uninstall, enable/disable
modules, features, etc. In this case I test them on the main
application instance (/var/www/btranslator
). Since both
applications are clones of the GitHub repository, it is easy to push
commits from btranslator_dev to github and to pull them from
github to btranslator.
However, sometimes it is better to test modifications and make sure that they work, before pushing them to github. This can be done if the code on btranslator is a git clone of the code on btranslator_dev (instead of being a clone from github).
The script dev/git-clone-dev.sh
makes just this. It replaces the
code of btranslator with a git clone of the dev branch from
btranslator_dev. Then the workflow is like this:
cd /var/www/btranslator_dev/profiles/btranslator git checkout master git merge dev [--squash] git push git branch -D dev git checkout -b dev
So, after merging to master and pushing to github, we delete the branch dev and create a new one.
cd /var/www/btranslator/profiles/btranslator git pull
All the work that is described on the sections above is about development and local testing that is done on a working copy (sandbox) of a chroot installation. This is usually installed on my personal machine (that I use for development).
At some point, all the modifications have to be transferred to a public server, where the application is in "production", performing "live". On that public server there is the same chroot environment as in the development server. The synchronisation of the application can be done via git push and pull.
However drush rsync and drush sql-sync offer another option for synchronisation. For more details see:
drush help rsync drush help sql-sync drush topic docs-aliases
These commands use drush aliases, which allow also remote
execution of drush commands. On my development environment I have
created the file /etc/drush/remote.aliases.drushrc.php
, which has
a content like this:
<?php $aliases['live'] = array ( 'root' => '/var/www/btranslator', 'uri' => 'http://l10n.org.al', 'remote-host' => 'l10n.org.al', 'remote-user' => 'root', 'ssh-options' => '-p 2201 -i /root/.ssh/id_rsa', 'path-aliases' => array ( '%profile' => 'profiles/btranslator', '%data' => '/var/www/btranslator_data', '%pofiles' => '/var/www/PO_files', '%exports' => '/var/www/exports', '%downloads' => '/var/www/downloads', ), 'command-specific' => array ( 'sql-sync' => array ( 'simulate' => '1', ), 'rsync' => array ( 'simulate' => '1', ), ), ); $aliases['test'] = array ( 'parent' => '@live', 'root' => '/var/www/btranslator', 'uri' => 'http://www2.l10n.org.al', 'remote-host' => 'www2.l10n.org.al', 'command-specific' => array ( 'sql-sync' => array ( 'simulate' => '0', ), 'rsync' => array ( 'simulate' => '0', ), ), );
It defines the aliases live and test. The test/stage application
is almost identical to the live/production one, however it is not
for public use. The idea is to test there first any updates/upgrades
of the application, in order to make sure that they don't break any
things, before applying them to the real live application. In my case
it is placed on a different server, however it can also be placed on
the same server as the live application (just make a clone of the main
application with dev/clone.sh test
).
When everything is set up correctly, the synchronisation can be done as simply as this:
drush rsync @live @test drush sql-sync @live @test drush rsync @live @dev drush sql-sync @live @dev
Note: Synchronising this way from @test to @live or from @dev to @live, usually is a HUGE mistake, but the simulate option on the config file will make sure that it fails.
For drush commands to work remotely, ssh daemon has to be running on the remote server, inside the chroot environment. By default it is not installed, but it can be installed with the script dev/install-sshd.sh. This script will also take care to change the ssh port to 2201, in order to avoid any conflicts with any existing daemon on the host environment, and also for increased security.
For remote access to work correctly, the public/private key ssh access should be set up and configured as well. For more detailed instructions on how to do it see: http://dashohoxha.blogspot.com/2012/08/how-to-secure-ubuntu-server.html


To bring quality, style and the wish for good fortune to all of our guests. We provide a high-end experience through Chinese cuisine.
TOWN combines a variety of Chinese cuisine to excite and delight our customers. Our vision for the future is to create experiential dining that is more than just a night out. We aim to bring quality and luxury across all aspects of our brand. The approach of TOWN is to develop our brand with the understanding of both our culture and consumer insights. Within our vision always lives the promise of inspiring creativity, conversation, and quality. Our audience is a high-end clientele who values a dining experience. The age range of our customers is from early 30s-60s. We would like them to come back for both personal dining and events.
Our Restaurant uses 100% Recycled materials, not only for takeout, but for dining as well from napkins to our take out containers.


DiscordMessage
public struct DiscordMessage : DiscordClientHolder
Represents a Discord chat message.
-
The attachments included in this message.
Declaration
Swift
public let attachments: [DiscordAttachment]
-
Who sent this message.
Declaration
Swift
public let author: DiscordUser
-
The snowflake id of the channel this message is on.
Declaration
Swift
public let channelId: String
-
A reference to the client.
Declaration
Swift
public weak var client: DiscordClient?
-
The content of this message.
Declaration
Swift
public let content: String
-
When this message was last edited.
Declaration
Swift
public let editedTimestamp: Date
-
The embeds that are in this message.
Declaration
Swift
public let embeds: [DiscordEmbed]
-
The snowflake id of this message.
Declaration
Swift
public let id: String
-
Whether or not this message mentioned everyone.
Declaration
Swift
public let mentionEveryone: Bool
-
List of snowflake ids of roles that were mentioned in this message.
Declaration
Swift
public let mentionRoles: [String]
-
List of users that were mentioned in this message.
Declaration
Swift
public let mentions: [DiscordUser]
-
Used for validating a message was sent.
Declaration
Swift
public let nonce: String
-
Whether this message is pinned.
Declaration
Swift
public let pinned: Bool
-
The reactions a message has.
Declaration
Swift
public let reactions: [DiscordReaction]
-
The timestamp of this message.
Declaration
Swift
public let timestamp: Date
-
Whether or not this message should be read by a screen reader.
Declaration
Swift
public let tts: Bool
-
The channel that this message originated from. Can return nil if the channel couldn’t be found.
Declaration
Swift
public var channel: DiscordChannel?


T9
问题描述 :
A while ago it was quite cumbersome to create a message for the Short Message Service (SMS) on a mobile phone. This was because you only have nine keys and the alphabet has more than nine letters, so most characters could only be entered by pressing one key several times. For example, if you wanted to type “hello” you had to press key 4 twice, key 3 twice, key 5 three times, again key 5 three times, and finally key 6 three times. This procedure is very tedious and keeps many people from using the Short Message Service.
This led manufacturers of mobile phones to try and find an easier way to enter text on a mobile phone. The solution they developed is called T9 text input. The “9″ in the name means that you can enter almost arbitrary words with just nine keys and without pressing them more than once per character. The idea of the solution is that you simply start typing the keys without repetition, and the software uses a built-in dictionary to look for the “most probable” word matching the input. For example, to enter “hello” you simply press keys 4, 3, 5, 5, and 6 once. Of course, this could also be the input for the word “gdjjm”, but since this is no sensible English word, it can safely be ignored. By ruling out all other “improbable” solutions and only taking proper English words into account, this method can speed up writing of short messages considerably. Of course, if the word is not in the dictionary (like a name) then it has to be typed in manually using key repetition again.
Figure 8: The Number-keys of a mobile phone.
More precisely, with every character typed, the phone will show the most probable combination of characters it has found up to that point. Let us assume that the phone knows about the words “idea” and “hello”, with “idea” occurring more often. Pressing the keys 4, 3, 5, 5, and 6, one after the other, the phone offers you “i”, “id”, then switches to “hel”, “hell”, and finally shows “hello”.
Problem
Write an implementation of the T9 text input which offers the most probable character combination after every keystroke. The probability of a character combination is defined to be the sum of the probabilities of all words in the dictionary that begin with this character combination. For example, if the dictionary contains three words “hell”, “hello”, and “hellfire”, the probability of the character combination “hell” is the sum of the probabilities of these words. If some combinations have the same probability, your program is to select the first one in alphabetic order. The user should also be able to type the beginning of words. For example, if the word “hello” is in the dictionary, the user can also enter the word “he” by pressing the keys 4 and 3 even if this word is not listed in the dictionary.
输入:
Each scenario begins with a line containing the number w of distinct words in the dictionary (0<=w<=1000). These words are iven in the next w lines in ascending alphabetic order. Every line starts with the word which is a sequence of lowercase letters from the alphabet without whitespace, followed by a space and an integer p, 1<=p<=100, representing the probability of that word. No word will contain more than 100 letters.
Following the dictionary, there is a line containing a single integer m. Next follow m lines, each consisting of a sequence of at most 100 decimal digits 2�, followed by a single 1 meaning “next word”.
输出:
For every number sequence s of the scenario, print one line for every keystroke stored in s, except for the 1 at the end. In this line, print the most probable word prefix defined by the probabilities in the dictionary and the T9 selection rules explained above. Whenever none of the words in the dictionary match the given number sequence, print “MANUALLY” instead of a prefix.
Terminate the output for every number sequence with a blank line, and print an additional blank line at the end of every scenario.
样例输入:
2 5 hell 3 hello 4 idea 8 next 8 super 3 2<PHONE_NUMBER>1 7 another 5 contest 6 follow 3 give 13 integer 6 new 14 program 4 5 77647261 6391 4681 26684371 77771
样例输出:
Scenario #1: i id hel hell hello i id ide idea Scenario #2: p pr pro prog progr progra program n ne new g in int c co con cont anoth anothe another p pr MANUALLY MANUALLY
解题代码:
//* @author: import java.util.Comparator; import java.util.HashMap; import java.util.PriorityQueue; import java.util.Scanner; class node { char ch;// 字符 int val;// 权值 int lv;// 层次 node father;// 父结点 HashMap< Character, node> next; node(char ch, int val, int lv, node father) { this.ch = ch; this.val = val; this.lv = lv; this.father = father; next = new HashMap< Character, node>(); } node() { next = new HashMap< Character, node>(); lv = 0; } } class trie { private static char t9[][] = { {}, {}, { 'a', 'b', 'c' }, { 'd', 'e', 'f' }, { 'g', 'h', 'i' }, { 'j', 'k', 'l' }, { 'm', 'n', 'o' }, { 'p', 'q', 'r', 's' }, { 't', 'u', 'v' }, { 'w', 'x', 'y', 'z' } }; node root = null; public void add(String str, int val) { node curr = root; for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); // 没有结点就建立结点 node next; if ((next = curr.next.get(ch)) == null) { curr.next.put(ch, new node(ch, val, curr.lv + 1, curr)); curr = curr.next.get(ch); } else { curr = next; curr.val += val; } } } public void find(String num_str) { int length; int num[]; // 找出1的位置，确定结束点 int one_pos = num_str.indexOf('1'); if (one_pos < 0) { length = num_str.length(); } else { length = one_pos; } // 字符转换为数字 num = new int[length]; for (int i = 0; i < length; i++) { num[i] = num_str.charAt(i) - '0'; } // 建立优先队列 PriorityQueuepq = new PriorityQueue (26, new Comparator () { // 优先规则：层次从小到大，权值从大到小，字母表顺序 public int compare(node a, node b) { if (a.lv == b.lv) { if (a.val == b.val) { return a.ch - b.ch; } else { return b.val - a.val; } } else { return a.lv - b.lv; } } }); // 把根加入队列 pq.add(root); // 对trie树进行BFS遍历 int lv = 0; while (pq.size() > 0) { // 把所有可能接下来的结点列出，加入队列 node curr = pq.poll(); // 反推结果 if (curr.lv > lv) { char res[] = new char[curr.lv]; node c = curr; while (c != root) { res[c.lv - 1] = c.ch; c = c.father; } System.out.println(res); lv++; } if (lv < num.length) { int dig = num[curr.lv]; for (int i = 0; i < t9[dig].length; i++) { node next; if ((next = curr.next.get(t9[dig][i])) != null) { pq.add(next); } } } } // 填空 for (int i = lv; i < length; i++) { System.out.println("MANUALLY"); } } trie() { root = new node(); } } public class Main { public static void main(String[] args) throws Exception { Scanner cin = new Scanner(System.in); int cas = cin.nextInt(); for (int th = 1; th <= cas; th++) { System.out.printf("Scenario #%d:\n", th); // 对每一个测试用例建立一棵trie树 trie tr = new trie(); int w = cin.nextInt(); while (w-- > 0) { tr.add(cin.next(), cin.nextInt()); } int m = cin.nextInt(); while (m-- > 0) { String src = cin.next(); tr.find(src); System.out.println(); } System.out.println(); } } }
代码是给出了，但是解析的也太不清晰了吧！如 13 abejkcfghid jkebfghicda
第一步拆分为 三部分 (bejk, cfghi, d) * C(13,3)，为什么要这样拆分，原则是什么？
为什么暴力求解方法循环到sqrt(n) 就可以了呢
位运算真赞
#pragma pack(2) 这个用法太坑爹
这个应该是最朴素的KMP实现
清华也会出这么无聊的题
有谁知道直接遍历的方法中第8行是什么意思嘛？
C语言版本的代码好像有点问题
1234百位上出现的次数应该是200吧。
终于明白了递归和dp的关系，多谢分享！
这个问题别太纠结了，不同的编译器结果不一
正在练习，很有帮助
刚开始学，非常好


Oil Painting
Home
Improvement Tips
Blog
Other Hobbies
Contact
Contact Us
Address
777 Yes St
Email<EMAIL_ADDRESS>Phone: 3333 3333


{% extends "base.mail.html" %} {% load djmoney %} {% load i18n %} {% block content %}
{% blocktrans context 'email' %}
Hi support,
We have received some feedback on identity verification {{ full_name }} ({{ email }}).
Please check out the comments and make the appropriate changes.
They should submit their identity verification again as soon as possible.
{% endblocktrans %}


1134 124th Ave NE
Bellevue, WA 98543
(425)117-5687
Professional Experience
Chipotle Mexican Grill
- Worked as a Crew Member from March 2017 to April 2018
- Served food, restocked inventory, and handled customers on the line
- Cleaned tables, floors, bathrooms, kitchen, prep room, and dishes
- Closed the restaurant on weekdays
Entry Level Carpenter
- September 2018 to August 2019
- Experience in roofing and sealing and basic home repairs
- Painted walls, ceilings, cabinets, window frames, and door frames (both exterior and interior)
- Installed and repaired interior doors, cabinets, and drawers
- Installed kitchen and bathroom vinyls
Skills
- Knowledgeable in Microsoft Word, PowerPoint, Excel, and Access
- Knowledgeable in computer hardware and accessories
Education
Bellevue High School
- Graduated with a 3.5 GPA (June 2018)
Bellevue College
- Working toward the Business Analyst track for the Information Systems AAS


The boys who like sports look very handsome and sunny.
There are so many countries in the world, each country has its own language and culture, however sports exist across countries, such as basketball, football and so on, then sports can be a channel of communication between different countries.
Peoples who like sports, no matter your age, gender or country, as long as you pick up basketball or play football, we all have the same communication tools，and sports can also help us strengthen our bodies.
People who love sports are the most lovely, confident and sunny people.
I used my cellphone HUAWEI NCE-AL00 for this photo.
This page is synchronized from the post: ‘Sports guy’


In this sample, the Tooltip Custom Element's "autoHide" property is set to false. When "autoHide" is off, to close a tooltip, you will have to click it or to open another tooltip that have identical name.


| First Slide | Conference Presentation Judo | (Notes) |
A substantial amount of the sense of this talk is not in the slides. This document will try to relate some of the things I said during the talk itself that might not otherwise be apparent. It may also elaborate, amplify, and explain where necessary.
The notes will also explain the jokes, so if you read the notes without reading the slides first, you'll be getting explanations of jokes you haven't heard, and none of it will be funny. So read the slides before the notes, or concurrently with the notes.
As in the talk itself, everything in these notes is intended seriously, even when it appears to be facetious.
Earlier that morning I had given a talk on Mailing List Judo, which was a tongue-in-cheek guide to the best way to navigate the social obstacles of the perl5-porters mailing list and to get your patches to Perl incorporated into the main source. The 'judo' of the title referred to the idea that one could use the negative features of the mailing list against themselves.
That class finished with a slide that said "Come back next year for my talk on Conference Presentation Judo" over a picture of a happy baby. (See below for more details about the baby.) I was serious about the Conference Presentation Judo talk, and in the days before the conference I made several pages of notes for it.
Just before I left for the conference, Kevin Lenzo wrote to tell me there had been a cancellation and to ask if I could fill an extra slot. I gave Kevin a choice of five talks, and he chose this one.
The picture on this slide is an extreme closeup of my face. Observant viewers sometimes remark that it's unusual that my pupil is so dilated even though it appears that I'm looking directly into a light. When this picture was taken I had just returned from the ophthalmologist, who had forcibly dilated my pupil so he could look in.
The talk was aimed primarily at people who will be giving a three-hour tutorial at a conference like TPC or Usenix. Many people have told me that they think it will be helpful to them in preparing talks of other lengths for other venues.
Several former TPC tutorial speakers were in the room. Also present was Robert Spier, who was scheduled to give his first TPC tutorial the following month. I had originally been scheduled to speak at the same time as Robert, but I had my talk moved so that Robert could attend.
I really do believe that most tutorial speakers are terrible. One of the perks of doing a tutorial is that you get to attend the other tutorials for free. I rarely last through more than half an hour of anyone else's tutorial. Partly this is just a short attention span, and partly it's that I pick things up much quicker than the typical student. But a lot of it is that the tutorials are very poorly organized and presented.
Readers should note that this talk is about tricks that might not be obvious and advice you haven't heard before---I'm not going to explain the fundamentals of public speaking, such as "always face the audience." This talk assumes you've heard that already.
This slide originally carried a picture of Damian. I took it out before the conference because I decided that it didn't make any important point except to reveal one of the more unpleasant sides of my personality.
Both Damian and my wife agreed that it was funny, so here it is:
On the previous slide, I considered mentioning that one of the ways in which some people fail to have apititude for tutorial presentation is to have a small bladder. I was blessed with an enormous bladder, which is a valuable asset. I was going to put a picture of a bladder on the slide. I decided against the whole thing because I didn't want to telegraph the joke that appears on this slide.
After the talk, Damian and I were discussing these slides, and Damian congratulated me on the clever visual pun in the illustration.
I said, "What pun?"
"Well, of course, she's just bowing."
"No, she isn't."
"What's she doing, then?"
"She's doing exactly what the slide is about."
"Ugggggh."
I agree, it would have been very clever to think of using a picture of someone who was merely bowing. It never occurred to me. My approach to things is more blunt and direct than that.
As far as I know, I have never done this.
I have nothing in particular to say about this slide, so I'll address a couple of issues I forgot to mention in the talk. In a talk of longer than about twenty minutes, you should really have some water handy. You can get into big trouble if your mouth dries out in the middle. Obviously, it can become difficult to continue talking. Even worse, some people have the problem that if they try to talk with an insufficiently lubricated mouth, their spit tends to fly around a lot. Ick.
The converse of this, however, is that you should be careful not to drink too much unless you're one of those lucky people like me who doesn't have to care. I usually go through about a quart and a half of water in a 90-minute talk, but not everyone can do this. Ration your water supply unless you're sure you can handle it all. Don't try this at home folks; I'm a trained professional.
Do not try to drink coffee while you're talking. This is for several reasons. First and most obviously, the caffeine is a diuretic. But more important, coffee is a lot more viscous than water is, and if you try to drink and talk at the same time, you are likely to inhale some. Stick to water.
Similarly, it's probably a good idea to avoid eating while talking. The problems here are manifold and obvious: You might choke. You might spray food particles around. You might become impossible to understand. You might inadvertently let the audience see the food after you've chewed it but before you've swallowed it. (Ick.) Like all the advice in this talk, this must be adjusted for each person.  Why?  You have to work with what you have.
The advice on this slide is crucial, and not at all obvious without the explanation, which I delivered orally.
The reason you must not discharge the class early or late for break is this: If you let them out them early, the hotel staff will not yet have finished setting up the coffee and cake service. If you discharge them late, the other classes will already have eaten up the best cakes. The cakes are the high point of the tutorial for many people, and if you screw up the cake schedule, you will be savaged on the evaluations. People love cake.
The picture illustrates this, showing me in the act of enjoying a Sacher Torte. My in-laws sent this to us from the Hotel Sacher in Vienna.
This section intentionally left blank.
This is one of those slides where I was afraid that people would think I was being facetious. I wasn't. Gilbert Highet says much the same thing in The Art of Teaching. A talk with good presentation and poor content beats one with good content and poor presentation. This is because the first talk will at least pass the time amusingly; the second will be a deadly bore and you won't learn anything anyway.
Of course, the trick is to have good presentation and good content.
By the way, I recommend The Art of Teaching very highly. And here's an interesting phenomenon: If you look at the Amazon customer reviews of it, you find that everyone agrees that it's great except for M.Ed. students in Missouri and northwestern Illinois.
Apparently when I got to the "Introduction to XML" slides, a gentleman in the audience turned pale. He got out his laptop, brought up the slides for his own "Introduction to XML" class, and they matched my fake slides almost exactly.
Despite this, I swear that the assertion on slide 14 is true: I was not thinking of any specific instructor or class. I just chose XML as an unusually boring and buzzword-ridden example.
The truth is, the problem of long pointless introductions in tutorials is almost universal. Nearly everyone does it.
This was exactly the reason that I started the Lightning Talks sessions. I decided that if the speakers couldn't get to the point promptly, then dammit, I was going to force them to get there or else get off the stage. It has worked pretty well. Every year has a couple of people who can't seem to say anything, but I get rid of them quickly.
Voltaire once wrote "I am sorry that this letter was so long, but I did not have time to make it shorter." To prepare good talks or articles, authors must ask themselves "What am I really trying to say here? Why is it important?" The severe constraint of a five-minute time limit forces a distillation of thought and a clarity of exposition not usually found in longer talks.
Some day I'll write an essay on the theme "Constraint is liberating."
Some time ago Nat Torkington pointed to a discussion of conference design which criticized 45-minute sessions as too short. This article said, in part:
Last fall at the O'Reilly P2P & Web Services Conference I noticed that the short sessions (45 minutes) prevented every relevant point from being addressed and discussed.
The author of the article apprently considers this a disadvantage. To me, it seems like a benefit.
Panels and sessions served as instigators of discussions that continued in the hall afterwards, or over lunch in the courtyard.
Also an advantage, in my opinion if not the author's. Having conference attendees come up to a microphone to ask questions discourages dialogue; encourages a hierarchy of authority; discourages networking; encourages thoughtlessness. Having conference attendees meet the speakers in the hallway or over lunch does the opposite. The participants can have a meaningful exchange of complex ideas, conversing as equals, instead of being forced into the roles of supplicant and hierophant.
And, of course, having long conference sessions encourages a lot of blather.
Nat asked folks for feedback on this, and I said:
I'm sure my opinion won't be a surprise, but I think that even 45-minute sessions are too long for most speakers. If you give them any more time, they just waste it. If they want to talk for twice as long, let them cut the talk in half and send two proposals.
TPC used to have groups of three related 20-minute talks scheduled into a one-hour slot. I liked those. If I were scheduling a conference, my motto would be "twenty is plenty."
This slide raises a question that's puzzled me for a long time: Why do people attend these three-hour lectures anyway? I talked with Conway about this once, and he had some useful things to say, and pointed out that for many people, the lecture really is a good way to learn a few things. Still, I think these classes are far from optimal.  If you get seven people, they'll get a better class and save money. If you get twelve people, they'll save a lot of money. I don't know why more people don't do this.
I'm afraid some people interpreted my remark about 45-minute attention spans to be vaguely insulting to conference attendees. But it was certainly not intended that way. Really nobody can pay attention for more than about 45 minutes. Certainly I can't, and I have unusual powers of concentration.
I guess that the standard deviation of attention span is about 15 minutes, so that about 2/3 of the audience gets distracted by the end of the first hour.
At this point I asked for a show of hands to learn how many people had heard this advice. Most of them had.
It's amazing that this awful advice has such a hold on people. If you contrast the traditional advice with my advice, it seems to me that mine sounds a lot more commonsensical. You're giving a technical talk; the attendees have gone to a lot of trouble and expense to be there. What could be more natural than "Get to the point"?
One of the things that playwrights learn is that if you want the audience to remember something, you have to tell them three times. That's true. But that doesn't mean that they should be told three times in exactly the same way---A playwright who tried to do that would die in the gutter, and so will you.
That brings us to the third piece of advice ("Don't repeat; embellish"), which requires a little elaboration. You want to present each important idea more than once, because a lot of the audience won't really get it after the first example. So you show a second, different example, which has an interesting variation. The people who didn't fully grasp the concept the first time around now have an opportunity to see it again. The people who did get it the first time around will remain alert and interested because of the variation.
Here's an example. I want to convert a recursive function to an iterator. One example is a directory tree walker. A later example is a genomic sequence generator. (Given a pattern like <CGA>TT<CG>TT, produce strings like CTTCTT, GTTCTT, ATTCTT, CTTGTT, ...) Structurally, these are quite similar. But the tree walker involves some system programming details, while the sequence generator involves some parsing details. breadth-first and depth-first search both yield sensible results for directory trees, but only depth-first search makes sense for the sequences. With the sequences, a random search order can be interesting, so I introduce that as a variation. People who didn't understand the details of the tree walker get to see them over again, and people who did understand it get to compare the two examples and ponder the differences.
The photograph on this slide was taken by Meng Wong on his vacation in Australia.
Meng has also kindly provided the web server that is serving the talk to you. Thank you, Meng.
Notice that this one slide is the "introduction section".
The list of examples is rather devious. "Generating DNA sequences" is there because everyone knows that Perl was important for the Human Genome Project and the bioinformatics is a major research area, funded by the government and so on. If iterators are useful in bioinformatics, they therefore have some importance in the real world.
"Database searches" is there to convince the people who weren't convinced by bioinformatics. It's completely generic and completely universal. Every single person in the room has to perform database searches. It's also there because it's boring. Some people refuse to believe that anything interesting has any real value, so I always try to include an example from cost accounting if I can. Databases aren't as dull as cost accounting, but they're dull enough.
"Permutations" is there to hook the math-heads and academics. It's also there to impress people who don't know what permutations are but who are impressed by big words.
The thing to notice here is how quickly I dive into the technical details. Slide 1 is the introduction section. Slide 2 introduces a specific problem we're going to solve. Slide 3 shows complete code; slides 4-5 explain how it works. Slide 6 presents the problems with the approach. Slides 7-9 show that these same problems appear in the context of permutation generation (the 'solution' in the Perl Cookbook has the same severe defects) and database search. Having established that these are common problems, I then show the solution: Slide 10-12 introduces the solution in the context of databases, because Perl's DBI module provides a ready-made example. Slide 12 ends by calling the solution structure an iterator; slide 13 backs up and answers the question "What is an iterator?" Now that the class has seen several examples of the problem we're solving, and one well-known example that uses iterators as a solution, they're ready to appreciate why they might care about the answer to the question "What is an iterator?".
Even if someone falls asleep after 45 minutes, they will know what iterators are for and have several examples of places where they are used and places where it would be a good idea to use them. They have an analogy with filehandles, which are a special case, and Perl's 'each' and 'readdir' operators, ditto. They don't know any techniques for implementing iterators, because I showed those after they fell asleep, but the code is still in the book and they can read it later. Mission accomplished.
I think this may be the single best slide I've ever made.
Pictures don't have to be irrelevant or colorful. Even a monochrome box-and-arrow diagram breaks up the monotony of slide after slide of unrelenting text.
The atrocious pun here is that this was the illustration from the first page of a tutorial section on "autoloading".
This year I redid all my diagrams. I felt like a complete dumbass for having taken so long to figure this out.
Meng tells me that magazine designers follow the same rule. If they have a picture of a person, they will flip it over if necessary to get the person to be looking at the gutter instead of at the margin. I boastfully note that I figured this out for myself.
I wish I had used a better example person on this slide; I don't know why I went with Amelia Earhart. These notes show a better example. I use this picture of Randal Schwartz every chance I get because Randal appears to be so interested in the text.
Here we see a piece of useful advice: Everyone loves a happy baby.  Hey, it's a dog-eat-dog world out there and if I can make more money by exploiting innocent babies, that's what I will do.
I found this picture by doing a Google image search for "happy baby". I got thirty thumbnails of the thirty happiest babies you've ever seen.
Appeal to base psychology whenever possible. People are wired to love happy babies. People are wired to think that fruit beautiful.  If you want people to be disgusted by C++, putting some turds on the page is the most effective thing you can do. People will feel real disgust, not in the front part of their brains, but way at the back, in the microcode. (I probably don't need to list all the ways this plan could backfire, do I?)
Everyone in the class wishes you would go at a different speed. Some people want you to go faster, some slower. On this slide, "median rate" means a rate which is faster than half the audience would most prefer and slower than the other half would most prefer. While this is the speed that's closest to everyone's preference, it's not optimal.
By '75-80% mark' I mean that I try to run my classes at a speed that is faster than 75-80% of the people in the class would most prefer.
Since hardly anyone will retain everything in your talk, you want to construct the talk in sections that are as independent as possible. The way to do that is to structure the talk like a tree. Graphs with cycles have more dependencies. You should cover the root nodes first because everything else depends on them and at the beginning of the talk everyone is still awake for it.
At a 75-80% speed, people will miss stuff; it will go by too fast for them to understand. But that was going to happen anyway.
The thing about synchronization points is very important. It's all very well to imagine your talk as the development of a single brilliant argument from start to finish, but if you do it that way, almost nobody will follow the whole thing. It's better to break the talk into sections that can be swallowed one at a time. Then if someone sleeps through section 7 and wakes up for section 8, they still get some value out of section 8, and they can use their knowledge of section 8 later on when they go back and try to reread the notes for section 7.
I guess the short version of all this is: If you have sections, you can go faster. The slower people will learn more because they can get some of the sections on the first pass and fill in the missing sections later; the faster people will learn more because you went faster.
My original plan for this talk was going to have "Seven Conference Attendees to Watch Out For", but the only one I could think of was the Guy in the Second Row. I do not know why he always sits in the second row. He's not always a guy; I had a female Guy in the Second Row once.
My life has been full of Guys in the Second Row, but I had a very specific person in mind when I wrote this slide. Originally, there was a picture of him on the slide. Then I decided it was unfair, and added a note about how the person on slide 28 was actually much worse. Then I took the original person off of slide 27 and just went with the slide 28 person.
About two minutes before I was due to give the talk I discovered that the version of the slides I had handy was an older version that had the unfair version of slide 27. Fortunately I was able to download the updated version in time.
This is a picture of me. This would probably have been more obvious if you had been at the talk.
Once I recognized the phenomenon of guy-in-the-second-row-ism, it didn't take me long to figure out that I was one of them. This is probably why I find Second-Row-ism so darn annoying. The faults we dislike most in others are those that remind us most of our own faults.
For a typical example, listen to Adam Turoff's talk on open source presentation systems.
I got this idea from Phil Agre. Unfortunately I can't find his original remarks. But almost everything Phil writes is worth reading, so have a look around his site. In particular, Networking on the Network contains useful advice for how to get the most out of a conference.
If you run out of time on slide 111 of 120, the evaluations will complain that you didn't finish the talk. But if you run out of time on slide 120 after having skipped slides 103, 105, 107, 109, 111, 113, 115, 117, and 119, nobody will complain at all. Go figure.
So, for example, my Tricks of the Wizards class ends with:
| Topic | # slides |
|---|---|
| Returning a False Value | 2 |
| The Self-Replacing Stub | 2 |
| Schwartzian Transform | 4 |
| Build your own 'map' (additional example) | 3 1 |
| Debug printing of strings | 1 |
| Debug printing of lists | 1 |
| Matching many patterns at once | 3 |
| Booleannumbers | 1 |
| Selecting n different things | 1 |
| Quick return with warning | 1 |
Conference attendees like to see a big fat book. It makes them feel like they got their money's worth, even if most of the book is crap. After the conference is over and they've forgotten the tutorial, they still have the book, which proves to them (and their boss) that they were exposed to education.
One implication of this is that people will be happier if you print on only one side of each page; this makes the book twice as thick. It also gives the attendees a convenient place to make notes. (On the other hand, if your slides don't have space for notes already, you probably have too much text on the slides.) The big downside is that one-sided printing wastes trees.
An easy way to bulk out the book is to attach a bunch of technical specs such as RFCs. The Bonus Section approach is more valuable and interesting. Even a small Bonus Section is worth having.

Nearly everyone seems to have the problem of having too much material rather than too little.  You want people to see the results of your hard work. The result is that the class is too long and bloated. Having a bonus section makes it psychologically easier to chop stuff out of the class. You don't have to consign it to the trash can; it will go in the Bonus Section.
People attending my Stolen Secrets of the Wizards of the Ivory Tower class at YAPC this year will note that I didn't follow my own advice here. I digressed extensively in the middle of a discussion of memoization to discuss ISO paper formats. A brief digression would have been acceptable. It probably would have been better to stick to the subject.
The evaluations may be worthless, but that's what the conference staff uses to decide whom to invite back next year, so you need to get good ones. That's why this talk is all about making sure your class gets the best cakes.
Remember, unless at least sixty percent of the class says you're going too fast, then you're going too slow.
Good advice for this life in general. You can't count on getting approval or encouragement from other people, so concentrate on geting approval from yourself.
I sometimes imagine myself standing in judgement before God. God asks me, "Did you do the best job you could?" I want to be able to say that I did. If I can imagine telling God that I did good work, then that's good enough for me. If God is happy with my talk, then the conference attendees should be satisfied too.
If you do begin with a joke, it must be a relevant joke. You can't win the audience by starting off with "A priest and a rabbi were fishing..."
This talk started with a couple of jokes. They were very successful. Bathroom humor may be juvenile, but it's universal. People are less offended by it than I thought they might be. The same caveat applies here, though: If you aren't a bathroom humor sort of person, then stay away from bathroom humor. I think one reason I can get away with it is that there's no coyness on my nature.
The advice on this slide has a more general version: Don't take any advice that is contrary to your nature, including the advice in this talk. If you're not a cynical, manipulative bastard, or if you hate babies, you might want to avoid pictures of happy babies. If pictures aren't working for you, maybe you shouldn't have them. There's probably even someone out there who can't give the best possible talk unless they sabotage the cake schedule.
This reminds me of a very clever suggestion that Meng made a few weeks ago. In one of my talks, I have a picture of two-headed sperm:
I was initially worried that some people might be offended by this picture. Meng's suggestion was that if anyone was offended, to tell them that it was a picture of gorilla sperm, which would make it all right.
This is very funny, but only because it's true.
I like to get Kurt Starsinic primarily because he's friendly looking. Kurt has an unusually honest, open-looking face. He also smiles a lot.
Incidentally, if you do have trouble with stage fright, here's a trick that worked well for me for a long time. I found that playing the harmonica in the bathroom before the talk was very helpful. Partly this is because it's distracting, and partly because it forces deep, rhythmic breathing. I don't expect you to run out and learn to play the harmonica, but the advice about distractions and deep breathing applies to everyone.
This is Placido the octopus. My wife and I have several octopuses at home, but Placido is the one who accompanies me to all my talks. Some people would probably to bring prefer a bear or a doggie.
Placido was named after Placido Polanco, a utility infielder for the St. Louis Cardinals. After YAPC was over, Placido and I went to the Cardinals game and were delighted to discover Polanco playing third base. (I had completely forgotten that Polanco played for St. Louis.) He was two for four with a double, scoring one run and driving in two. The Cardinals beat the Reds 3-2.
It's a good idea in general to keep your hands out of your pockets while you're speaking. If nothing else, it projects nervousness.  If there isn't any change in your pocket, you may fondle unconsciously. All of this is very bad.
I'm not sure that this is actually good advice. It might be better to live your life without ever speaking ill of anyone. Sorry, I'm not yet a perfect sage.

This is the thing about audiences that drives me the most bananas. Why do they have to be so uppity about little typos? But they are, and I've had to learn to live with it. When God asks me if I did my work as well as I could, I don't want to have to admit that my slides were full of typos.
If I were going to write an essay about how to give a good talk, the practice session would be the most important thing on the list after going to the bathroom beforehand. The practice session gives you a chance to find out what's unclear. The practice session gives you a chance to find out whether your first draft is fifty percent too long or only twenty percent. If you find yourself waving your arms a lot at certain points in the practice session, that tells you that you should add diagrams to the slides at those points. In the middle of the practice session, you can stop and take notes about how to improve the slides. Practice sessions are more informal, so you won't be as scared and the audience will be more forgiving.
You can make some money by charging people five or ten bucks to come to the practice session; the attendees will be glad of the chance to get a $300 tutorial for $10. This also gets you valuable exposure, and people will leave feeling that you did them a big favor, especially if you spend some of the admission fees on making a handout to give them. Everyone comes out happy.
Incidentally, this slide demonstrates that even the simplest illustration is better than no illustration at all. I think the giant comma is hilarious.
Good conference presentation wear is slacks and a button shirt with a collar. You must look tidy and confortable.  I always roll up the sleeves of my shirt, which may be untidy, but otherwise the sleeves bother me. Also, I like the way it looks, and for me, it's important to feel that I'm physically attractive when I give a talk.
Wearing suits does not make me uncomfortable---sometimes I wear mine just for fun---but it sure does make conference attendees uncomfortable. I was slammed on the evaluations for the suit. People were quite offended that I would dare appear before them in a suit. Geeks are very anti-suit. I don't think this is a good thing; I think it reflects an underlying insecurity and lack of self-knowledge. A suit is just clothes; putting one on doesn't change you into a different person. But most geeks don't seem to be comfortable enough with their own identities to feel safe dressing differently than usual.
Back before I was completely comfortable with the idea of wearing a suit, I explained it to myself by saying that I was in disguise, sneaking around deviously undercover, and that made me feel better. After a little while I got used to it. I think it's a bad sign that so many geeks are so frightened by the very thought of a suit.
Always say 'thank you' at the end. That's just ordinary manners.
Thank you. I hope you found this helpful.
| More Talks | Copyright © 2002 M. J. Dominus |
Return to: Universe of Discourse main page | Perl Paraphernalia | Classes and Talks
mjd-perl-yak@plover.com