Python is a popular programming language. It was created by Guido van Rossum, and released in 1991.
It is used for:
- web development (server-side),
- software development,
- mathematics,
- system scripting.
- AI and ML
- Automation
When Python 2.7 was still supported, a lot of functionality in Python 3 was kept for backward compatibility with Python 2.7. With the end of Python 2 support, these backward compatibility layers have been removed, or will be removed soon. Most of them emitted a DeprecationWarning warning for several years. For example, using collections.Mapping instead of collections.abc.Mapping emits a DeprecationWarning since Python 3.3, released in 2012.
Perhaps the most well-known statement type is the if statement. For example: >>> x = int(input("Please enter an integer: ")) Please enter an integer: 42 > There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is short for ‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for the switch or case statements found in other languages.
>if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More
>
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence
he break statement, like in C, breaks out of the innermost enclosing for or while loop. Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the iterable (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:
> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print(n, 'equals', x, '*', n//x)
... break
... else:
... # loop fell through without finding a factor
... print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)
When used with a loop, the else clause has more in common with the else clause of a try statement than it does with that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.
The continue statement, also borrowed from C, continues with the next iteration of the loop:
>>> for num in range(2, 10):
... if num % 2 == 0:
... print("Found an even number", num)
... continue
... print("Found an odd number", num)
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9
The continue statement, also borrowed from C, continues with the next iteration of the loop:
>>> for num in range(2, 10):
... if num % 2 == 0:
... print("Found an even number", num)
... continue
... print("Found an odd number", num)
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9
4.5. pass Statements The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:
>>>
>>> while True:
... pass # Busy-wait for keyboard interrupt (Ctrl+C)
...
This is commonly used for creating minimal classes:
>>>
>>> class MyEmptyClass:
... pass
...
Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:
>>> def initlog(*args):
... pass # Remember to implement this!
...


Preparation time
less than 30 mins
Cooking time
1 to 2 hours
Serves
Serves 4
In this dish the garlic subtly flavours the chicken thanks to being blanched before added to the pot. Serve alongside delicious vegetables and a cauliflower purée for an extra special Sunday roast.
Preheat the oven to 180C/Gas 4.
Bring a small saucepan of water to the boil and add the garlic. Blanch and refresh in ice cold water. Repeat, changing the water.
Heat the oil in a large, lidded casserole dish. Add the vegetables, garlic and herbs and cook for 2-3 minutes. Put the chicken on top and pour in the stock. Put on the lid and roast for 1½ hours, or until cooked through. Remove the lid for the last half hour of cooking.
Meanwhile, for the purée place the cauliflower and milk in a large saucepan and cook for 8-10 minutes. Drain, reserving the milk. Place the cauliflower in a blender and add one ladle full of milk at a time until the purée reaches a smooth consistency.
Bring a large pan of water to the boil and cook the beetroots for 10-12 minutes, or until tender. Drain the beetroots and leave to cool, then peel.
Bring a large pan of salted water to the boil, add the carrots and cook for 2-3 minutes, then drain.
Heat a large frying pan and add the butter, when foaming add the beetroots, carrots and kale. Cook for 2-3 minutes.
Leave the chicken to rest covered in foil. Strain the liquid left in the casserole into a saucepan and reduce over a medium heat until you have the consistency of gravy.
Carve the chicken and place on plates with the vegetables. Pour over the gravy and serve.


Privacy Policy for COURSEC
Preamble
In recognition,- that the usage of COURSEC Application (“app” OR “application”) necessitates sharing of information including but not limited to personal data, location, educational, device software/hardware specifications (“information”, unless contrary to the context) of the user(“you”) with the app;
- that as part of the use of the app you may upload files including but not limited to academic notes, excerpts of books, classroom lectures (audio/video), syllabus, course modules, snippets, charts, diagram, (“content”) that the app and its administrators (“us”, “we”) understand the sensitivity of the information and content provided by you and the potential misuse to which the same can be subjected to;
- that we are bound both under the relevant statutes and our commitment to protect information and content from potential misuse;
- that the requirement for disclosure and that you should be knowledgeable of the uses and purposes the information is, might or in future may be, put to;
AND IN FURTHERENCE OF ALL ABOVE MENTIONED This document sets forth the Privacy Policy (“policy” OR “the policy”) of the app and lays down the practices and procedures of governing the sharing and use of information provided by you to the app.
Objective and Purpose
The principal activity on the app involves sharing of the content uploaded by you in course of which information provided may also be available to other users, us and parties affiliated with the app. The purpose of the policy is to apprise you of the app’s usage of information and content provided you. In fulfilment of the same we encourage you to carefully read the policy and understand the terms of usage vis-à-vis the information and content provided to the app. By use of the app you agree to consent to the practises and uses described here regarding the information and content. You further undertake to agree to the changes and revisions that may be made by us in the policy as and when the need for the same arises and that no separate consent for the same will be required or asked for by you.
Policy on Information
- Collection
- user name;
- e-mail address
- Google and/or Facebook Login; (including profile picture, if any)
- Institute/school/coaching/college/university name;(in which you are enrolled currently) location;(residential address/city/pincode)
- any other information that may be required and from time to time.
- Uses
- Collection
- Uses
Use of the app necessitates your sharing of certain information in order to help us serve you and for a better experience in course of use of the app. This information is collected as part of the “Sign Up” done at the time of first registration on the app.
Generally, the information provided is used primarily for the purpose of providing you a distinct identity for a better experience during your use of the app.
The e-mail address provided will be used for authenticating user during registration.
The Gmail and/or Facebook account access is used as Login ID which is saved for future use of the app by you. By providing us Gmail and/or Facebook account access you agree to share information associated with such account including profile/display picture, if any, on such account.
Location/institute/school/coaching/college/university name is used as personally identifiable information.
During your use of the app the information provided by you is accessible and/or visible to other users of the app in form of “user profile” associated with your account with the app.
Upon deactivation of account/uninstallation of app/deletion of the user profile the information provided to us may remain intact in our servers for a period of time and may be used for future interaction between you and the app.
Policy on Content
The primary activity on the app involves sharing of content provided by you with other users. The app enables you to share content including but not limited to notes, question papers, e-books in the file formats .docx,.pdf,.png,.jpeg,.ppt.` The content in the form as described above is uploaded by you through the registered account created via “sign up” process of the app.
The content provided by you may be accessed, viewed and downloaded by other users of the app. The app has minimum control on the manner such content may be used by the other users. In this regard we owe no liability on account of any loss, monetary or otherwise, suffered by you on account of any such use by any other user of the app. Once the content is uploaded by you the same is saved in the servers of the app. We reserve the right to use, delete or modify the content or employ it for any other purposes at discretion. The content does not get removed from the servers on event of deletion of content by user, deletion of the account or uninstallation of the app from device by you and remains available for viewing, accessing and downloading by other users or for any other purposes by us.
Third Parties
On being redirected to another website, web-page, app etc the respective privacy policy of such website, webpage or app will govern the use by you and therefore the same should be carefully read and consulted by you It is the firm policy of the app to not to share information provided by you with any third party except in the manner provided by this policy reviewed and updated from time to time. In cases not provided by this policy sharing of information with third parties will be subject to permission in this behalf provided by you to us.
Disclosure
We reserve the right to disclose the information and content without any prior permission in cases including but not limited to:
- order/injunction/request from any Court;
- order/request from any law enforcement agency;
- request of other users or persons, on proper consideration of circumstances;
- on our discretion in event of any extra-ordinary circumstance.
Redressal/Contact Us
In case of any complaint, grievance, clarification, request you may contact us at:
Privacy Officer,
coursec.in@gmail.com


Saving your work ...
Saving your work first ...
Anthony
Make Divelist
Learn Dives
Springboard
Dive Group
All Groups
Forward
Back
Reverse
Inward
Twist
Performed within
Anytime
1 Month
Experience level
Known well
Learning
Don't know
Find dive
Sort by
Predicted score (highest first)
Predicted score (lowest first)
Dive ID (001 first)
Dive ID (5434 first)
Date last performed (most recent first)
Date last performed (oldest first)
Untitled Divelist
Save
Export
New List
Load...
Select dives from the database on the left, or
autogenerate a divelist based on:
Highest predicted score »
Most practiced dives »
Most recently performed dives »
View as:
List
Chart


In my opinion, ray casting is a beautiful concept that is not that hard to grasp, but the quality resources are rare. We will learn the math behind it so you can implement it in your future projects with ease. I will try to make it as comprehensible as possible, explain all the caveats and issues you may stumble upon. We will also talk about optimization and how can spatial hash maps significantly help you. I will also provide some basic live examples for you to try out. Please note that demos were written to be as simple as possible, do not expect enterprise-grade code - we only learn about the concept, not the implementation.
Well, it does not tell us much, does it? Let me simplify that. Ray casting is a fundamental and popular technique used to determine the visibility of specific objects (polygons) by tracing rays from the eye (for instance, player’s hero) on every pixel (well, not quite in our case - more on that later) and finding the nearest intersections with objects.
Ray casting has many uses, especially in three-dimensional space. I outlined three, in my opinion, the most important, which are commonly used in 2D game engines:
The most well-known game that used this technique is Wolfenstein 3D. Rays were traced to determine the closest objects, and their distance from the player position was used to appropriately scale them.
PIP problem asks whether a given point lies inside, outside, or on the boundary of a polygon. Using the ray casting algorithm, we can count how many times the point intersects the edges of the polygon. If the number of the intersections is even, the point is on the outside of the polygon. If the number of the intersections is odd, the point is on the inside or on the boundary of a polygon.
This is the problem we will specifically tackle in this article - determining which objects are visible by the player and illuminating the visible area.
In this section we will go through basics such as calculating intersection points, casting rays, sorting intersection points to illuminate the visible area, and few words about circles. I will provide interactive demos at each stage so you do not get lost and see the results immediately.
It is all about those intersection points. Let's learn step by step how to find them and how to use them. We will derive a line parametric equation first, calculate intersection points and finally learn how to determine which one of them is the closest efficiently.
Let us talk about lines and their parametric equation first.
We can express vector \(\overrightarrow{AP}\) by the following equation: \(\overrightarrow{AP} = t\overrightarrow{AB}\), where \(t\) is an equation parameter defining how much do we stretch (\(|t| > 1\)) or shrink (\(|t| < 1\)) and if we flip the direction (\(t < 0\)) of vector \(\overrightarrow{AP}\) in relation to vector \(\overrightarrow{AB}\).
Let me show you few examples:
As you might have noticed, we can use \(t\) as a scale factor: \(|AP| = |t||AB|\). We will use that fact when determining the closest intersection point.
Now we can easily see, that if we want the point to be contained on:
Having all of that sorted out, we can finally derive the parametric equation:
\[
\begin{align}
\overrightarrow{AP} &= t \overrightarrow{AB} \\
P - A &= t (B - A) \\
P &= t(B - A) + A \\
\end{align}
\]
If you still do not know what happens here, I can recommend an awesome short lecture by Norm Prokup: Parametrizing a Line Segment - Concept.
Assume that point \(P\) is the intersection point of line-segment defined by points \(A\) and \(B\), and ray defined by points \(C\) and \(D\). Point \(P\) is then expressed by set of two equations: \[ \left\{\begin{align} P &= s(B - A) + A\text {, where } 0 \leq s \leq 1 \text{, and} \\ P &= r(D - C) + C\text {, where } r \geq 0 \text{.} \end{align}\right. \]
Solve for \(s\) and \(r\): \[ \left\{\begin{align} s(B_x - A_x) + A_x &= r(D_x - C_x) + C_x \Rightarrow s = \tfrac{r(D_x - C_x) + (C_x - A_x)}{B_x - A_x} \\ s(B_y - A_y) + A_y &= r(D_y - C_y) + C_y \Rightarrow r = \tfrac{s(B_y - A_y) + (A_y - C_y)}{D_y - C_y} \end{align}\right. \]
Substitute \(s\) into the second equation: \[ \begin{align} &\tfrac{r(D_x - C_x) + (C_x - A_x)}{B_x - A_x} (B_y - A_y) + A_y = r(D_y - C_y) + C_y \\[10pt] &r \tfrac{(D_x - C_x)(B_y - A_y)}{B_x - A_x} + \tfrac{(C_x - A_x)(B_y - A_y)}{B_x - A_x} + A_y = r(D_y - C_y) + C_y \\[10pt] &r (\tfrac{(D_x - C_x)(B_y - A_y)}{B_x - A_x} - (D_y - C_y)) = (C_y - A_y) - \tfrac{(C_x - A_x)(B_y - A_y)}{B_x - A_x} \\[10pt] &r \tfrac{(D_x - C_x)(B_y - A_y) - (D_y - C_y)(B_x - A_x)}{B_x - A_x} = \tfrac{(C_y - A_y)(B_x - A_x) - (C_x - A_x)(B_y - A_y)}{B_x - A_x} \\[10pt] &r = \tfrac{(C_y - A_y)(B_x - A_x) - (C_x - A_x)(B_y - A_y)}{(D_x - C_x)(B_y - A_y) - (D_y - C_y)(B_x - A_x)} \\[10pt] &r = \tfrac{(B_x - A_x)(C_y - A_y) - (C_x - A_x)(B_y - A_y)}{(D_x - C_x)(B_y - A_y) - (B_x - A_x)(D_y - C_y)} \\[10pt] \end{align} \]
Substitute \(r\) into the first equation: \[ \begin{align} &s(B_x - A_x) + A_x = \tfrac{s(B_y - A_y) + (A_y - C_y)}{D_y - C_y} (D_x - C_x) + C_x \\[10pt] &s(B_x - A_x) + A_x = s \tfrac{(B_y - A_y)(D_x - C_x)}{D_y - C_y} + \tfrac{(A_y - C_y)(D_x - C_x)}{D_y - C_y} + C_x \\[10pt] &s (\tfrac{(B_y - A_y)(D_x - C_x)}{D_y - C_y} - (B_x - A_x)) = (A_x - C_x) - \tfrac{(A_y - C_y)(D_x - C_x)}{D_y - C_y} \\[10pt] &s \tfrac{(B_y - A_y)(D_x - C_x) - (B_x - A_x)(D_y - C_y)}{D_y - C_y} = \tfrac{(A_x - C_x)(D_y - C_y) - (A_y - C_y)(D_x - C_x)}{D_y - C_y} \\[10pt] &s = \tfrac{(A_x - C_x)(D_y - C_y) - (A_y - C_y)(D_x - C_x)}{(B_y - A_y)(D_x - C_x) - (B_x - A_x)(D_y - C_y)} \\[10pt] &s = \tfrac{(A_x - C_x)(D_y - C_y) - (D_x - C_x)(A_y - C_y)}{(D_x - C_x)(B_y - A_y) - (B_x - A_x)(D_y - C_y)} \\[10pt] \end{align} \]
Having \(s\) and \(r\) calculated, we can calculate \(P\) using one of the equations from the set.
We only need the closest intersection point to properly draw the visible area. The naive solution would be to calculate distances between the ray starting point and intersection points using the Pythagorean Theorem: \(\sqrt{(C_x - P_x) ^ 2 + (C_y - P_y) ^ 2}\). Remember the line equation parameter, though? I have already mentioned that we can use it as a scale factor. As we want to compare distances on ray, we can check for the smallest \(r\) parameter value: \(|\overrightarrow{CP_1}| < |\overrightarrow{CP_2}| \Leftrightarrow |r_1| < |r_2|\).
In the following section we will go through two different ways rays might be cast. We will compare them and mention their pros and cons.
First way is to cast rays in all directions by specified offset angle. For instance, we could cast 30 rays in total offseted by \(12^\circ\). Let's see how to generate all those rays first.
Let \(P_1 = (x_1, y_1)\) be an anchor point of our rays, and let \(P_2 = (x_2, y_2)\) be a some point on a line going through \(P_1\) at angle \(\phi\):
We can define \(x_2\) as \(x_1 + dx\) and \(y_2\) as \(y_1 - dy\) (our y-axis is inverted hence why the minus sign).
Now we need to derive formulas for \(dx\) and \(dy\):
\[
\left\{\begin{align}
\sin(\phi) &= \tfrac{dy}{\mathit{dist}} \Rightarrow dy = \mathit{dist} * \sin(\phi) \\
\cos(\phi) &= \tfrac{dx}{\mathit{dist}} \Rightarrow dx = \mathit{dist} * \cos(\phi)
\end{align}\right.
\]
\(\mathit{dist}\) in our case has an arbitrary (greater than 0) value (we are looking for any point on the line), so we are safe to assume \(\mathit{dist} = 1\) to simplify the calculations. Having it all considered, \(P_2 = (x_1 + \sin(\phi), y_1 - \cos(\phi))\), where \(\phi\) is our angle offset.
Casting rays on vertices is most likely your go-to solution. Instead of casting rays in all directions, we can simply cast them on our polygons' vertices. Depending on the number of vertices, we can save computing power by not casting useless rays. In the next sections you will see how does it impact animation smoothness and also learn how to further optimize the whole process.
This is where the real fun begins. We will illuminate the visible area by filling a giant polygon.
To correctly order vertices to build a proper polygon, we need to sort them by angle first. We will use \(atan2(y, x)\) function for that. You can read more about it here.
Let's compare both ray casting methods:
Both of them looks glitchy, jumpy and inaccurate. Let's take a closer look why.
Notice what happens when rays are cast directly on vertices - they should go beyond that vertex but we are getting only the closest intersection point:
The most common solution is casting two extra rays offseted by small angle (in both directions) for every cast ray. Consider ray \(AB\) starting at \(A = (A_x, A_y)\) going through \(B = (B_x, B_y)\). We want to find such point \(C = (C_x, C_y)\) that ray \(AC\) would be rotated by \(\phi\) with \(A\) being the origin point. \(C\) coordinates would be as follow:
\[
\left\{\begin{align}
C_x &= (B_x - A_x)\cos(\phi) - (B_y - A_y)\sin(\phi) + A_x \\
C_y &= (B_y - A_y)\cos(\phi) + (B_x - A_x)\sin(\phi) + A_y
\end{align}\right.
\]
Note that we do not need to do it for the first method - simply add or substract the offset from the angle we are calculating from.
For further explanation you can check this article.
Let's see how the illumination behaves after changes:
It did not help much for the first method. We could decrease angle offset (hence increase number of rays) but the result will still be poor. On the other hand, the second method looks very smooth and accurate. From now on, we will not be talking about the first method anymore.
We may want to somehow limit player's visibility. We can achieve that by creating a clipping region of desired shape. In the demos below, I used a CanvasRenderingContext2D.clip() method.
As you might have noticed, there is no optimization whatsoever - we are still calculating all the intersection points. We will get back to it once we learn about spatial hashmaps.
I have rarely seen a real use-case scenario for ray casting on circles. Please treat this section as an extra where I only briefly talk about it. I will provide you with equations and basic demos, the rest is up to you.
Let \(P\) be an intersection point, \(A\) a ray's anchor point, \(B\) a point on the ray, \(C\) a circle's center point and \(r\) a circle's radius. \[ \left\{\begin{align} P_x &= t(B_x - A_x) + A_x \\ P_y &= t(B_y - A_y) + A_y \\ r ^ 2 &= (P_x - C_x) ^ 2 + (P_y - C_y) ^ 2 \end{align}\right. \] Solve for \(t\): \[ \begin{align} r ^ 2 &= P_x ^ 2 - 2P_xC_x + C_x ^ 2 + P_y ^ 2 - 2P_yC_y + C_y ^ 2 \\ r ^ 2 &= (t(B_x - A_x) + A_x) ^ 2 - 2(t(B_x - A_x) + A_x)C_x + C_x ^ 2 \\ &+ (t(B_y - A_y) + A_y) ^ 2 - 2(t(B_y - A_y) + A_y)C_y + C_y ^ 2 \\ r ^ 2 &= t ^ 2 (B_x - A_x) ^ 2 + 2t(B_x - A_x)A_x + A_x ^ 2 - 2t(B_x - A_x)C_x - 2A_xC_x + C_x ^ 2 \\ &+ t ^ 2 (B_y - A_y) ^ 2 + 2t(B_y - A_y)A_y + A_y ^ 2 - 2t(B_y - A_y)C_y - 2A_yC_y + C_y ^ 2 \\ 0 &= t ^ 2 ((B_x - A_x) ^ 2 + (B_y - A_y) ^ 2) \\ &+ 2t((B_x - A_x)A_x - (B_x - A_x)C_x + (B_y - A_y)A_y - (B_y - A_y)C_y) \\ &+ A_x ^ 2 - 2A_xC_x + C_x ^ 2 + A_y ^ 2 - 2A_yC_y + C_y ^ 2 - r ^ 2 \\ 0 &= t ^ 2 ((B_x - A_x) ^ 2 + (B_y - A_y) ^ 2) \\ &+ 2t((B_x - A_x)(A_x - C_x) + (B_y - A_y)(A_y - C_y)) \\ &+ (A_x - C_x) ^ 2 + (A_y - C_y) ^ 2 - r ^ 2 \end{align} \] Solve the quadratic equation: \[ \left\{\begin{align} a &= (B_x - A_x) ^ 2 + (B_y - A_y) ^ 2 \\ b &= 2((B_x - A_x)(A_x - C_x) + (B_y - A_y)(A_y - C_y)) \\ c &= (A_x - C_x) ^ 2 + (A_y - C_y) ^ 2 - r ^ 2 \\ \Delta &= b ^ 2 - 4ac \end{align}\right. \]
Only if \(\Delta = 0\): \[ \begin{align} t = \tfrac{-b}{2a} \end{align} \] Only if \(t \geq 0\): \[ \left\{\begin{align} P_x &= t(B_x - A_x) + A_x \\ P_y &= t(B_y - A_y) + A_y \end{align}\right. \]
Only if \(\Delta > 0\): \[ \left\{\begin{align} t_1 &= \tfrac{-b -\sqrt{\Delta}}{2a} \\ t_2 &= \tfrac{-b +\sqrt{\Delta}}{2a} \\ \end{align}\right. \] Only if \(t_i \geq 0\): \[ \left\{\begin{align} P_{i_x} &= t_i(B_x - A_x) + A_x \\ P_{i_y} &= t_i(B_y - A_y) + A_y \end{align}\right. \]
We need to find two tangent lines to a given circle passing through a ray anchor point.
Let \(P_i\) be tangent points, \(A\) a ray's anchor point, \(C\) a circle's center point and \(r\) a circle's radius.
We will also be moving all points using translation vector \(\overrightarrow{v} = (-C_x, -C_y)\): \(X^\prime = X + \overrightarrow{v}\), so the circle's center is at \((0,0)\).

\]
Only if \(\Delta = 0\): \[ \left\{\begin{align} P_y ^ \prime &= \tfrac{-b}{2a} \\ P_x ^ \prime &= \tfrac{r ^ 2 - P_y ^ \prime A_y ^ \prime }{A_x ^ \prime} \end{align}\right. \] \[ \left\{\begin{align} P_x &= P_x ^ \prime + C_x \\ P_y &= P_y ^ \prime + C_y \end{align}\right.  \]
There is still one issue - it will not work if \(A_x ^ \prime = 0\).
Take a closer look at the following equation: \(r ^ 2 = P_x ^ \prime A_x ^ \prime + P_y ^ \prime A_y ^ \prime\).
If \(A_x ^ \prime = 0\), the equation becomes: \(r ^ 2 = P_y ^ \prime A_y ^ \prime\) - we cannot substitute \(P_x ^ \prime\) anymore.
 \]
Only if \(\Delta = 0\): \[ \left\{\begin{align} P_x ^ \prime &= \tfrac{-b}{2a} \\ P_y ^ \prime &= \tfrac{r ^ 2}{A_y ^ \prime} \end{align}\right. \] \[ \left\{\begin{align} P_x &= P_x ^ \prime + C_x \\ P_y &= P_y ^ \prime + C_y \end{align}\right. \]
Only if \(\Delta > 0\): \[ \left\{\begin{align} P_{1_x} ^ \prime &= \tfrac{-b -\sqrt{\Delta}}{2a} \\ P_{2_x} ^ \prime &= \tfrac{-b +\sqrt{\Delta}}{2a} \\ P_{i_y} ^ \prime &= \tfrac{r ^ 2}{A_y ^ \prime} \end{align}\right. \] \[ \left\{\begin{align} P_{i_x} &= P_{i_x} ^ \prime + C_x \\ P_{i_y} &= P_{i_y} ^ \prime + C_y \end{align}\right. \]
Note that we can do the same for \(A_y ^ \prime = 0\), however, it is optional.
If \(A_x ^ \prime = A_y ^ \prime = 0\), there are no solutions.
In this section, we will discuss the usage of spatial hashmaps and modified Bresenham's line algorithm. I will not go into implementation details as they are commonly available on the Internet. I will, however, provide you with some demos to try these out and come up with your own ideas on where to use them.
Currently, we are drawing all polygons and calculating all intersection points, but it is pretty much useless. In most cases, our play area will be much bigger than the viewport. By using spatial hashmaps, we can quickly determine which polygons are visible to the player and perform adequate calculations.
Basically, we want to divide the play area into smaller cells (of predefined size). Each cell consists of a list containing our shapes (most likely line-segments). If a single shape spans across multiple cells, it will be included in all of them.
The name of this technique suggests using hashmaps (eg. cells would be named something like X+":"+Y), but in our case, using a simple 2D array might be more desired.
Here is a simple demo showing how it might work:
We can use them for viewports as mentioned previously, and also visibility circles and flashlights.
Well, it is high time we did something with finding the closest intersection points. Using spatial hashmaps and modified Bresenham's line algorithm, we can traverse the grid in an efficient manner making as few checks as required. The algorithm should stop when the first cell with an intersection point is found.
You can read more about Bresenham's line algorithm here, and its modified version here.
I think I have covered everything to help you get started. I will try my best to expand it in the future if I spot something needing an additional explanation. I have also created a little cheatsheet for you to quickly recap some of the topics and derived formulas.
If you enjoyed the read be sure to star and watch this repository on GitHub. You might also want to follow me for more content like that in the future. Also do not forget to create an issue if one of the topics seems to be poorly explained or you have other suggestions.
Stay tuned for more!


GENmeTHAT
No language stated.
You didn't choose a language, please select one.
okay
Generate names!
Select a language
Get


To make images resize responsively to page width, you can add the class responsive-img
to your image tag. It will now have a max-width: 100%
and height:auto
.
Media can be styled in different ways using Materialize.
menu
cloud
edit
To make images appear circular, simply add class="circle"
to
them

This is a square image. Add the "circle" class to it to make it appear circular.

If your video does not have video controls, add the no-controls
class to the video container.


Try out our Premium Member services: Virtual Legal Assistant, Query Alert Service and an ad-free experience. Free for one month and pay only if you like it.
9, 10 & 11 * IN THE HIGH COURT OF DELHI AT NEW DELHI Pronounced on 16th January, 2009 + W.P. (C) 7516/2007, W.P. (C) 7517/2007, W.P. (C) 7605/2007 W.P. (C) 7516/2007 REGENT AUTOMOBILES P.LTD. W.P. (C) 7517/2007 MULTAN AUTOMOBILE ENGINEERS W.P. (C) 7605/2007 FLYING FASHIONS ..... Petitioners Through : Mr. Dinesh Agnani with Ms. Leena Tuteja, Advocate. versus GOVT. OF N.C.T. OF DELHI THR. SECRETARY & ORS. ..... Respondents CORAM: HON'BLE MR. JUSTICE S. RAVINDRA BHAT 1. Whether the Reporters of local papers Yes may be allowed to see the judgment? 2. To be referred to Reporter or not? Yes 3. Whether the judgment should be Yes reported in the Digest? S.RAVINDRA BHAT, J. (ORAL)
1. These Writ Petitions were heard together, with consent of the counsel for the parties as they involved common questions of fact and law. WP (C) 7516, 7517 & 7605/07 Page 1 of 13
2. All the petitioners claim to be aggrieved by the directions issued by the Joint Commissioner of Industries acting on behalf of the Commissioner (the 2nd respondent and 3rd respondent, hereafter referred to collectively as 'the Commissioner'), requiring them to furnish bank guarantees for specified amounts.
3. Briefly the facts are that the petitioners are industrial units engaged in manufacture. In one case (WP (C) 7605/07), the petitioner is involved in garment manufacture; in the other two cases, the petitioners deal in automotive parts. All of them claim that the respondents are an "appropriate authority" for the purpose of collecting apportionment cost of Common Effluent Treatment Plant (hereafter referred to as „Plant‟). Their averments are that a Common Effluent Treatment Plant Society was formed in 1996 to achieve the objective of setting up of plants and their administration. The Society sets up plants in various industrial areas and apportions costs from its members. The petitioners contend that the measures taken by the respondents are part of the cleaning up process of the environment including cleaning effluents in the Yamuna River.
4. As a result, the National Capital Territory of Delhi enacted the Delhi Common Effluent Treatment Plants Act, 2000 (hereafter „the Act‟) with the object of recovering dues towards setting up of such plants in Industrial estates. The petitioners refer to various provisions of the Act concerning setting up of an appropriate authority, its functions and the powers vested in WP (C) 7516, 7517 & 7605/07 Page 2 of 13 it to issue orders and directions. They also refer to Rules framed in 2001 (hereafter „the Rules‟) under the Act prescribing the formula for apportionment of plants and their maintenance.
5. The petitioners complain that the costing method adopted by the authority is never transparent and has been arbitrary. Thus the Society has been charging Rs. 100/- per sq. mt. together with ad hoc amounts depending on the size of the industrial unit. It is alleged that the petitioners have made complete payment towards apportionment of costs and have also complied with all further demands by the society. They advert to installation of effluent treatment plants in view of their business activities. They contend about various inspections by the Commissioner from time to time; and that as and when any deficiency in regard to maintenance of the plant was pointed out, they were rectified. In the circumstances, they now impugn the order dated 27.9.07, which refers to a visit by a joint inspection team on 10.8.2007 to their premises and further alleges that irregularities were noticed in regard to the observance of parameters and norms for polluting industries. After giving notice, to which the petitioners replied, the respondents directed them to furnish bank guarantees for various sums. In W.P. (C) 7605/07, the amount of bank guarantee sought for is Rs. 5 lakhs; in W.P. (C) 7517/07 it is Rs. 3 lakhs and in W.P. (C) 7516/07, it is Rs. 5 lakhs.
6. The petitioners contend that the directions to furnish bank guarantees for specific amounts are without any legal authority and in any event based WP (C) 7516, 7517 & 7605/07 Page 3 of 13 on utterly vague premises. It is submitted that if there was violation of any norms, they could have been visited with consequences spelt out under the Act or under other laws such as, Water (Prevention and Control of Pollution) Act; Air (Prevention and Control of Pollution) Act; or the Hazardous Wastes Act. The petitioners contend that the provisions of the Act do not empower the CEPT Society or the respondents to issue vague or open-ended directions of the kind impugned in this case. All that the respondents are empowered to do in case of non-compliance with the provisions, is to levy penalty upon the errant unit, after holding appropriate enquiry as is deemed necessary. It is claimed that the power to issue directions has to be exercised reasonably and not contrary to express provisions of the Act.
7. The respondents contend that the Act empowers the authorities to seek information under Section 8 of the Act; the authorities are also enabled to enter and inspect the premises by virtue of Section 9. Section 16 prescribes that the authority can give appropriate directions. It is contended that these provisions are sufficient pointers to the respondents‟ amplitude of powers, which extend to issuing directions to the concerned Unit, to furnish bank guarantees.
8. It was contended during the hearing that the surveys conducted by the Delhi Pollution Control Committee (DPCC) showed that many Units were discharging effluents directly in to the conveyance system without pre- treatment resulting in high Bio-Oxygen Demand and Chemical Oxygen WP (C) 7516, 7517 & 7605/07 Page 4 of 13 Demand. This was also corroborated in the analysis report of the CETP Plant. A joint inspection team visited the premises of various units. This inspection and survey of 25 units disclosed that 17 of them were operating without plant and the sludge they were supposed to maintain were missing. Those plants were given show cause notices, replies to which were found unsatisfactory. On account of these facts, the impugned directions were issued.
9. The above discussion would show that the controversy between the parties pertains to the impugned directions issued by the respondents, requiring the petitioners to furnish bank guarantees for various determined amounts. The impugned orders are in identical format except so far as the amounts are concerned. One such order made in the case of petitioner in W.P. 7605/07 is extracted below: -
"1. Whereas, during the visit of Joint Inspection Team on 10.8.07 at the premises of M/s. FLYING FASHIONS certain irregularities were noticed, that of non-observance of parameters/norms prescribed for such polluting industries for pre-treating of effluent and other violations as communicated vide Notice No.1029 dated 13.8.2007. 2, Whereas, the said occupier has filed written reply on 21.8.2007 explaining the reasons etc. After carefully going through the documents submitted by the occupier, the reasons/facts have been found vague/unsatisfactory as such no remedial measures were promised to observe the parameters of Pollution Control Authorities as well as provisions of CETP Act & Rules.
"It is pertinent to mention here that under article 21 of the Constitution of India the wholesome environment is the fundamental right of every citizen which needs a right living atmosphere congenial to human existence as interpreted by the WP (C) 7516, 7517 & 7605/07 Page 5 of 13 Hon'ble Supreme Court". Moreover toxic pollutants cannot be gifted to the public at the cost of others benefit.
3. Therefore, the undersigned as per powers conferred upon him under Section 16 of the CETP Act 2000 read with Rule 10 of CETP Rules 2001 now issues following direction in connection with the said notice dated 13.8.2007.
(I) That, the pre-treatment of the effluent should be as per the prescribed parameters by way of operating the apparatus/ETP installed at the premises regular non- operation is resulting higher level of BOD, COD & TDS etc. at the CETP, which is difficult to control without pre- treatment before discharging the effluent into the Conveyance System by the occupiers.
(II) That, no effluent should be directly discharged into the main sewer line other than the conveyance system. (III) That, O&M charges must be paid by the occupier to the CETP Society regularly.
(IV) That, hygienic working conditions must be maintained for & non skilled/workforce as per labour Laws.
(V) That, the sludge should be stored in sealed containers and must ensure of the proper stock of the Chemicals.
(VI) That, there should be proper dosing of the chemical in the pretreatment process so that parameters are met in the Analysis report.
(VII) That, only qualified operators should be engaged to operate the apparatus/ETP and a proper logbook be maintained about working hours & sludge generated. (VIII) That, quarterly returns must be filed by the occupier to the Appropriate Authority filing all the information correcting & timely.
(IX) That, as a guarantee to observe the above mention conditions, a bank guarantee of Rs. 5,00,000/- (Five Lakhs only) should be executed by the said Occupier in the name of "the President of India" through Secretary-cum- Commissioner, Department of Industries Govt. of Delhi valid for 2 years to be submitted to the Appropriate WP (C) 7516, 7517 & 7605/07 Page 6 of 13 Authority within 10 days from the issue of this letter. In case of non-compliance, directions issued on 13.8.2007 will be made confirmed and the Authorities will be requested for disconnection of electricity and water of the said defaulter."
10. The petitioners contend that provisions of the Act do not enable or empower the respondents to issue such directions; the respondents assert that it does. It would, in the circumstances, be necessary to discuss some of its provisions and also extract the relevant provisions of the Act. The Delhi Common Effluent Treatment Plants Act was enacted in the year 2000. Its avowed objects are to provide for recovery of dues - in respect of capital and recurring cost of Common Effluent Treatment Plants set up in industrial estates - as arrears of land revenue. Section 2 (2) defines "appropriate authority" as Commissioner of Industries or such other officer not below the rank of Joint Director; Section 2 (3) states that „CETP‟ means Common Effluent Treatment Plant. By Section 3 an obligation is cast on the industrial estates, either themselves or with one or more industrial estates in Delhi, to constitute a registered CETP Society, duly approved by the appropriate authority, to set up and operate a CETP Plant for the participating Units.
Section 6 defines the functions of the appropriate authority; the main function is to recover any unpaid dues from occupier(s), to ensure the proper setting up operation and maintenance of CETPs in Delhi. These functions include the apportionment of cost amount from occupiers, recoveries of dues from such persons and taking other steps towards achieving the object of the WP (C) 7516, 7517 & 7605/07 Page 7 of 13 Act. Section 7 provides for levy and collection of apportioned costs. Sections 9, 11, 16, 17 and 18 read as follows: -
"9. Power of entry and inspection - Subject to the provisions of this clause, any person empowered by the appropriate authority in this behalf shall have a right at any time to enter with such assistance as he considers necessary any place for the purpose of performing any of the functions of the appropriate authority as may be prescribed in rules.
11. Penalty for non-payment within the specified time - If any amount payable by any person is not paid within the date specified in the order it shall be deemed to be in arrears and the appropriate authority may after such inquiry as it deems fit, impose on such person a penalty not exceeding the amount in arrears.
16. Power to give directions - Notwithstanding anything contained in any other law, but subject to the provisions of this Act, the appropriate authority may, in exercise of its powers and performance of its functions under this Act, issue any directions in writing to any occupier, society, person, officer or authority, and such occupiers, society, person, officer or authority shall be bound to comply with directions.
Explanation - For the avoidance of doubts, it is hereby declared that the power to issue directions under this Clause includes the power to direct -
(a) the closure, prohibition or regulation of any industry, establishment, operation or process; or
(b) the stoppage or regulation of supply of electricity, water orany other service.
17. Failure to comply with directions - (1) Whoever fails to comply with the directions given under sub clause (2) or sub-clause (3) of clause 8 within such time as may be specified in the direction shall be liable to pay a penalty which may extend up to ten thousand rupees and in case the failure continues, with an additional penalty which may extend up to five hundred rupees for every day during which such failure continues after the imposition of the penalty of the first such failure.
(2) Whoever fails to comply with any direction issued under clause 15 shall, in respect of each such failure, be liable to pay a penalty WP (C) 7516, 7517 & 7605/07 Page 8 of 13 which may extend up to thirty thousand rupees and in case the failure continues, with an "additional penalty which may extend up to five thousand rupees for e very day during which such failure continues after the first such failure.
18. Penalty for certain acts - whoever-
(a) Obstructs any person acting under the orders or directions of the appropriate authority from exercising his powers and performing his functions under this Act; or
(b) Fails to furnish to any officer or other employee of the appropriate authority any information required by him for the purpose of this Act; or
(c) In giving any information, which he is required to given under this Act knowingly or willfully makes a statement, which is false in any material particular.
Shall be liable to pay a penalty, which may extend up to five thousand rupees. "
11. Section 19 provides for residual penalty for contravention of certain provisions of Act and Section 20 specifically enacts for contravention by Companies. But for Section 16 it can be argued that the entire range of sanctions including penalties have been specifically provided by various provisions such as Section 11, 18, 19 & 20. The question, therefore, is - whether the general power to issue directions comprehends the power to require bank guarantees to be furnished.
12. Now, there is no doubt that the Act enables the authorities set up under it to supervise and regulate plants and mandate best practices for avoidance of water pollution. The scheme of the Act and its preambular declaration clearly point to the respondent authorities‟ WP (C) 7516, 7517 & 7605/07 Page 9 of 13 power extending towards setting up of CETP Societies, installation of plants and apportionment of costs and their recovery. Section 8 (2) entitles the appropriate authority to direct a person who in its opinion is discharging effluents to give such information in such form as may be specified in the directions for the purpose of enabling the appropriate authority to perform the functions conferred on it by or under the Act. The power to issue directions, includes the power to close, or prohibit or regulate any industry, establishment, operation or process; or to stop or regulate the supply of electricity, water or any other service.
13. In this context, it will be also useful to consider Rule 10 of Delhi Common Effluent Treatments Plants Rules, 2001, which states as follows: -
"10. Directions
(i) Any direction issued by the appropriate authority under the Act/rules shall be in writing.
(ii) The direction shall specify the nature of action to be taken and the time within which it shall be complied with by the person/occupier, officer or the authority to whom such direction is given.
(iii) When the direction/order is for the closure/sealing/auction of an industry, process or operation or stoppage or regulation of electricity or water or any other service affecting the carrying on any industry, operation or process and issued to an officer or an authority, a copy of the direction shall also be endorsed to the occupier of the premises/industry, operation or process, as the case may be and objections, if any, filed by the occupier with an WP (C) 7516, 7517 & 7605/07 Page 10 of 13 officer designated in this behalf shall be dealt with in accordance with the provisions of the Act.
Provided that no opportunity of being heard shall be given to the occupier if he has already been heard earlier and the directions for the stoppage or regulation of electricity or water or closure/sealing/auction of an industry was the resultant decision of the Government, appropriate authority or the appellate authority, as the case may be, after such earlier hearing."
14. It is an established rule of statutory interpretation that every provision, which confers a power should be construed in its own terms, enabling the authority the full range of options, which may naturally fall within it. (Asstt. Collector of Central Excise, Calcutta -vs- National Tobacco Co of India AIR 1972 SC 2563; Jamaluddin Ahmad -vs- Abusaleh Najmuddin 2003 (4) SCC 257); likewise the express grant of a certain kind of power implies, in cases, exclusion of other powers. This rule also iterates that everything necessary to carry out the purposes of the grant can be done by the authority entrusted with the power (Ref. State of U.P. -vs- Poosu, AIR 1976 SC 1750; State of Karnataka - vs- Vishwabharathi Housing Co-operative Society AIR 2003 SC 1043).
15. The petitioners‟ contention, though attractive that the power to issue directions cannot comprehend the issuance of directions to furnish guarantees, cannot be accepted. The power to issue directions, under Section 16 extends to "regulate" the industry or unit. The expression "regulate" in the context, wherever used, has to be given the widest meaning. In a remedial or regulatory enactment, as the Act WP (C) 7516, 7517 & 7605/07 Page 11 of 13 undeniably is, this expression acts as a crucial power conferral on the authorities - the extent of such power is even closure of the industry or unit. Such being the case, the court cannot limit the options available to statutory authorities to meet emerging challenges, towards ensuring compliance with the provisions. In given cases, the Commissioner may not deem it appropriate to take the extreme step of closing down the unit; yet, to ensure that good practices are put in place, he may issue specific directions, and as a measure to ensure compliance, require furnishing of guarantee, valid for a period, or as to enable him to invoke it, to remedy the harm, which is sought to be addressed by the Act or rules framed under it. In arriving at this conclusion, the overriding nature of Section 16, which begins with a non obstante clause, cannot be lost sight of.
16. The above analysis however, is not dispositive of these petitions. The authorities, in these cases, though clothed with the power to direct the petitioners to furnish guarantees, have however, not shown how and why such action was necessary. The show cause notice issued in each case, is stereotypical; it does not reflect what are, according to the authorities, infraction of standards or directions, which had to be remedied by the units. Crucially, the show cause notices, preceding the impugned orders did not even mention about the possibility of issuance of orders requiring bank guarantees to be furnished. Again, WP (C) 7516, 7517 & 7605/07 Page 12 of 13 similarly in the case of the impugned order, the list of matters to be done by unit(s) is general, not specific to the individual activity. Nor does it indicate application of mind to what exists on the site, and what is the standard required to be, but not complied. Although a meticulous and exacting standard cannot and should not be insisted by courts, while considering the validity of such orders, yet, the authority should point to some thinking vis-à-vis what exists at the unit, which requires remedying that in turn has to be conditioned by furnishing of a bank guarantee.
17. In view of the above discussion, the petitions have to be partly allowed. The challenge, on the ground of lack of power of the respondents, must fail; however, the impugned orders cannot, for reasons mentioned in the preceding paragraph, be sustained. They are accordingly quashed. No costs.
S. RAVINDRA BHAT (JUDGE) JANUARY 16, 2009 /vd/ WP (C) 7516, 7517 & 7605/07 Page 13 of 13


I.4 Building Development Acquisition
Acquisitions – Building Development (I.4.)
The acquisition
tasks for Building Development are very similar to the acquisition tasks for the Land Developer except that the
Building Developer must be focused on estimating the probabilities of leasing the building while it is under
construction as well as selling the property to a Building Operator.
Determine if the building-ready pad can
be acquired at a price that, when improved with the building, yields a required rate of return on total cost
(Rtc).
The Building Developer usually buys the finished lot with equity capital and intends to start
construction the day of closing! Consequently, creative financing is not that important. However, the Building
may negotiate certain terms in the purchase agreement that will prevent the Land Developer from impairing the
competitiveness and profitability of the project. For example, the following provisions may be appropriate:
- Restrict the Land Developer’s ability to sell lots to competitive projects for a certain period of time,
say three years, or until the newly constructed building reaches a certain occupancy level.
- Provide a “first right of offer” to the Building Developer when additional lots are offered for sale.
- Estimate the Building Operators purchase price (based on overall capitalization rates) as well possible
holdback that may be a condition of the sale. The Building Developer needs to pay off the construction loan at
the time of sale so the hold backs cannot be too restrictive.
Determine if the building can be competitively bid by contractors and sub-contractor.
- Building developers usually have preferred general contractor and major sub-contractors. The
availability of these firms is a critical determinant of when or if the Building Developer decides to
acquire the building pad.
- Current pricing of the construction project is imperative because the Building Developer may be using old or
inaccurate building costs estimates.
Determine if the property be pre-leased or leased up during construction.
- The best way for a Building Developer to create value is by pre-leasing the Building or leasing it up
during construction.
- The Building Developer needs to understand the leasing market and develop a strategy to secure competitive
leases
Estimate if the current market conditions improve or remain steady during construction and lease-up
- If the current market conditions are good, how long will they last?
- If the current market conditions are bad, when will they change? We always recognize market bubbles after they
occur, when it is too late to act.
- The Building Development period needs to include the pre-construction time, the building
construction time, and the expected lease-up period.
Determine the expected “spread” sufficient to justify the risk.
- Does the expected return justify the risks involved in the Building Development?
- The value created must be greater than the cost of the project so that the profit or spread is reward for the
risk-taking.
Estimate the capital requirements of the Building Development.
- The building developer need determine:
- how much capital is needed (uses of funds)
- who can provide the capital (sources of funds)
- how long the capital is needed (investment duration)
- Equity investors are needed to acquire the finished building lot and to fund cash flow deficits during the
construction and lease-up period. These are usually the soft costs.
- Construction loans are needed to fund as much of the direct construction costs (the hard costs) as
possible
- Construction loan extensions, often called mini-perms,” are useful to manage the lease-up risks.


--- layout: post title: How to use hardware monitors with NetBSD ---
Today, there are various environmental sensor ICs available on modern mainboards, which are able of monitoring fan speed, cpu and system temperature, and voltage for example. NetBSD currently supports the National Semiconductor LM78, LM79 and compatible hardware monitors (the lm(4) device), the VIA VT82C686A hardware monitor (the viaenv(4) device) and ACPI aware hardware monitors (the acpi(4) subsystem) through its Environmental Systems API. These devices are not enabled by default, you need to recompile your kernel with the following additional lines in your kernel config file:
For the National Semiconductor LM78, LM79 and compatible monitors (you may need to adjust the I/O port settings):
lm0 at isa? port 0x290
For the VIA VT82C686A hardware monitor:
viapm* at pci? dev ? function ? viaenv* at viapm?
For ACPI enabled monitors (thanks to Joel Carnat for the hint):
options MPACPI acpi0 at mainbus0 acpiacad at acpi? acpibat* at acpi? acpibut* at acpi? acpiec* at acpi? acpilid* at acpi? acpitz* at acpi?
After booting your new kernel, you can access your hardware sensors, using the envstat(8) command. For example, to display
all supported sensors, type envstat -l
, and to actually read the environmental sensors, simply type
envstat
. For more information about using the envstat(8)
tool, refer to the manpage.


| Opcode/Instruction | Op/En | 64-Bit Mode | Compat/Leg Mode | Description |
|---|---|---|---|---|
|
0F 21/r MOV r32, DR0–DR7 |
MR | N.E. | Valid | Move debug register to r32. |
|
0F 21/r MOV r64, DR0–DR7 |
MR | Valid | N.E. | Move extended debug register to r64. |
|
0F 23 /r MOV DR0–DR7, r32 |
RM | N.E. | Valid | Move r32 to debug register. |
|
0F 23 /r MOV DR0–DR7, r64 |
RM | Valid | N.E. | Move r64 to extended debug register. |
| Op/En | Operand 1 | Operand 2 | Operand 3 | Operand 4 |
| MR | ModRM:r/m (w) | ModRM:reg (r) | NA | NA |
| RM | ModRM:reg (w) | ModRM:r/m (r) | NA | NA |
Moves the contents of a debug register (DR0, DR1, DR2, DR3, DR4, DR5, DR6, or DR7) to a general-purpose register or vice versa. The operand size for these instructions is always 32 bits in non-64-bit modes, regardless of the operand-size attribute. (See Section 17.2, “Debug Registers”, of the Intel® 64 and IA-32 Architectures Soft-ware Developer’s Manual, Volume 3A, for a detailed description of the flags and fields in the debug registers.)
The instructions must be executed at privilege level 0 or in real-address mode.
When the debug extension (DE) flag in register CR4 is clear, these instructions operate on debug registers in a manner that is compatible with Intel386 and Intel486 processors. In this mode, references to DR4 and DR5 refer to DR6 and DR7, respectively. When the DE flag in CR4 is set, attempts to reference DR4 and DR5 result in an undefined opcode (#UD) exception. (The CR4 register was added to the IA-32 Architecture beginning with the Pentium processor.)
At the opcode level, the reg field within the ModR/M byte specifies which of the debug registers is loaded or read. The two bits in the mod field are ignored. The r/m field specifies the general-purpose register loaded or read.
In 64-bit mode, the instruction’s default operation size is 64 bits. Use of the REX.B prefix permits access to addi-tional registers (R8–R15). Use of the REX.W or 66H prefix is ignored. Use of the REX.R prefix causes an invalid-opcode exception. See the summary chart at the beginning of this section for encoding data and limits.
IF ((DE = 1) and (SRC or DEST = DR4 or DR5)) THEN #UD; ELSE DEST ← SRC; FI;
The OF, SF, ZF, AF, PF, and CF flags are undefined.
| #GP(0) | If the current privilege level is not 0. |
| #UD |
If CR4.DE[bit 3] = 1 (debug extensions) and a MOV instruction is executed involving DR4 or DR5. If the LOCK prefix is used. |
| #DB | If any debug register is accessed while the DR7.GD[bit 13] = 1. |
| #UD |
If CR4.DE[bit 3] = 1 (debug extensions) and a MOV instruction is executed involving DR4 or DR5. If the LOCK prefix is used. |
| #DB | If any debug register is accessed while the DR7.GD[bit 13] = 1. |
| #GP(0) | The debug registers cannot be loaded or read when in virtual-8086 mode. |
Same exceptions as in protected mode.
| #GP(0) |
If the current privilege level is not 0. If an attempt is made to write a 1 to any of bits 63:32 in DR6. If an attempt is made to write a 1 to any of bits 63:32 in DR7. |
| #UD |
If CR4.DE[bit 3] = 1 (debug extensions) and a MOV instruction is executed involving DR4 or DR5. If the LOCK prefix is used. If the REX.R prefix is used. |
| #DB | If any debug register is accessed while the DR7.GD[bit 13] = 1. |


FB-PageSearch
Search Pages
Created by: Gaurav Srivastava
Frontend Developer
Page search using facebook public API.
No external javaScript libraries used.
See particular page details.
Offline storage to store page like data.


1. Introduction
This section is non-normative.
This CSS Namespaces module defines syntax for using namespaces in CSS. It defines the @namespace rule for declaring a default namespace and for binding namespaces to namespace prefixes. It also defines a syntax for using those prefixes to represent namespace-qualified names. It does not define where such names are valid or what they mean: that depends on their context and is defined by a host language, such as Selectors ([SELECT]), that references the syntax defined in the CSS Namespaces module.
Note that a CSS client that does not support this module will (if it properly conforms to CSS’s forward-compatible parsing rules) ignore all @namespace rules, as well as all style rules that make use of namespace qualified names. The syntax of delimiting namespace prefixes in CSS was deliberately chosen so that these CSS clients would ignore the style rules rather than possibly match them incorrectly.
1.1. Terminology
Besides terms introduced by this specification, CSS Namespaces uses the terminology defined in Namespaces in XML 1.0. [XML-NAMES] However, the syntax defined here is not restricted to representing XML element and attribute names and may represent other kinds of namespaces as defined by the host language.
In CSS Namespaces a namespace name consisting of the empty string is taken to represent the null namespace or lack of a namespace.
@namespace empty ""; @namespace "";
The type selectors elem
, |elem
,
and empty|elem
are equivalent.
2. Declaring namespaces: the @namespace rule
The @namespace at-rule declares a namespace prefix and associates it with a given namespace name (a string). This namespace prefix can then be used in namespace-qualified names such as the CSS qualified names defined below.
@namespace "http://www.w3.org/1999/xhtml"; @namespace svg "http://www.w3.org/2000/svg";
The first rule declares a default namespace http://www.w3.org/1999/xhtml
to be applied to names that have no explicit namespace component.
The second rule declares a namespace prefix svg
that is used to apply the namespace http://www.w3.org/2000/svg
where the svg
namespace prefix is used.
In CSS Namespaces, as in Namespaces in XML 1.0, the prefix is merely a syntactic construct; it is the expanded name (the tuple of local name and namespace name) that is significant. Thus the actual prefixes used in a CSS style sheet, and whether they are defaulted or not, are independent of the namespace prefixes used in the markup and whether these are defaulted or not.
<qml:elem xmlns:qml="http://example.com/q-markup"></qml:elem>
and the following @namespace declarations at the beginning of a CSS file:
@namespace Q "http://example.com/q-markup"; @namespace lq "http://example.com/q-markup";
The selectors Q|elem and lq|elem in that CSS file
would both match the element <qml:elem>
.
(The selector qml|elem would be invalid, because CSS namespaces only recognize prefixes declared in CSS, not those declared by the document language.)
2.1. Syntax
The syntax for the @namespace rule is:
@namespace <namespace-prefix>? [ <string> | <url> ] ; <namespace-prefix> = <ident>
Any @namespace rules must follow all @charset and @import rules
and precede all other non-ignored at-rules and style rules in a style sheet.
For CSS syntax this adds [ namespace [SCDOCDC]* ]*
immediately after [ import [SCDOCDC]* ]*
in the stylesheet
grammar.
A syntactically invalid @namespace rule (whether malformed or misplaced) must be ignored. A CSS style sheet containing an invalid @namespace rule is not a valid style sheet.
A URI string parsed from the URI
syntax must be treated as a literal string:
as with the STRING
syntax,
no URI-specific normalization is applied.
All strings—
2.2. Scope
The namespace prefix is declared only within the style sheet in which its @namespace rule appears. It is not declared in any style sheets importing or imported by that style sheet, nor in any other style sheets applying to the document.
2.3. Declaring Prefixes
A namespace prefix, once declared, represents the namespace for which it was declared and can be used to indicate the namespace of a namespace-qualified name. Namespace prefixes are, like CSS counter names, case-sensitive.
If in the namespace declaration the namespace prefix is omitted,
then the namespace so declared is the default namespace.
The default namespace may apply to names that have no explicit namespace prefix:
modules that employ namespace prefixes must define in which contexts the default namespace applies.
For example, following [XML-NAMES],
in Selectors [SELECT] the default namespace applies to type selectors—
Note: Note that using default namespaces in conjunction with type selectors can cause UAs that support default namespaces and UAs that don’t support default namespaces to interpret selectors differently.
If a namespace prefix or default namespace is declared more than once only the last declaration shall be used. Declaring a namespace prefix or default namespace more than once is nonconforming.
3. CSS Qualified Names
A CSS qualified name is a name explicitly located within (associated with) a namespace.
To form a qualified name in CSS syntax,
a namespace prefix that has been declared within scope is prepended to a local name
(such as an element or attribute name),
separated by a "vertical bar" (|
, U+007C).
The prefix, representing the namespace for which it has been declared,
indicates the namespace of the local name.
The prefix of a qualified name may be omitted to indicate that the name belongs to no namespace,
i.e. that the namespace name part of the expanded name has no value.
Some contexts (as defined by the host language)
may allow the use of an asterisk (*
, U+002A)
as a wildcard prefix to indicate a name in any namespace,
including no namespace.
@namespace toto "http://toto.example.org"; @namespace "http://example.com/foo";
In a context where the default namespace applies
toto|A
- represents the name
A
in thehttp://toto.example.org
namespace. |B
- represents the name
B
that belongs to no namespace. *|C
- represents the name
C
in any namespace, including no namespace. D
- represents the name
D
in thehttp://example.com/foo
namespace.
The syntax for the portion of a CSS qualified name before the local name is given below,
both for qualified names that allow wildcard prefixes (wqname
)
and for qualified names that disallow wildcard prefixes (qname
).
(The syntax uses notation from the Grammar appendix of CSS 2.1. [CSS21] Note this means that comments, but not white space, are implicitly allowed between tokens.):
qname_prefix : namespace_prefix? '|' ; wqname_prefix : [ namespace_prefix? | '*' ] '|' ; qname : qname_prefix? ident ; wqname : wqname_prefix? ident ; wqwname : wqname_prefix? [ ident | '*' ] ;
CSS qualified names can be used in (for example) selectors and property values as described in other modules. Those modules must define handling of namespace prefixes that have not been properly declared. Such handling should treat undeclared namespace prefixes as a parsing error that will cause the selector or declaration (etc.) to be considered invalid and, in CSS, ignored.
Changes
Changes made since the 29 September 2011 Recommendation:
- Added predefined qname, wqname, and wqwname productions, to make those constructs easier for other specs to use.
Acknowledgments
This draft borrows heavily from earlier drafts on CSS namespace support by Chris Lilley and by Peter Linss and early (unpublished) drafts on CSS and XML by Håkon Lie and Bert Bos, and XML Namespaces and CSS by Bert Bos and Steven Pemberton. Many current and former members of the CSS Working Group have contributed to this document. Discussions on<EMAIL_ADDRESS>and in other places have also contributed ideas to this specification. Special thanks goes to L. David Baron, Karl Dubost, Ian Hickson, Björn Höhrmann, and Lachlan Hunt for their comments.


Background Size
Work in progress!
More detailed documentation is coming soon, but in the meantime here's a quick class reference.
Class reference
Customizing
By default Tailwind provides utilities for auto
, cover
, and contain
background sizes. You can change, add, or remove these by editing the backgroundSize
section of your config.
Responsive and State Variants
By default, only responsive variants are generated for background size utilities.
You can control which variants are generated for the background size utilities by modifying the backgroundSize
property in the modules
section of your Tailwind config file.
For example, this config will also generate hover and focus variants:
Disabling
If you don't plan to use the background size utilities in your project, you can disable them entirely by setting the backgroundSize
property to false
in the modules
section of your config file:


Trang chủ
Trường đại học Công nghệ Sài Gòn
Thông báo
This is a primary alert—check it out!
This is a success alert—check it out!
This is a danger alert—check it out!
This is a warning alert—check it out!
Tin tức & sự kiện
This is a primary alert—check it out!
This is a success alert—check it out!
This is a danger alert—check it out!
This is a warning alert—check it out!
Thông tin tuyển dụng
This is a primary alert—check it out!
This is a success alert—check it out!
This is a danger alert—check it out!
This is a warning alert—check it out!
Chủ đề
This is a primary alert—check it out!
This is a success alert—check it out!
This is a danger alert—check it out!
This is a warning alert—check it out!


Ohio offices partner to preserve future of online checkbook
by EndPlayCOLUMBUS, Ohio (AP) - Two state government offices previously at odds over Ohio's online checkbook are partnering to keep the website going.
The state treasurer's office and the Office and Budget and Management recently announced the collaboration. Under previous administrations, the two offices launched separate, competing sites for searching state spending information.
Republicans Lt. Gov. Jon Husted (HYOO'-sted) and Treasurer Robert Sprague said collaboration will mean better service at lower cost and will enhance transparency for the media and public.
Their plan calls for OhioCheckbook.com, which provides government spending data, to continue while folding in revenue information from OBM's Interactive Budget.
Then-Treasurer Josh Mandel (MAHN'-dehl) launched OhioCheckbook.com in 2014. He accused then-Gov. John Kasich (KAY'-sik) of undermining the site's future. Both are Republicans.
Kasich said the budget office could provide more thorough information.


My Team
A
Manager
Employee Id: 1
101
<EMAIL_ADDRESS>B
Engineer
Employee Id: 2
aaa
<EMAIL_ADDRESS>C
Intern
Employee Id: 3
UNC
cc@example.com


Odell Beckham Jr. Says He Told Mike Tomlin: ‘You Disrespected Me; You Know Who I Am’ (VIDEO)
by Darrelle LincolnCleveland Browns wide receivers Odell Beckham Jr. and Jarvis Landry yawned after big plays in their “Thursday Night Football” matchup against the Pittsburgh Steelers. That was done for a reason.
Because over the summer, Steelers coach Mike Tomlin faked a yawn after being asked about facing OBJ twice a season.
During the 4th quarter, Tomlin and Beckham could be seen engaged in a conversation on the field.
Days later, Odell has finally revealed what he and Tomlin said during that conversation.
“I said, ‘You disrespected me,’’’ Beckham told Mary Kay Cabot of cleveland.com. “I said, ‘You know who I am.’ And he said ‘I know who you are. That’s why we’re doubling you all game,’ and this and that.’’
Odell made sure to remind people that he was not disrespecting Tomlin.
“We were just talking,’’ Beckham said. “There’s never been no beef with me and no coach. We were just talking s—.’’


Music
-
Summer of Panic
October 2019
Tracklist
- In the Darkest Corners
- Medic
- Plastic Bottle Rye
- Summer of Panic
-
Lantern in Her Hand b/w Lazarus
April 2019
Tracklist
- Lantern in Her Hand
- Lazarus
-
Basement Songs
August 2018
Tracklist
- Basement Song
- Little Sirens
Bandcamp
Spotify
YouTube


Idukki district is a densely forested, mountainous region in the south Indian state of Kerala. In the north, Anamudi mountain towers over Eravikulam National Park, where the rare, blue Neelakurinji flower blooms every 12 years. Nearby, Munnar is a hill station known for its sprawling tea plantations and Tea Museum. Farther south is the vast, curved Idukki Dam and Periyar National Park, a tiger and elephant reserve.
Munnar
Periyar National Park
Eravikulam NP
Vagamon


-- no code yet
Baud Rate
9600
57600
115200
Serial Scan Timeout For Response:
10
1
10
1
1
1
9
45
0
1
3.1
64
10
50
1
100
1
100
0
abc
text
abc
text
text
abc
abc
abc
abc
5
list
list
list
list
,
100
50
0
#ff0000
#3333ff
0.5
0
0
0
0
0
TRUE
0
50
0
512
0
0
0
0
0
0
500
0
LOW
1
OUTPUT
0
0
LOW
0
1
2
Please enter a device filename.
OK
Cancel
Files On Chip
init.lua
test.html
Upload as start code
Upload as...
Upload other...
Download...
Delete File
Do this code!


Airy book & record store offering new & used items in a multilevel space adorned with local art.
Learn moreThree Women is a 2019 non-fiction book by Lisa Taddeo. It is her debut book and was published on July 9, 2019, by Avid Reader Press, an imprint of Simon & Schuster. It covers the sexual and emotional lives of three women from different backgrounds and regions of the United States.
Read MoreSuch a Fun Age is a 2019 novel by Kiley Reid. It is her debut novel and was published by G. P. Putnam's Sons on December 31, 2019. It tells the story of a young black woman who is wrongly accused of kidnapping while babysitting a child, and the events that follow it.
Read MoreA bold and subversive retelling of the goddess's story," this #1 New York Times bestseller is "both epic and intimate in its scope, recasting the most infamous female figure from the Odyssey as a hero in her own right.
Read MoreAn unforgettable story of four women who, through grit and ingenuity, became stars in the cutthroat, high-stakes, male dominated world of venture capital in Silicon Valley, and helped build some of the foremost companies of our time.
Read MoreThis book club explores dystopia and the post-apocalypse in their bewildering array of forms with our host, NY Times bestselling author Peter Clines. Yes, we’re doomed, but we’re doomed together.
All book clubs require a ticket, and include the book and a dedicated
moderator – to keep the
discussion on track! All clubs meet at The Last Bookstore.
You can get your ticket (which includes us shipping the book to you!) at this link right here –
OR just come in to the store and look for our book club display (near the book tunnel).
If you choose the on-line option (the one with shipping), please send a mailing addy to
<EMAIL_ADDRESS>PETER CLINES is a generations-back New Englander (we’re talking tall hats and buckled shoes and
half-the-population-dies-every-winter generations-back) who broke with tradition and moved to
Southern California.
After more than thirty years of writing, fifteen years in the film industry, and six years of
writing about writing for the film industry, plus getting several short stories and a novel or
ten published (one of which–Paradox Bound–hit the NYT Bestseller list), he feels he has some
experience and useful advice to offer.
Your thoughts on this may vary…


Here is an example of a message that distributes market data. When the message is created the required field with the number of repeating groups is set to zero. This is because QuickFIX will automatically set this field for you when you add groups. This way there is never an inconsistancy between the number of entries in the field and in the message.
See this code in C#, VB.NET, PYTHON, RUBY// create a market data message FIX42::MarketDataSnapshotFullRefresh message(FIX::Symbol("QF")); // repeating group in the form of MessageName::NoField FIX42::MarketDataSnapshotFullRefresh::NoMDEntries group; group.set(FIX::MDEntryType('0')); group.set(FIX::MDEntryPx(12.32)); group.set(FIX::MDEntrySize(100)); group.set(FIX::OrderID("ORDERID")); message.addGroup(group); // no need to create a new group class if we are reusing the fields group.set(FIX::MDEntryType('1')); group.set(FIX::MDEntryPx(12.32)); group.set(FIX::MDEntrySize(100)); group.set(FIX::OrderID("ORDERID")); message.addGroup(group);
To pull a group out of a message you need to supply the group you wish to pull out. You should first inspect the number of entries field (which the group is named after) to get the total number of groups. The message that was created above is now parsed back out below.
See this code in C#, VB.NET, PYTHON, RUBY// should be 2 FIX::NoMDEntries noMDEntries; message.get(noMDEntries); FIX42::MarketDataSnapshotFullRefresh::NoMDEntries group; FIX::MDEntryType MDEntryType; FIX::MDEntryPx MDEntryPx; FIX::MDEntrySize MDEntrySize; FIX::OrderID orderID; message.getGroup(1, group); group.get(MDEntryType); group.get(MDEntryPx); group.get(MDEntrySize); group.get(orderID); message.getGroup(2, group); group.get(MDEntryType); group.get(MDEntryPx); group.get(MDEntrySize); group.get(orderID);


Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Integer eget aliquet nibh praesent tristique magna. Vulputate ut pharetra sit amet aliquam id.
Euismod nisi porta lorem mollis aliquam.
There are many variations of passages of Lorem Ipsum available, but theses majority have suffered alteration in some form,
by injected humour, or randomised words which don’t look even slightly believable. It uses a dictionary of over 200 Latin words,
combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable.
Consequat interdum varius sit amet mattis vulputate. Eu scelerisque felis imperdiet proin fermentum leo vel orci.
-
Who are beguiled and demoralized by the charms of pleasure of the momont,
so blinded by desire, that they cannot
-
Blinded by desire, that they cannot
-
Accusatium doloremque laudantium, totam rem aperiam.


Folktale uses GNU Make for development tooling. From there you can compile the source code, run tests, perform cleanup routines, or check your source code for style errors.
Folktale uses GNU Make for development tooling. From there you can compile the source code, run tests, perform cleanup routines, or check your source code for style errors.
Note: before you can do anything in Folktale you must initialise the documentation tools:
$ git submodule init
$ git submmodule update
$ make tools
Running make
or make help
will show you all of the available development
tasks.
Running make compile
will compile the source code using Babel.
After this you can import the objects in the REPL and interact with them.
Running make compile-annotated
will compile the source code with the special documentation
marks. You can either use make documentation
to generate HTML docs from that, or
require('./documentation')
in a Node REPL to read the docs from there.
Running make test
will compile the project and run all of the tests. Running
make test-all
will also test the examples in the documentation. You can run
tests in a PhantomJS (a headless WebKit browser) using make test-browser
.
Running make lint
will check all of the source code for style
inconsistencies. The coding style used by Folktale is described later in this
document.
Finally, running make clean
will remove any compiled files from your working
directory, but will keep all other files intact. You can always run make
compile
again to re-build the project.


Last week, the Longest Health Center tested and processed
670 students and employees for COVID. Of those,
136 students came back positive
(increased from last week) and
0 employees came back positive
(decreased from last week). The
overall positivity rate is
20.3% whereas the
student and employee
positivity rates are 23.2%
and 0.0%
respectively.


On the tube in the 70s – in pictures
by Photographs by Mike GoldwaterThe tube photographs of Mike Goldwater, shot between 1970 and 1980, capture intimate private moments of tenderness and humour behind the hustle and bustle of the human traffic. Be transported back to a time when it was fine to talk (and smoke) on London’s underground
- London Underground 1970-1980 by Mike Goldwater is published by Hoxton Mini Press
Westbourne Park 1979
Piccadilly Circus 1978
Oxford Circus 1979
Northern line 1975
Wembley Park 1979
Tottenham Court Road 1977
Northern line 1974
Moorgate 1973
King’s Cross 1972
Holborn 1978
Baker Street 1979
Oxford Circus 1978


Reports any of non-static initializers
in classes. Some coding standards prohibit such initializers, preferring initialization to be done
in constructors or field initializers. Non-static initializers
may also be inadvertently created by deleting the static keyword,
resulting in obscure bugs.
Powered by InspectionGadgets


---
layout: default
categories: plugin
title: Leaflet Zoomslider
prefix: leaflet-zoomslider
description: Adds a vertical slider that allows for greater control when picking a zoom level.
tags:
- bsd
code: https://github.com/kartena/Leaflet.zoomslider
license: BSD
---


@* * Copyright 2010-2013 Artima, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @import controllers.Application.scalatestScaladocsPageUrl @import controllers.Application.scaladocsPageUrl @userGuidePage("Or and Every") {
The Or
and Every
types of Scalactic allow you to represent errors as an “alternate return
value” (like Either
) and to optionally accumulate errors.
Or
represents a value that is one of two possible types, with one type being “good”
(a value wrapped in an instance of Good
)
and the other “bad”
(a value wrapped in an instance of Bad
).
Or
Or
differs from Scala's Either
type in that
Either
treats both its Left
and Right
alternatives in an identical manner, whereas
Or
treats its two alternatives differently: it favors
Good
over Bad
.
Because of this, it is more convenient to work with Or
s
when you prefer one alternative over the other; for example, if one alternative represents a valid result
and another represents an error.
To illustrate, imagine you want to create instances this Person
class from user input strings:
case class Person(name: String, age: Int)
You might write a method that parses the name from user input string and returns an
Option[String]
: None
if the string is empty or blank, else the
trimmed string wrapped in a Some
:
def parseName(input: String): Option[String] = { val trimmed = input.trim if (!trimmed.isEmpty) Some(trimmed) else None }
You might also write a method that parses the age from user input string and returns an
Option[Int]
: None
if either the string is not a valid integer or
it is a negative integer, else the string converted to an integer wrapped in a Some
:
def parseAge(input: String): Option[Int] = { try { val age = input.trim.toInt if (age >= 0) Some(age) else None } catch { case _: NumberFormatException => None } }
With these building blocks you could write a method that parses name and age input
strings and returns either a Person
, wrapped in a Some
, or
None
if either the name or age, or both, was invalid:
def parsePerson(inputName: String, inputAge: String): Option[Person] = for { name <- parseName(inputName) age <- parseAge(inputAge) } yield Person(name, age)
Here are some examples of invoking parsePerson
:
parsePerson("Bridget Jones", "29") // Result: Some(Person(Bridget Jones,29)) parsePerson("Bridget Jones", "") // Result: None parsePerson("Bridget Jones", "-29") // Result: None parsePerson("", "") // Result: None
Now imagine you want to give an error message back if the user's input is invalid.
You might rewrite the parsing methods to return an Either
instead. In this
case, the desired result is a valid name or age, which by convention should be placed
on the right of the Either
. The left will be a String
error
message. Here's the new parseName
function, which returns an Either[String, String]
:
def parseName(input: String): Either[String, String] = { val trimmed = input.trim if (!trimmed.isEmpty) Right(trimmed) else Left(s""""${input}" is not a valid name""") }
And here's the new parseAge
function, which returns an Either[String, Int]
:
def parseAge(input: String): Either[String, Int] = { try { val age = input.trim.toInt if (age >= 0) Right(age) else Left(s""""${age}" is not a valid age""") } catch { case _: NumberFormatException => Left(s""""${input}" is not a valid integer""") } }
The new parsePerson
method will return an Either[String, Person]
:
def parsePerson(inputName: String, inputAge: String): Either[String, Person] = for { name <- parseName(inputName).right age <- parseAge(inputAge).right } yield Person(name, age)
Note that Either
requires you to add .right
at the end of each generator in the for
expression. Although the convention is to place the
valid result on the right, you must explicitly (and repetitively) indicate that you've done so by transforming
the Either
to a RightProjection
by invoking .right
at each step.
Given this implementation, the parsePerson
method will now short-circuit at the first sign
of trouble (as it did when we used an Option
), but you now get the first error message returned
in a Left
. Here are some examples:
parsePerson("Bridget Jones", "29") // Result: Right(Person(Bridget Jones,29)) parsePerson("Bridget Jones", "") // Result: Left("" is not a valid integer) parsePerson("Bridget Jones", "-29") // Result: Left("-29" is not a valid age) parsePerson("", "") // Result: Left("" is not a valid name)
Either
with “attitude”
Because Or
declares one alternative to be “good” and the other “bad,”
it is more convenient than Either
in this kind of situation. One difference to note with
Or
is that the Good
alternative is on the left, Bad
on the right.
The reason is that Or
is designed to be written using infix notation, and placing the
“happy path” first is more readable. For example, instead of writing:
Or[Int, ErrorMessage]
You can write:
Int Or ErrorMessage
Here's how the parseName
method might be written using an Or
, where
ErrorMessage
is a type alias for String
declared in the org.scalactic
package object:
import org.scalactic._ def parseName(input: String): String Or ErrorMessage = { val trimmed = input.trim if (!trimmed.isEmpty) Good(trimmed) else Bad(s""""${input}" is not a valid name""") }
You can think of the String
Or
ErrorMessage
result
type like this:
TheparseName
method will return a nameString
or, if the input string is not a valid name, anErrorMessage
.
Here's how the parseAge
method might be written:
def parseAge(input: String): Int Or ErrorMessage = { try { val age = input.trim.toInt if (age >= 0) Good(age) else Bad(s""""${age}" is not a valid age""") } catch { case _: NumberFormatException => Bad(s"""${input}" is not a valid integer""") } }
Given these implementations, here's how you'd write the parsePerson
method:
def parsePerson(inputName: String, inputAge: String): Person Or ErrorMessage = for { name <- parseName(inputName) age <- parseAge(inputAge) } yield Person(name, age)
Because of Or
's attitude, you need not write .good
at the end of
each generator. Or
will keep going so long as each step produces a Good
,
short circuiting at the first sign of a Bad
. Here are a few invocations of this
parsePerson
method:
parsePerson("Bridget Jones", "29") // Result: Good(Person(Bridget Jones,29)) parsePerson("Bridget Jones", "") // Result: Bad("" is not a valid integer) parsePerson("Bridget Jones", "-29") // Result: Bad("-29" is not a valid age) parsePerson("", "") // Result: Bad("" is not a valid name)
Or
Another difference between Or
and Either
is that Or
enables
you to accumulate errors if the Bad
type is an Every
.
An Every
is similar to a Seq
in that it contains ordered elements, but
different from Seq
in that it cannot be empty. An Every
is
either a One
,
which contains one and only one element, or a Many
, which contains two or
more elements.
Note: an Or
whose Bad
type is an Every
, or one of its subtypes,
is called an “accumulating Or
.”
To rewrite the previous example so that errors can be accumulated, you need first to return an Every
as the Bad
type. Here's how you'd change the parseName
method:
def parseName(input: String): String Or One[ErrorMessage] = { val trimmed = input.trim if (!trimmed.isEmpty) Good(trimmed) else Bad(One(s""""${input}" is not a valid name""")) }
Because parseName
will either return a valid name String
wrapped in a
Good
, or one error message, wrapped in a Bad
, you would write the
Bad
type as One[ErrorMessage]
. The same is true for parseAge
:
def parseAge(input: String): Int Or One[ErrorMessage] = { try { val age = input.trim.toInt if (age >= 0) Good(age) else Bad(One(s""""${age}" is not a valid age""")) } catch { case _: NumberFormatException => Bad(One(s""""${input}" is not a valid integer""")) } }
Because a for
expression short-circuits on the first Bad
encountered, you'll
need to use a different approach to write the parsePerson
method. In this example, the
withGood
method from trait Accumulation
will do the trick:
import Accumulation._ def parsePerson(inputName: String, inputAge: String): Person Or Every[ErrorMessage] = { val name = parseName(inputName) val age = parseAge(inputAge) withGood(name, age) { Person(_, _) } }
Trait Accumulation
offers overloaded withGood
methods that take 1 to
22 accumulating Or
s, plus a function taking the same number of corresponding
Good
values. In this example, if both name
and age
are
Good
s, the withGood
method will pass the good name String
and age Int
to the Person(_, _)
function, and return the resulting Person
object wrapped in a Good
. If either name
and age
, or both,
are Bad
, withGood
will return the accumulated errors in a Bad
.
The result of parsePerson
, if Bad
, will therefore contain either one or two
error messages, i.e., the result will either be a One
or a Many
.
As a result, the result type of parsePerson
must be Person
Or
Every[ErrorMessage]
. Regardless of whether a Bad
result contains one
or two error messages, it will contain every error message. Here's some invocations of
this accumulating version of parsePerson
:
parsePerson("Bridget Jones", "29") // Result: Good(Person(Bridget Jones,29)) parsePerson("Bridget Jones", "") // Result: Bad(One("" is not a valid integer)) parsePerson("Bridget Jones", "-29") // Result: Bad(One("-29" is not a valid age)) parsePerson("", "") // Result: Bad(Many("" is not a valid name, "" is not a valid integer))
Note that in the last example, the Bad
contains an error message for both name and age.
Every
s
The previous examples demonstrate constructing a one-element Every
with
a factory method in the One
companion object. You can similarly create an Every
that contains more than one
using a Many
factory method. Here are some examples:
One(1) Many(1, 3) Many(1, 2, 3)
You can also construct an Every
by passing one or more elements to the Every.apply
factory method:
Every(1) Every(1, 2) Every(1, 2, 3)
Every
does not extend Scala's Seq
or Traversable
traits because these require that
implementations may be empty. For example, if you invoke tail
on a Seq
that contains just one element,
you'll get an empty Seq
:
scala> List(1).tail res6: List[Int] = List()
On the other hand, many useful methods exist on Seq
that when invoked on a non-empty Seq
are guaranteed
to not result in an empty Seq
. For convenience, Every
defines a method corresponding to every such Seq
method. Here are some examples:
Many(1, 2, 3).map(_ + 1) // Result: Many(2, 3, 4) One(1).map(_ + 1) // Result: One(2) Every(1, 2, 3).containsSlice(Every(2, 3)) // Result: true Every(1, 2, 3).containsSlice(Every(3, 4)) // Result: false Every(-1, -2, 3, 4, 5).minBy(_.abs) // Result: -1
Every
does not currently define any methods corresponding to Seq
methods that could result in
an empty Seq
. However, an implicit converison from Every
to collection.immutable.IndexedSeq
is defined in the Every
companion object that will be applied if you attempt to call one of the missing methods. As a
result, you can invoke filter
on an Every
, even though filter
could result
in an empty sequence—but the result type will be collection.immutable.IndexedSeq
instead of Every
:
Every(1, 2, 3).filter(_ < 10) // Result: Vector(1, 2, 3) Every(1, 2, 3).filter(_ > 10) // Result: Vector()
You can use Every
s in for
expressions. The result will be an Every
unless
you use a filter (an if
clause). Because filters are desugared to invocations of filter
, the
result type will switch to a collection.immutable.IndexedSeq
at that point. Here are some examples:
scala> import org.scalactic._ import org.scalactic._ scala> for (i <- Every(1, 2, 3)) yield i + 1 res0: org.scalactic.Every[Int] = Many(2, 3, 4) scala> for (i <- Every(1, 2, 3) if i < 10) yield i + 1 res1: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4) scala> for { | i <- Every(1, 2, 3) | j <- Every('a', 'b', 'c') | } yield (i, j) res3: org.scalactic.Every[(Int, Char)] = Many((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c)) scala> for { | i <- Every(1, 2, 3) if i < 10 | j <- Every('a', 'b', 'c') | } yield (i, j) res6: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
The Accumlation
trait also enables other ways of accumulating errors.
combined
If you have a collection of
accumulating Or
s, for example, you can combine them into one Or
using combined
, like this:
List(parseAge("29"), parseAge("30"), parseAge("31")).combined // Result: Good(List(29, 30, 31)) List(parseAge("29"), parseAge("-30"), parseAge("31")).combined // Result: Bad(One("-30" is not a valid age)) List(parseAge("29"), parseAge("-30"), parseAge("-31")).combined // Result: Bad(Many("-30" is not a valid age, "-31" is not a valid age))
validatedBy
Or if you have a collection of values and a function that transforms that type of value into an accumulating
Or
s, you can validate the values using the function using validatedBy
, like this:
List("29", "30", "31").validatedBy(parseAge) // Result: Good(List(29, 30, 31)) List("29", "-30", "31").validatedBy(parseAge) // Result: Bad(One("-30" is not a valid age)) List("29", "-30", "-31").validatedBy(parseAge) // Result: Bad(Many("-30" is not a valid age, "-31" is not a valid age))
zip
You can also zip two accumulating Or
s together. If both are Good
, you'll get a
Good
tuple containin both original Good
values. Otherwise, you'll get a Bad
containing every error message. Here are some examples:
parseName("Dude") zip parseAge("21") // Result: Good((Dude,21)) parseName("Dude") zip parseAge("-21") // Result: Bad(One("-21" is not a valid age)) parseName("") zip parseAge("-21") // Result: Bad(Many("" is not a valid name, "-21" is not a valid age))
when
In addition, given an accumlating Or
, you can pass one or more validation functions to when
on the Or
to submit that Or
to further scrutiny. A validation function accepts a Good
type and returns a Validation[E]
,
where E
is the type in the Every
in the Bad
type. For an Int
Or
One[ErrorMessage]
, for example
the validation function type would be Int
=>
Validation[ErrorMessage]
. Here are a few examples:
def isRound(i: Int): Validation[ErrorMessage] = if (i % 10 == 0) Pass else Fail(i + " was not a round number") def isDivBy3(i: Int): Validation[ErrorMessage] = if (i % 3 == 0) Pass else Fail(i + " was not divisible by 3")
If the Or
on which you call when
is already Bad
, you get the same (Bad
) Or
back, because
no Good
value exists to pass to the valiation functions:
parseAge("-30").when(isRound, isDivBy3) // Result: Bad(One("-30" is not a valid age))
If the Or
on which you call when
is Good
, and also passes all the validation functions (i.e., the
all return None
), you again get the same Or
back, but this time, a Good
one:
parseAge("30").when(isRound, isDivBy3) // Result: Good(30)
If one or more of the validation functions fails, however, you'll get a Bad
back contining every error. Here are some examples:
parseAge("33").when(isRound, isDivBy3) // Result: Bad(One(33 was not a round number)) parseAge("20").when(isRound, isDivBy3) // Result: Bad(One(20 was not divisible by 3)) parseAge("31").when(isRound, isDivBy3) // Result: Bad(Many(31 was not a round number, 31 was not divisible by 3))
Note that you can use when
to accumulate errors in a for
expression involving an accumulating Or
, like this:
for (age <- parseAge("-30") when (isRound, isDivBy3)) yield age // Result: Bad(One("-30" is not a valid age)) for (age <- parseAge("30") when (isRound, isDivBy3)) yield age // Result: Good(30) for (age <- parseAge("33") when (isRound, isDivBy3)) yield age // Result: Bad(One(33 was not a round number)) for (age <- parseAge("20") when (isRound, isDivBy3)) yield age // Result: Bad(One(20 was not divisible by 3)) for (age <- parseAge("31") when (isRound, isDivBy3)) yield age // Result: Bad(Many(31 was not a round number, 31 was not divisible by 3))
Nothing
Because Or
has two types, but each of its two subtypes only takes a value of one or the other type, the Scala compiler will
infer Nothing
for the unspecified type:
scala> Good(3) res0: org.scalactic.Good[Int,Nothing] = Good(3) scala> Bad("oops") res1: org.scalactic.Bad[Nothing,String] = Bad(oops)
Often Nothing
will work fine, as it will be widened as soon as the compiler encounters a more specific type.
Sometimes, however, you may need to specify it. In such situations you can use this syntax:
scala> Good(3).orBad[String] res2: org.scalactic.Good[Int,String] = Good(3) scala> Good[Int].orBad("oops") res3: org.scalactic.Bad[Int,String] = Bad(oops)
If you want to specify both types, because you don't like the inferred type, you can do so like this:
scala> Good[AnyVal, String](3) res4: org.scalactic.Good[AnyVal,String] = Good(3) scala> Bad[Int, ErrorMessage]("oops") res5: org.scalactic.Bad[Int,org.scalactic.ErrorMessage] = Bad(oops)
But you may find the code is clearer if you instead use a type ascription, like this:
scala> Good(3): AnyVal Or String res6: org.scalactic.Or[AnyVal,String] = Good(3) scala> Bad("oops"): Int Or ErrorMessage res7: org.scalactic.Or[Int,org.scalactic.ErrorMessage] = Bad(oops)
Next, learn about Requirements.


Next Generation Software
Introduction
How does MASM32 work
Code Design
Tools & Toys
Code Portability
Licence
Credits