Baseline for an "Adequate" AI
Software engineering is about engineering and engineering is about generate a produce of adequate quality, given the available constraints. What does that mean for AI-enhanced software?
Within any optimizer or data mining toolkit we can find hundreds of classifiers, regression tools, neural nets, support vector machines, evolutionary algorithms, ant-colony optimizers, etc etc, etc. These primitives can be combined in millions of ways, then tuned in quadrillions of ways (see the very active research literature on all these methods). So given a new problem, which learner/optimizer should we apply?
This is a very hard problem. Wolpert reports in his famous No Free Lunch Theorems that if some optimizer/learner works best for some data, then some other optimizer/learner will work best for other data. This means that when new data arrives, you need commissioning experiments; i.e. try a variety of techniques before you can find what words best for the local data.
(Aside: it turns out that the NFL has some good news for us: the greater the performance gain desired, the fewer the learners exist that produce at least such a performance gain. See the Hyperband optimizer for an adaptive approach to pruning away less-than-great methods. Also, for many learners/optimizers, their performance is indistinguishable for anything less than some ε value. So if we divide the output space into bins of width ε means we can stop looking once we find a few methods that falls into the best ε bins.)
When conducting such commissioning experiments, it is methodologically useful to have a baseline method; i.e. an algorithm which can generate floor performance values. Such baselines let a developer quickly rule out any method that falls “below the floor”. With this, researchers and industrial practitioners can achieve fast early results, while also gaining some guidance in all their subsequent experimentation (specifically: “try to beat the baseline”).
Using baselines for analyzing algorithms has been endorsed by several experienced researchers:
- In his textbook on empirical methods for artificial intelligence, Cohen strongly recommends comparing supposedly sophisticated systems against simpler alternatives. In the machine learning community,
- Holte uses the OneR baseline algorithm as a scout that runs ahead of a more complicated learners as a way to judge the complexity of up-coming tasks.
- In the software engineering community, Sarro et al
et al. recently proposed baseline methods for effort estimation. - Shepperd and Macdonnel argue convincingly that measurements are best viewed as ratios compared to measurements taken from some minimal baseline system.
- Work on cross-versus within-company cost estimation has also recommended the use of some very simple baseline
- I've offered several good baseline AI tools for SE tasks. In both the following, my graduate students were able to replace widely used very complex solutions with much simple alternative. For example:
So for this subject, we propose replacing the question of "what AI tool is best" with two other questions that make more sense to engineers racing to deliver products with limited time and resources:
- How can we quickly commission an initial, adequate, AI baseline system?
- What can we do to test and improve on that baseline?
But what is a "good" baseline?
Here's one list of what a "baseline" means. Items 1..10 are adapted from Sarro, TOSEM'18. (which we extend with our own notes). The other items come from my experience.
Note also that the following list offers a road map for future research in SE+AI. Find cases where some of these points do not matter. Find ways to enhance existing systems such that they perform better on the following criteria. Etc. The key thing to note about the following is that one system may not satisfy all these criteria (in fact, no known system satisfied all of them). That said, each of the following points is important. And by reflecting on the value of each point for a particular AI application, we naturally consider and review (and possibly discard) important design alternatives.
The Checklist
Now stay calm citizens of FSS'18. The following is not as complex as it looks. while there are many complex ways to support the following, there are also very simple ways that can work very well for each. And for your project, you only have to understand a one of the following.
1. SIMPLE: Be simple to describe, implement, and interpret (i.e. interpret the output for business uses).
- My current "simplest" methods is Fast-and-Frugal decision trees (or see also here); which is available in a nice R-package.
2. REASONABLE: Offer comparable performance to standard methods.
- So note the great paradox of simplicity research
-
Curious fact: evaluation can get so hard that we usually try to milk it for everything that can.
So "cross val" experiments lead us to ensemble learning then to boosting;
"round robin" lead to transfer learning;
"jiggle a little" lead to evolutionary methods;
evolutionary methods.
It is very hard to be simple
- Cause the simplest thing has to be compared against other, more complex, things.
3. STABLE: Be deterministic stable in its outcomes
- I've replaced deterministic with stable, since I think that is more important.
- Instability is very unsettling for software project managers struggling to find general policies. Project managers lose faith in the results of software analytics if those results keep changing. Also, such instability prevents project managers from offering clear guidelines on what to change, or what to avoid, in a project.
- And instability plagues SE data. For example:
- Here, Fig1, are the coefficients learned by regression on 20 67% samples of some training data. Note their WILD instability.
- One trick for increasing stability is not to focus on all the smaller details
- e.g. when learning regression equations, do not use all the variables;
- e.g. when learning rules, avoid wide conditions
- e.g. when learning trees, do not learn deep trees).
- Of course, if you optimize for simplicity, you may pay a performance penalty.
4a. INTUITIVE: Be applicable to mixed qualitative and quantitative data.
- It is good to use numeric and symbolic data.
- It is useful to be able to initial a systems with qualitative intuitions.
- Then, at least, you can compare the output to what folks already
believe.
- But be warned, in SE, the beliefs of many developers are... dubious.
- If for no other reasons that humans have numerous cognitive
biases
- For a really long list of those biases, see Wikipedia or this chart
- Then, at least, you can compare the output to what folks already
believe.
- It is useful to be able to guide model construction via high-level qualitative goals.
- One useful technology here are Bayes nets which can be either initially drawn by people, then revised by data miners, or vice versa.
- Another trick is to use some incremental rule learning algorithm that updates many possible new rules, then scores them by their distance to old rules (and the best new rules are those that are closest to old and score highest). In that rig, user background beliefs would become the first generation rules.
- Yet another method is to use multi-objective optimizers that fit rule learner to human biases.
4b. COMPREHENSIBLE:
This is connected to 4a.
- Essential for communities critiquing ideas.
- If the only person reading a model is a carburetor, then we can expect little push back. But if your models are about policies that humans have to implement, then I take it as axiomatic that humans will want to read and critique the models.
5. GENERAL: Offer some explanatory information regarding the prediction by representing generalized properties of the underlying data.
- Many systems offer only "point" solutions; i.e. examples of what might be useful.
- Given N attributes, a point solution offers exact values for all attributes.
- E.g. the output of most evolutionary programs
- E.g. all instance-based (nearest neighbor) methods
- E.g. A happy author might be editing this particular file and this particular time and place.
- Given N attributes, a point solution offers exact values for all attributes.
- Some systems offer solutions that hold over a volume;
- I.e. they ignore some values while saying things like x > 10 for others.
- E.g. Happy authors might be editing html files on many computers (and when they do it does not matter).
- One way to generalize a instance-based method is to cluster the solutions, then only report ranges that are different in different clusters.
6. NO MAGIC: Have no magic parameters within the modeling process that require tuning.
- E.g. for random forests, engineers have to decide on how many trees are included in the forest.
- Alternatively, if such tunings exist, then the must be some automatic method for selecting what tunings are best for particular data sets.
7. AVAILABLE: Be publicly available via a reference implementation and associated environment for execution.
- In this day and age of Docker images and package managers and Github-like environments where everyone can load up each other's code at the drop of a hat, it makes no sense for some baseline tool to be inaccessible.
8. USEFUL: Generally be more accurate than a random guess or (e.g. an estimate based purely on the distribution of the response variable).
- E.g. evaluate the output via "standardarized error"; i.e. compare the prediction to some some prediction generated from (say) the median value of the response variable.
9. CHEAP: Do not be expensive to apply.
- Here we mean that the CPU, Ram, and disk space required to make something work is not crazy high.
- "CHEAP is important since ~Reproducing and improving an old ideas means that you can reproduce that old result. Also, certifying that new ideas often means multiple runs over many sub-samples of the data. Such reproducibility and certification is impractical when such reproduction is impractically slow
10. ROBUST: I.e. does not change much over different data splits and validation methods?
- And if it does vary wildly, can it find ways to find regions in the data where the data conclusions are stable.
11. GOAL-AWARE: Different goals means different models. AND multiple goals = no problem!
- This is important since most data miners build models that optimizer for a single goal (e.g. minimize error or least-square error) yet business users often want their data miners to achieve many goals.
- For example, if we want to ask "what to do" rather than "what is", then we need a planner, not a classifier. Of course, in that case, the classifier can be used as a what-if guide to assess different plans.
12. CONTEXT-AWARE: context-aware:
Easy path context awareness: first cluster the data, then build different models for different clusters: see NbTrees.
- Knows that local parts of data generate different models.
- E.g. hierarchically clusters the data and builds one model per cluster.
- While general principles are good, so too is how to handle particular contexts. For example, in general, exercise is good for maintaining healthy. However, in the particular context of patients who have just had cardiac surgery, then that general principle has to be carefully tailored to particular patients. ideas need to be updated.
13. HUMBLE:
Easy path to
certification envelopes: cluster data, report k items per cluster.
- Can publish succinct certification envelope that can report when new data is
out-of-scope to what was seen before.(so we know when not to trust)
- This is important since the delivered data mined models should be able to recognize when new data is out-of-scope of anything they’ve seen before. This means, at runtime, having access to the data used to build that model.
- Note that phrase succinct here: certification envelopes cannot include all the data relating to a model, otherwise every hard drive in the world will soon fill up.
- Another form of humility is knowing when the baseline should be replaced with something else. Holte uses the OneR baseline algorithm as a scout that runs ahead of a more complicated learners as a way to judge the complexity of up-coming tasks.
14. STREAMING:
- Can run over an infinite stream of data, updating itself (or knows when to go back to old versions of itself).
- Easy path to anomaly detection: cluster data, report items that fall far from each cluster. Can detect anomalies (when new inputs differ from old training data). This is the trigger for re-learning.
15. SHARABLE: Knows how to transfer models, data, between contexts.
Easy path to lightweight sharing: just share reduced data from context awareness.
- Need some way to keep the volume of shared data down (otherwise "sharing" would clog the Internet).
- Such transfer may requires some transformation of the source data to the target data.
16. PRIVACY-AWARE:
Easy path to privacy: within the clusters of the certification envelope, just share k items per cluster, each slightly mutated. See LACE2.
- Can hide an individual's data
- This is essential when sharing a certification envelope
Project
The project of this class is to apply the above to AI tools applied to SE problems. Even trying to apply the above and not getting anywhere, would also be fine (just as you long as you document your comprehension of the ideas of baselines, along the way). So go seek, or build, good baselines:
- Take any SE problem and ask are the current methods "baselines?". Would simpler alternatives suffice?
- Can you make the method simpler to use;
- e.g. replace it with something much simpler to implement and explain
- e.g. apply an optimizer to a data mining to find better settings from that data miner?
- If you replace the complex with the simpler, what (if any) is the performance penalty?
- Can you make the method use less RAM or be faster to use;
- e.g. see what happens if you learn on just X% of the data (randomly
selected) for
X ∈ {50,25,10,5,1}%? - If you apply a prototype generator, can you select/build a very small
subset of the data from which learning is faster and just as effective?
- Finding prototypes can be as easy as "cluster and take just a few from each cluster"
- But there are many other methods
- eg. apply a data miner to an optimizer to divide up the data to make the whole process much faster? See 500+ faster than deep learning.
- e.g. see what happens if you learn on just X% of the data (randomly
selected) for
- Does that method need additional support to enable explanation of their output?
- Do their models fail the stability test?
- How does that method respond if you run it N times on 90% of the data?
- And if they do, can you find regions of the data where the performance is stable?
- How to reduce the CPU and RAM and runtime requirements of that method by large amounts e.g. see 500+ faster than deep learning.
- If we stream over the data, how soon does this model stabilize?
- If we inject mutations into the data, can this method be used to recognize that strange data? Once the weird data arrives, how long (if ever) before the model recovers?
- If a model is update, can be it done some minimally; i.e. with least change to the existing model?
- etc
- etc
- etc
All Connected
The more we compress the smaller the memory and the faster we learn and the less we need to share (so more privacy).
The more we understand the data's prototypes the more we know what is usual/ unusual so we more we know what is anomalous so the easier it is to offer a certification envelope
Note that if our compression method is somehow hierarchical and if we track the errors seen by our learners in different subtrees then the more we know which parts of the model need revising (and which can stay the same). Which means we only make revisions to the parts that matter, leaving the rest stable.
Other Requirements
No eval tools
Tests conclusion stability
- across multiple data sets (if available)
- or across multiple subsets of know scenarios
See Evaluation for many examples of that kind of evaluation.
- Note that these can significantly increase the computational cost of using learners.
- Hence, the need to faster, lighter AI algorithms.
No support for stats tests
- Check if this treatment has same effect as that treatment.
- Need at least two tests: significance and effect size
- I also think you need a third test;
- Something that clusters the treatments before the other tests are applied
- Reduces the number of other statistical tests.
- E.g the Scott-Knot test.


56 tweets from the party may not appear in this replay feed because they have been deleted by the author


Over the past few weeks I've gotten to know Ruby on a pretty good level. I wouldn't call us best friends, but I would say we are pretty friendly and spent quite a bit of time together. It is still a bit of an adjustment switching to JavaScript, but overall they really are not all that different. There are some changes in syntax and logic, but you can get the same tasks accomplished with similar steps in many cases.
In Ruby it is very easy to declare a variable. You just type the variable name equal to the variable value.
name = value
In Javascript it is still easy, just a little longer.
var name = value
While getting to know Ruby, I learned a bit about hashes. Hashes are key value pairs that store information in no particular order.
hash= {hash_key: hash_value, hash_key2: hash_value2}
In JavaScript, hashes are referred to as objects and written slightly differently.
var hash= {hash_key: hash_value, hash_key2: hash_value2,}
You can call upon the value using either bracket or dot notation.
hash[hash_key]
hash.hash_key
Ah, such a simple symbol but such a tough thing to bang into my head. In Ruby semicolons are not used for statements, yet in JavaScript they are used after every statement but not after curly brackets.
var x=0; x++ //semicolon obligatory
var x=0 //semicolon optional
x++ //semicolon optional
The semicolon is only obligatory when you have two or more statements on the same line, and is optional to seperate statements on seperate lines. You SHOULD NOT put a semicolon after closing a curly brace. The only exception are when declaring a variable or function with empty values.
var object= {};
I highly suggesting out this page for a more complete guide to semicolons.
Looping in JavaScript is much more limited than in Ruby. While there are numerous options with Ruby, there are only for loops and while loops in JavaScript.
While loops are the more basic way to iterate through a set of data.They start with a condition and then execute a block of code while that condition is true. When the condition is no longer true, the code stops and the loop ends. Here is a while loop in Ruby.
while (x < 5)
puts x
x +=1
end
Here is the same while loop in JavaScript.
while (x<5){
console.log(x);
x++;
}
So while the syntax is different, the logic is the same.
For loops are formatted by setting a statement to be executed before beginning the loop, defining the condition for running the loop, and executing the code each time the loop runs. Here is a for loop in Ruby.
for n in 1..10
if n <= 5
puts n
end
end
The same for loop in Javascript
for (var x=1; x<=5; x++){
console.log(x);
}
Both blocks of code are taking variable x and mulptiply it by five until it reaches 5.
In these small examples you can see that you can accomplish the same tasks but with very different languages. Ruby and Javascript are both object-oriented languages. They have similar value types (numbers, strings, booleans, functions). They store data in variables. They evaluate functions (okay, methods in Ruby), and they have similar loops, conditionals, and operators.


SWRLTab
Protégé Desktop plugin for working with the SWRL rule and SQWRL query languages.
The plugin provides two tabs: the SWRLTab, which can be used to manage SWRL rules, and the SQWRLTab,
which works with SQWRL queries.
The tabs can be activated via the "Windows > Tabs..." menu item.
Please refer to the wiki for
detailed documentation.
Version Information
2.0.8 (16th December, 2019)
- Travis CI updates (no code updates)li>
2.0.7 (16th December, 2019)
- Fixed non terminating decimal divide issue
2.0.6 (14th December, 2018)
- Fixed incorrect translation of disjoint object properties to Drools
2.0.5 (15th October, 2017)
- Fixed some core temporal built-in bugs
2.0.4 (20 August, 2017)
- Fixed additional SQWRL collection bug
2.0.3 (14th August, 2017)
- Fixed SQWRL collection bug


Clarice Lispector
The writer whom vision transcends time and place
Here's a time line of Clarice's life:
- 1920 - She was born in Ukraine
- 1922 - She moved to Brazil with her family, amidst the disasters engulfing her native land following the First World War
- 1942 - While in law school in Rio, she began publishing her first journalistic work and short stories, catapulting to fame at the age of 23 with the publication of her first novel, Near to the Wild Heart (Perto do Coração Selvagem), written as an interior monologue in a style and language that was considered revolutionary in Brazil
- 1944 - She left Brazil, following her marriage to a Brazilian diplomat, and spent the next decade and a half in Europe and the United States
- 1959 - After returning to Rio de Janeiro, she began producing her most famous works, including the stories of Family Ties (Laços de Família), the great mystic novel The Passion According to G.H. (A Paixão Segundo G.H.), and what is arguably her masterpiece, Água Viva
- 1966 - Injured in an accident, she spent the last decade of her life in frequent pain, steadily writing and publishing novels and stories
- 1977 - Shortly after The Hour of the Star (A Hora da Estrela) was published, Lispector was admitted to the hospital. She had inoperable ovarian cancer, though she was not told the diagnosis. She died on the eve of her 57th birthday and was buried on December 11, at the Jewish Cemetery of Caju, Rio de Janeiro


Do we need friends in life?
I met many great people and with time I lost touch with tem. Its not that I forget them just getting busy with jobs.
We don't need friends but having them is good also its a emotional need and we may want to have a friend no matter how lone wolf we are.


| [Top] | [Contents] | [Index] | [ ? ] |
Version 2.2 – March 2023
This package provides classes that simplify the publishing of objects using Java’s Management Extensions (JMX). These published objects can be investigated with jconsole or another JMX client. Included is also a programmatic JMX client which you can use to connect to and interrogate remote JMX servers as well as a web/HTTP interface so you can publish JMX beans to a browser or other web client.
To get started quickly using SimpleJMX, see section Start Using Quickly. You can also take a look at the examples section of the document which has various working code packages. See section Example Code. There is also a PDF version of this documentation.
Gray Watson http://256stuff.com/gray/
| 1. Start Using Quickly | Start using SimpleJMX quickly. | |
| 2. Using SimpleJMX | How to use SimpleJMX. | |
| 3. Example Code | Usage examples to help you get started. | |
| 4. Open Source License | Open Source license for the project. | |
| Index of Concepts | Index of concepts in the manual. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To use SimpleJMX you need to do the following steps. For more information, see section Using SimpleJMX.
@JmxResource
annotation to the top of each class you want to publish via JMX. See section Naming Objects.
@JmxResource(domainName = "your.domain", description = "Runtime counter") public class RuntimeCounter { |
@JmxAttributeField
annotation to each of the attribute fields that you want to expose via reflection over JMX.
See section Exposing Fields and Methods.
@JmxAttributeField(description = "Start time in millis", isWritable = true) private long startTimeMillis; |
If you want to annotate the get/set/is attribute methods instead then use the @JmxAttributeMethod
annotation on those
methods. See section @JmxAttributeMethod Annotation.
@JmxAttributeMethod(description = "Run time in seconds or milliseconds") public long getRunTime() { |
@JmxOperation
annotation to each of operation methods that you want to make accessable over JMX.
See section @JmxOperation Annotation.
@JmxOperation(description = "clear the cache") public void clearCache() { |
// create a new JMX server listening on a port JmxServer jmxServer = new JmxServer(8000); jmxServer.start(); |
jmxServer.register(someObject); jmxServer.register(someOtherObject); |
For more extensive instructions, see section Using SimpleJMX.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| 2.1 Downloading Jar | Downloading the SimpleJMX jar. | |
| 2.2 Naming Objects | How to name the objects. | |
| 2.3 Exposing Fields and Methods | How to expose fields and methods. | |
| 2.4 Starting a JMX Server | Starting a JMX server. | |
| 2.5 Register Objects | Registering objects for publishing. | |
| 2.6 Publishing Using Code Definitions | How to define the name and exposed items programmatically. | |
| 2.7 Using the JMX Client | Using the programmatic JMX client. | |
| 2.8 Using With the Spring Framework | Using SimpleJMX with the Spring framework. | |
| 2.9 Exposing Beans Over HTTP | Using the internal web server to expose JMX beans. | |
| 2.10 Using the JVM Platform JMX Server | Using the JVM platform JMX server. | |
| 2.11 Using With Maven | How to use with Maven. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To get started with SimpleJMX, you will need to download the jar file. The SimpleJMX release page is the default repository but the jars are also available from the central maven repository.
The code works with Java 6 or later.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you publish an object you need to tell JMX what the object’s unique name is and where it should be located in the various folders shown by jconsole. There are a couple of different ways to do this with SimpleJMX:
| 2.2.1 @JmxResource Annotation | Using the SimpleJMX @JmxResource Annotation | |
| 2.2.2 Self Naming Objects | Allow the object to name itself |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The @JmxResource
annotation is used to define that the resource is to be published via JMX and how it is to be named.
@JmxResource(domainName = "your.domain", description = "Runtime counter") public class RuntimeCounter { ... |
The above example shows that the RunetimeCounter
object is to be published via JMX inside of the your.domain
folder with a text description.
The fields in @JmxResource
are:
domainName
Domain name of the object which turns into the top-level folder inside of jconsole. This must be specified unless the object is self-naming. See section Self Naming Objects.
beanName
Name of the JMX object in the jconsole folder. The default is to use the class name.
folderNames
Optional array of strings which translate into sub-folders below the domain-name folder. Default is for
the object to show up in the domain-name folder. The folder names can either be in name=value
format in which case
they should be in alphabetic order by name. They can also just be in value
format.
Folders are used when you have a large number of JMX objects being published and you want to group the objects so that you can find them faster than scrolling through a large list. For example, all of your database objects could go in the folder "database" while the database connections could go into the sub-folder "database/connections".
@JmxResource(domainName = "your.domain", folderNames = { "database", "connections" }) public class MySqlDatabaseConnection { |
description
Textual description of the class for jconsole or other JMX clients. Default is something like: "Information about class-name".
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Instead of using the @JmxResource
annotation to define the name/folders for your JMX object, you can have the
object implement the JmxSelfNaming
interface. This allows the object to name itself and will override any settings
from the @JmxResource
annotation, if it is specified.
It is particularly necessary to make your object JmxSelfNaming
if there are to be multiple of them published via JMX.
For example, if you have multiple database connections that you want to publish then to ensure that they have a unique name,
each of the objects should be self-naming and should provide a unique name that identifies itself:
// we only use this to set the domain name and the folders @JmxResource(domainName = "your.domain", folderNames = { "database", "connections" }) public class DatabaseConnection extends BaseJmxSelfNaming implements JmxSelfNaming { @Override public String getJmxBeanName() { // return our toString as our name return toString(); } } |
In the above example, we extend the BaseJmxSelfNaming
abstract class which has default implementations for all of the
JmxSelfNaming
methods, so all we need to do is override what we want to change.
The methods in the JmxSelfNaming
interface are:
String getJmxDomainName();
Return the domain name of the object. Return null to use the one from the @JmxResource
annotation instead.
String getJmxBeanName();
Return the name of the object. Return null to use the one from the @JmxResource
annotation instead.
JmxFolderName[] getJmxFolderNames();
Return the appropriate array of folder names used to built the associated object name. Return null for no folders in which case the bean will be at the top of the hierarchy in jconsole without any sub-folders.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Once we have named our object, we need to tell the JMX server which fields and methods should be exposed to the outside world. JMX can expose what it calls attributes, operations, and notifications. At this time, only attributes and operations are supported by SimpleJmx.
Attributes can be primitives or simple types such as String
or java.util.Date
. With SimpleJMX you can expose them by using reflection
on the object’s fields directly using the @JmxAttributeField
annotation or instead via the get/set/is methods using the
@JmxAttributeMethod
annotation.
Operations are methods that do not start with get/set/is but which perform some function (ex: resetTimer()
,
clearCache()
, etc.). They can be exposed with the @JmxOperation
annotation.
| 2.3.1 @JmxAttributeField Annotation | Using the SimpleJMX @JmxAttributeField Annotation | |
| 2.3.2 @JmxAttributeMethod Annotation | Using the SimpleJMX @JmxAttributeMethod Annotation | |
| 2.3.3 @JmxOperation Annotation | Using the SimpleJMX @JmxOperation Annotation |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SimpleJMX allows you to publish your primitive or simple types by annotating your fields with the @JmxAttributeField
annotation.
@JmxAttributeField(description = "Start time in millis", isWritable = true) private long startTimeMillis; |
In the above example, the startTimeMillis
long field will be visible via JMX. It will show its value which can be
changed because isWriable
is set to true. isReadable
is set to true by default. The description is available
in jconsole when you hover over the attribute.
The fields in the @JmxAttributeField
annotation are:
String description
Description of the attribute for jconsole. Default is something like: "someField attribute".
boolean isReadible
Set to false if the field should not be read through JMX. Default is true.
boolean isWritable
Set to true if the field can be written by JMX. Default is false.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Instead of publishing the fields directly, SimpleJMX also allows you to publish your attributes by decorating the
get/set/is methods using the @JmxAttributeMethod
annotation. This is only for methods that start
with getXxx()
, setXxx(...)
, or isXxx()
.
The Xxx
name should match precisely to line up the get and set JMX features. For example, if you are getting and setting the
fooBar
field then it should be getFooBar()
and setFooBar(...)
. isFooBar()
is also allowed if foobar
is a boolean
or Boolean
field.
Notice that although the field-name is fooBar
with a lowercase ’f’, the method name camel-cases it and turns
it into getFooBar()
with a capital ’F’. In addition, the getXxx()
method must not return void and must have no arguments.
The setXxx(...)
method must return void
and must take a single argument. The isXxx()
method is allowed if it
returns boolean or Boolean and the method has no arguments.
Exposing a get method allows you to do some data conversion when the value is published. Exposing a set method allows you to do data validation.
@JmxAttributeMethod(description = "Run time in seconds or milliseconds") public long getRunTime() { |
The only field in the @JmxAttributeMethod
annotation is the description. The annotation on the get...
method shows that it
is readable and the annotation on the set...
method shows that it is writable.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Operations are methods that do not start with get/set/is but which perform some function. They can be exposed with the
@JmxOperation
annotation. The method can either return void
or an object. It is recommended that the method return
a primitive or a simple object that is in Jconsole’s classpath already. Otherwise Jconsole will be unable to display it.
It also should not throw an unknown Exception
class.
@JmxOperation(description = "clear the cache") public void clearCache() { ... |
A pattern that is common is to return a String
from the method to provide some feedback to the remote user and to catch
and return any exceptions as a String
.
@JmxOperation(description = "clear the cache") public void clearCache() { try { // do the cache clearing here return "Cache cleared"; } catch (Exception e) { return "Threw exception: " + e; } } |
The fields in the @JmxOperation
annotation are:
String description
Description of the attribute for jconsole. Default is something like "someMethod operation".
String[] parameterNames
Optional array of strings which gives the name of each of the method parameters. The array should be the
same length as the parameterDescriptions
array. Default is something like "p0".
@JmxOperation(parameterNames = { "minValue", "maxValue" }, parameterDescriptions = { "low water mark", "high water mark" }) public void resetMaxMin(int minValue, int maxValue) { ... |
String[] parameterDescriptions
Optional array of strings which describes each of the method parameters. The array should be the same
length as the parameterNames
array.
OperationAction operationAction
This optional field is used by the JMX system to describe what sort of work is being done in this operation.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The JmxServer
class proves a server that jconsole and other JMX clients can connect to. The easiest way to do this is
to choose a port to use, define the server, and then start it:
// create a new JMX server listening on a port JmxServer jmxServer = new JmxServer(8000); // start our server jmxServer.start(); |
Instead of starting your own server, you can have the JmxServer
make use of the MBeanServer
that was started
by the JVM platform. It gets the server from a call to ManagementFactory.getPlatformMBeanServer()
.
// define a server that makes use of the platform MBeanServer JmxServer jmxServer = new JmxServer(true); |
Before your program exits, it is best to stop the server, so the following try/finally block is a good pattern to use:
// create a new JMX server listening on a port JmxServer jmxServer = new JmxServer(8000); try { // start our server jmxServer.start(); ... // register objects with the server and do other stuff here ... } finally { // un-register objects // stop our server jmxServer.stop(); } |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To published objects via the server via JMX you must register them with the JmxServer
:
jmxServer.register(someObject); |
There also is an unregister(...)
method which will un-publish from the server:
jmxServer.unregister(someObject); |
The objects that are registered must be named and the fields and methods that are to be exposed must be specified.
The register(...)
and unregister(...)
methods allow you to publish JMX information about dynamic objects
that get created and destroyed at runtime. For example, if you want to see details about an attached client connection,
you could do something like the following:
// accept a connection Socket socket = serverSocet.accept(); ClientHandler handler = null; try { // create our handler handler = new ClientHandler(socket); // register it via jmx jmxServer.register(handler); // handle the connection handler.handle(); } finally { socket.close(); if (handler != null) { // unregister it from JMX jmxServer.unregister(handler); } } |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sometimes, you want to expose a class using JMX but you don’t control the source code or maybe you don’t want to put the SimpleJMX annotations everywhere. If this is the case then you also have the option to expose just about any object programmatically.
The JmxServer
has a register function which takes just an Object
, an ObjectName
which can be generated with
the use of the ObjectNameUtil
class, and an array of attribute-fields, attribute-methods, and operations.
The object-name can also be defined using the JmxResourceInfo
object that defines the fields in the @JmxResource
programmatically.
JmxResourceInfo resourceInfo = new JmxResourceInfo("your.domain", "beanName", new String[] { "database", "connections" }, "your resource desription"), |
The attribute-fields are specified as an array of JmxAttributeFieldInfo
objects that are associated with fields that are
exposed through reflection:
JmxAttributeFieldInfo[] attributeFieldInfos = new JmxAttributeFieldInfo[] { new JmxAttributeFieldInfo("startMillis", true /* readable */, false /* not writable */, "When our timer started"), }; |
The attribute-methods are specified as an array of JmxAttributeMethodInfo
objects that are associated with fields that are
exposed through get/set/is methods:
JmxAttributeMethodInfo[] attributeMethodInfos = new JmxAttributeMethodInfo[] { new JmxAttributeMethodInfo("getRunTime", "Run time in seconds or milliseconds"), }; |
The operations are specified as an array of JmxOperationInfo
objects that are associated with operation methods:
JmxOperationInfo[] operationInfos = new JmxOperationInfo[] { new JmxOperationInfo("restartTimer", null /* no params */, null /* no params */, OperationAction.UNKNOWN, "Restart the timer"), }; |
To register the object you would then do:
jmxServer.register(someObject, ObjectNameUtil.makeObjectName("your.domain", "SomeObject"), attributeFieldInfos, attributeMethodInfos, operationInfos); |
For more information, take a look at the random-object example program. See random object example.
You can also use the PublishAllBeanWrapper
which exposes all public fields and methods as attributes or operations.
All public fields will be exposed as an attribute and if not-final will be exposed as writable. All public methods that
start with is
or get
will be exposed as attributes and if they have a set
method will be writable.
All other public methods will be exposed as operations.
Take a look at the publish-all example program to see working code that uses this class. See publish all example.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SimpleJMX also includes a programmatic, simple JMX client which you can use to interrogate JMX servers. You connect to the server by specifying the host and port.
JmxClient client = new JmxClient("server1", 8000); |
To get a list of the available beans use the
Set<ObjectName> beanNames = jmxClient.getBeanNames(); |
Then you can get the attributes and operations associated with an ObjectName
:
MBeanAttributeInfo[] attributeInfos = jmxClient.getAttributesInfo(objectName); MBeanOperationInfo[] operationInfos = jmxClient.getOperationsInfo(objectName); |
You can then get an attribute from the info or invoke an operation:
boolean showSeconds = jmxClient.getAttribute(objectName, attributeInfo.getName()); client.invokeOperation(objectName, operationInfo.getName()); |
You can also get attributes by strings instead of ObjectName
s:
boolean showSeconds = jmxClient.getAttribute("your.domain", "RuntimeCounter", "showSeconds"); |
If you need to construct the object name directly then you can use ObjectName
static methods. This is
particularly useful if you use Jconsole to find a bean that you want to operate on via the JmxClient
. Just
copy the ObjectName
field associaed to a bean from Jconsole and then do something like the following:
int availableProcessors = client.getAttribute( ObjectName.getInstance("java.lang:type=OperatingSystem"), "AvailableProcessors"); |
You can also call operations with string arguments:
client.invokeOperation(ObjectName.getInstance("java.lang:type=Memory"), "gc"); |
See the JmxClient
javadocs for more information
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SimpleJMX has an optional dependency on the Spring Framework jar(s). This means that if you have the Spring framework
included in your project, you can make use of the BeanPublisher
class which will automagically register the beans
from your spring XML configuration files to the JmxServer
class. The BeanPublisher
class will register
classes that have the @JmxResource
annotation, that implement the JmxSelfNaming
interface, that are of
type that are of type JmxBean
, and are of type PublishAllBeanWrapper
.
Here’s a sample bean configuration:
<!-- registers @JmxResource and JmxSelfNaming classes with the server --> <bean id="beanPublisher" class="com.j256.simplejmx.spring.BeanPublisher"> <property name="jmxServer" ref="jmxServer" /> </bean> <!-- our JMX server which publishes our JMX beans --> <bean id="jmxServer" class="com.j256.simplejmx.server.JmxServer" init-method="start" destroy-method="stop"> <property name="registryPort" value="8000" /> </bean> |
Notice that the JmxServer
is configured with an init-method
and destroy-method
which cause the JMX
server to be started and stopped when the application context is loaded and closed.
You can also wire a JMX bean for another bean that is not using the @JmxResource
annotation and does not implement
the JmxSelfNaming
interface with the help of the JmxBean
class:
<!-- some random bean defined in your spring files --> <bean id="someBean" class="your.domain.SomeBean"> ... </bean> <!-- publish information about that bean via JMX --> <bean id="jmxServerJmx" class="com.j256.simplejmx.spring.JmxBean"> <!-- helps build the ObjectName --> <property name="jmxResourceInfo"> <bean class="com.j256.simplejmx.common.JmxResourceInfo"> <property name="jmxDomainName" value="your.domain" /> <property name="jmxBeanName" value="SomeBean" /> </bean> </property> <!-- defines the fields that are exposed for JMX --> <property name="attributeFieldInfos"> <array> <bean class="com.j256.simplejmx.common.JmxAttributeFieldInfo"> <property name="name" value="someCounter" /> </bean> </array> </property> <!-- defines the get/is/set methods exposed --> <property name="attributeMethodInfos"> <array> <bean class="com.j256.simplejmx.common.JmxAttributeMethodInfo"> <property name="methodName" value="getSomeValue" /> </bean> </array> </property> <!-- defines the operations (i.e. non get/is/set) methods exposed --> <property name="operationInfos"> <array> <bean class="com.j256.simplejmx.common.JmxOperationInfo"> <property name="methodName" value="someMethod" /> </bean> </array> </property> <property name="target" ref="jmxServer" /> </bean> |
Take a look at the spring example program to see working code that uses this class. See spring framework example.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SimpleJMX contains a simple web-server implementation that uses Jetty so that you can access
JMX information from a web browser or other web client using the JmxWebServer
class. To use this class you
need to provide a Jetty version in your dependency list or classpath.
// first start the jmx server JmxServer jmxServer = new JmxServer(JMX_PORT); jmxServer.start(); // register your beans as normal jmxServer.register(counter); // create a web server listening on a specific port JmxWebServer jmxWebServer = new JmxWebServer(WEB_PORT); jmxWebServer.start(); |
We recommend that you run the JMX server even if you are planning to use the web server most of the time. You still
register beans via the JmxServer
and any beans added to the platform MBeanServer
will be visible via your
browser.
Take a look at the web-server example program to see working code that uses this class. See web server example.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SimpleJMX allows you to start your own JMX server on a particular port. One of the benefits of using the JmxServer
server instead of the JVM platform server is that you can specify both the registry and server ports. This allows you to
better control what ports need to be exposed through a firewall.
Sometimes, however, you will instead want to use the JMX MBeanServer
that is built into JVM platform and that is
enabled by command line parameters to the java
command. To enable JMX on the command-line you need to use the
following system properties:
com.sun.management.jmxremote
– turns on JMX
com.sun.management.jmxremote.port
– sets the registry port
com.sun.management.jmxremote.authenticate
– enables or disables authentication
com.sun.management.jmxremote.ssl
– enables or disables SSL connections
For example:
java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=9999 \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false \ -jar yourApplication.jar |
WARNING: You should disable authentication and SSL only if necessary. If you are trying to use JMX over an insecure network then this will create a security hole.
JMX is actually a two connection protocol. Your JMX client connects first to the RMI registry port which returns what
IP/port to call to connect to the application for JMX. Depending on the complexity of your network configuration, it may
be that the JVM attaches the JMX server to an IP that is not one that the client can contact. In this case, you may need
to use the java.rmi.server.hostname
property to define what name/IP the RMI registry should report back.
java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=9999 \ ... -Djava.rmi.server.hostname=<IP_ADDRESS> \ ... |
To run the JmxServer
but still use the MBeanServer
that was started by the JVM platform, you use the
boolean
constructor and pass true
to it:
// define a server that makes use of the platform MBeanServer JmxServer jmxServer = new JmxServer(true); |
There is also a jmxServer.setUsePlatformMBeanServer(true)
method to use with Spring injection.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To use SimpleJMX with maven, include the following dependency in your ‘pom.xml’ file:
<dependency> <groupId>com.j256.simplejmx</groupId> <artifactId>simplejmx</artifactId> <version>2.2</version> </dependency> |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Here is some example code to help you get going with SimpleJMX. I often find that code is the best documentation of how to get something working. Please feel free to suggest additional example packages for inclusion here. Source code submissions are welcome as long as you don’t get piqued if we don’t chose your’s.
This is a simple application which publishes a single object. See the source code on github.
This is an example showing how to programmatically expose using JMX a random object without SimpleJMX annotations: See the source code on github.
This is an example showing how you can use SimpleJMX with the Spring Framework. See the source code on github. The example spring config file is also available.
This is an example showing how you can use SimpleJMX to expose JMX beans over HTTP to web browsers. See the source code on github.
This is an example that shows how you can use the PublishAllBeanWrapper
to publish information about a random
object. See the source code on github.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document is part of the SimpleJMX project.
Copyright 2023, Gray Watson
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that this permission notice appear in all copies.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
The author may be contacted via the SimpleJMX home page.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| Jump to: | @
A C D E F G H I J L M N O P Q R S T U W |
|---|
| Jump to: | @
A C D E F G H I J L M N O P Q R S T U W |
|---|
| [Top] | [Contents] | [Index] | [ ? ] |
| [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Gray Watson on March 5, 2023 using texi2html 1.82.
The buttons in the navigation panels have the following meaning:
| Button | Name | Go to | From 1.2.3 go to |
|---|---|---|---|
| [ < ] | Back | Previous section in reading order | 1.2.2 |
| [ > ] | Forward | Next section in reading order | 1.2.4 |
| [ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
| [ Up ] | Up | Up section | 1.2 |
| [ >> ] | FastForward | Next chapter | 2 |
| [Top] | Top | Cover (top) of document | |
| [Contents] | Contents | Table of contents | |
| [Index] | Index | Index | |
| [ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated by Gray Watson on March 5, 2023 using texi2html 1.82.


Curly or dread hair style tutorial 03 Nov 2019, 16:45 by Dwayne Jones Dwayne Jones writes: Video tutorial on make curly hair or dreads in Blender.


Test 1
The Idea:
QED Services International, Inc, was contracted by Whitewater Unified School District to write an Expression Calculator to help their students learn basic algebra through calculus. As in the project was quite large in its scope, QED Services International, Inc, has subcontracted you to finish writing a “proof of concept” program for them. Under a previous contract, you’ve written a class for them, called fraction, but due to an excessive amount work, they have had to subcontract this entire portion of the project to you.
As we know, an Algebraic Expression consists of at least one term, where a term consists of constants multiplied by a variable raised to a power. Constants and powers, per the contract QED Services International, Inc, signed with you can be positive or negative fractions, positive or negative decimals, or positive or negative integers.
The goal of this project is for you to develop a "command line" Algebraic Expression calculator that will accept up to 26 arbitrarily long algebraic expressions composed of terms, as described above.
The program, named calculate, if started on the command line with no parameters, when ready for input, a prompt such as INPUT: or COMMAND: must be printed. After each successful operation, this prompt will re-appear asking for the next command. Naturally, if the user enters just the return key, then the program will terminate.
When the COMMAND: or INPUT: prompt appears, the user will have the following options:
They can enter one of the following commands: LET, EVAL, or PRINT.
a. The command LET must be followed by a space, then a letter (A – Z), a space, then an equal sign (=), then by the algebraic expression the user wishes to assign to this letter. (e.g. LET F = 2X + 4. The result printed upon successful completion will be F = 2X + 4 in this example.
b. The command EVAL must be followed by a space, then the letter representing a pre-stored algebraic expression, followed by the value within parentheses. (e.g. EVAL F(1/4) ) The program will then print F(1/4) = 4 1/2
c. The command PRINT must be followed by a space then the letter representing a pre-stored algebraic expression (e.g PRINT F). The program will respond by printing F = 2X + 4, for example.
2. They can enter one of the following:
a. An expression, such as F = G + H, where F, G, and H are all pre-stored algebraic expressions. Upon completion, the program will print F = 2X + 4, for example.
b. An expression, such as F = G - H, where F, G, and H are all pre-stored algebraic expressions. Upon completion, the program will print F = 2X + 4, for example.
c. An expression, such as F = G * H, where F, G, and H are all pre-stored algebraic expressions. Upon completion, the program will print F = 2X + 4, for example
d. An expression, such as F = G’, where G’ is the derivative of G. As with the proceeding, the resultant algebraic expression will be printed.
e. This is the same as the above, but with the ability to enter an arbitrary derivative (such as F = G’’’). As with the proceeding, the resultant algebraic expression will be printed.
3. They can enter LOAD followed by a file name. This will load up to 26 pre-defined, or saved earlier, algebraic expressions. (See below for additional when there are more than one parameter on the command line)
4. They can enter SAVE followed by a file name. This will save the contents of the 26 algebraic expressions to a file. As with all of the programs that you have done, the program must ensure that files are not accidentally overwritten and so forth. File names for these files must end in “.exp”
Command Line Parameters:
When there is one parameter on the command line after the name of the program, it will load the file associated with that name. If there is no extension on the name given, the default extension of “.exp” must be added to the file name before opening the file. Conversely, if there is a /h or /? As the parameter, then a “help message” must be displayed to the user and the program terminates.
When there are two parameters on the command line after the name of the program, the first parameter must be the word EXECUTE or RECORD. The next parameter is a “script” file, which is composed of commands, as stated from the above section which deals with input from the command line. If the word EXECUTE is present, then the program must read the file and perform all of the statements within the file. If the word in RECORD, then the program must save to a file all of the commands that the user enters in via the command line. Script files must have an extension of “.spt”; and, as above, the “.spt” must be added if the user did not provide it.
If there are more than two parameters on the command line, then the program must “error out.” This means to notify the user that the program will be quitting and why it did so.
Program Requirements
Hints:
Rules of the Test:
Extra Credit:
Hints:
http://www.repositorio.ufop.br/bitstream/123456789/4361/1/ARTIGO_ImplementingComputerAlgebra.pdf
https://en.wikipedia.org$WIKI_REFERENCE$/wiki/Symbolic_computation
http://www.ukma.edu.ua/~yubod/teach/compalgebra/%5BJoel_S._Cohen%5D_Computer_algebra_and_symbolic_comp(BookFi.org).pdf
Test 2
The Idea:
QED Services International, LLC, was contracted by Whitewater Unified School District to write an Complex Number Calculator to help their students learn how to do "arithmetic" with complex numbers. As in the project was quite large in its scope, QED Services International, LLC, has subcontracted you to finish writing a “proof of concept” program for them. Under a previous contract, you’ve written a class for them, called mixedNumber (that inherits from another class you have written called Fraction), but due to an excessive amount work, they have had to subcontract this entire portion of the project to you.
As we know, a complex number can consist of only a real number, only an imaginary number, or the "sum" of a real number with an imaginary number (3+2i, for example).
The goal of this project is for you to develop a program that will allow a user to input complex numbers (which can include only real number, only an imaginary number, or a "sum" of a real number with an imaginary number) that will be stored into "variables" labeled A to Z.. On input, only ONE complex number can be entered to assigned to a variable. All mathematical operations will be done with variables.
The program, named complexCalculate, if started on the command line with no parameters, when ready for input, a prompt such as INPUT: or COMMAND: must be printed. After each successful operation, this prompt will re-appear asking for the next command. Naturally, if the user enters just the return key, then the program will terminate.
When the COMMAND: or INPUT: prompt appears, the user will have the following options:
a. The command LET must be followed by a space, then a letter (A – Z), a space, then an equal sign (=), then by the complex number the user wishes to assign to this letter. (e.g. LET F = 2 + 4i). The result printed upon successful completion will be F = 2 + 4iin this example.
b. The command PRINT must be followed by a space then the letter representing a pre-stored complex number (e.g PRINT F). The program will respond by printing F = 2 + 4i, for example.
c. The command SAVE shall be followed by a filename. If the filename does not end in .complex, the program shall ensure that it ends in .complex by either adding this extension or correcting the extension that the user provided. Of course, all verification of overwriting files, etc, must be done.
d. The command LOAD shall be followed by a filename. If the filename does not end in .complex, the program shall ensure that it ends in .complex by either adding this extension or correcting the extension that the user provided.
e. The command EXIT shall exit the program. If the user has not immediately prior to this command saved the memory contents, the program shall prompt the user if they wish to save the data to a file. If they do, the restrictions for SAVE apply.
f. The command WEXIT shall be followed by a filename. The program will exit the program after following the guidelines for SAVE above.
2. They can enter one of the following:
a. An expression, such as F = G + H, where F, G, and H are all pre-stored complex numbers. Upon completion, the program will print F = 2 + 4i, for example.
b. An expression, such as F = G - H, where F, G, and H are all pre-stored complex number. Upon completion, the program will print F = 2 + 4i, for example.
c. An expression, such as F = G * H, where F, G, and H are all pre-stored complex number. Upon completion, the program will print F = 2 + 4i, for example
d. An expression, such as F = G^H, where F is the result of raising G to the H power (in complex number operations). As with the proceeding, the resultant complex number will be printed.
e. An expression, such as F = G / H, where F, G, and H are all pre-stored complex number. Upon completion, the program will print F = 2 + 4i, for example
f. Compute the Conjugate of Complex number by entering F = ~G. F would then hold 2 - 4i if G held 2 + 4i
g, Trig(F) would display the polar coordinate version of the complex number.
3. They can enter LOAD followed by a file name. This will load up to 26 pre-defined, or saved earlier, complex numbers. (See below for additional when there are more than one parameter on the command line)
4. They can enter SAVE followed by a file name. This will save the contents of the 26 complex numbers to a file. As with all of the programs that you have done, the program must ensure that files are not accidentally overwritten and so forth. File names for these files must end in “.complex”
Command Line Parameters:
Program Requirements
Hints:
Rules of the Test:
Extra Credit:
Write a program that will take an algebraic expression consisting of mixed numbers, integers, decimal numbers, or fractions and the basic mathematical operators (add, subtract, multiply, divide, and parentheses) and then re-write the algebraic expression in Reverse Polish Notation. (see http://en.wikipedia.org$WIKI_REFERENCE$/wiki/Reverse_Polish_notation and http://en.wikipedia.org$WIKI_REFERENCE$/wiki/Shunting-yard_algorithm )
Notice that in order to do this, you must have a stack!!!! C++, graciously, has a pre-made stack which you can use. You must include <stack> and tell it what type of data you'll be sending it. cplusplus.com has complete documentation on the built-in stack class.
Examples:
Algebraic <==> RPN
3 * 4 <==> 3 4 *
3 * ( 4 + 2 ) <==> 4 2 + 3 *
(4 + 5) / ( 5 + 6) <==> 4 5 + 5 6 + /
In order to do this assignment, you must develop a class that will accept a C++ string, using the insertion operator (<<) and then, via the extraction operator (>>) it will place the resultant RPN expression into a string. Conversely, the class may need to read from a file or the console, and write to either.
Your program must take as input from the command line a file that contains one or more algebraic expressions and write out a file with the RPN translations of each algebraic expression. If the command line is empty, then it must prompt for an expression, and keep translating, until an empty line is entered.
Revise the Shunting Yard program so that will take an algebraic expression consisting of positive or negative real numbers, fractions, mixed numbers, or integers and the basic mathematical operators (add, subtract, multiply, divide, and parentheses) and then re-write the algebraic expression in Reverse Polish Notation. For this version, you must verify that the numbers entered are correct (meaning 4.2.2 is NOT a valid number!) (see http://en.wikipedia.org$WIKI_REFERENCE$/wiki/Reverse_Polish_notation (Links to an external site.) and http://en.wikipedia.org$WIKI_REFERENCE$/wiki/Shunting-yard_algorithm (Links to an external site.) )
Notice that in order to do this, you must have a stack!!!!
Examples:
Algebraic <==> RPN
3.5 * 4.2 <==> 3.5 4.2 *
3 * ( .14 + 2.1 ) <==> 0.14 2.1 + 3 *
(4 + 5) / ( 5 + 6) <==> 4 5 + 5 6 + /
1. Fix the program, doubleDimensionArray, done in class on 9/5/18 so that the program does not de-reference a null pointer as well as the other "errors" that are in the program.
3. Write a program that will read the files created by the program above and display them on the screen and allow the user to edit the data by row and column address. After all editing, the program will rewrite the file with the modifications. Note that editing can include deleting all content, changing the value(s) in any particular cell(s), or reloading the matrix with random numbers within a given range. The program must "guarantee" that files will not be overwritten; unless the user desires the file to be overwritten.
Write two programs, one which will ask the user for the following information:
When the program executes, it will write to the file the number of random numbers the file contains first, then the random numbers. If writing to the screen, the numbers must be in equal sized columns, with the column size based upon the largest number of digits, including the negative sign, plus two spaces. (HINT: The number of digits in a positive integerr is 1 + (int)log10(n) where n is the number in question.)
The second program will ask the user for the name of the file to be read, or given via the command line as an argument to the program, and then dynamically create an array. Then it will read in all of the numbers, and then display them in unsorted and sorted fashion (with, of course, the output being in proper columnar form.
Both programs must check for "errors" and handle accordingly. (Such as the input file not existing, the output file already existing, and so forth.)


?6
7
8
9
10
The
New
York
copyright
reserved
Botanical
Garden
FLORA
NEOTROPICA
Sideroxylon
salicifolium
(L.
)
Lam.
T.D.PENNINBTQN
1986
PLANTS
OF
THE
DOMINICAN
REPUBLIC
Dipholis
salicifolia
(L.)
A.
DC.
Pet.
Bio.
Alain
H.
Liogier
Tree,
5
m.
high
+;
flowers
ferrugi
neous;
common
on
calcareous
soil
Ca–ada
del
Agua,
Payaso,
Barah©na
Prov.
PROF.
MARCANOŃCOLECTOR
nÁ>.
5217
herb.jimenez
March
20,
1967
NEW
YORK
BOTANICAL
GARDEN
EW
Yo^S
BOTANICAL
g4(?dfN
.
01443888
01443888
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


| Haward Robinson | |
|---|---|
| Email: |<EMAIL_ADDRESS>|
| Contact: | +8801812345678 |
| Country: | Bangladesh |
| State: | Dhaka |
| City / Town: | Dhaka City |
| Area: | Dhanmondi |
| Zip: | 1205 |
| Address: | House: 76/A, Green Road, Kathal Bagan |
| Rating |
| Haward Robinson | |
|---|---|
| Email: |<EMAIL_ADDRESS>|
| Contact: | +8801812345678 |
| Country: | Bangladesh |
| State: | Dhaka |
| City / Town: | Dhaka City |
| Area: | Dhanmondi |
| Zip: | 1205 |
| Address: | House: 76/A, Green Road, Kathal Bagan |
| Rating |


Apr 25, 2017
Modular Interfaces
Modular UIs are easier to edit in the long run. When your interface is divided into distinct parts, you can also separate chunks of code by following that divisions. Than you can adjust to the real world without tedious redesigns:
- You can just swap UI modules in an HTML or template file.
- You can edit a module in its own file — no need to dig into complex code that’s responsible for many things.


ch.lambdaj.function.closure
Interfaces
ClosureResult
Classes
Closure
Closure0
Closure1
Closure2
Closure3
Closure4
ClosuresFactory
DelayedClosure
Switcher
Exceptions
WrongClosureInvocationException


Work
Contact
About
More design..
aniela Trulls
hello hellooooooo
E-comerce: Home Decor
E-conerce - Hme Decor
Album Rater
Plato Bookshop
Daniela
Trulls


Fly
By cloudwalker 2020
You put me on the outside
what did you expect would happen
I had no choice
but look in
at it
and wonder
Wits
By cloudwalker 2020
I didn’t come to fool you
you were there without your wits
I had to put a price on it
then
you deemed yourself unfit
in ten minutes you said 3 months
its never going to be enough
I am now here to fool you and call your bluff
you choose not to listen nor to read
so I took the truth away
you've not one wit to lead
as you signed the end of my delay
scribbling in a tiny note book
with your mumbling something and nothing
I started not to care
but I'm still feeling angry
when you rush to your lair
I guess your off then
to find your missing wit
the moral of the lesson though was to not be such a big twit
Sorry
By cloudwalker 2020
arriving together without a backbone between them
mr devils advocate, mr fudge and mr poker face
micro facilitator translator transcriber judge jury attack-dog and note-taker but not mediator
then a diva deceiver don’t believe her took up the lead
with
surround sound their impacts were read
but as I had practiced
telling them I was sorry
practicing and practicing
just to pretend
not to be heard
had to be careful with what I said
as
diva deceiver don’t believe her opened her mouth
I interrupted
asking note-taker I wasn't aware of a law for this kind of stuff
then thinking and feeling so mean
I wanted to take a pin
and prick the fat bloated queen.
leaving rather quickly still no backbone between them
headfirst they squeezed down the shaft in a flurry
as for lies dont worry
and for truth its too late
words are just words and quite out-of-date
I didn’t mean to say sorry, sorry
I only came to pretend
I only came because I had to
to play your game right to the end.

The virus chooses a new costume everday and Fridays
to enthrall themselves and all who attend
you think to yourself
is this it
you hesitate
you cant think
your like on the brink
you dont want do what your told
your suspicious and clever
you want to live forever
but the bully
is now chucky, dressed like a five year old
better be careful while I work
better be careful of the bark
better mind my back
better shut-up keep myself still and keep my mind sharp
its like stepping in dog shit with every step you take
its feeling like it should be home time your tired and withdrawn
then you realize its just gone dawn
its like running a race but your going the wrong way
and you then realize you are the only one made to pay
it feels like a bad dream
you want to scream but nothing comes out
and your stuck in a play
its only act one scene number two
when two old muppets say
it was terrible
it was rubbish
Booooooooooooooooo
If the bully had half a brain
it would be dangerous
no mistake
if you took that pin and pricked
it would burst flatulence
it will summon its minions its toys and demons
it will attack you
hurling insults smirking belching farting and poking
no i'm not joking
take courage and the knowledge
if that’s how they behave
that your doing the right thing and your ok
put up a fight
its better to be brave
your going to live
your going to breath
your human
and you will live to see another day
Virus
By cloudwalker 2020
Act 1 scene 1 - Its there before you get there
On day one
I see you’ve defaced my cv
I don’t say a word
but
still your keen to tell to me shut-up
as you talk
value in opinion is important
whether 1 day 5 year of service here.
Still I have said little
when
sly-man goes by with a twittle.
'Why don’t you go and do the dishes’
‘Your not being resourced on anything’
‘Go solve it yourself because we don’t know’
‘Do you have any friends here’
‘Well pick it up we’re not moving’
'Well I hope youv'e washed it, your old skirt'
‘You don’t have any allies here do you do you do you’
‘I can’t be seen with you’
Stickies with ‘who’s-your-best-friend’
I still say little.

Your women’s meeting is a sham
a ridicule
to blame another man.
Atrocities down south
you’re proud to claim
you don’t care about what
happened
down there
you’re are not from here
so you just don’t care.
Wāhine shame.
Act 2 Scene 1 - Precious
You have plentiful words like
pineapple, llama and dinosaur stickers
for person of the day
fantasy figurines, costumes and colouring-in
precious
to
reward
stifle conversation, demolish and prove others worthless.
You have celebratory cakes with a machiavellian twist
icy toppings and bitter undertones
glasses of what-is-your-poison
with a generous dash of nepotism from the fizzy wine under you desk
lashings of unsavoury liaison
to the man clutching matching tattoos
tightly coupled with hr
precious.
Bizzare.

Muting
And back-stabbing colleagues makes your day
contempt is a hammer for those who in your way
Then choosing a good dash of
grooming
monitoring
those it will let stay.

Well she has had all the chances
as you beckon me in
to unwittingly participate
for an informal what-is-it day
to which I asked for in self review.
But its a calculated manipulation
a sabotage a cover
I just don’t know it
yet.
One head is in a telly and note-taker is voice over.

So I make a quick decision
before its to late
I get up
while your heads still in the tv
quick
I’m out the door
before you know I have even gone
I swear.
This is it
going back is just wrong
you didn’t can’t won’t think
what are the chances of this happening.
Code Smell
By cloudwalker 2020
Part 1. Deep Dive
26 have gone including me
I’m exiled and isolated
a quiet relief
It gives me
time to peruse
be home undercover
checking your rules or is it a ruse
The clean-up
is underway
sweeping swathes of documents out of the way
details are ignored, destroyed and manipulated.
Its covering up its tracks
wiping the slate clean
deleting records and tirades of messages that match
permissions changed
new rules made after the fact.
You think I’m daft
but I have a good memory
copies, notes and recordings
of
private and confidential info that you slacked
of me
for a discord.
Part 2. Pluck
You write about diversity for all fellows
but those words aren’t even yours
you’ve plucked and cherry-picked someones else’s values
misused
misguided
misinformed
misinterpreted
shape unshifting a culture
adorning bad behaviour
powering those
care plans
collateral
to
give yourself favour.
Part 3. Hocus Pocus
Your congratulating yourselves
for
fast tracking immigration
they are better passing through
adorning yourselves with promotions
and
back-tracking
accolades for seeing it through
to keep
you agreeable
you happy
oh
what fun it must have been
for you.

If it isn’t enough
you overcharge and deceive the man
does he know it. Probably.
Gossiping is
unhealthy don’t you know it can make you green
with
your constant reviews and your magic pen
nagging
dragging me down
down the rabbit hole.
Down
down
down.
Done.
Wasp can gasp
By cloudwalker 2020
Orchestrating its moves
the wasp gathers momentum
it can’t dance like a bee
nor jump like a flea
it can’t glide like a monarch
or tread softly like me
but
for hysterical theatrics
a show
fantastic
with a sting in its tail the wasp can gasp
its a
cheap nasty thrill with a poisonous rasp
Mr No and Mr Basic
cloudwalker 2021
coming...
Thrive St
By cloudwalker 2020
If there was a law for playing the
game of work
fairly
how would it go
If you bully, intimidate or harass you forfeit {n} turns
and will need to skip backwards
to Humble St
singing ‘the woolly mammoth is dead’
all day
every day
till game end.
 I did”
and
be put on a games watch list.
...
stand on Hibull St and...


Ghani hold talks with top U.S. officials regarding the release of high level HQN leaders
by Khaama PressThe Afghan President Mohammad Ashraf held talks with the top U.S. officials to review steps for the release of high level leaders of Haqqani terrorist network.
Presidential spokesperson Sediq Sediqqi said “In two separate phone calls, President Ghani spoke to Secretary Mike Pompeo and National Security Adviser Robert O’Brien on November 18 to review the steps necessary to implement President Ghani’s recent decision to release the three high-level Taliban/Haqqani detainees.”
Sediqqi further added “The U.S. officials reiterated their support for President Ghani’s decision and committed to work closely together to respond to any possible Taliban violence in the event the group don’t respond in good faith.”
“Both sides agreed that a ceasefire and/or a reduction in violence was a necessary pre-condition for kick-starting the intra-Afghan negotiations to reach a political settlement,” he said, adding that “Both the Secretary and Ambassador O’Brien praised the performance of the Afghan security forces including their ongoing efforts in eliminating ISIS-K’s safe havens in Nangharar, and reaffirmed continued American support to these forces so that Afghanistan can never again be used as a platform for international terrorism.”
Sediqqi had earlier announced that the government has reversed its decision to release the three high level Haqqani terrorist network leaders, blaming the Taliban group for the suspension of the prisoners swap.
He said the Taliban group failed to respect the conditions of the swap process, emphasizing that the government would take further actions in the light of the interests and benefits of Afghanistan.
President Mohammad Ashraf Ghani last week announced that the government is intending to release the three senior Haqqani network leaders in exchange for the release of the two American University lecturers.
The Taliban group kidnapped the two American University lecturers from West of Kabul city in August of 2016.
Author
-
The Khaama Press News Agency is the leading and largest English news service for Afghanistan with over 3 million hits a month. Independent authors/columnists and experts are welcomed to contribute stories, opinions and editorials. Send stories to news@khaama.com.


Welcome to DecentLand . . .
under construction
decent.land is a social media network built on Arweave's Permaweb.
To be more precise, Decent Land is a lego of self and sub-protocols.
You can register (create) account on decent.land using your Arweave wallet only!
Once you register, an username will be bound to your wallet address. However, usernames aren't unique, user's uniqueness is identified by user-id which is the public wallet address .
Permanent registration @ UBul0QyGMKtJZ0PFBZRSO_M7CEBm7e9eWh-MJClG7go
the Tribus is a new kind of social network communities, it's an "chat over PSC" . That is, a PSC or Profit Sharing Community is like the DAO on Ethereum. A Tribus is like a community owned subreddit The admin have no power over the community members, unless they unite on one decision -- democracy
The Tribus is based on the Community Ownership Economy model.
PublicSquare Tribus homepage @ : fPA6DRraKyGQOFc1kIKOnm0XBflgsG8jyoVSVHWf4jM


Games
Meld
Threes
but with autoplay AI
Ya See?
Yahtzee but in
PICO-8
Friendl
Wordle
but with local 2 player, kinda like Mastermind.
Dance
Base movement logic and a single scene of
Crypt of the Necrodancer
- June


The application encountered an error whilst processing your request.
Please check application logs for more details.


Datasets
To create these maps we will be using the following datasets:
Boroughs - New York City boroughs. Download from NYC Planning - Open Data. Choose "Borough Boundaries (Clipped to Shoreline)", under "Borough Boundaries & Community Districts".
MapPLUTO - New York City MapPLUTO file (latest version), containing all the lots in New York and their attributes. The original PLUTO files can be downloaded from NYC Planning - Open Data. For more information about the PLUTO files and what each of the fields means take a look at the useful PLUTO data dictionary (in the same link).
Hydrography - New York City hydrography. Download from NYC Open Data. Once you get to the NYC OpenData page, click
Export
and choose theShapefile
format.Planimetric - New York City planimetric data. Download from NYC Open Data. This is a pretty large dataset. It includes geographical data for boardwalks, curbs, medians, parks, open space, railroad, and roadbed, amongst others. This dataset comes in the form of a
geodatabase
. Download the zip file.Building footprints - New York City's building footprints. Download from NYC Open Data. Once you get to the NYC OpenData page, click
Export
and choose theShapefile
format.NTAs - New York City's neighborhood tabulation areas. Download from NYC Planning - Open Data. These are not the traditional NYC neighborhoods. These areas "were created to project populations at a small area level, from 2000 to 2030 for PlaNYC, the long-term sustainability plan for New York City... This criterion resulted in combinations of neighborhoods that probably would not occur if one were solely designating boundaries of historical neighborhoods. Moreover, the neighborhood names associated with the neighborhood tabulation areas are not intended to be definitive." Once you get to the NYC Planning Open Data page, download the
shapefile
format.
A packaged file of the above data can be found at brwn.co/L1D. Note that this package may contain partial datasets meant for this tutorial. To get the full datasets please refer to the links above.
Adding Layers
The first step in creating a basic map is to open QGIS and add the layers you downloaded.
To add shapefiles click on the
Add Vector Layer
button. Other types of data will be added using the other buttons, but in this tutorial we will only be using vector data (shapefiles). Other types of data include rasters, csv (comma separated values), and postGIS layers.Start by adding the Boroughs layer. The reason we start with this one is because we know it has the right projection for New York City (NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet). Since map projects will automatically take the projection of the first layer we add, by loading this layer first we make sure we are working with the right one.
Under
Soruce
, click on the three dots and make sure you select the file with the extension.shp
. Remember that a shapefile is actually made up of 5 or 6 individual files with different extensions. Normally, these individual files are the following:.shp - The main file that stores the feature geometry (required).
.shx - The index file that stores the index of the feature geometry (required).
.dbf - The dBASE table that stores the attribute information of features (required).
.sbn and .sbx - The files that store the spatial index of features (these might get corrupted, see note at the end of this tutorial).
.prj - The file that stores the coordinate system information.
For more information on these extensions and others see this explanation by ESRI.
To double check your map took the right projection, take a look at the bottom right corner of your computer and verify that it says
EPSG:2263
, which is the "European Petroleum Survey Group" code for the NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet projection.Go ahead and add the rest of the files you downloaded, except for the planimetric data.
For this one, you need to choose
Directory
underSource Type
, and underType
chooseOpenFileGDB
. Choose the folder, not individual files inside it. And once you hitAdd
, QGIS will prompt you to select one or multiple layers to add. Here, select and add the one calledRoadbed
.Once you've added all the layers you downloaded, you need to organize them in the layer panel. Remember that the layers will be drawn in the same order they appear in the panel: the top layer will be drawn last, on top of the other ones.
The final order of the layers should be something like this (from top to bottom):
Building Footprints
Roadbed
MapPLUTO
Hydrography
Neighborhood Tabulation Areas
Boroughs
These layers will probably come with different names but you can rename them by right-clicking on them in the Layers Panel and selecting
Rename
.If when you zoom in to one of the layers some of its features disappear see the note at the end of the tutorial.
Basic Symbology
Symbology is one of the most important concepts in mapping.
At its most basic level, symbology stands for changing the color, line weight, size or outline of a layer.
However, and more importantly, it also means changing the appearance of a layer based on one or multiple of its attributes.
In this tutorial we will do both, simple color changes and more advanced symbologies based on attributes.
As you may have seen, QGIS assigns random colors to each of the layers you add. To change the appearance of each layer do the following:
First, since we are interested in creating a land use map of a part of New York, you should zoom in into our target area. To do this, right-click on the Lots layer and click
Zoom to Layer
. This is also very useful when for some reason you've panned away from your layers and you can't find them on your map. Just right-click on any of them and selectZoom to Layer
to go back to them.Second, let's deactivate the layers we won't be using for now, so that we don't see them in the map. These are the building footprints layer and the neighbohood tabulation areas one.
There are multiple ways of changing the appearance of a layer. The easiest (and simplest) is to double-click on the icon (point, line or polygon) next to the layer name, or on the actual layer name on the layer panel. This brings up the
Layer Properties
panel. There, selecte theSymbology
tab. In there you can change the fill (color), stroke weight and fill (outline) and the size of the icon (if using points or icons).In this panel change the style for the following layers in the following ways:
Roadbed:
Fill color: #ffffff (HTML notation)
Fill style: Solid
Outline style: No pen
Hydrography:
Fill color: #d4e9ed (HTML notation)
Fill style: Solid
Outline style: No Pen
Boroughs:
Fill color: #ececec (HTML notation)
Fill style: Solid
Outline style: No Pen
To change the appearance of the background, select the
Project
menu, and in there selectProject Properties
. Then, in theGeneral
tab you can change theBackground color
to #d4e9ed (HTML notation) to match the water layer.
Classification by Categories
Finally, we will symbolize the PLUTO (Lots) layer. However, since we want to differentiate between the different land use types, instead of simply symbolizing all the features in the layer with the same color, we will classify it based on different categories in its attribute table.
First, right-click and open the layer's attribute table. There you will see a field called
LandUse
which contains a code for each of the 11 land use types (more information on the land use field, and on all the fields in this dataset, can be found in the PLUTO Data Dictionary). This is the code we will use to symbolize the layer. Close the attribute table.Just like for the other layers, right-click on the Lots layer and choose
Properties
. Go to theSymbology
tab. Here, however, chooseCategorized
instead ofSingle symbol
in the drop-down menu at the top.Next, choose the
LandUse
field in theColumn
option.Click on
Classify
to classify the data and display the different values. Here, QGIS goes through all the values in the attribute table for that particular field and assigns a color to each one of them. The default color assignment is random.Land use maps have a standard set of colors so we have to go into each type and manually change the color. Double click on each symbol and adjust them according to the following list:
01 (One & Two Family Buildings): #fffebc
02 (Multi-Family Walk-Up Buildings): #f3ab3d
03 (Multi-Family Elevator Buildings): #9e7025
04 (Mixed Residential & Commercial Buildings): #ef9c6f
05 (Commercial & Office Buildings): #d64139
06 (Industrial & Manufacturing): #a060c3
07 (Transportation & Utility): #f7cffc
08 (Public Facilities & Institutions): #3b70f6
09 (Open Space & Outdoor Recreation): #81af79
10 (Parking Facilities): #ababab
11 (Vacant Land): #2c2c2c
In addition, add the land use type name in the
Legend
column.Finally, to change the outline for all the categories, click on the
Symbol, Change...
button and set the stroke color to #999999 and the stroke width to 0.1 milimeter.Click
OK
to close the properties panel.
Adding Labels
We will use the Neighborhood Tabulation Areas layer to add some labels to our map.
First, activate it by clicking on the checkbox next to its name on the Layers panel. Next, double clikck on it to open its properties.
Under
Symbology
chooseNo symbols
.Under the
Labels
tab chooseSingle labels
. And underLabel with
choose the "ntaname" column.If you click
OK
you will notice that some of the labels say something like "park-cemetery-etc". In order to not display these labels we will create a "rule based" label expression. Go back to the layer's properties and in theLabels
tab, chooseRule-based labeling
instead ofSingle labels
. Here we will write a short rule to ignore those labels that begin with "park-cemetery".Here, double click on the "+" sign at the bottom of the panel to add a rule. Then, next to the
Filter
option, type the following rule:"ntaname" not like 'park-cemetery%'
. Finally, below make sure in theLabel with
field you select "ntaname".Finally, to make sure the text is more visible, add a white
Buffer
around it.Click
OK
to close the properties panel.
Print Composer
The Print Composer is where you will format your map for its final output. Here you will specify the output size, you will add a legend, a scale bar, a north arrow (if needed) and any additional text (titles, sources, explanations and credits). Although the Print Composer exists as its own window it will still be linked to the map Project we have been working on.
First, create a new Print Composer in
Project
,New Print Layout
. Give it a custom name if you want, although this is not necessary.Once you are in the Print Composer you need to add a new map. Think of it as if you had a blank piece of paper and you were adding a window onto the map you've been working on. That window is a link to your Project and if you change things in the Project those changes will still be reflected in the Print Composer.
To add a new map, click on the button
Add new map
on the left-hand panel and draw a rectangle on the blank page.Once you add the map you can adjust its size and position by dragging it from its corners.
You might notice that if you change the size of the map it doesn't necessarily update. To avoid this, on the right-hand panel, where it says
Main properties
, click onUpdate preview
.To move the content inside the Print Composer (as opposed to the whole page) use the
Move item content
tool on the left-hand panel.Next, you need to center and zoom in the map on the area you want to focus on. For the purposes of this tutorial, we will center around downtown Manhattan and downtown Brooklyn. To do this, move the content of the map to this area and on the right-hand panel, under
Main properties
, adjust yourScale
to 28,000.If any of the colors or line weights seem too big or two small or not correct, you can always go back to the Project and change them there. When you return to your Print Composer you can update your preview and the changes will be reflected.
Add a scale bar by going to
Add Item
Add scalebar
and clicking on the map.The default scale bar is too big. To change this, go to the right-hand panel, in the top part make sure you select the
Scalebar
, and adjust its properties in theMain Properties
panel. You can also adjust its units, its colors and even its font.To add a legend click on
Add Item
Add legend
and then click on the map. You will notice that QGIS automatically generates a line in the legend for every layer in the map. We only need the land use ones, so we need to customize the legend:On the right-hand panel, under Legend items uncheck
Auto update
and then select the layers that you don't want in the legend and remove them with the 'minus' button. Do the same thing inside the Lots layer with the categories you don't want to display.Also, further down, uncheck the
Background
option.Under
Spacing
change theSymbol space
to 0.00mm.And under
Fonts
change theItem font
to 8.Since we did not rotate the map we don't need to add a north arrow. If you rotate your map you must add a north arrow. If you wanted to, you could add a north arrow by clicking on
Add Item
Add arrow
.Finally, to add a title and a 'source' text, click on the
Add new label
button on the left-hand panel and click on the map. Customize these labels by changing their color, size and location.The last step is to export the map as a .pdf file. Use the
Export as PDF
button on the top toolbar and save your map.Your final map should look something like this:
Classification by Values
The second map we will create will show the heights of the buildings in this same area. However, since what we are showing now are continious numerical values, we will use a graduated classification method, as opposed to a categorized one. In addition, this time we will use the building footprint layer instead of the lots one.
Return to your map project and deactivate your Lots layer and activate your BuildingFootprints one.
Now open the attribute table of the BuildingFootprints layer. You will notice a field called
heightroof
. This is the one we will symbolize on this map.Open the BuildingFootprints properties and in the
Sybology
tab chooseGraduated
. In theColumn
field chooseheightroof
and hit theClassify
button in the bottom.You will notice that QGIS creates 5 classes. This default classification method is called
Equal Interval
. Before you hitOK
click on theSymbol
button and set theStroke style
toNo Pen
. This way you'll be able to see the results of the classification method much better.Once you hit
OK
you will notice that with this classification method the tallest buildings appear red but the majority of other buildings are all grouped into the lowest group and are all white.Open the
Symbology
panel again and click on theHistogram
tab. Click onLoad Values
. Here, you can clearly see how this classification method is creating the buckets for your data. As you can see, most of the values are somewhere below 100, and they are all grouped into a single bucket.Now go back to the
Classes
tab and change the classification method toNatural Breaks (Jenks)
. You might get a warning saying that this method could take a long time. If you have a large dataset you should be careful. However, the dataset that we are using is small enough. Once the classification is done, go to theHistogram
tab. You can see how QGIS has now created different buckets and most of the shorter buildings are spread amongst the two first buckets. The Natural Breaks (Jenks) methods attempts to minimize the difference within groups while maximizing the difference between groups. Many datasets will be best classified using this method.Other methods of classification include Quantiles and Standard Deviations. Go ahead and explore them and see how they change our perception of the data on the map.
Finally, choose the Natural Breaks (Jenks) method and change the
Color ramp
toMagma
. Once you've done this, right-click on the color scale and chooseInvert color scale
.The last step is to adjust a bit the values to make them easier to understand. Double-click on each row and change the value to the following:
0-50
50-100
100-250
250-800
800-1408
Click
OK
to close the properties panel.
Definition Queries
Now, let's say that you want to add a layer showing the parks, just to give our map a bit more context. We could take the Lots layer, symbolize it by land use again, and make all other land use types, except for parks, tranparent. But there's an easier way. We can write query to only show those features where the field land use equals the one we want.
From the preivous map we already know that we can use the
LandUse
field in the Lots layer to select the parks. The corresponding value is '09'. So first, activate the Lots layer again by clicking ont he checkbox next to it in the layers panel and then double-click on the layer to go to itsProperties
.In the
Properties
window go to theSource
tab and there click on theQuery Builder
button.Now in the scroll through the fields and double-click on the
LandUse
on. You will see it populate theProvide specific filter expression
window.Next, either type or click on the "=" sign, and then click on the
All
button. This will bring up a list of all the different values in that field.As you can see, all the LandUse values are there. Double-click on "09" to make it appear in the
Provide specific filter expression
window. Now the full expression should read"LandUse" = '09'
.You could also directly type in the expression but just be careful with the use of single and double quotations. Single quotoation marks denote a
String
(a piece of text), and double quotations denote a field.Once you do this you will see that only the parks and open spaces are visible from the Lots layer.
The last thing to do is to give the featues in this layer a color that denotes parks but that doesn't distract too much from what we are trying to show - the heights of the buildings. To do this go to the Lots layer
Properties
and in theSymbology
tab chooseSingle symbol
. Give this symbol a fill color of #d5ebd6.Finally, return to the
Print Composer
and add all the necessary elements to your map: legend, scalebar, title, and source.Your final map should look something like this:
Note
If, after adding some dataset, you zoom in and some of the features disappear,
you probably need to rebuild the dataset's "Spatial Index". To do this right-click on
the layer, select Properties
and go to Source
. Under
Geometry and Coordinate reference system
click on Create Spatial Index
.
This should solve your problem. Sometimes, specially with the New York City PLUTO files,
the "Spatial Index" is tied to one of the attribute fields and when you zoom in only
the features with that specific attribute show up. "Spatial Index" are specially useful
when doing operations over large datasets, for example see this post.


- Software Engineer -
- Full Stack Developer -
- Always Learning -
Hello, world! My name is Jonathan Yang and I am a full stack software engineer living in Southern California. I love learning, building, and designing new things! I'm always exploring online resources in the pursuit of personal growth.
Learning about current trends, best practices, and gaining knowledge should be never-ending! I also enjoy collaborating with others and view every challenge as a new opportunity. Feel free to take a look at my resume and reach out if you have any questions!