We are aiming to maintain high competency and provide high quality data analysis services to all our Galaxy users.
Therefore we request that you acknowledge this service by including the members of the Australian Galaxy Team as co-authors if they have made a significant intellectual and/or organizational contribution to the work described (conceptualization, design, data analysis, data interpretation and/or input into drafting, revising or writing any portion of the manuscript).
If you use Galaxy Australia in your research, please cite the GVL paper:
Afgan E, Sloggett C, Goonasekera N, Makunin I, Benson D, Crowe M, Gladman S, Kowsar Y, Pheasant M, Horst R, Lonie A. Genomics Virtual Laboratory: A Practical Bioinformatics Workbench for the Cloud. PLoS One. 2015 Oct 26;10(10):e0140829.
Additional funding of projects and/or provision of material expenses are welcome as well, to help support our growing Galaxy community in Australia.


Vital's Details
Vital's Details
Height
Weight
Calculated BMI
Temperature (°F)
Pulse
Respiratory Rate
Blood Pressure
 /
Blood Oxygen Saturation


{{template "stylesheets" .}}
Brucheion 1.0.0
NEW WORK
User: {{.user}}
WorkURN:
Please enter a CTS URN: It has 4 colons (and ends on one ending on one). After "urn:cts:[yourcollection]:", you have to provide at least workgroup ID and work ID separated by a ".". Additionaly, you can provide version and exemplar IDs.
Scheme:
What is the citation scheme of the work? For example, "1.1.1" could resemble "book/chapter/paragraph".
Workgroup:
Workgroup in natural language.
Title:
Title in natural language.
Version:
Version in natural language.
Exemplar:
Exemplar in natural language.
Online:
Boolean; usually "true".
Language:
Language ID


All the standard button swatches can be applied to lists. The framework assigns a default list theme swatch of "c" (silver in the default theme) and swatch "b" (blue in default theme) for dividers. Below is a default themed list.

The list item color scheme can be changed to any button color theme swatch by adding the data-theme
attribute to the list, and setting the letter theme swatch. Here is the same list above with the "a" swatch applied.

data-theme attributes also work at the LI-level, for styling a single item.
The theme for list dividers can be set by adding the data-divider-theme
to the list and specifying a swatch letter. Here is an example of the same list above with swatch "d" set on the dividers.

The theme for count bubbles can be set by adding the data-count-theme
to the list and specifying a swatch letter. Here is an example with swatch "e" set on the dividers.

The default icon for each list item is arrow-r
. To override this, set the data-icon
attribute on the desired list item to the name of a standard icon. To prevent icons from appearing altogether, set the data-icon
attribute to "false".

Notices

Alerts

No icon

For split lists which a second button, the framework default to "b" for the theme swatch (blue in the default theme) Here is a default split list:

To specify the color swatch for the icon button on the right, add the data-split-theme
to the list and specify a swatch letter. This attribute can also be added to individual split inside list items by adding a data-theme
attribute to specific links (see second list item).
The icon for the split theme can set at the list level by adding the data-split-icon
to the list and specifying a standard icon. This attribute can also be added to individual split inside list items by adding a data-icon
attribute to specific links (see second list item).

A swatch
B swatch
C swatch
D swatch
E swatch


Posted by Jostein on July 2, 2020
Posted by Jostein on June 22, 2020
Posted by Jostein on June 10, 2020
Posted by Jostein on October 12, 2019
Posted by Jostein on December 25, 2017
Posted by Jostein on November 8, 2017


Why is this retrospective being held? What will it cover? Retrospectives, similarly to any other meeting, are more effective
if the participants align their expectations before getting into it.
Read the prime directive
The statement is invaluable for setting the meeting tone. Make it visible to all participants, and read it out loud before
running your retrospective activity.
Go for it!
It is time to gather data, talk about the positive stuff, recognize people and seek improvements. Select an activity, create
and customize your board. Go for it!
MIT License
Copyright (c) 2017 Fun Retrospectives
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


{% extends "djangobmf/module_modal_base.html" %} {% load i18n %} {% block title %}{{ title }}{% endblock %} {% block base_content %} {% if perms_lacking %}
{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}
{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would require deleting the following protected related objects:{% endblocktrans %}
{% blocktrans with escaped_object=object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktrans %}


The ggf-opacity classes adds transparency to an element.
Normal (100% opacity):
ggf-opacity-min (75% opacity):
ggf-opacity (60% opacity):
ggf-opacity-max (25% opacity):


Activate the traps located in the interior of the island.
Once activated, the flames do not distinguish friend from foe. Used properly,
the trap is a very effective deterrent to invasion. Of course, it costs a
fortune!
[npc_%objectId%_Link castle/chamberlain/trap_select-Aden_1.htm|Activate the trap near the entrance of the inner castle.]
[npc_%objectId%_Link castle/chamberlain/trap_select-Aden_2.htm|Activate the trap behind the garden in the inner castle.]
[npc_%objectId%_default|Back]


“Every strike brings me closer to the next home run.”
― Babe Ruth
Babe Ruth exhibits his triumphant philosophy through this prodigious statement.
Every legend was once a beginner.
What makes them different is their perseverance and dedication. Most of you don’t want success as much as you want sleep. Pain will last for a minute or day. But if we quit it will last forever. Most of you don’t want success as much as you want sleep. We give up easily and we don’t climb our way towards the epitome.
I have heard an interesting anecdote:
A manager at a Company took a group of his employees to a golf course, where he introduced them to a virtuoso Golfer.
He made them watch him perform. He had a bunch of golf clubs , bats, pool sticks, anything you can think of that would be long and could be used to hit a golf ball. Out in the course were markers at 25, 50, 75, 100 yards on out to about 300 yards. This man went through a half hour display of hitting golf balls to these markers and landing every ball within about 2-feet of the marker.  He was an absolute magician and could drive 300 yards, perfectly straight with a putter and hit a golf ball 100 yards (or to any marker) with a baseball bat just as well. It was unbelievable.
After this impressive display, the sales manager told the employees that he paid him $ 20,000 in cash to do that 30 minute show and paid for all of his expenses as well.
The showman told the employees the following:
“I bet you’re wondering how I am so good at hitting golf balls and how I can command such a high price for this short display of my talents. It’s not that I am a gifted golfer. I don’t have a great score on the course when I play an actual game. It’s not that I have natural talent. It took me a very long time to get good at these things.
His simple point was that he gave 100% of his time to his job for those short bursts of time and didn’t waste his time at all while he was working at his job. That’s the secret.

But, someone who is applying himself, 100% of the time is supposed to get ahead in life. You can be that person, if you live your live courageously and engrossing yourself into your work.


Documentation for GPML Matlab Code
The code provided here demonstrates the main algorithms from Rasmussen
and Williams: Gaussian Processes
for Machine Learning.
The code is written in Matlab®, and should work with version 6 and version
7. Bug reports should be sent to the authors. All the code including
demonstrations and html documentation can be downloaded in a tar or
zip
archive file. Please read the copyright
notice.
After unpacking the tar or zip file you will find
3 subdirectories: gpml, gpml-demo and doc.
The directory gpml contains the basic functions for GP regression,
GP binary classification, and sparse approximate methods for GP regression.
The directory gpml-demo contains
Matlab® scripts with names "demo_*.m". These provide small
demonstrations of the various programs provided.
The directory doc contains four html files providing
documentation. This information can also be accessed via
the www at http://www.GaussianProcess.org/gpml/code.
The code should run directly as provided, but some demos require a lot of
computation. A significant speedup may be attained by compiling the mex
files, see the rudimentary instructions on how to do this in the README file.
The documentation is divided into three sections:
Regression
Basic Gaussian process regression (GPR)
code allowing flexible specification of the covariance function.
Binary Classification
Gaussian process classification (GPC)
demonstrates implementations of Laplace and EP approximation methods for binary
GP classification.
Sparse Approximation methods for Gaussian Process Regression
Approximation methods for GPR demonstrates the
methods of subset of datapoints (SD), subset of regressors (SR)
and projected process (PP) approximations.
Other Gaussian Process Code
A table of other sources of useful Gaussian process software, unrelated to the
book, may be found here. This
includes pointers a number of packages that can handle multi-class
classification, e.g. fbm (Radford Neal),
c++-ivm (Neil Lawrence), gpclass (David
Barber and Chris Williams), klr (kernel multiple
logistic regression, by Matthias Seeger), and
VBGP (Mark Girolami and Simon Rogers).
Go back to the web page for
Gaussian Processes for Machine Learning.
Last modified: Tue Mar 21 10:43:51 CET 2006


Python has several different versions and a number of ways it can be set up on each operating system. This section will help you install Python if the simple approach in Chapter 1 didn’t work, or if you want to install a different version of Python than the one that came with your system.
Python is included by default on almost every Linux system, but you might want to use a different version than the default. If so, first find out which version of Python you already have installed:
$ python --version
Python 2.7.6
This shows that the default version is Python 2.7.6. However, you might have a version of Python 3 installed as well. To check, issue the following command:
$ python3 --version
Python 3.5.0
Python 3.5.0 is also installed. It’s worth running both commands before you attempt to install a new version.
###Installing Python 3 on Linux
If you don’t have Python 3 or if you want to install a newer version of Python 3, you can use a package called deadsnakes
, which makes it easy to install multiple versions of Python:
$ sudo add-apt-repository ppa:fkrull/deadsnakes
$ sudo apt-get update
$ sudo apt-get install python3.5
These commands will install Python 3.5 to your system. The following command will start a terminal session running Python 3.5:
$ python3.5
>>>
You’ll also use this command when you configure your text editor to use Python 3, and when you run programs from a terminal.
Python is already installed on most OS X systems, but you might want to use a different version than what’s installed by default. First, find out which version of Python you already have installed:
$ python --version
Python 2.7.6
This shows that the default version is Python 2.7.6. However, you might have a version of Python 3 installed as well. To check, issue the command python3 –version. You’ll probably get an error message, but it’s worth checking to see if the version you want is already installed.
###Installing Homebrew
If you only have Python 2 installed, or if you have an older version of Python 3, you can install the latest version of Python 3 using a package called Homebrew.
Homebrew depends on Apple’s Xcode package, so open a terminal and run the following command:
$ xcode-select --install
Click through the confirmation dialogs that pop up. Next, install Homebrew with the following command:
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Make sure you include a space between curl -fsSL
and the URL. The -e
in this command tells Ruby (the programming language Homebrew is written in) to execute the code that’s downloaded here. You should only run commands like this from sources you trust.
To confirm that Homebrew was installed correctly, run the following command:
$ brew doctor
Your system is ready to brew.
This output means you’re ready to install Python packages through Homebrew.
###Installing Python 3
To install the latest version of Python 3, enter the following:
$ brew install python3
You can check which version was installed:
$ python3 --version
Python 3.5.0
$
Now you can start a Python 3 terminal session using the command python3
, and you can ues the python3
command to configure your text editor so it runs Python programs with Python 3 instead of Python 2.
Python isn’t usually included by default on Windows, but it’s worth checking to see if it exists on your system. Open a command window and run the following command:
> python --version
Python 3.5.0
If you see output like this, Python is already installed, but you might want to install a newer version if your version is not up to date. If you see an error message, you’ll need to download and install Python.
###Installing Python 3 on Windows
Go to http://python.org/downloads/ and click the version of Python you want. Download the installer, and when you run it make sure to check the Add Python to PATH option. This will let you use the python
command instead of having to enter your system’s full path to python, and you won’t have to modify your system’s environment variables manually. After you’ve installed Python, issue the python --version
command in a new terminal window. If it works, you’re done.
###Finding the Python interpreter
If you’ve installed Python and the simple command python
doesn’t work, you’ll need to tell Windows where to find the Python interpreter. To find it, open your C drive and find the folder with a name starting with Python (you might need to enter the word python
in the Windows Explorer search bar to find the right folder). Open the folder, and look for a file with the lowercase name python. Right-click this file and choose Properties; you’ll see the path to this file under the heading Location.
In the terminal window, use the path to confirm the version you just installed:
$ C:\\Python35\python --version
Python 3.5.0
###Adding Python to your Path variable
It’s annoying to type the full path each time you want to start a Python terminal session. If you add the path to the system you can just use the command python
. (If you already check the Add Python to PATH box when installing, you can skip this step.)
Open your system’s Control Panel, choose System and Security, and then choose System. Click Advanced System Settings. In the window that pops up, click Environment Variables. In the box labeled System variables, look for a variable called Path
. click Edit. In the box that pops up, click in the box labeled Variable value and use the right arrow key to scroll all the way to the right. Be careful not to overwrite the existing variable; if you do, click Cancel and try again. Add a semicolon and the path to your python.exe file to the existing variable:
%SystemRoot%\system32\...\System32\WindowsPowerShell\v1.0\;C:\Python35
Close your terminal window and open a new one. This will load the new Path
variable into your terminal session. Now when you enter python --version
, you should see the version of Python you just set in your Path
variable. You can now start a Python terminal sesion by just entering python
at a command prompt.


Sofitel Cairo Nile El Gezirah
Sofitel El Gezirah is a 5-star luxury hotel with a private promenade along the Nile. It is within a walking distance from the Opera house and Cairo Tower, as well as Egyptian Museum and Khan El Khalili. It features infinity outdoor pool. Free WiFi is available in all areas.
All guest rooms at the Sofitel El Gezirah hotel feature air conditioning, satellite TV, free basic WiFi and minibar. Many rooms provide far-reaching views along the River Nile and across the city of Cairo.
The hotel has 7 restaurants, which include Moroccan, Egyptian and international specialties. There are also 5 bars including the trendy Ana's bar and the library tea lounge.
Sofitel El Gezirah Cairo has a range of leisure facilities, including a spa complete with a swimming pool, a hammam, and fitness centre. A hot tub is available with massage packages. Tours and trips can be arranged at the concierge desk.
Sofitel El Gezirah is 20 km from the international airport. Private on site car parking is available.
This property also has one of the best-rated locations in Cairo! Guests are happier about it compared to other properties in the area.


 You can speak, write, pitch, and persuade. You can make a Power Point, or make art.
You work every day, solving problems. You get a ton done.
Now, let’s say you suddenly became terrified for the world’s future. What would you do?
You can call Congress, or attend a protest. And you should. But is that it? Why stop there? Why set aside everything you’ve learned, everything you are, to be simply one more terrified person on a phone line, or marching in a street?
What if you did the following, as well?
- Pick an issue area you care about.
- Find other people you are excited to work with. (We can help.)
- Do activism full-time using every connection, skill, tool, and trick at your disposal—until you win.
This is a proposal for defending the world. And it's a good one. If you’re feeling like the world needs defending right now, keep reading.
Yes. This may not be obvious, but it’s true: many of your powerful, hard-won skills are highly transferable to the work of political action.
If you’re a designer, you can make things that spread like wildfire on the web, rally millions, and focus the public’s attention on your issue.
If you’re a software developer, you can build creative new ways for people to come together—at key moments—and grab media attention, or apply pressure to policymakers.
If you’ve got experience in writing, journalism, or communications, you can make moves that dominate the media narrative on an issue, and surround policymakers with your framing of an issue.
And of course, if you already have experience in activism or in policymaking, you may already have great instincts about how to move decisionmakers on an issue.
We write this as two people who have been doing this work for some time.
For years, we’ve been practicing the approaches that suddenly, more than ever, every issue needs: approaches that achieve surprising upset victories, against the odds.
The world has been getting... weird lately. But new, massive opportunities to make it better are emerging all the time. So the world needs teams like ours, in every issue area. We need some company out here.
We’ve launched one A-Team so far which was focused on creating a digital strategy to pass NY Health Act, a bill for single payer healthcare in New York state. In order to launch more A-Teams, we are focused right now on finding people who could be a strong match for one of our co-founder roles. These are full-time, salaried positions with benefits. If a contract set-up is better for you, that works too.
A-Teams Political Strategist Co-founder: We are seeking the founding political strategist and campaign director to lead an A-Team. You should have a strong, insider-level understanding of the political process, but with an outsider’s optimism, creativity, and ability to speak about issues in ways that resonate with other outsiders, such as the public or any key constituency you need to move. Is this you? Read more and apply here: A-Teams Political Strategist Co-founder
A-Teams Technical Co-founder: We are seeking the founding technical leader for an A-Team. You should be supremely comfortable making and launching novel and creative additions to people’s online life, whether for web, mobile, or walled gardens like Facebook. Can you build stuff for web and mobile that looks good, works well, and speaks to people with a strong, clear voice? Read more and apply here: A-Teams Technical Co-founder
A-Teams Design Co-founder: We are seeking the founding designer / front-end developer for an A-Team. Your role will be to explain complex issues—and get people to take effective political action—using design, copy, and code. We’re looking for someone with very strong visual and interaction design skills who can move from mockups to HTML/CSS, or design directly in code. Read more and apply here: A-Teams Design Co-founder
Not a fit for any of these roles? As we launch more A-Teams, we’ll be looking for additional team members, so feel free to email us with project ideas or more about you. We’re happy to keep you in mind for future teams and may want to talk sooner.
The name of our organization is Fight for the Future. Our names are Holmes Wilson and Tiffiniy Cheng. For the past 5 and a half years we’ve been toiling away on a previously somewhat obscure set of political issues facing the Internet.
During that time, we helped create two of the biggest victories for grassroots power in the past decade: the 2015 victory for Net Neutrality and the 2012 victory against SOPA & PIPA.
Neither was supposed to be winnable. Insiders said we were crazy to even try.
Both were against the most powerful corporate lobbies in America: the media and pharmaceutical lobbies (MPAA and PhrMA) on SOPA/PIPA, and then the cable and telecom lobby (NCTA) on Net Neutrality.
Claiming credit is dubious business. But in both cases, we're pretty sure victory wouldn't have happened without interventions we created, and many knowledgeable insiders agree. (These were team efforts, so there are several organizations and individuals for whom the same is also true—that is, that we wouldn't have won without them.)
We did this with a tiny fraction of the resources and conventional power our opponents enjoyed. We're two friends from high school. There have been 5-10 people with us on our team—some of the best people we've found to do this kind of activism. We do most of our activism online, but we organize real-life protests sometimes too. We’re funded by donations (large & small) but when we started our careers we were entirely unfunded, doing it for the pure pleasure of winning.
We believe our experience—of big victories on small budgets—puts us in a special position to make a proposal, to everyone on the planet trying to answer the question "Oh my god, what should I do?"
If you’re looking for an answer to that question, keep reading, or apply.
You probably have some questions!
Yes! And yes, we know, evaluating the realness and good faith of things you see on the Internet is hard. But we are real activists with a real organization that does real campaigns. Check us out and Google us to get a feel for who we are. Or send us an email.
Activism Teams, or A-Teams, are new, small, interdisciplinary teams focused on defending or improving some aspect of the world.
An A-Team is like a special ops team for activism, with all the skills needed to create political change.
A-Teams can write persuasively; speak with a strong voice online (with design, images, video, and code); size up their target’s internal power structures and weaknesses; and build strategies to rally the public, focusing collective action at the right pressure points, at the right time.
When you work in politics, it’s shocking how incomplete most political pushes are, even major ones.
This is easy to observe. How many major, upcoming issues have an excellent, digestible explanation online? How many pair that explanation with something simple and meaningful that the average person—once convinced—can go out and do? Google it: Obamacare, Immigration, Deportation, Medical Marijuana. Not many issues have a clear, prominent source for information and action, do they?
At a time like this, is that acceptable? No way.
A-Teams can rapidly fill these gaps, and that’s just the beginning.
A-Teams shine at building a drumbeat of stories and moments. They can organize provocative, interesting collective action that grabs the public’s attention, and ensure their target is getting pressure from all necessary angles. That's how we turned the tide against SOPA.
Then they can do it again and again, riveting public & press attention and overwhelming the ability of the adversary—whether an industry lobby, or an administration—to spin a counter narrative. That's how we won net neutrality.
A-Teams shine at rapid response. When a story breaks, conventional organizations respond with a tweet, an email, or a press release. But A-Teams make something epic happen, fast. Protests all around the country. Some creative symbol of support or resistance, on social media, the streets, and local news. That's how we responded when the FBI wanted an iPhone backdoor.
A-Teams work great when a large number of people want something to happen (or not happen) but entrenched power, corruption, or the status quo is pushing the other way. Fueled by that shared collective intent, staring at a political barrier, A-Teams find a way through to the other side.
Anything! Seriously!
As an A-Team, you pick an issue that matters, and try to win tangible, significant changes. And actually do it. The Internet has changed the game on what we can achieve. Once you go full-time—or start volunteering for people who are—you’ll be shocked at what you achieve. We promise.
It doesn’t matter the issue. Social change can come from media pressure, large mobilizations, small groups of insiders, influential outsiders, righteous narratives, technological shifts, or simply the discovery and spread of some big new idea. In most cases it’s some combination of some or all of these, over a period of months or years.
The cool thing is, all of these factors are things a typical human can figure out how to influence. So think of them as levers of change, levers you can learn to pull. It just takes time and dedication, focusing on a problem enough to figure out what action is going to fix it and how.
This isn’t any secret; it’s how the most powerful lobbyists, advertisers, and public relations firms have worked since their inception.
This is a much better question, though it’s a harder one to answer.
Since there are a million things to do, it’s usually best for A-Teams to focus on issues behind major human problems, or places where humanity is at risk of really, deeply screwing up.
Think big.
You have to use your instinct and play to your strengths. Where can you have the most impact?
Here are just a few examples of A-Team objectives that could be crucially important right now.
- Healthcare / ACA
- Climate
- Immigration
- The Wall
- Voting Rights
- Corruption
- Racism / Fascism
- Police
- Prisons
- Ending the drug war
- Voting rights / Voter supression
- Foreign policy
- Internet
- Telecom
- Competition
- Economic populism
- Renewable energy
- Food & agriculture
If one of these interests you, or if you have another objective you’re burning to pursue, let us know. Note: you don't need to have a specific project idea to apply, If you do, we are happy to discuss it, but if not, we can figure that out later. Your skills and motivation are what matters most.
We plan to fund each A-Team position for at least a year, assuming founders produce campaigns at the level we expect.
After that first year, if the A-Team is successfully producing hard-hitting campaigns, we expect the team to spin out into its own organization.
We've seen firsthand that once you start making a big impact on an issue area, there are lots of ways to get funding. If you’re operating in a space where there are existing nonprofit organizations, you can figure out where they get funding, make friends with them, and be helpful to them. Your costs as a tiny team are so much lower than theirs, so you can get by on much smaller grants, or just one or two large ones. Once you prove your usefulness, some coalition allies will want to keep you in the game, and they’ll likely give you pointers on funding.
As you start to build large audiences, you can ask them to donate, too. And look out for individuals or organizations who support what you’re doing and might be able to give more. If you’re doing something really cutting edge, individual supporters might be the best fit at first. The world is a random place and very political people become wealthy sometimes. You'll be pleasantly surprised by the donors you find.
The world isn’t short on funding. It’s short on people who can take a donation of $100,000 or $1,000,000 and actually change the world in some big way. Once you learn how, and have a track record, you'll find funding if you look. And we're committed to helping each new team do just that.
If you already have a small activism team making a big, measurable impact but you’re having problems fundraising, then definitely be in touch. We can very likely speed up your search for funding.
Have a question? Email us<EMAIL_ADDRESS>Want to be a part of this? Check out the openings above and apply.
That’s all for now. We can tell you more about where to focus and how to win. But right now you’ve a choice to make. You can keep calling Congress, and keep showing up at local vigils when something disastrous happens. (And you should.) But you can also take your skills, build a team, and do something much, much bigger.
Should I skip the rest of the page and just read this FAQ?
No! Definitely read the whole page :) This is just where we're putting responses to some common questions.
Where is the money coming from?
Fight for the Future for now, and we're looking for more funding for more teams, and longer runs.
How does compensation work?
This is a full time position. Compensation is market rate and commensurate with skills and experience either through a contract rate or a salary (with full health care benefits), depending on what works best for you.
Do you have a timeline/commitment in mind for the co-founder role?
We can talk about this during the interview process, but are open to discussing what works best for you.
How does the structure of an A-Teams work and will you help match me with a co-founder?
We know the ideal set-up for an A-Team’s leadership is a Political Strategist working with either a Technical or Design Co-founder which is why we’re looking for both types of candidates. If we decide you are strong match for one, we’ll help match you with the other co-founder during interview process and finalize the political issue and opportunity as well. You’ll need other members (volunteers and potentially part-time contract staff, depending on the plan) for your team and part of your role will be to recruit the rest of your team. But we can help with that too.
If you have ideas for co-founders you would like to work, by all means, encourage them to apply!
Are you funding other things, like films, TV shows, apps, books, software projects, journalism, community spaces, etc?
Nope. Just A-Teams. We're looking for a single-issue focus, a political opportunity, and a strategy for winning which includes tapping into the power of the Internet.
There are many other valid ways to change the world of course, but we think this particular one (A-Teams) is very effective and not getting used as much as it should. We want to change that, and our resources are limited, so we have to stay focused on this singular mission.
Do I really have to send in an application?
That would be best, but if you have questions or just want to introduce yourself, email us<EMAIL_ADDRESS>What's your metric for success, for a team?
Ultimately, policy change, or a significant shift in the national debate. Or, on a shorter timeline, at least the precursors to policy change: visible, palpable political pressure on important targets.
What's your metric for success, for yourselves?
Being able to make a dozen solid new A-Teams happen on top issues while continuing work in our issue area (Internet freedom) would be a solid success. If that works, we think we’ll be able to go much farther. We think the limiting thing will be finding the right people, and the right structure.
How many groups will you try to create?
As many as we can, but we want to have some significant level of contact with each group in the first months/year at least so probably half a dozen teams in the first year.
Are you funding teams outside the US?
No, just US based teams. If you live outside the US, feel free to email us. We can potentially match you with a team as a volunteer or work with you on FFTF campaigns.
Is there a deadline?
The next application deadline is Friday, June 1st. But apply soon because the world moves fast.
Is this a scam?
No, but don't take our word for it. Please take the time to carefully Google us and our work. (Understanding us and our work will probably help with your application too, if you choose to apply.)
Do A-Teams have to use the Internet in some way?
Yes, but that doesn't mean you need any technical expertise to start. Part of what we think is happening now is that the Internet has made collective action much easier, creating all kinds of new opportunities for creative activism. So if you can code that's great (some of us are learning now using this delightful book) but you really just need to be able to write, and speak, and think about how to use whatever skills you have to tap the Internet's potential. (But you should definitely be able to think creatively about how to use the Internet to help you win. It's a very big deal.)
What do you get out of this?
Epic victories we will die knowing we helped make happen. Also, more company! We're committed to remaining small. This is our way to grow: helping start other A-Teams.
Our stretch goal is that we can make starting an A-Team a thing people know they can do, the way doing a startup, working for a community-based nonprofit, or going to grad school are things people do.
What if I don't get the job?
Please, find some way to keep doing it anyway. The world needs you.


--- layout: default ---
As part of my work as an education writer, I have researched a number of topics in-depth. Below, you'll find links to various projects, past and present.
Teaching Machines: My forthcoming book on the cultural history of ed-tech and the long-running drive to automate teaching and learning.
The History of Ed-Tech Companies: Timelines describing how the largest ed-tech companies and organizations came to dominate education policy
Ed-Tech Trends: An annual review of the 10 most significant "trends" in education technology (or rather, a review of the stories that people tell in the hopes products and services and ideas become trends).
Ed-Tech Funding: An open data initiative to track education technology companies that receive angel and venture capital investment from 2010 to 2018.
The Ed-Tech Industry Network: An analysis of some of the investor and entrepreneur networks that have emerged from companies like Blackboard and Kaplan. (This research was funded, in part, through a Spencer Education Journalism Fellowship.)
The Blockchain: What is the blockchain? And how might it be utilized in education technology? (Or rather, please, let's not.)
The Week in Robots: A weekly summary of news about robots and artificial intelligence.
Horizon Report Data Liberation: Freeing the annual Horizon Report data from PDFs.
Ed-Tech and Science Fiction: A list of novels, short stories, television, and films that explore the future of education.
Technology Predictions: Who's making predictions about the future? (And can or will these predictions ever come true?)
The Monsters of Education Technology 4: A collection of my lectures and keynotes from 2017.
The Curse of the Monsters of Education Technology: A collection of my lectures and keynotes from 2016.
The Revenge of the Monsters of Education Technology: A collection of my lectures and keynotes from 2015.
The Monsters of Education Technology: A collection of my lectures and keynotes from 2014.
Ed-Tech Guide: What should educators and technologists know about ed-tech?
Adopt-A: A Knight Foundation-funded project to "adopt" a federal agency data-set and clean it up.
OER in K-12: A review of the availability and usage of open educational researches, along with an investigation into some of the barriers to adoption.
Learning to Code: What resources are available for learning to program? What works, what doesn't work, and why? (And for whom?)
Image credits: Bryan Mathers, Noun Project. Updated June 2019


---
layout: default
title: Home
---
I am currently a software engineer at Kodiak Robotics.
We are a startup working on self-driving trucks (and of course, we're hiring!).
I am a roboticist working at the intersection of machine learning, planning and decision-making, and imitation learning.
Broadly, I am interested in enabling robots to address challenging problems in smart and useful ways,
usually through a combination of state-of-the-art research, rigorous software development processes, system integration, and field testing.
I've been lucky to work at a variety of amazing places,
including Apple (in the Special Project Group),
EPFL (Ecole Polytechnique Federale de Lausanne),
CMU's Robotics Institute,
Google's self-driving car project, and CSIRO in Australia.
You can learn more about my trajectory on my about page,
or see cool robots I've worked with on my
videos page.
If you're interested in my publications, you can also find them
here.
Lastly, I have an infrequently-updated blog which primarily serves as a space for notes to myself.


The HarmonyOS Student Club India at VIT-AP is an extension to Application Library Engineering Group. Huawei’s HarmonyOS is a next-generation operating system that empowers interconnection and collaboration between smart devices.


{% extends 'base.html' %} {% block content %} {%if request.user.is_authenticated%}
Chat rooms are Web sites or programs that allow people to send text messages to one another in real time. The chat room works as a virtual room, where groups of people send messages that others can read instantaneously.
You must authenticate to view this page.


Well Pump Main is OFF
Well Pump Main is ON
| ThreeDayRain program | {{greenhouse_variables.ThreeDayRain}} | |
| RainyDay program | {{greenhouse_variables.RainyDay}} | |
| MakeItRain program | {{greenhouse_variables.MakeItRain}} | |
| Valve 1 State | {{greenhouse_variables.valve1State}} | |
| Valve 2 State | {{greenhouse_variables.valve2State}} |


The {@link org.apache.juneau.jena.RdfSerializer} class is the top-level class for all Jena-based serializers.
Language-specific serializers are defined as inner subclasses of the RdfSerializer
class:
- {@link org.apache.juneau.jena.RdfSerializer.Xml}
- {@link org.apache.juneau.jena.RdfSerializer.XmlAbbrev}
- {@link org.apache.juneau.jena.RdfSerializer.NTriple}
- {@link org.apache.juneau.jena.RdfSerializer.Turtle}
- {@link org.apache.juneau.jena.RdfSerializer.N3}
Static reusable instances of serializers are also provided with default settings:
- {@link org.apache.juneau.jena.RdfSerializer#DEFAULT_XML}
- {@link org.apache.juneau.jena.RdfSerializer#DEFAULT_XMLABBREV}
- {@link org.apache.juneau.jena.RdfSerializer#DEFAULT_TURTLE}
- {@link org.apache.juneau.jena.RdfSerializer#DEFAULT_NTRIPLE}
- {@link org.apache.juneau.jena.RdfSerializer#DEFAULT_N3}
Abbreviated RDF/XML is currently the most widely accepted and readable RDF syntax, so the examples shown here will use that format.
For brevity, the examples will use public fields instead of getters/setters to reduce the size of the examples.
In the real world, you'll typically want to use standard bean getters and setters.
To start off simple, we'll begin with the following simplified bean and build it up.
public class Person {
// Bean properties
public int id;
public String name;
// Bean constructor (needed by parser)
public Person() {}
// Normal constructor
public Person(int id, String name) {
this.id = id;
this.name = name;
}
}
The following code shows how to convert this to abbreviated RDF/XML:
// Create a new serializer with readable output.
RdfSerializer s = new RdfSerializerBuilder().xmlabbrev().property(RdfProperties.RDF_rdfxml_tab, 3).build();
// Create our bean.
Person p = new Person(1, "John Smith");
// Serialize the bean to RDF/XML.
String rdfXml = s.serialize(p);
It should be noted that serializers can also be created by cloning existing serializers:
// Create a new serializer with readable output by cloning an existing serializer.
RdfSerializer s = RdfSerializer.DEFAULT_XMLABBREV.builder().property(RdfProperties.RDF_rdfxml_tab, 3).build();
This code produces the following output:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/">
<rdf:Description>
<jp:id>1</jp:id>
<jp:name>John Smith</jp:name>
</rdf:Description>
</rdf:RDF>
Notice that we've taken an arbitrary POJO and converted it to RDF.
The Juneau serializers and parsers are designed to work with arbitrary POJOs without requiring
any annotations.
That being said, several annotations are provided to customize how POJOs are handled to produce usable RDF.
2.1 - Namespaces
You'll notice in the previous example that Juneau namespaces are used to represent bean property names.
These are used by default when namespaces are not explicitly specified.
The juneau
namespace is used for generic names for objects that don't have namespaces associated with them.
The juneaubp
namespace is used on bean properties that don't have namespaces associated with them.
The easiest way to specify namespaces is through annotations.
In this example, we're going to associate the prefix 'per'
to our bean class and all
properties of this class.
We do this by adding the following annotation to our class:
@Rdf(prefix="per")
public class Person {
In general, the best approach is to define the namespace URIs at the package level using a package-info.java
class, like so:
// RDF namespaces used in this package
@RdfSchema(
prefix="ab",
rdfNs={
@RdfNs(prefix="ab", namespaceURI="http://www.apache.org/addressBook/"),
@RdfNs(prefix="per", namespaceURI="http://www.apache.org/person/"),
@RdfNs(prefix="addr", namespaceURI="http://www.apache.org/address/"),
@RdfNs(prefix="mail", namespaceURI="http://www.apache.org/mail/")
}
)
package org.apache.juneau.sample.addressbook;
import org.apache.juneau.xml.annotation.*;
This assigns a default prefix of "ab" for all classes and properties within the project,
and specifies various other prefixes used within this project.
Now when we rerun the sample code, we'll get the following:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/">
<rdf:Description>
<per:id>1</per:id>
<per:name>John Smith</per:name>
</rdf:Description>
</rdf:RDF>
Namespace auto-detection ({@link org.apache.juneau.xml.XmlSerializerContext#XML_autoDetectNamespaces}) is enabled
on serializers by default.
This causes the serializer to make a first-pass over the data structure to look for namespaces.
In high-performance environments, you may want to consider disabling auto-detection and providing an explicit list of namespaces to the serializer
to avoid this scanning step.
// Create a new serializer, but manually specify the namespaces.
RdfSerializer s = new RdfSerializerBuilder()
.xmlabbrev()
.property(RdfProperties.RDF_rdfxml_tab, 3)
.autoDetectNamespaces(false)
.namespaces("{per:'http://www.apache.org/person/'}")
.build();
This code change will produce the same output as before, but will perform slightly better since it doesn't have to crawl the POJO tree before serializing the result.
2.2 - URI properties
Bean properties of type java.net.URI
or java.net.URL
have special meaning to the RDF serializer.
They are interpreted as resource identifiers.
In the following code, we're adding 2 new properties.
The first property is annotated with @BeanProperty to identify that this property is the
resource identifier for this bean.
The second unannotated property is interpreted as a reference to another resource.
public class Person {
// Bean properties
@Rdf(beanUri=true)
public URI uri;
public URI addressBookUri;
...
// Normal constructor
public Person(int id, String name, String uri, String addressBookUri) throws URISyntaxException {
this.id = id;
this.name = name;
this.uri = new URI(uri);
this.addressBookUri = new URI(addressBookUri);
}
}
We alter our code to pass in values for these new properties.
// Create our bean.
Person p = new Person(1, "John Smith", "http://sample/addressBook/person/1", "http://sample/addressBook");
Now when we run the sample code, we get the following:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/">
<rdf:Description rdf:about="http://sample/addressBook/person/1">
<per:addressBookUri rdf:resource="http://sample/addressBook"/>
<per:id>1</per:id>
<per:name>John Smith</per:name>
</rdf:Description>
</rdf:RDF>
The {@link org.apache.juneau.annotation.URI} annotation can also be used on classes and properties
to identify them as URLs when they're not instances of java.net.URI
or java.net.URL
(not needed if @Rdf(beanUri=true)
is already specified).
The following properties would have produced the same output as before. Note that the @URI annotation is only needed
on the second property.
public class Person {
// Bean properties
@Rdf(beanUri=true) public String uri;
@URI public String addressBookUri;
Also take note of the {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_uriResolution},
{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_uriRelativity}, and
and {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_uriContext}
settings that can be specified on the serializer to resolve relative and context-root-relative URIs to fully-qualified URIs.
This can be useful if you want to keep the URI authority and context root information out of the bean logic layer.
The following code produces the same output as before, but the URIs on the beans are relative.
// Create a new serializer with readable output.
RdfSerializer s = new RdfSerializerBuilder()
.xmlabbrev()
.property(RdfProperties.RDF_rdfxml_tab, 3);
.relativeUriBase("http://myhost/sample");
.absolutePathUriBase("http://myhost")
.build();
// Create our bean.
Person p = new Person(1, "John Smith", "person/1", "/");
// Serialize the bean to RDF/XML.
String rdfXml = s.serialize(p);
2.3 - @Bean and @BeanProperty annotations
The {@link org.apache.juneau.annotation.Bean} and {@link org.apache.juneau.annotation.BeanProperty} annotations
are used to customize the behavior of beans across the entire framework.
In addition to using them to identify the resource URI for the bean shown above, they have various other uses:
- Hiding bean properties.
- Specifying the ordering of bean properties.
- Overriding the names of bean properties.
- Associating transforms at both the class and property level (to convert non-serializable POJOs to serializable forms).
For example, we now add a birthDate
property, and associate a swap with it to transform
it to an ISO8601 date-time string in GMT time.
By default, Calendars
are treated as beans by the framework, which is usually not how you want them serialized.
Using swaps, we can convert them to standardized string forms.
public class Person {
// Bean properties
@BeanProperty(swap=CalendarSwap.ISO8601DTZ.class) public Calendar birthDate;
...
// Normal constructor
public Person(int id, String name, String uri, String addressBookUri, String birthDate) throws Exception {
...
this.birthDate = new GregorianCalendar();
this.birthDate.setTime(DateFormat.getDateInstance(DateFormat.MEDIUM).parse(birthDate));
}
}
And we alter our code to pass in the birthdate.
// Create our bean.
Person p = new Person(1, "John Smith", "http://sample/addressBook/person/1", "http://sample/addressBook", "Aug 12, 1946");
Now when we rerun the sample code, we'll get the following:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/">
<rdf:Description rdf:about="http://sample/addressBook/person/1">
<per:addressBookUri rdf:resource="http://sample/addressBook"/>
<per:id>1</per:id>
<per:name>John Smith</per:name>
<per:birthDate>1946-08-12T00:00:00Z</per:birthDate>
</rdf:Description>
</rdf:RDF>
2.4 - Collections
Collections and arrays are converted to RDF sequences.
In our example, let's add a list-of-beans property to our sample class:
public class Person {
// Bean properties
public LinkedList<Address> addresses = new LinkedList<Address>();
...
}
The Address
class has the following properties defined:
@Rdf(prefix="addr")
public class Address {
// Bean properties
@Rdf(beanUri=true) public URI uri;
public URI personUri;
public int id;
@Rdf(prefix="mail")
public String street, city, state;
@Rdf(prefix="mail")
public int zip;
public boolean isCurrent;
}
Next, add some quick-and-dirty code to add an address to our person bean:
// Create a new serializer (revert back to namespace autodetection).
RdfSerializer s = new RdfSerializerBuilder().xmlabbrev().property(RdfProperties.RDF_rdfxml_tab, 3).build();
// Create our bean.
Person p = new Person(1, "John Smith", "http://sample/addressBook/person/1", "http://sample/addressBook", "Aug 12, 1946");
Address a = new Address();
a.uri = new URI("http://sample/addressBook/address/1");
a.personUri = new URI("http://sample/addressBook/person/1");
a.id = 1;
a.street = "100 Main Street";
a.city = "Anywhereville";
a.state = "NY";
a.zip = 12345;
a.isCurrent = true;
p.addresses.add(a);
Now when we run the sample code, we get the following:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/"
xmlns:mail="http://www.apache.org/mail/"
xmlns:addr="http://www.apache.org/address/">
<rdf:Description rdf:about="http://sample/addressBook/person/1">
<per:addressBookUri rdf:resource="http://sample/addressBook"/>
<per:id>1</per:id>
<per:name>John Smith</per:name>
<per:addresses>
<rdf:Seq>
<rdf:li>
<rdf:Description rdf:about="http://sample/addressBook/address/1">
<addr:personUri rdf:resource="http://sample/addressBook/person/1"/>
<addr:id>1</addr:id>
<mail:street>100 Main Street</mail:street>
<mail:city>Anywhereville</mail:city>
<mail:state>NY</mail:state>
<mail:zip>12345</mail:zip>
<addr:isCurrent>true</addr:isCurrent>
</rdf:Description>
</rdf:li>
</rdf:Seq>
</per:addresses>
</rdf:Description>
</rdf:RDF>
2.5 - Root property
For all RDF languages, the POJO objects get broken down into simple triplets.
Unfortunately, for tree-structured data like the POJOs shown above, this causes the root node of the tree to become lost.
There is no easy way to identify that person/1
is the root node in our tree once in triplet form, and in
some cases it's impossible.
By default, the {@link org.apache.juneau.jena.RdfParser} class handles this by scanning
all the nodes and identifying the nodes without incoming references.
However, this is inefficient, especially for large models.
And in cases where the root node is referenced by another node in the model by URL, it's not possible to locate the root at all.
To resolve this issue, the property {@link org.apache.juneau.jena.RdfSerializerContext#RDF_addRootProperty} was introduced.
When enabled, this adds a special root
attribute to the root node to make it easy to locate by the parser.
To enable, set the RDF_addRootProperty property to true on the serializer:
// Create a new serializer.
RdfSerializer s = new RdfSerializerBuilder()
.xmlabbrev()
.property(RdfProperties.RDF_rdfxml_tab, 3),
.addRootProperty(true)
.build();
Now when we rerun the sample code, we'll see the added root
attribute on the root resource.
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/"
xmlns:mail="http://www.apache.org/mail/"
xmlns:addr="http://www.apache.org/address/">
<rdf:Description rdf:about="http://sample/addressBook/person/1">
<j:root>true</j:root>
<per:addressBookUri rdf:resource="http://sample/addressBook"/>
<per:id>1</per:id>
<per:name>John Smith</per:name>
<per:addresses>
<rdf:Seq>
<rdf:li>
<rdf:Description rdf:about="http://sample/addressBook/address/1">
<addr:personUri rdf:resource="http://sample/addressBook/person/1"/>
<addr:id>1</addr:id>
<mail:street>100 Main Street</mail:street>
<mail:city>Anywhereville</mail:city>
<mail:state>NY</mail:state>
<mail:zip>12345</mail:zip>
<addr:isCurrent>true</addr:isCurrent>
</rdf:Description>
</rdf:li>
</rdf:Seq>
</per:addresses>
</rdf:Description>
</rdf:RDF>
2.6 - Typed literals
XML-Schema datatypes can be added to non-String
literals through the {@link org.apache.juneau.jena.RdfSerializerContext#RDF_addLiteralTypes}
setting.
To enable, set the RDF_addLiteralTypes property to true on the serializer:
// Create a new serializer (revert back to namespace autodetection).
RdfSerializer s = new RdfSerializerBuilder()
.xmlabbrev()
.property(RdfProperties.RDF_rdfxml_tab, 3),
.addLiteralTypes(true)
.build();
Now when we rerun the sample code, we'll see the added root
attribute on the root resource.
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j="http://www.apache.org/juneau/"
xmlns:jp="http://www.apache.org/juneaubp/"
xmlns:per="http://www.apache.org/person/"
xmlns:mail="http://www.apache.org/mail/"
xmlns:addr="http://www.apache.org/address/">
<rdf:Description rdf:about="http://sample/addressBook/person/1">
<per:addressBookUri rdf:resource="http://sample/addressBook"/>
<per:id rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</per:id>
<per:name>John Smith</per:name>
<per:addresses>
<rdf:Seq>
<rdf:li>
<rdf:Description rdf:about="http://sample/addressBook/address/1">
<addr:personUri rdf:resource="http://sample/addressBook/person/1"/>
<addr:id rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</addr:id>
<mail:street>100 Main Street</mail:street>
<mail:city>Anywhereville</mail:city>
<mail:state>NY</mail:state>
<mail:zip rdf:datatype="http://www.w3.org/2001/XMLSchema#int">12345</mail:zip>
<addr:isCurrent rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">true</addr:isCurrent>
</rdf:Description>
</rdf:li>
</rdf:Seq>
</per:addresses>
</rdf:Description>
</rdf:RDF>
2.7 - Non-tree models and recursion detection
The RDF serializer is designed to be used against tree structures.
It expects that there not be loops in the POJO model (e.g. children with references to parents, etc...).
If you try to serialize models with loops, you will usually cause a StackOverflowError
to
be thrown (if {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_maxDepth} is not reached first).
If you still want to use the XML serializer on such models, Juneau provides the
{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_detectRecursions} setting.
It tells the serializer to look for instances of an object in the current branch of the tree and
skip serialization when a duplicate is encountered.
Recursion detection introduces a performance penalty of around 20%.
For this reason the setting is disabled by default.
2.8 - Configurable properties
See the following classes for all configurable properties that can be used on this serializer:
- {@link org.apache.juneau.BeanContext} - Bean context properties.
- {@link org.apache.juneau.jena.RdfSerializerContext} - Serializer context properties.
2.9 - Other notes
- Like all other Juneau serializers, the RDF serializer is thread safe and maintains an internal cache of bean classes encountered.
For performance reasons, it's recommended that serializers be reused whenever possible instead of always creating new instances.
The {@link org.apache.juneau.jena.RdfParser} class is the top-level class for all Jena-based parsers.
Language-specific parsers are defined as inner subclasses of the RdfParser
class:
- {@link org.apache.juneau.jena.RdfParser.Xml}
- {@link org.apache.juneau.jena.RdfParser.NTriple}
- {@link org.apache.juneau.jena.RdfParser.Turtle}
- {@link org.apache.juneau.jena.RdfParser.N3}
The RdfParser.Xml
parser handles both regular and abbreviated RDF/XML.
Static reusable instances of parsers are also provided with default settings:
- {@link org.apache.juneau.jena.RdfParser#DEFAULT_XML}
- {@link org.apache.juneau.jena.RdfParser#DEFAULT_TURTLE}
- {@link org.apache.juneau.jena.RdfParser#DEFAULT_NTRIPLE}
- {@link org.apache.juneau.jena.RdfParser#DEFAULT_N3}
For an example, we will build upon the previous example and parse the generated RDF/XML back into the original bean.
// Create a new serializer with readable output.
RdfSerializer s = new RdfSerializerBuilder()
.xmlabbrev()
.property(RdfProperties.RDF_rdfxml_tab, 3)
.addRootProperty(true)
.build();
// Create our bean.
Person p = new Person(1, "John Smith", "http://sample/addressBook/person/1", "http://sample/addressBook", "Aug 12, 1946");
Address a = new Address();
a.uri = new URI("http://sample/addressBook/address/1");
a.personUri = new URI("http://sample/addressBook/person/1");
a.id = 1;
a.street = "100 Main Street";
a.city = "Anywhereville";
a.state = "NY";
a.zip = 12345;
a.isCurrent = true;
p.addresses.add(a);
// Serialize the bean to RDF/XML.
String rdfXml = s.serialize(p);
// Parse it back into a bean using the reusable XML parser.
p = RdfParser.DEFAULT_XML.parse(rdfXml, Person.class);
// Render it as JSON.
String json = JsonSerializer.DEFAULT_LAX_READABLE.serialize(p);
System.err.println(json);
We print it out to JSON to show that all the data has been preserved:
{
uri: 'http://sample/addressBook/person/1',
addressBookUri: 'http://sample/addressBook',
id: 1,
name: 'John Smith',
birthDate: '1946-08-12T00:00:00Z',
addresses: [
{
uri: 'http://sample/addressBook/address/1',
personUri: 'http://sample/addressBook/person/1',
id: 1,
street: '100 Main Street',
city: 'Anywhereville',
state: 'NY',
zip: 12345,
isCurrent: true
}
]
}
3.1 - Parsing into generic POJO models
The RDF parser is not limited to parsing back into the original bean classes.
If the bean classes are not available on the parsing side, the parser can also be used to
parse into a generic model consisting of Maps
, Collections
, and primitive
objects.
You can parse into any Map
type (e.g. HashMap
, TreeMap
), but
using {@link org.apache.juneau.ObjectMap} is recommended since it has many convenience methods
for converting values to various types.
The same is true when parsing collections. You can use any Collection (e.g. HashSet
, LinkedList
)
or array (e.g. Object[]
, String[]
, String[][]
), but using
{@link org.apache.juneau.ObjectList} is recommended.
When the map or list type is not specified, or is the abstract Map
, Collection
, or List
types,
the parser will use ObjectMap
and ObjectList
by default.
In the following example, we parse into an ObjectMap
and use the convenience methods for performing data conversion on values in the map.
// Parse RDF into a generic POJO model.

String name = m.getString("name");
int id = m.getInt("id");
// Get a value convertable from a String.
URI uri = m.get(URI.class, "uri");
// Get a value using a swap.
CalendarSwap swap = new CalendarSwap.ISO8601DTZ();
Calendar birthDate = m.get(swap, "birthDate");
// Get the addresses.
ObjectList addresses = m.getObjectList("addresses");
// Get the first address and convert it to a bean.
Address address = addresses.get(Address.class, 0);
However, there are caveats when parsing into generic models due to the nature of RDF.
Watch out for the following:
- The ordering of entries are going to be inconsistent.
- Bean URIs are always going to be denoted with the key "uri".
Therefore, you cannot have a bean with a URI property and a separate property named "uri".
The latter will overwrite the former.
This isn't a problem when parsing into beans instead of generic POJO models.
- All values are strings.
This normally isn't a problem when using ObjectMap
and ObjectList
since
various methods are provided for converting to the correct type anyway.
- The results may not be what is expected if there are lots of URL reference loops in the RDF model.
As nodes are processed from the root node down through the child nodes, the parser keeps
track of previously processed parent URIs and handles them accordingly.
If it finds that the URI has previously been processed, it handles it as a normal URI string and doesn't
process further.
However, depending on how complex the reference loops are, the parsed data may end up having the
same data in it, but structured differently from the original POJO.
We can see some of these when we render the ObjectMap
back to JSON.
System.err.println(JsonSerializer.DEFAULT_LAX_READABLE.serialize(m));
This is what's produced:
{
uri: 'http://sample/addressBook/person/1',
addresses: [
{
uri: 'http://sample/addressBook/address/1',
isCurrent: 'true',
zip: '12345',
state: 'NY',
city: 'Anywhereville',
street: '100 Main Street',
id: '1',
personUri: 'http://sample/addressBook/person/1'
}
],
birthDate: '1946-08-12T00:00:00Z',
addressBookUri: 'http://sample/addressBook',
name: 'John Smith',
id: '1',
root: 'true'
}
As a general rule, parsing into beans is often more efficient than parsing into generic models.
And working with beans is often less error prone than working with generic models.
3.2 - Configurable properties
See the following classes for all configurable properties that can be used on this parser:
- {@link org.apache.juneau.BeanContext} - Bean context properties.
- {@link org.apache.juneau.jena.RdfParserContext} - Parser context properties.
3.3 - Other notes
- Like all other Juneau parsers, the RDF parser is thread safe and maintains an internal cache of bean classes encountered.
For performance reasons, it's recommended that parser be reused whenever possible instead of always creating new instances.
Juneau provides fully-integrated support for RDF serialization/parsing in the REST server and client APIs.
The next two sections describe these in detail.
4.1 - REST server support
There are four general ways of defining REST interfaces with support for RDF media types.
Two using the built-in Juneau Server API, and two using the JAX-RS integration component.
- Create a servlet that subclasses from {@link org.apache.juneau.rest.jena.RestServletJenaDefault}.
This includes serialization and parsing for all Jena supported types, including all supported flavors of RDF.
- Create a servlet that subclasses from {@link org.apache.juneau.rest.RestServlet} and specify the
RDF serializers and parsers using the {@link org.apache.juneau.rest.annotation.RestResource#serializers()} and
{@link org.apache.juneau.rest.annotation.RestResource#parsers()} on the entire servlet class, or
the {@link org.apache.juneau.rest.annotation.RestMethod#serializers()} and {@link org.apache.juneau.rest.annotation.RestMethod#parsers()}
annotations on individual methods within the class.
- Register {@link org.apache.juneau.rest.jaxrs.rdf.DefaultJenaProvider} with JAX-RS to provide support RDF support for all JAX-RS resource.
This includes serialization and parsing for all Juneau supported types (JSON, XML, HTML...), including all supported flavors of RDF.
- Create and register a subclass of {@link org.apache.juneau.rest.jaxrs.BaseProvider} and specify the serializers and parsers to use on JAX-RS resources.
In general, the Juneau REST server API is much more configurable and easier to use than JAX-RS, but beware that the author may be slightly biased in this statement.
4.1.1 - Using RestServletJenaDefault
The quickest way to implement a REST resource with RDF support is to create a subclass of {@link org.apache.juneau.rest.jena.RestServletJenaDefault}.
This class provides support for all the RDF flavors in addition to JSON, XML, HTML, and URL-Encoding.
The reason why RDF support was not added to {@link org.apache.juneau.rest.RestServletDefault} directly was to keep the Jena prerequisites
out of the org.apache.juneau.rest
package.
The AddressBookResource
example shown in the first chapter uses the RestServletJenaDefault
class.
The start of the class definition is shown below:
// Proof-of-concept resource that shows off the capabilities of working with POJO resources.
// Consists of an in-memory address book repository.
@RestResource(
messages="nls/AddressBookResource",
title="$L{title}",
description="$L{description}",
htmldoc=@HtmlDoc(
links="{options:'?method=OPTIONS',doc:'doc'}"
),
properties={
@Property(name=RdfProperties.RDF_rdfxml_tab, value="3"),
@Property(name=RdfSerializerContext.RDF_addRootProperty, value="true"),
@Property(name=SerializerContext.SERIALIZER_quoteChar, value="'"),
@Property(name=HtmlSerializerContext.HTML_uriAnchorText, value=TO_STRING)
},
encoders=GzipEncoder.class
)
public class AddressBookResource extends RestServletJenaDefault {
Notice how serializer and parser properties can be specified using the @RestResource.properties()
annotation.
The RDF_rdfxml_tab and RDF_addRootProperty are properties on the RDF serializers.
The SERIALIZER_quoteChar property is common to all serializers.
The remaining properties are specific to the HTML serializer.
The $L{...}
variable represent localized strings pulled from the resource bundle identified by the messages
annotation.
These variables are replaced at runtime based on the HTTP request locale.
Several built-in runtime variable types are defined, and the API can be extended to include user-defined variables.
See {@link org.apache.juneau.rest.RestContext#getVarResolver()} for more information.
This document won't go into all the details of the Juneau RestServlet
class.
Refer to the org.apache.juneau.rest documentation for more information on the REST servlet class in general.
The rest of the code in the resource class consists of REST methods that simply accept and return POJOs.
The framework takes care of all content negotiation, serialization/parsing, and error handling.
Below are 3 of those methods to give you a general idea of the concept:
// GET person request handler
@RestMethod(name="GET", path="/people/{id}/*", rc={200,404})
public Person getPerson(RestRequest req, RestResponse res, @Path int id) throws Exception {
res.setPageTitle(req.getPathInfo());
return findPerson(id);
}
// POST person handler
@RestMethod(name="POST", path="/people", guards=AdminGuard.class, rc={307,404})
public void createPerson(RestResponse res, @Body CreatePerson cp) throws Exception {
Person p = addressBook.createPerson(cp);
res.sendRedirect(p.uri);
}
// DELETE person handler
@RestMethod(name="DELETE", path="/people/{id}", guards=AdminGuard.class, rc={200,404})
public String deletePerson(RestResponse res, @Path int id) throws Exception {
Person p = findPerson(id);
addressBook.remove(p);
return "DELETE successful";
}
The resource class can be registered with the web application like any other servlet, or can be
defined as a child of another resource through the {@link org.apache.juneau.rest.annotation.RestResource#children()} annotation.
4.1.2 - Using RestServlet with annotations
For fine-tuned control of media types, the {@link org.apache.juneau.rest.RestServlet} class
can be subclassed directly.
The serializers/parsers can be specified through annotations at the class and/or method levels.
An equivalent AddressBookResource
class could be defined to only support RDF/XML using
the following definition:
@RestResource(
serializers={RdfSerializer.XmlAbbrev.class},
parsers={RdfParser.Xml.class},
properties={
@Property(name=RdfProperties.RDF_rdfxml_tab, value="3"),
@Property(name=RdfSerializerContext.RDF_addRootProperty, value="true"),
@Property(name=SerializerContext.SERIALIZER_quoteChar, value="'")
}
)
public class AddressBookResource extends RestServlet {
Likewise, serializers and parsers can be specified/augmented/overridden at the method level like so:
// GET person request handler
@RestMethod(name="GET", path="/people/{id}/*", rc={200,404},
serializers={RdfSerializer.XmlAbbrev.class},
parsers={RdfParser.Xml.class},
properties={
@Property(name=RdfProperties.RDF_rdfxml_tab, value="3"),
@Property(name=SerializerContext.SERIALIZER_quoteChar, value="'")
}
)
public Person getPerson(RestRequest req, RestResponse res, @Path int id) throws Exception {
res.setPageTitle(req.getPathInfo());
return findPerson(id);
}
The {@link org.apache.juneau.rest.annotation.RestMethod#serializersInherit()} and
{@link org.apache.juneau.rest.annotation.RestMethod#parsersInherit()} control how various artifacts
are inherited from the parent class.
Refer to org.apache.juneau.rest for additional information on using these annotations.
4.1.3 - Using JAX-RS DefaultJenaProvider
RDF media type support in JAX-RS can be achieved by using the {@link org.apache.juneau.rest.jaxrs.rdf.DefaultJenaProvider} class.
It implements the JAX-RS MessageBodyReader
and MessageBodyWriter
interfaces for all Juneau supported media types.
The DefaultJenaProvider
class definition is shown below:
@Provider
@Produces(
"application/json,text/json,"+ // JsonSerializer
"application/json+simple,text/json+simple,"+ // JsonSerializer.Simple
"application/json+schema,text/json+schema,"+ // JsonSchemaSerializer
"text/xml,"+ // XmlDocSerializer
"text/xml+simple,"+ // XmlDocSerializer.Simple
"text/xml+schema,"+ // XmlSchemaDocSerializer
"text/html,"+ // HtmlDocSerializer
"application/x-www-form-urlencoded,"+ // UrlEncodingSerializer
"text/xml+soap,"+ // SoapXmlSerializer
"text/xml+rdf,"+ // RdfSerializer.Xml
"text/xml+rdf+abbrev,"+ // RdfSerializer.XmlAbbrev
"text/n-triple,"+ // RdfSerializer.NTriple
"text/turtle,"+ // RdfSerializer.Turtle
"text/n3,"+ // RdfSerializer.N3
"application/x-java-serialized-object" // JavaSerializedObjectSerializer
)
@Consumes(
"application/json,text/json,"+ // JsonParser
"text/xml,"+ // XmlParser
"text/html,"+ // HtmlParser
"application/x-www-form-urlencoded,"+ // UrlEncodingParser
"text/xml+rdf,"+ // RdfParser.Xml
"text/n-triple,"+ // RdfParser.NTriple
"text/turtle,"+ // RdfParser.Turtle
"text/n3,"+ // RdfParser.N3
"application/x-java-serialized-object" // JavaSerializedObjectParser
)
@JuneauProvider(
serializers={
JsonSerializer.class,
JsonSerializer.Simple.class,
JsonSchemaSerializer.class,
XmlDocSerializer.class,
XmlDocSerializer.Simple.class,
XmlSchemaDocSerializer.class,
HtmlDocSerializer.class,
UrlEncodingSerializer.class,
SoapXmlSerializer.class,
RdfSerializer.Xml.class,
RdfSerializer.XmlAbbrev.class,
RdfSerializer.NTriple.class,
RdfSerializer.Turtle.class,
RdfSerializer.N3.class,
JavaSerializedObjectSerializer.class
},
parsers={
JsonParser.class,
XmlParser.class,
HtmlParser.class,
UrlEncodingParser.class,
RdfParser.Xml.class,
RdfParser.NTriple.class,
RdfParser.Turtle.class,
RdfParser.N3.class,
JavaSerializedObjectParser.class,
}
)
public final class DefaultJenaProvider extends BaseProvider {}
That's the entire class. It consists of only annotations to hook up media types to Juneau serializers and parsers.
The @Provider, @Produces, and @Consumes annotations are standard JAX-RS annotations, and the @JuneauProvider annotation is from Juneau.
To enable the provider, you need to make the JAX-RS environment aware of it.
In Wink, this is accomplished by adding an entry to a config file.
<web-app version="2.3">
<servlet>
<servlet-name>WinkService</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>applicationConfigLocation</param-name>
<param-value>/WEB-INF/wink.cfg</param-value>
</init-param>
</servlet>
Simply include a reference to the provider in the configuration file.
org.apache.juneau.rest.jaxrs.DefaultJenaProvider
Properties can be specified on providers through the {@link org.apache.juneau.rest.jaxrs.JuneauProvider#properties()} annotation.
Properties can also be specified at the method level by using the {@link org.apache.juneau.rest.annotation.RestMethod#properties} annotation, like so:
@GET
@Produces("*/*")
@RestMethod( /* Override some properties */
properties={
@Property(name=RdfProperties.RDF_rdfxml_tab, value="3"),
@Property(name=SerializerContext.SERIALIZER_quoteChar, value="'")
}
)
public Message getMessage() {
return message;
}
Limitations
In general, the Juneau REST API is considerably more flexible than the JAX-RS API, since you can specify and override
serializers, parsers, properties, transforms, converters, guards, etc... at both the class and method levels.
Therefore, the JAX-RS API has the following limitations that the Juneau Server API does not:
- The ability to specify different media type providers at the class and method levels.
For example, you may want to use RdfSerializer.Xml
with one set of properties on
one class, and another instance with different properties on another class.
There is currently no way to define this at the class level.
You can override properties at the method level, but this can be cumbersome since it would have to be
done for all methods in the resource.
- The Juneau Server API allows you to manipulate properties programatically through the {@link org.apache.juneau.rest.RestResponse#setProperty(String,Object)}
method, and through the {@link org.apache.juneau.rest.annotation.Properties} annotation.
There is no equivalent in JAX-RS.
4.1.4 - Using JAX-RS BaseProvider with annotations
To provide support for only RDF media types, you can define your own provider class, like so:
@Provider
@Produces(
"text/xml+rdf,"+ // RdfSerializer.Xml
"text/xml+rdf+abbrev,"+ // RdfSerializer.XmlAbbrev
"text/n-triple,"+ // RdfSerializer.NTriple
"text/turtle,"+ // RdfSerializer.Turtle
"text/n3"+ // RdfSerializer.N3
)
@Consumes(
"text/xml+rdf,"+ // RdfParser.Xml
"text/n-triple,"+ // RdfParser.NTriple
"text/turtle,"+ // RdfParser.Turtle
"text/n3" // RdfParser.N3
)
@JuneauProvider(
serializers={
RdfSerializer.Xml.class,
RdfSerializer.XmlAbbrev.class,
RdfSerializer.NTriple.class,
RdfSerializer.Turtle.class,
RdfSerializer.N3.class,
},
parsers={
RdfParser.Xml.class,
RdfParser.NTriple.class,
RdfParser.Turtle.class,
RdfParser.N3.class,
},
properties={
@Property(name=RdfProperties.RDF_rdfxml_tab, value="3"),
@Property(name=SerializerContext.SERIALIZER_quoteChar, value="'")
}
)
public final class MyRdfProvider extends BaseProvider {}
Then register it with Wink the same way as DefaultJenaProvider
.
4.2 - REST client support
The {@link org.apache.juneau.rest.client.RestClient} class provides an easy-to-use REST client interface with
pluggable media type handling using any of the Juneau serializers and parsers.
Defining a client to support RDF media types on HTTP requests and responses can be done in one line of code:
// Create a client to handle RDF/XML requests and responses.
RestClient client = new RestClientBuilder(RdfSerializer.XmlAbbrev.class, RdfParser.Xml.class).build();
The client handles all content negotiation based on the registered serializers and parsers.
The following code is pulled from the main method of the ClientTest
class in the sample web application, and
is run against the AddressBookResource
class running within the sample app.
It shows how the client can be used to interact with the REST API while completely hiding the negotiated content type and working with nothing more than beans.
String root = "http://localhost:9080/sample/addressBook";
// Get the current contents of the address book
AddressBook ab = client.doGet(root).getResponse(AddressBook.class);
System.out.println("Number of entries = " + ab.size());
// Delete the existing entries
for (Person p : ab) {
String r = client.doDelete(p.uri).getResponse(String.class);
System.out.println("Deleted person " + p.name + ", response = " + r);
}
// Make sure they're gone
ab = client.doGet(root).getResponse(AddressBook.class);
System.out.println("Number of entries = " + ab.size());
// Add 1st person again
CreatePerson cp = new CreatePerson(
"Barack Obama",
toCalendar("Aug 4, 1961"),
new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, true),
new CreateAddress("5046 S Greenwood Ave", "Chicago", "IL", 60615, false)
);
Person p = client.doPost(root + "/people", cp).getResponse(Person.class);
System.out.println("Created person " + p.name + ", uri = " + p.uri);
// Add 2nd person again, but add addresses separately
cp = new CreatePerson(
"George Walker Bush",
toCalendar("Jul 6, 1946")
);
p = client.doPost(root + "/people", cp).getResponse(Person.class);
System.out.println("Created person " + p.name + ", uri = " + p.uri);
// Add addresses to 2nd person
CreateAddress ca = new CreateAddress("43 Prairie Chapel Rd", "Crawford", "TX", 76638, true);
Address a = client.doPost(p.uri + "/addresses", ca).getResponse(Address.class);
System.out.println("Created address " + a.uri);
ca = new CreateAddress("1600 Pennsylvania Ave", "Washington", "DC", 20500, false);
a = client.doPost(p.uri + "/addresses", ca).getResponse(Address.class);
System.out.println("Created address " + a.uri);
// Find 1st person, and change name
Person[] pp = client.doGet(root + "?q={name:\"'Barack+Obama'\"}").getResponse(Person[].class);
String r = client.doPut(pp[0].uri + "/name", "Barack Hussein Obama").getResponse(String.class);
System.out.println("Changed name, response = " + r);
p = client.doGet(pp[0].uri).getResponse(Person.class);
System.out.println("New name = " + p.name);
The code above produces the following output.
Number of entries = 2
Deleted person Barack Obama, response = DELETE successful
Deleted person George Walker Bush, response = DELETE successful
Number of entries = 0
Created person Barack Obama, uri = http://localhost:9080/sample/addressBook/people/3
Created person George Walker Bush, uri = http://localhost:9080/sample/addressBook/people/4
Created address http://localhost:9080/sample/addressBook/addresses/7
Created address http://localhost:9080/sample/addressBook/addresses/8
Changed name, response = PUT successful
New name = Barack Hussein Obama


While I had posted before about how I felt that I had found the ideal tooling for my Zettelkasten in VimWiki, I hit some growing pains with the toolset as I continued to add to my notes. When my notes were fairly small it made a lot of sense to keep all of the notes in one, large document, but that got to be difficult to work with. My Zettelkasten is still far from huge compared to the examples of others on the internet; it is around 250 unique notes at the time of writing. I bounced around to a couple other tools when I decided to move away from VimWiki and I am happily (for now, I suppose) using Foam.
I don’t intend to imply that I jumped ship from VimWiki as soon as editing my notes became the slightest bit difficult, quite the opposite in fact. I prefer using Vim for most of my text editing needs so staying in Vim to edit my notes reduced the resistance for switching mental modes to taking notes from my usual code writing. I found two additions to my VimWiki workflow that made editing easier.
The first addition was isn’t a dedicated tool, really, but was a new addition to my Vim skills. I learned more about folding sections in Vim and set up my config to indent VimWiki headers. This allowed me to reduce the visual clutter of the many notes in the wiki file. This created a new problem, though, because I used the first line or two of each note as a way of determining what it was about when adding backlinks. This meant that I had to constantly fold and unfold notes, defeating most of the approach’s benefits.
The second addition was an excellent plugin for Vim that allowed me to view the VimWiki headers in a standard ctags sidebar. This made it possible to see the hierarchy of notes based on their Zettelkasten tags in a simple viewer. This had the same issue as the folding addition, though, in that I couldn’t see the description when trying to make links between documents. It was an improvement but I still struggled to find the right place to add new notes and to find existing notes when creating links.
It became pretty clear that the recommended folder structure for a Zettelkasten in most tools is to use one markdown file for each note. This adds a bit more of a clear hierarchical structure to the notes than Luhman seemed to recommend in his personal Zettelkasten, but I actually have found this structure to be an improvement. The consensus seems to be a bit split on file naming, whether to use descriptive names or just the Zettelkasten identifier. I chose to put both in the file name, and so far it has made for a nice balance of easy discoverability of the note’s topic and conciseness. The recommended structure for Dendron used one large root folder and dots to indicate the document hierarchy. I found this large folder to have many of the same shortcomings that the single VimWiki had, it was hard to navigate. The nested folder structure gave me the ability to easily find notes and only see the notes that I was concerned with.
I found out about Obsidian from their beta announcement on Hacker News right around the time that I started to hit those growing pains with VimWiki. This convenient timing combined with the excellent feature set of Obsidian’s app made it a perfect choice for switching away from VimWiki. I was more easily able to create and edit links in Obsidian and the Obsidian editor added a very neat graph view showing the relationship between notes. This graph view helped cement for me the idea that the Zettelkasten should be a “second brain” with each note as a neuron connecting to others to form a brain-like network.
It was much easier to add a lot more information to my Zettelkasten when using Obsidian as the editor. The folder based structure made it easier to find the right place to add items and the autocompletion for adding links between notes helped me connect notes better than before. The autocompletion wasn’t great though; it seemed to look for any note name that contained one of the letters in the search rather than considering the search to be a real word. This behavior meant that I often had to type out the whole name of the note anyways.
My issues with the link autocompletion and a worry about Obsidian’s licensing with work-related notes led me to look further for a similar Zettelkasten tool. I also discovered Dendron through a Hacker News post and liked that it was built on Visual Studio Code rather than a standalone editor. Visual Studio Code is my other editor of choice along with Vim so using a Zettelkasten tool in VSCode would give me that same-environment benefit that VimWiki had. Switching to Visual Studio Code brought back a number of of convenient text editing shortcuts that I hadn’t realized I had missed until I switched, namely the ability to delete a whole line in a keyboard shortcut.
Dendron’s link autocompletion also seemed to have issues, though. It wouldn’t split up search queries into individual letters like Obsidian, thankfully, but often the plugin would crash or would it fail to redirect me to the linked file properly. The graph view would similarly crash quite often. This is all understandable given that Dendron is in a beta stage currently, but I was a bit frustrated with the instability given how much I relied on the tool for note taking.
Once again, I found a new option for my Zettelkasten through a Hacker News post. This time the tool was a very similar alternative to Dendron, a set of Visual Studio Code plugins called Foam. Foam covered a similar feature set as Obsidian and Dendron with the addition of a Jekyll/Github Pages integration. I hope to, at some point, clean up my Zettelkasten and get it added to my personal site here since it can be added to a Jekyll site. Foam didn’t add much other new functionality besides that, but so far Foam has been able to reliably handle my ever-growing Zettelkasten with no crashes or major bugs. The link autocompletion is excellent so I am able to write links to other documents without the cognitive overload of trying to remember their Zettelkasten identifiers. The graph view isn’t quite as nice as Obsidian’s but it does the trick, showing me what notes have proper links and which ones need some attention.
Overall, I’m very happy with Foam. The other tools I tested along the way were suitable but I’ve found a great fit for my workflow in Foam. I’ll be sure to report back with a follow-up blog post again as my notes grow further, hopefully I’ll be able to report that Foam still fits my needs.


 It will be held from October 13th till October 16th.
It is an inimitable product of Delhi’s unique lust for life and BRCA’s proverbial tendency towards excellence.
It is a 4 day extravaganza with equal parts of awesomeness in organization and turnout.
We are young, wild, free and exuberant. Come join us as we celebrate and indulge in the joys of life.
0+
footfall
0 artists from
0 countries
0+ competitive
events
0 INR
prize money
a show for everyone
With hundreds of exciting events, Rendezvous promises to be a delight for every palate. Big names like Hoobastank, Arijit Singh, Vishal Shekhar, Shankar Ehsaan Loy and many more have graced Rendezvous with their presence. The extravaganza hosts International artists, competitions and much more, all packed into one epic cultural fiesta!


Portfolio - Anna Reithmeir |
I developed a small Android application for an augmented art gallery experience. When the back-camera is used the app augments real-world artwork while the front-camera interacts with the user's face by enhancing his or her face with selected pieces ao art. I developed the app in order to try out AR development in Unity.
--> C# Android Unity Vuforia
Neural networks have proven to be useful for the prediction of the3D protein structure. This is usually done by representing the amino acid sequences as multiple sequence alignments (MSA). However, the complexity of computing such
MSAs poses a challenge which is why a method which does not rely on the computation of MSAs is desirable.
In the scope of my Bachelor thesis, I investigated to what extent the use of NLP methods such as word embeddings and LSTMs can
improve the performance of deep neural networks in protein structure prediction without the use of MSAs.
Moreover, I investigated if multi-task learning of additional structural features further improve the predictions.
--> PyTorch LSTMs NLP Multitask Learning
I developed a tool to detect code plagiarisms in student coding homework submitted to the ARTEMIS platform. The results are shown graphically in the form of graphs. I implemented a bash script which accesses the student homeworks via git, compares them to each other and produces similarity graphs.
--> Linux Bash
I ported the OctNet code from Lua/C++ to Python to make it usable with PyTorch.
--> C++ Lua Pybind11 PyTorch
Development of a VR image gallery for the Leap Motion. The user interacts directly with the gallery through gestures and motion.
--> C# Unity Leap Motion
In the scope of a uni project I developed a program which reconstructs images from X-ray dark-field signals. The GUI is realized with Qt.
--> C++ Qt
11.2.19, "Method and system for viewing virtual elements"


I am persuing my Electrical Engineering Degree From University of Engineering and Technology,Lahore Campus. I have interest in programmong and have grip on several programming languages too. I have also completed several Web Devolopment Projects e.g this portfolio and many other sites.
View Full DetailsDid my Matriculation from Govt. Central Model School, Lower Mall, Lahore with 90% marks.
Completed my FSc from Govt. Islamia College Civil Lines, Lahore(in Pre Engineering)with 90% marks.
Currently studing Electrical Engineering form UET,Lahore with a CGPA of 3.3.
Skills make you rich, not theories


LOGO
Item1
(current)
Side Menu Items
Item2
Home
(current)
Login
SignUp
Item 1
Description 1
Item 2
Description 2
Item 2
Description 2
Previous
Next
Info
Information Box
Profile and all other information goes here
link
Another link


Scheduler
Complete my Registration
All symbols are allowed, at least 1 upper case, 1 lower case, and 1 number required. Minimum 8 characters.
Complete Registion
By clicking the complete registion button
I agree to the
Terms & Conditions.


dualPrint
Which would be the last page to print?
How many slides or pages per side?
Which would be the first page to print?
Odd, set of pages to print first.
Even, set of pages to print on the back.
About dualPrint
dualPrint is a multi-platform application that
Copyright © 2012 Javier O. Cordero Pérez
This software is under the MIT License
1.2
dualPrint
Built in Illumination Software Creator
generates print sets for multiple pages per
sheet, two-sided, printing.
For more information click License.


Kevin Pan
05.28.20
The year 2020 can be summed up in one word: transition. Whether a school year was cut short or events were canceled altogether, changes have been made swiftly and across the board; including methods of teaching. Schooling consists of how the professors, teachers, instructors, etc. conduct themselves in transmitting the necessary information to their students, but the other half is how the students learn and whether they’re staying up-to-date in the latest classwork.
College offers many forms of freedom that are often taken for granted, at least they used to be. While you may not be walking to class, making sure you’re “present,” even in an online format, is crucial. Don’t discount an entire class just because it’s only offered online, odds are that it was either online or not at all.
Another important aspect of online learning is creating a routine. Don’t sleep in until 12 p.m. just because you can, create a daily routine that mimics normalcy as much as possible. Create a schedule that is conducive to your education as much as possible, just because things aren’t back to normal doesn’t mean that you should let the day slip away.
Organizing your assignments is also a priority in remaining on top of your assignments. Sometimes it can feel cluttered with various tabs open in your browser, each pertaining to different classes, so don’t feel afraid to revert to the classic pen and paper. Writing down due dates and assignments for each class can help with an orderly and concise environment.
Make sure to balance your in-person classes and your online ones. Set aside time for both and study for your online class as if you were physically there. Don’t let the stigma surrounding online education affect the level of effort you dedicate to your studies. Juggling both types of formats can be confusing at times so don’t hesitate to take a step back and evaluate what you need to do.
In summary, handling online classes is new and unexplored for some of us, but it doesn’t have to be crippling. Here are some tips to make your transition a little easier:


U2.W4. Technical Blog Entry
Covering: Enumerable #Map
January 20, 2015
The topic we will be covering today is the topic of the .map Enumerable (which is also known as .collect) This particular enumerable is a non-destructive method that will take information from an input array, make a copy of the array, and the loop through every element of the array and perform actions you specified in the block (the instructions for the .map enumerable).
For example, you may want to take an array, and find out what each of the elements will look like capitalized, but you still want to keep the original array intact. You could use .map to output a capitalized array while keeping the original array intact.
cat_array = ["tabby", "tom", "puss-in-boots"] big_cat = cat_array.map{|x| x.capitalize} puts big_cat #=> ["Tabby", "Tom", "Puss-in-boots"] puts cat_array #=> ["Tabby", "Tom", "Puss-in-boots"]
This is a really helpful method for iterating over an exiting array or hash if you need to keep your original array for whatever reason. It'll output your transformed array or hash as an entirely new object.