3/12 email from Brooklyn
From: "Michelle J. Anderson, President, Brooklyn College"<EMAIL_ADDRESS>Date: March 12, 2020 at 11:50:01 PM EDT To: Brooklyn College Announcements<EMAIL_ADDRESS>Subject: COVID-19: Brooklyn College is CLOSED on Friday, March 13 Reply-To: "Michelle J. Anderson, President, Brooklyn College"<EMAIL_ADDRESS>COVID-19 Update: Brooklyn College is Closed on Friday, March 13
Dear Brooklyn College community,
I write to inform you that a member of the Brooklyn College community tested positive for the coronavirus (COVID-19) this evening. The student is in the hospital under medical care, and our thoughts are with her for a full and speedy recovery.
The student takes two classes on Tuesday evenings and she was last on campus on March 3. She did not develop symptoms until Thursday, March 5, and tested positive this evening, Thursday, March 12. Because she was asymptomatic at the time she was last on campus, the risk to our community is low. However, out of an abundance of caution, Brooklyn College will be closed tomorrow, Friday, March 13. All students, staff, faculty, and visitors should NOT come to any of the College's buildings.
We will use the day tomorrow to consult further with public health officials and to deep clean the building on campus where the student was. We have notified her instructors and the other students in her Tuesday night classes.
As always, if you feel sick, please contact a health care provider. If you don't have a health care provider, please call 311. Hospital staff cannot ask you about your immigration status or deny you care based on your ability to pay.
Your health and safety are our number one priority. Please continue to visit the Brooklyn College webpage at www.brooklyn.cuny.edu/coronavirus for the latest information, which we update daily.
Thank you,
Michelle J. Anderson President


a11y-media-player Audio demo
Audio demo, standalone with thumbnail image and width set
Audio demo with height set to 165px (use this for iframes)


Applied XML Dev.Conf. Message Board Heating Up
Here. The message board for the Applied XML Developer's Conference is heating up a bit. I set it up for the audience to be able to communicate during the presentations, but folks are already using it to coordinate Dev.Conf.-related activites. Enjoy.


{% extends "nav.html" %} {% block header %} {% block title %} Pet Profile Admin {% endblock %} {% block html_head %} {% endblock %}
| Submitted | Pet Name | Applicant | Home Type | Rent Own | Address | Kids | Kid Text | Other Pets | Other Pets Text | Why Adopt? | Status | Date Updated | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01/26/2020 | Sunshine | John Smith | House | Own | 123 Sesame Street Portland, OR 97214 |
Yes | Young Kids | No | Kids are old enough to have pets. | New | Pet ✔ ✘ | ||
| 01/15/2020 | Bun Bun | Rachel Green | Apartment | Rent | 564 Windy Winds Lane Bellevue, WA 98004 |
No | Yes | 1 dog, 2 cats | Love animals! The more the merrier! | Approved | 01/20/2020 | Pet ✔ ✘ | |


--- layout: projectpages title: "Total Number of Days Accessed" author: "partha" categories: visuals1 caption: Total number of days tools section of platform is accessed tags: [tools, total_number_of_days] image: feature : pest_project1.png ---
This chart gives us the sense of number of days platform is accessed by students during our period of observation. Each bar corresponds to a school and we have number of days on y-axis. Different colors correspond to different tools.


SUNNYSMILE
HOME
ACTIVITIES
FACILITIES
ABOUT US
CONTACT
Welcome to Sunny Smile Kindergarten
Sunny Smile
Previous
Next


---
layout: components
title: Notification
current: notification
---
An on-screen notification to inform users that something important has happened.
The GOV.UK design system includes a notification banner with further information on their usage.
Example
{% include example.html component="notification" size="s" %}
Information notification
{% include example.html component="notification" example="information" size="xs" %}
Success notification
{% include example.html component="notification" example="success" size="xs" %}
Success notification (no title)
{% include example.html component="notification" example="success-no-title" size="xs" %}
Warning notification
{% include example.html component="notification" example="warning" size="s" %}


Rules refer to the options you can pass to whitelister instructing it how to filter and validate input. Some rules apply to all types while other rules are specific to one or more types.
Rules are usually an object, for example: {% highlight js %} const rules = { user_id: { type: 'integer' }, email: { type: 'email', required: true }, }; {% endhighlight %} If you only need to pass a type rule, use shorthand: {% highlight js %} const rules = { user_id: 'integer', email: { type: 'email', required: true }, }; {% endhighlight %} Finally, you can pass a "custom" rule in the form of a function: {% highlight js %} const rules = { user_id: { type: 'integer' }, email: (val) => { if (val ===<EMAIL_ADDRESS>{ return<EMAIL_ADDRESS>} return val; }, }; {% endhighlight %}
{% for rule in site.data.rules %}{{ rule.description }}
{% highlight js %} {{ rule.example }} {% endhighlight %} types: {{ rule.types }}


The Black Hoof
Cocktail Bar
Rhum Corner
The Black Hoof
THANKS FOR 10 GREAT YEARS! THE HOOF IS NOW CLOSED.


|
On the applicability of the Hadamard as an input modulator for problems of classification.
v2.2
Documentation for lg.
|
NAMESPACE VISUALIZATION. More...
Functions | |
| int | findminsquare (int num) |
| HIDDEN FUNCTIONS. More... | |
| void | findvecrange (float *data, const int size, double *min, double *max) |
| Find the minimum and maximum value in a vector of numbers. More... | |
| void | save_vec (std::string path, const Tensor_float &vector) |
| PUBLIC FUNCTIONS. More... | |
| void | save_multiple_vec (std::string path, const lg::Tensor_float vector) |
| Save vectors to image More... | |
| void | save_multiple_vec (std::string path, const lg::Tensor_float vector, int table_width, int table_height) |
| Save vectors to image, all the vectors must be of the same size. More... | |
| void | save_vec (std::string path, const lg::Tensor_float &vector, int width, int height) |
| Save vector to image using a specific width and height for the image. More... | |
NAMESPACE VISUALIZATION.
| int lg::visualization::findminsquare | ( | int | num | ) |
HIDDEN FUNCTIONS.
Find the nearest perfect square of a number
Definition at line 34 of file visualization.cpp.
| void lg::visualization::findvecrange | ( | float * | data, |
| const int | size, | ||
| double * | min, | ||
| double * | max | ||
| ) |
Find the minimum and maximum value in a vector of numbers.
Definition at line 44 of file visualization.cpp.
| void lg::visualization::save_multiple_vec | ( | std::string | path, |
| const lg::Tensor_float | vector | ||
| ) |
Save vectors to image
Definition at line 77 of file visualization.cpp.
| void lg::visualization::save_multiple_vec | ( | std::string | path, |
| const lg::Tensor_float | vector, | ||
| int | table_width, | ||
| int | table_height | ||
| ) |
Save vectors to image, all the vectors must be of the same size.
Definition at line 114 of file visualization.cpp.
| void lg::visualization::save_vec | ( | std::string | path, |
| const lg::Tensor_float & | vector, | ||
| int | width, | ||
| int | height | ||
| ) |
Save vector to image using a specific width and height for the image.
Definition at line 146 of file visualization.cpp.
| void lg::visualization::save_vec | ( | std::string | path, |
| const lg::Tensor_float & | vector | ||
| ) |
PUBLIC FUNCTIONS.
Save vector to image
Definition at line 59 of file visualization.cpp.


{% extends "admin/admin_base.html" %} {% block page_title %} {% if form.type.data == "replaces" %} {{ current.bibjson().title }} continues… {% else %} {{ current.bibjson().title }} is continued by… {% endif %} {% endblock %} {% block admin_content %}
Please provide the Journal Title and ISSN(s) for the journal that is continued by {{ current.bibjson().title }}.
This will create a record in DOAJ so do not use this option if the journal already exists. Once you submit this form, a new journal record will be created and you may edit the other associated metadata fields.
{% endif %} {% if form.type.data == "is_replaced_by" %}Please provide the new Journal Title and new ISSN(s) that continue {{ current.bibjson().title }}. Once you submit this form, a new journal record will be created and you may edit the other associated metadata fields.
{% endif %}


(Deprecated API)
(Deprecated API)
(Deprecated API)
Includes enterprise licensing and support
This article covers some of the map styling and data feed aggregation techniques that were used to build the 2010 Election Ratings gadget, and some general concepts around visualizing complex datasets that change over time.
This map application visualizes data based on both State and County boundaries, and each polygon must be rendered according to a set of attributes that change daily. Developers who are familiar with displaying lots of data in Maps will notice that in this case the states and districts are not being rendered as vectors on the client, but as tiled image overlays. We made this choice because we knew the number and complexity of polygons would be greater than most browsers can render responsively. This is a common problem many developers face, and for this project we used a relatively new way of storing and styling complex geographic data for display in maps: Fusion Tables.
Fusion Tables provides access to its underlying data using the FusionTablesLayer in the Google Maps Javascript V3 API. You can use an SQL-like syntax to query for a subset of the data and then display the results on a map. The process is quick and easy to implement.
Before we could style or render the State and County polygons, we needed to acquire the attribute data that would be joined to the polygons and used to color each one appropriately. In this project, we had multiple disparate XML feeds we needed to parse, upload to Fusion Tables, and check for updates daily.
To check for daily updates of the election ratings, we set up App Engine cron jobs to retrieve the data from each feed and compare that data to what was stored in Fusion Tables. Data was updated in Fusion Tables if the information in the table no longer matched the data in the feed. To keep our code simple, we used the Placemat library to access the Fusion Tables API, and our workflow (minus the xml parsing) followed these 3 steps:
1. Authenticate to FT
auth_uri = 'https://www.google.com/accounts/ClientLogin' authreq_data = urllib.urlencode({ 'Email': username, 'Passwd': pw, 'service': 'fusiontables', 'accountType': 'HOSTED_OR_GOOGLE'}) auth_req = urllib2.Request(auth_uri, data=authreq_data) auth_resp = urllib2.urlopen(auth_req) auth_resp_body = auth_resp.read() auth_resp_dict = dict(x.split('=') for x in auth_resp_body.split('\n') if x) authtoken = auth_resp_dict['Auth']
2. Retrieve data in FT
encoded_query_params = urllib.urlencode({'sql': "SELECT rowid,rating,color FROM %d" % (tableid)}) path = "http://www.google.com/fusiontables/api/query?%s" % (encoded_query_params) headers = { 'Authorization': 'GoogleLogin auth=%s' % (authtoken), } serv_req = urllib2.Request(path, '', headers) serv_resp = urllib2.urlopen(serv_req) ft_data = serv_resp.read()
3. Update Fusion Tables
path = 'http://www.google.com/fusiontables/api/query' data = urllib.urlencode({'sql': "UPDATE %d SET rating='%s',color='%s' WHERE ROWID='%s'" % (tableid, rating, color, rowid)}) headers = { 'Authorization': 'GoogleLogin auth=%s' % (authtoken), 'Content-Type': 'application/x-www-form-urlencoded', } serv_req = urllib2.Request(path, data, headers) serv_resp = urllib2.urlopen(serv_req) response = serv_resp.read()
Since App Engine cron jobs are limited to a maximum of 30 seconds, we had to be efficient in retrieving the data from Fusion Tables and comparing this data to the current data. A simple approach of fetching the rows from Fusion Tables one-by-one would take too long, but fetching the entire dataset from Fusion Tables in one SELECT statement and holding this data in memory before the data was compared was a big timesaver.
There are some awesome features in App Engine and Fusion Tables that made the data aggregation process much simpler. For one, setting up cron jobs was a snap in App Engine. The merging capabilities in Fusion Tables really came in handy, as well. Merging is a left outer join, for those familiar with relational databases. We set up a separate table for each feed, and merged all tables into a single view using the id for the geographic area as a key.
Now we were ready to merge this Fusion Table with a table of actual geometries, which we downloaded from the US Census and imported into Fusion Tables. We then merged this view with the geometry for each geographic region. Because we made these geometry tables (such as this one) public, anyone can create new Fusion Tables by combining a table of their own attributes and these geometries to easily create choropleth maps with their own attribute data. See for youself an example of a final merged table.
Now that the data was ready, it was time to make sure it looked good. Fusion Tables supports a variety of styling options to ensure you can tell your story with your data. For this application we used the 'Column' option to set a specific polygon color (and opacity) for each possible rating.
With Fusion Tables all prepped with data and associated styles, it’s just a simple two line javascript call to get the data into your map:
var layer = new google.maps.FusionTablesLayer(table_id); layer.setMap(map);
That was easy! In the case of this particular dataset, we didn’t want to show polygons that had no associated rating at all, so we also set a query on the layer to ignore those rows with no associated color rating:
var query = ["select geo from",table_id,"where 'color' > 0"].join(' '); layer.setQuery(query);
Even though the Polygons are rendered server side we can still display custom data in our infoWindows. In this case we can use the FusionTablesMouseEvent to determine which polygon was clicked on and get the associated content. Then we used jQuery tabs (see here for an example) to help with the formatting of the results.
As with most mapping applications, getting your data in order is the most time consuming part of the project. Once that's out of the way, displaying complex spatial data in your Maps mashup is straightforward with Fusion Tables, and AppEngine’s cron jobs make periodic updates a breeze. But even if you are just displaying some static data on your map, don't forget to use Styled Maps for your base, and to customize the default cartography in your Fusion Tables layer for maximum effect.


Load Balancer Configuration Tool
This tool is designed to help create an optimal balance between apache-based load balancers and JBoss/Tomcat application servers. Input information about your current or planned deployment to generate a configuration files and advice about how you can increase your environment's performance.


| DOSE: T+ 0:00 |
0.5 tablets |
oral |
MDMA |
| T+ 1:00 |
0.5 tablets |
oral |
MDMA |
First, some background. I had just finished university. This was very disturbing because I realized that I had outrageously postponed certain changes that I had to make (basically becoming more social and getting a life) and that I had totally missed out on all the fun aspects of university.
I was interested in raves because I had read a lot of good things about raves. It seemed like something I really needed. At the same time I was afraid to go because I knew I wasn't ready for that. I told a friend (who I will now refer to as
) that I'd like to go with him sometime, and so he ended up inviting me to a party with 100-200 people. Basically, I overrode a sense of unease and anxiety and I went anyways.
I had also read a lot about E and I was really impressed with the effects that people describe. I was even more impressed with how some people said that it caused a lasting positive change. I really wished that would happen to me.
suggested that I go sober so that I don't end up getting too impressed with raves and E. (I actually wanted that to happen.) He didn't think I was at risk of a bad trip; he thought that E bad trips happen randomly and that they have probably more to do with something people ate than with set and setting. (I believed him, but in retrospect I'm sure he was wrong.)
When I got there I was anxious. Then I saw that where I got there was just basically a room with some people sitting and standing around and talking and another room with people dancing. I had no clue what to do and that was disturbing. (Note: I hadn't been to anything for any definition of the word 'party' since grade 6 or so.) introduced me to some of his friends but I was like 'What's the point? What do I do now? Why do I care?' I felt like I should leave except that would be even worse. Eventually I calmed down and I got to know some people I was talking to them, and maybe sometimes I made some attempt at dancing.
Basically, I was having a good time, but it wasn't even close to a spectacularly good time. I took E because I really wanted to try it and because I thought it'd let me get past some more insecurities and inhibitions and let me have a better time. I was told to try a half first. This did seem to have some subtle effect... like it did sort of facilitate being social end enjoying the music, but it wasn't much of an effect. I also felt a sort of 'tripping' feeling which wasn't accompanied by any trippy effects. I knew that there must be more to E than that, and so after an hour I took the other half.
The next significant thing I remember is lightly running his fingers through my hair and that felt *really* good. OTOH some of the people I met tried some rolling tricks on me, but it really do much.  I was having a good time. I remember dancing and realizing that this sort of thing could really help heal me.
The bad part came soon after this. I became *very* aware of how I had been lonely and I how I was totally starved for any interaction with people and especially any sort of exchange of affection. (I don't mean anything sexual; I guess E sort of turned off that need for the time being). However, I couldn't actually *do* anything... I'd just end up stuck analyzing what to do and what is okay. I just kept hitting that wall over and over again and every time it felt worse.
I also started realizing various things like things that I had kept myself from thinking about were now clear. I really wanted to talk to and tell him some stuff that seemed important. Then I finally talked to him and I started telling him pointless unrelated stuff and giving disclaimers while becoming increasingly upset with myself for not saying what I really meant. I then told him that I loved him. What I meant was that I had fallen in love with him a while ago, but I was just unaware of that. Now it all seemed so clear and I finally somehow managed to communicate that. He understood that and he basically said that he loves me but that he can't ever love me that way. He then kissed me on the cheek. I just felt like I had just done some horrible thing.
These two paragraphs basically are 'the bad part', but nothing I could possibly write could convey how stressful it felt. I think it was the most intense thing I've ever experienced. It's interesting how there was nothing physically special about this; like I didn't do anything bad, there were no consequences, and in any case I've dealt with much worse problems.
It was just that usually I'm very good at blocking emotions and not thinking about something by flooding by brain with useless repetitive thoughts. This is unpleasant but not intense. E didn't let me do any of that; there was no escape; I just had to face everything. E also amplified my emotions. I thought that it would suppress unpleasant 'problem' feelings but intensify pleasant feelings. I was so wrong. Perhaps E encouraged positive feelings but it also amplified anxiety very effectively.
Basically I freaked out internally, but I didn't freak out externally. I talked to various people, watched people dancing, etc. However, I guess I sort of disconnected.
[Erowid Note: Driving while intoxicated or tripping is dangerous and irresponsible because it endangers other people. Don't do it!]
After I left I started feeling as if something incredibly horrible had happened. I felt like I had blown my last chance. I drove home letting myself microsleep because I didn't care. When I got home I took a shower and I started having some 'micro flashbacks' to random events from the party. I wasn't just remembering the things; it practically felt like being there. This continued as I tried to get some sleep. When I woke up those 'micro flashbacks' were gone but I still felt pretty bad.
Over the next few days I started having longer flashbacks.  I tried to ignore these and that sort of helped. They decreased in intensity and they were gone after a week.
I think that the E let me make some significant progress, but because of the bad part I just backtracked and somehow rebelled against anything related to the experience. I ignored all the realizations. I couldn't stand any music that could be in any way related to raves, and I actually felt like destroying some CDs. I couldn't stand to see people hugging on TV. I thought that everything I saw people do is shallow and unreal.
I had a really hellish week after that trip. My parents contributed to that but having a bad trip on E was definitely a big part of the reason. I re-discovered some of the things I figured out while on E but I still denied a lot of it. By the end of the week I actually stopped feeling terrible and I could enjoy the music.
I seemed to fully recover after the week but the experience greatly discouraged me from making any other attempts to be social. I also couldn't really think about the experience clearly. I mostly just remembered the bad parts. I practically hid all the good parts from myself.
In retrospect the obvious problems were just overriding and ignoring my own objections and taking E as if it was guaranteed to provide the great experience it does for many others. I should have treated it just like any other psychedelic drug. I still don't actually regret doing it. I feel that not doing that because I was uneasy with it would have been worse.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Mirage is all about mocking out your API server. You define route handlers to respond to your Ember app’s AJAX requests.
Here’s a simple example of a handler:
// app/mirage/config.js
export default function() {
this.get('/api/users', function() {
return {
users: [
{ id: 1, name: 'Zelda' },
{ id: 2, name: 'Link' },
{ id: 3, name: 'Epona' },
]
}
});
}
Now whenever your Ember app makes a GET request to /api/users
, Mirage will respond with this data.
This works, and this is traditionally how HTTP mocking is done - but hard-coding fixture data directly into your route like this makes it inflexible. What if you want to see scenarios with different users, or want more control over the response data in your tests?
Instead of returning an array, let’s make this route dynamic by responding with all the users in Mirage’s in-memory database:
this.get('/api/users', function(db, request) {
return {
users: db.users
};
});
Now, if we want to change what data this route responds with, all we need to do is change the data in the database.
To actually seed our database with fake data, we’ll use factories. Factories are objects that dynamically generate data - think of them as blueprints for your database records.
You create factories by adding files under /mirage/factories/
:
// app/mirage/factories/user.js
import Mirage, { faker } from 'ember-cli-mirage';
export default Mirage.Factory.extend({
name(i) { return `Person ${i}`; },
age: 28,
admin: false,
avatar(i) { return faker.internet.avatar(); }
});
This factory will create objects like
{
name: 'Person 1',
age: 28,
admin: false,
avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/bergmartin/128.jpg'
},
{
name: 'Person 2',
age: 28,
admin: false,
avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/nemanjaivanovic/128.jpg'
}
and so on. This data will be inserted into your users
db table, giving each record a unique id
. The records will now be available to your route handlers.
To actually create factory data, use the server.create
or server.createList
methods in development
// app/mirage/scenarios/default.js
// Create 10 non-admin and 1 admin users for development
export default function(server) {
server.createList('user', 10);
server.create('user', { admin: true });
};
and in your acceptance tests
// tests/acceptance/users-test.js
test("I can view the users", function() {
var users = server.createList('user', 3);
visit('/users');
andThen(function() {
equal( find('li').length, 3 );
equal( find('li:first').text(), users[0].name );
});
});
You now have a simple way to set up your mock server’s initial data, both during development and on a per-test basis.
Mirage provides numerous shorthands to reduce the code needed for conventional API routes. For example, the route
this.get('/users', function(db, request) {
return {
users: db.users
};
});
can be written simply as
this.get('/users');
There are also shorthands for put
, post
and del
methods. Here’s a full set of resourceful routes for a user
resource:
this.get('/users');
this.get('/users/:id');
this.post('/users');
this.put('/users/:id');
this.del('/users/:id');
Shorthands make writing your server definition concise, so you should use them whenever possible. You can always fall back to a custom function when you need more control.
 Keep reading to learn more.


{% set project_name = config.PROJECT.get('name', '') %} {% set org_account = config.PROJECT.get('org_account', '') %} {% set bot_account = config.PROJECT.get('bot_account', '') %} {% set about_link = config.PROJECT.get('about_link', '') %}
'}} {% if org_account %} The new home is github.com/{{org_account}}. {% endif %} {% if about_link %} Read more about the migration plan. {% endif %} {{(org_account or about_link) and '
'}}We ask you for a permission so that we could also migrate
your Issue Tracker issues and comments.
It is OK to opt out.
Orphan messages will be owned by a
{% if bot_account %}
bot account
{% else %}
bot account
{% endif %}
and attributed to you through a note in a message text.
Please, sign in with your GitHub account and authorize the migrator application.
Sign in with GitHubThe migrator application requests the following permissions.
| Scope | Reason |
user:email |
To list email addresses
attached
to your account and associate them automatically (only verified addresses are added). |
public_repo |
To be able to re-create your issues and comments on behalf of you. |
Don't revoke access until the transition is finished!
Once it's done we'll revoke all user access tokens and delete them forever.
However, you may do it yourself,
just to be sure.
In order to associate all your contributions with the GitHub account we need to know email addresses you used to log in to Google Code with.
Well done! Thank you, now we've got all we need.
Please, add an email by signing in using your Google account.
To add another one, please, sign in using your Google account.
We don't store your Google access token.
It is only used once to retrieve your email address.
As always, you may revoke access manually.


@@include('../../renderings/components/global-header.html')
@@include('../../renderings/components/search.html')


Meir, a Talmudic scholar, and his wife Rivka have been married for ten years but have not been able to produce children, no matter how many prayers are recited or how many ritual baths Rivka takes to rid herself of "uncleanness." In the opening scene, Meir rises from his bed and goes through an elaborate series of prayers culminating in thanks to the Almighty that he was not born a female. The prayers are conducted while he wraps the leather thongs of the 'tfilin' around his arm, which altogether gives the appearance of a junky preparing for a fix. Instead of searching for a vein, Meir seems intent on mainlining God.
Rivka's younger sister Malka is in love with Jacov, but can not marry him. He has joined the Israeli army in defiance of the sect's ban on serving in the military. He is still deeply religious but is regarded as a renegade by the rest of the sect, who view any departure from the rigid code of conduct as evidence of godlessness.
Symbolizing this rigidity in the most dramatic fashion is Yossef, who attends the same Talmud school as Meir. When we first see the two men together, they launch into an extended disputation over whether it is more observant to put sugar into hot water when making tea on the Sabbath or vice versa. It turns out that the water should be poured over the tea and the sugar so as to preclude the possibility that the act amounts to cooking. Yossef is the sect firebrand and drives around in sound-truck during the week urging Jews to "close ranks" against their godless enemies, which includes both turncoats like Jacov and all Arabs.
Their rabbi has instructed Malka to break off with Jacov and marry Yossef. In a truly riveting but repulsive scene, Malka and Yossef are shown in bed on their wedding night. He first reads a prayer that is supposed to heighten the chances of procreation and then coldly instructs Malka to spread her legs. Without any foreplay, he mounts her like a ram and thrusts violently until he has climaxed.
Meanwhile, the rabbi has also instructed Meir to end his marriage with Rivka. The fact that she has not been able to conceive is regarded as a sin by the close-knit community and it is time for him to live up to his responsibility as a Jew. In their world, men are brought into the world to study the Talmud and women are there to support them. This means first of all procreating and secondly to cook and to keep the house clean.
Regarded by Time Magazine critic Richard Corliss as the greatest film ever made in Israel, "Kadosh" is director Amos Gitai's attempt to come to terms with what many secular Jews in Israel regard as a threat to their existence. The ultra-Orthodox Jews are a tightly-organized political faction that pressures Israel from the right. From the standpoint of Gitai, a left-wing Jew whose grandparents came to Palestine in the early part of the century as Labor Zionists, their orthodox cousins are an uncomfortable reminder of where they came from. While tokens of a backward and insular past are considered hindrances to civil society in the Israeli present, the more important question that the film-maker and most secular Jews are not prepared to confront revolves around their future. In truth it is very likely that within 25 years the only "true", i.e. observant, Jews will be the ultra-Orthodox.
The ultra-Orthodox sects, also known as the Hasidim, originated in 18th and 19th century Poland and Russia in a time of great economic stress and persecution. Marxist historian Ilan Halevi explains their origins in his "Question Juive":
"The internal crisis of the Shtetl, whose roots are to be found in the crisis of Polish feudalism, was exacerbated and radically aggravated. The domain of Polish sovereignty was shrinking rapidly. A kingdom that had stretched from the Baltic to the Black Sea grew smaller and smaller as around it tsarist Russia, the Hapsburg empire and the German states grew larger and larger. The Polish question became the European question and centuries-old Polish Jewry saw its territory carved up among several states Austria, which took Galicia, lightened the conditions of Jews there: but Russia, having seized the Ukraine and Byelorussia, oppressed them there, said Lenin, 'more harshly than the Negroes'. The Napoleonic conquest, short as it may have been, precipitated the disintegration, inducing a general upheaval in the empires of the centre and east. Following the French occupation, the whole map of the region was transformed. The new frontier of Austria and Russia, which shared the whole of what remained of Poland in 1815, cut the Ashkenazi world in two, divided the dynasties of Hasidic rabbis, and determined new sub-problematics. The sociological unity of Ashkenazi Judaism was beginning to fracture."
Against this pattern of disintegration, the Hasidic rabbis created cults based on three key elements that were supposed to function as life-rafts:
--Strict observance of rituals, particularly those involved with "cleanness"
--Reverence for the rabbi, who in most instances were seen as a potential Messiah
--Fervent recitation of prayers, dancing and singing meant to induce mystical states
For some secular Jews, and even some non-Jews, this last element has served to bring them into the fold. For instance, Bob Dylan drew close to the Lubavitcher Hasidic sect in the 1980s. He swapped these beliefs for Christian fundamentalism not too soon afterwards.
 The Lubavitchers have used political clout to gain preferential treatment to gain access to subsidized housing in a neighborhood where it is in short supply. Such tensions provided the backdrop for the riots that broke out during the Dinkins administration when the lead car of a Hasidic caravan struck and killed a black child. A Hasidic scholar Yankel Rosenbaum, identical to the film's characters, was stabbed during the violence and Dinkins was blamed for his death. The Hasidic community then delivered their votes to the "law-and-order" candidate Rudy Giuliani who has done everything possible to intimidate the black community, just the way that the current Labor government in Israel is using every means at its disposal to intimidate Arabs.
The contradictions of late capitalism are acting on worldwide Jewry in a manner that few Marxists--in my opinion--have fully understood. Social and economic processes are in motion that tend to create three distinct "peoples". One is the ultra-Orthodox sect depicted in the film. The second is the Israeli "Sabras", the native-born, largely secular, Jews who retain many of the values of any colonizing people like the Afrikaners. The third are the largely assimilated and secular Jews outside Israel who in a generation or two will retain nothing distinctly Jewish except perhaps their family name. The unique racial politics of worldwide Jewry will be forced to define itself in terms of how these various groups relate to worldwide capitalism and the oppressed Arab and Palestinian peoples. Political polarization will generate at least in some cases a radical response that the film "Kadosh" hints at. It is a positive sign that the film criticizes some of the most backward elements of Israel society and at least points the way toward a deepening critique of that society, including its secular but racist elements.
--Louis Proyect Marxist discussion is at: www.marxmail.org
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


printModel Prints reactions to the screen or to a file model a model structure rxnList either a cell array of reaction IDs, a logical vector with the same number of elements as reactions in the model, or a vector of indexes to remove (opt, default model.rxns) outputString a string that specifies the output of each reaction (opt, default '%rxnID (%rxnName)\n\t%eqn [%lower %upper]\n') outputFile a file to save the print-out to (opt, default is output to the command window) metaboliteList cell array of metabolite names. Only reactions involving any of these metabolites will be printed (opt) The following codes are available for user-defined output strings: %rxnID reaction ID %rxnName reaction name %lower lower bound %upper upper bound %obj objective coefficient %eqn equation %element equation using the metabolite formulas rather than metabolite names %unbalanced "(*)" if the reaction is unbalanced and "(-)" if it could not be parsed %lumped equation where the elemental compositions for the left/right hand sides are lumped NOTE: This is just a wrapper function around printFluxes. It is intended to be used when there is no flux distribution. Usage: printModel(model,rxnList,outputString,outputFile,metaboliteList) Rasmus Agren, 2013-02-20
0001 function printModel(model,rxnList,outputString,outputFile,metaboliteList) 0002 % printModel 0003 % Prints reactions to the screen or to a file 0004 % 0005 % model a model structure 0006 % rxnList either a cell array of reaction IDs, a logical vector 0007 % with the same number of elements as reactions in the model, 0008 % or a vector of indexes to remove (opt, default 0009 % model.rxns) 0010 % outputString a string that specifies the output of each reaction (opt, 0011 % default '%rxnID (%rxnName)\n\t%eqn [%lower %upper]\n') 0012 % outputFile a file to save the print-out to (opt, default is output to 0013 % the command window) 0014 % metaboliteList cell array of metabolite names. Only reactions 0015 % involving any of these metabolites will be 0016 % printed (opt) 0017 % 0018 % The following codes are available for user-defined output strings: 0019 % 0020 % %rxnID reaction ID 0021 % %rxnName reaction name 0022 % %lower lower bound 0023 % %upper upper bound 0024 % %obj objective coefficient 0025 % %eqn equation 0026 % %element equation using the metabolite formulas rather than 0027 % metabolite names 0028 % %unbalanced "(*)" if the reaction is unbalanced and "(-)" if it could not 0029 % be parsed 0030 % %lumped equation where the elemental compositions for the left/right 0031 % hand sides are lumped 0032 % 0033 % NOTE: This is just a wrapper function around printFluxes. It is 0034 % intended to be used when there is no flux distribution. 0035 % 0036 % Usage: printModel(model,rxnList,outputString,outputFile,metaboliteList) 0037 % 0038 % Rasmus Agren, 2013-02-20 0039 % 0040 0041 if nargin<2 0042 rxnList=model.rxns; 0043 end 0044 if isempty(rxnList) 0045 rxnList=model.rxns; 0046 end 0047 if nargin<3 0048 outputString='%rxnID (%rxnName)\n\t%eqn [%lower %upper]\n'; 0049 end 0050 if isempty(outputString) 0051 outputString='%rxnID (%rxnName)\n\t%eqn [%lower %upper]\n'; 0052 end 0053 if nargin<4 0054 outputFile=[]; 0055 end 0056 if nargin<5 0057 metaboliteList=[]; 0058 end 0059 0060 I=getIndexes(model,rxnList,'rxns',true)*1.00; %To convert it to "fluxes" 0061 0062 if ~isempty(metaboliteList) 0063 printFluxes(model, I, false, 0.1, outputFile,outputString,metaboliteList); 0064 else 0065 printFluxes(model, I, false, 0.1, outputFile,outputString); 0066 end


© Noah Loomans 2017-2021
This website is open-source under the MIT licence. The source-code can be found on sourcehut.


RedGPU - Examples
Basic
HelloWorld
Scene
View
Multi View
Primitive
Plane
Box
Sphere
Cylinder
Controller
Camera2D
Camera3D
ObitController
Object3D
Axis
Grid
SkyBox
Mesh
Sprite3D
Text
Method targetTo
Coordinate
Method screenToWorld
Method getScreenPoint
Method localToWorld
Method worldToLocal
pivotPoint
pivotPoint - Camera2D
Line
Line - LINEAR
Line - BEZIER
Line - CATMULLROM
Material
ColorMaterial
ColorPhongMaterial
ColorPhongTextureMaterial
BitmapMaterial
StandardMaterial
EnvironmentMaterial
RefractionMaterial
SpriteSheetMaterial
FlatMode of Material
Texture Sampler
BitmapTexture - Sampler
Light
AmbientLight
DirectionalLight
PointLight
Loader
GLTFLoader
gltfComplex
TODO - TextureLoader
MouseEvent
MouseEvent
mouseEvent in multi view
Particle
Particle
PostEffect
PostEffect
PostEffect Bloom
PostEffect Convolution
PostEffect Film
PostEffect Vignetting
Adjustments
PostEffect BrightnessContrast
PostEffect Gray
PostEffect HueSaturation
PostEffect Invert
PostEffect Threshold
Blur
PostEffect Blur
PostEffect BlurX
PostEffect BlurY
PostEffect GaussianBlur
PostEffect ZoomBlur
Pixelate
PostEffect HalfTone
PostEffect Pixelize


Andrés Sanoja UPMC - LIP6
separator.rb
Requires: Ruby 1.9.1+ (1.8.x versions won’t work) and rubygems 1.3.7+
Copyright (C) 2011, 2012 Andrés Sanoja, Université Pierre et Marie Curie - Laboratoire d’informatique de Paris 6 (LIP6)
Contributors: Stephane Gançarski - LIP6
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <www.gnu.org/licenses/>.
class for detect gaps between blocks and determine the kind of separation (horizontal and vertical)
# File lib/pagelyzer_separator.rb, line 74 74: def <=>(obj) 75: #define comparison type 76: if self.weight < obj.weight 77: 1 78: elsif self.weight > obj.weight 79: 1 80: else 81: 0 82: end 83: end
# File lib/pagelyzer_separator.rb, line 112 112: def bottom_crossed_by?(block,mode) 113: # permits to detect if a block is pass below a separator 114: if mode==:horizontal 115: return (block.min_y > @sp and block.min_y < @ep and block.max_y < @ep ) 116: else 117: return (block.min_x > @sp and block.min_x < @ep and block.max_x < @ep ) 118: end 119: end
# File lib/pagelyzer_separator.rb, line 85 85: def contains?(block,mode) 86: # permits to detect if a block is inside a separator 87: if mode == :horizontal 88: return ((@sp <= block.min_y) and (block.max_y <= @ep)) 89: else 90: return ((@sp <= block.min_x) and (block.max_x <= @ep)) 91: end 92: end
# File lib/pagelyzer_separator.rb, line 94 94: def covered_by?(block,mode) 95: # permits to detect if a separator is covered by a block 96: if mode==:horizontal 97: return (block.min_y <= @sp and @ep <= block.max_y) 98: else 99: return (block.min_x <= @sp and @ep <= block.max_x) 100: end 101: end
# File lib/pagelyzer_separator.rb, line 58 58: def points(block,mode) 59: #get the list of points in the separator polygon 60: polygon(block,mode).flatten 61: end
# File lib/pagelyzer_separator.rb, line 41 41: def polygon(block,mode) 42: #get the polygon representation of the separator 43: poly = [] 44: if mode == :horizontal 45: poly.push [block.min_x,@sp] 46: poly.push [block.max_x,@sp] 47: poly.push [block.max_x,@ep] 48: poly.push [block.min_x,@ep] 49: else 50: poly.push [@sp,block.min_y] 51: poly.push [@sp,block.max_y] 52: poly.push [@ep,block.max_y] 53: poly.push [@ep,block.min_y] 54: end 55: poly 56: end
# File lib/pagelyzer_separator.rb, line 121 121: def process_weight(mode) 122: #* assign a weight to a separator 123: #* greater distance greater weight 124: #* different types, font, background of content in both sides of separator higher weight 125: max_set = [] 126: @bright_side.each do |b| 127: max_dist = 0 128: @dark_side.each do |d| 129: if mode==:horizontal 130: dist = Point.new(0,b.max_y).distance_to? Point.new(0,d.min_y) 131: else 132: dist = Point.new(b.max_x,0).distance_to? Point.new(d.min_x,0) 133: end 134: if dist > max_dist 135: max_dist = dist 136: end 137: end 138: max_set.push max_dist 139: end 140: @weight = max_set.max unless max_set.empty? 141: 142: # backgrounds differents 143: bg = @bright_side.collect {|x| x.candidates_background_color_list}.flatten.uniq & @dark_side.collect {|x| x.candidates_background_color_list}.flatten.uniq 144: @weight += 10 if bg==[] 145: 146: #structures of blocks of two sides are are very similar (text, images, etc) decrease weight 147<EMAIL_ADDRESS>{|x| x.candidates_structure}.flatten.uniq.first 148<EMAIL_ADDRESS>{|x| x.candidates_structure}.flatten.uniq.first 149: @weight -=10 if a=='TITLE' and b!='TITLE' 150: @weight -=10 if a==b and a!='COMBINED' 151: 152: #fontsizes if different increase weight 153<EMAIL_ADDRESS>{|x| x.candidates_font_size_list}.flatten.max 154<EMAIL_ADDRESS>{|x| x.candidates_font_size_list}.flatten.min 155: a=0 if a.nil? 156: b=0 if b.nil? 157: @weight +=10 if a < b 158: end
# File lib/pagelyzer_separator.rb, line 63 63: def to_s 64: #string representation 65: sa = [] 66: sb = [] 67: 68: sa = @bright_side.collect{|x| x.id}.join(',') unless @bright_side.nil? 69: sb = @dark_side.collect{|x| x.id}.join(',') unless @dark_side.nil? 70: 71: "{(#{cformat(@sp)},#{cformat(@ep)}) W:#{@weight} A:[#{sa}] B:[#{sb}]} " 72: end
# File lib/pagelyzer_separator.rb, line 103 103: def top_crossed_by?(block,mode) 104: # permits to detect if a block is pass over a separator 105: if mode==:horizontal 106: return (block.min_y < @sp and block.max_y < @ep and block.max_y > @sp ) 107: else 108: return (block.min_x < @sp and block.max_x < @ep and block.max_x > @sp ) 109: end 110: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.


| optparse-package {optparse} | R Documentation |
Goal is to create an R package of a command line parser inspired by Python's “optparse” library.
optparse
is primarily intended to be used with
“Rscript”. It facilitates writing “#!” shebang scripts that
accept short and long flags/options. It can also be used from directly, but
is probably less useful in this context.
See package vignette for a more detailed example.
Notes on naming convention in package: 1. An option is one of the shell-split input strings. 2. A flag is a type of option. a flag can be defined as having no argument (defined below), a required argument, or an optional argument. 3. An argument is a type of option, and is the value associated with a flag. 4. A long flag is a type of flag, and begins with the string “–”. If the long flag has an associated argument, it may be delimited from the long flag by either a trailing =, or may be the subsequent option. 5. A short flag is a type of flag, and begins with the string “-”. If a short flag has an associated argument, it is the subsequent option. short flags may be bundled together, sharing a single leading “"-"”, but only the final short flag is able to have a corresponding argument.
Trevor Davis.
Some documentation and unit tests ported from Allen Day's getopt package.
The documentation for Python's optparse library, which this package is based on, is Copyright 1990-2009, Python Software Foundation.
Python's optparse
library, which this package is based on,
is described here: http://docs.python.org/library/optparse.html
example_file <- system.file("exec", "example.R", package = "optparse") example_file_2 <- system.file("exec", "display_file.R", package = "optparse") ## Not run: readLines(example_file) readLines(example_file_2) ## End(Not run)


Get Started
Let’s develop a small language that allows for simple computation together. Here’s a valid input file for that language:
puts(1 + 2)
puts(4 + 2)
To install the parslet library, please do a
gem install parslet
Now let’s write the first part of our parser. For now, we’ll just recognize simple numbers like ‘1’ or ‘42’.
require 'parslet'
class Mini < Parslet::Parser
rule(:integer) { match('[0-9]').repeat(1) }
root(:integer)
end
Mini.new.parse("132432") # => "132432"@0
Running this example will print “132432@0”. Congratulations! You just have
written your first parser. Running it on the input ‘puts(1)
’ will
not work yet. Let’s see what happens in case of a failure:
Mini.new.parse("puts(1)") # raises Parslet::ParseFailed
Here’s the error message provided by that exception: “Expected at least 1 of [0-9] at line 1 char 1.” parslet tries to find a number there, but can’t find one.
There are just two lines to the definition of this parser, let’s go through them:
rule(:integer) { match('[0-9]').repeat(1) }
rule
lets you create a new parser rule. Inside the block of that
:integer
rule, you find match('[0-9]').repeat(1)
.
This says: “match a character that is in the range 0-9
, then
match any number of those, but at least match one.”
root(:integer)
That second line just says: Start parsing at the rule called
:integer
.
Addition
Let’s go for simple addition. We’ll have to allow for spaces in our input, since those help make code readable.
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
Two things are new here: (and both in the second line)
- you can use (‘call’) other rules in your rules
.maybe
, the same as.repeat(0,1)
1, indicating that the thing before it is maybe present once in the input.
Essentially, you can think about parslet rules as instructing Ruby to “parse this” and “parse that”. Calling other rules can be looked at in the same way; you tell Ruby to go off, parse that subrule and then come back with the results. This helps when thinking about rule recursion. For example, a self-recursive rule like this one will of course create an endless loop:
rule(:infinity) {
infinity >> str(';')
}
Even though infinity seems to be delimited by ‘;’, in reality, infinity is
very long, especially towards the end. There is no way of knowing for the
parser when to stop processing infinity
and start reading
semicolons. Ergo, we need to make sure we talk about concrete items that
consume input first, and then do recursion. This way we ensure that our
grammar terminates, since in a way, it is like a normal program.
Here’s the full parser:
class Mini < Parslet::Parser
rule(:integer) { match('[0-9]').repeat(1) >> space? }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:operator) { match('[+]') >> space? }
rule(:sum) { integer >> operator >> expression }
rule(:expression) { sum | integer }
root :expression
end
def parse(str)
mini = Mini.new
mini.parse(str)
rescue Parslet::ParseFailed => failure
puts failure.parse_failure_cause.ascii_tree
end
parse "1 + 2 + 3" # => "1 + 2 + 3"@0
parse "a + 2" # fails, see below
As you can see, the parser got decorated with the space?
idiom.
Every atom of our language consumes the space right after it. This is a useful
convention that makes top level rules (the important ones) look cleaner.
Note also the addition of :operator
, :sum
and
:expression
. The runner code has been extended a bit, so as to
throw nice explanations of what went wrong when a parse failure is
encountered. Running the code on ‘a + 2
’ for example outputs:
Expected one of [SUM, INTEGER] at line 1 char 1. |- Failed to match sequence (INTEGER OPERATOR EXPRESSION) at line 1 char 1. | `- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1. | `- Expected at least 1 of [0-9] at line 1 char 1. | `- Failed to match [0-9] at line 1 char 1. `- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1. `- Expected at least 1 of [0-9] at line 1 char 1. `- Failed to match [0-9] at line 1 char 1.
This is what parslet calls an #error_tree
. Not only the output of
your parser, but also its grammar is constructed like a tree. When things go
wrong, every branch of the tree has its own reasons for not accepting a given
input. The #parse_failure_cause
method returns those reasons.
Our grammar has essentially two branches, SUM
and
INTEGER
. Can you see why all rules expect a number as the first
character?
Tree output (and what to do about it)
But if we leave the negative examples for a second; what happens if the parse succeeds? It turns out, not much:
parse "1 + 2 + 3" # => "1 + 2 + 3"@0
The only notable difference between input and output is that the output has an
extra ‘@0’ appended to it. This is related to line number tracking and will be
explained later on (or you can skip ahead and look up
Parslet::Slice
).
The code we now have parses the input successfully, but doesn’t do much else. Parslet hasn’t got its own opinion on what to do with your input. By default, it will just play it back to you. But parslet provides also a method of structuring its output:
# Without structure: just strings.
str('ooo').parse('ooo') # => "ooo"@0
str('o').repeat.parse('ooo') # => "ooo"@0
# Added structure: .as(...)
str('ooo').as(:ex1).parse('ooo') # => {:ex1=>"ooo"@0}
long = str('o').as(:ex2a).repeat.as(:ex2b).parse('ooo')
long # => {:ex2b=>[{:ex2a=>"o"@0}, {:ex2a=>"o"@1}, {:ex2a=>"o"@2}]}
You get to name things the way you want! This is also free. Seriously: parslet
requires you to add all the structure to its output. Annotate important parts
of your grammar with .as(:symbol)
and get back a tree-like
structure composed of hashes (sequence), arrays (repetition) and strings (like
we had initially).
Once you start naming things, you’ll notice that what you don’t name, disappears. Parslet assumes that what you don’t name is unimportant.
parser = str('a').as(:a) >> str(' ').maybe >>
str('+').as(:o) >> str(' ').maybe >>
str('b').as(:b)
parser.parse('a + b') # => {:a=>"a"@0, :o=>"+"@2, :b=>"b"@4}
Think of this like using a highlighter on your input: What is there not to like about neon yellow?
Making the parser complete
Let’s look at the complete parser definition that also allows for function calls:
class MiniP < Parslet::Parser
# Single character rules
rule(:lparen) { str('(') >> space? }
rule(:rparen) { str(')') >> space? }
rule(:comma) { str(',') >> space? }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
# Things
rule(:integer) { match('[0-9]').repeat(1).as(:int) >> space? }
rule(:identifier) { match['a-z'].repeat(1) }
rule(:operator) { match('[+]') >> space? }
# Grammar parts
rule(:sum) { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
rule(:arglist) { expression >> (comma >> expression).repeat }
rule(:funcall) { identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
rule(:expression) { funcall | sum | integer }
root :expression
end
require 'pp'
pp MiniP.new.parse("puts(1 + 2 + 3, 45)")
That’s really all there is to it — our language is a really simple language.
When fed with a string like ’puts(1 + 2 + 3, 45)
, our parser outputs
the following:
{:funcall=>"puts"@0, :arglist=> [{:left=>{:int=>"1"@5}, :op=>"+ "@7, :right=>{:left=>{:int=>"2"@9}, :op=>"+ "@11, :right=>{:int=>"3"@13}}}, {:int=>"45"@16}]}
Parslet calls this the intermediary tree. There are three types of nodes in this tree:
- Hashes: a node that has named subtrees
- Arrays: a node storing a collection of sub-nodes
- Strings are the leaves, containing the accepted source
The format of this tree is easy to work with and to read. Here’s what the above tree would look like as a graphic:
Where to go from here: An Interpreter
As nice as the format above is for printing and looking at – it may be difficult at times to get the information out of it again. Let’s look at how to transform the tree:
class SimpleTransform < Parslet::Transform
rule(funcall: 'puts', arglist: sequence(:args)) {
"puts(#{args.inspect})"
}
# ... other rules
end
tree = {funcall: 'puts', arglist: [1,2,3]}
SimpleTransform.new.apply(tree) # => "puts([1, 2, 3])"
Transformation is an entire topic by itself; this will be covered in detail later on. To whet your appetite, let me just give you a few teasers:
- Transformations match portions of your tree at any depth, replacing them with whatever you decide.
- In addition to
sequence(sym)
, there is alsosimple(sym)
andsubtree(sym)
. Those match simple strings and entire subtrees respectively. Caution with the latter.
Here’s how you would write a somewhat classical interpreter for our little language by using a transformation. Note that from this point on, there is not one way to go about this, but thousands; you are really free (and on your own):
class MiniP < Parslet::Parser
# Single character rules
rule(:lparen) { str('(') >> space? }
rule(:rparen) { str(')') >> space? }
rule(:comma) { str(',') >> space? }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
# Things
rule(:integer) { match('[0-9]').repeat(1).as(:int) >> space? }
rule(:identifier) { match['a-z'].repeat(1) }
rule(:operator) { match('[+]') >> space? }
# Grammar parts
rule(:sum) {
integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
rule(:arglist) { expression >> (comma >> expression).repeat }
rule(:funcall) {
identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
rule(:expression) { funcall | sum | integer }
root :expression
end
IntLit = Struct.new(:int) do
def eval; int.to_i; end
end
Addition = Struct.new(:left, :right) do
def eval; left.eval + right.eval; end
end
FunCall = Struct.new(:name, :args) do
def eval; p args.map { |s| s.eval }; end
end
class MiniT < Parslet::Transform
rule(:int => simple(:int)) { IntLit.new(int) }
rule(
:left => simple(:left),
:right => simple(:right),
:op => '+') { Addition.new(left, right) }
rule(
:funcall => 'puts',
:arglist => subtree(:arglist)) { FunCall.new('puts', arglist) }
end
parser = MiniP.new
transf = MiniT.new
ast = transf.apply(
parser.parse(
'puts(1,2,3, 4+5)'))
ast.eval # => [1, 2, 3, 9]
That’s a bunch of code for printing [1, 2, 3, 9]
. Welcome to the
fantastic world of compiler and interpreter writing!
1 As far as parsing goes. There is a subtle difference between
#repeat(0,1)
and #maybe
. Can you figure it out?


Please confirm
We need to confirm your email address. To complete the subscription process, please click the link in the email we just sent you.
keyboard_backspace Yupp, back to blog please!We need to confirm your email address. To complete the subscription process, please click the link in the email we just sent you.
keyboard_backspace Yupp, back to blog please!


Image Matcher
Locate
Add
{% raw %}
Music
Your browser does not support the
audio
element.
{% endraw %}


|
| string | country [get, set] |
| | Required. Country code. Ex: CA More...
|
| |
| string | pattern [get, set] |
| | Optional. A matching pattern. Ex: 888 More...
|
| |
| string | search_pattern [get, set] |
| | Optional. Strategy for matching pattern. Expected values: 0 "starts with" (default), 1 "anywhere", 2 "ends with". More...
|
| |
| string | Type [get, set] |
| | Optional.the type of number to search for. More...
|
| |
| string | features [get, set] |
| | Optional. Available features are SMS and VOICE, use a comma-separated values. Ex: SMS,VOICE More...
|
| |
| string | index [get, set] |
| | Optional. Page index (>0, default 1). Ex: 2 More...
|
| |
| string | size [get, set] |
| | Optional. Page size (max 100, default 10). Ex: 25 More...
|
| |
| bool? | has_application [get, set] |
| | Set this optional field to true to restrict your results to numbers associated with an application (any application). Set to false to find all numbers not associated with any application. Omit the field to avoid filtering on whether or not the number is assigned to an application. More...
|
| |
| string | application_id [get, set] |
| | The application that you want to return the numbers for More...
|
| |
◆ application_id
| string Nexmo.Api.Number.SearchRequest.application_id |
|
getset |
The application that you want to return the numbers for
◆ country
| string Nexmo.Api.Number.SearchRequest.country |
|
getset |
Required. Country code. Ex: CA
◆ features
| string Nexmo.Api.Number.SearchRequest.features |
|
getset |
Optional. Available features are SMS and VOICE, use a comma-separated values. Ex: SMS,VOICE
◆ has_application
| bool? Nexmo.Api.Number.SearchRequest.has_application |
|
getset |
Set this optional field to true to restrict your results to numbers associated with an application (any application). Set to false to find all numbers not associated with any application. Omit the field to avoid filtering on whether or not the number is assigned to an application.
◆ index
| string Nexmo.Api.Number.SearchRequest.index |
|
getset |
Optional. Page index (>0, default 1). Ex: 2
◆ pattern
| string Nexmo.Api.Number.SearchRequest.pattern |
|
getset |
Optional. A matching pattern. Ex: 888
◆ search_pattern
| string Nexmo.Api.Number.SearchRequest.search_pattern |
|
getset |
Optional. Strategy for matching pattern. Expected values: 0 "starts with" (default), 1 "anywhere", 2 "ends with".
◆ size
| string Nexmo.Api.Number.SearchRequest.size |
|
getset |
Optional. Page size (max 100, default 10). Ex: 25
◆ Type
| string Nexmo.Api.Number.SearchRequest.Type |
|
getset |
Optional.the type of number to search for.
The documentation for this class was generated from the following file:
- C:/Users/slore/Documents/projects/slorello89/nexmo-dotnet/Nexmo.Api/Number.cs


--- author: Steve Gill categories: app date: '2012-07-10 20:59:08' permalink: /2012/07/10/phonegap-community-roundup-%e2%80%93-june-2012/ slug: phonegap-community-roundup-%e2%80%93-june-2012 status: publish title: PhoneGap Community Roundup – June 2012 type: post format: html tags: - Community - Event ---
Two months ago we started the PhoneGap Community Release Notes. Thank you to everyone who contributed. If you're organizing a PhoneGap event, speaking on PhoneGap or writing a blog post, please add it to the release notes on Github.
We'll be posting the round up from each month and below is the roundup for the month of June.
JUNE 2012
PRESENTATIONS
Presentation from QCon: Cross-Platform Mobile Apps with HTML, JavaScript and PhoneGap by Christophe Coenraets
ARTICLES
Packaging a Sencha Touch 2 application with PhoneGap for Android by Andreas Sommer
Getting rid of the "Gray Box" in PhoneGap for Windows Phone by Andy Trice
Creating native-like user experiences in PhoneGap with App-UI by Andy Trice
Press Release: CodeProject announces Fourth Annual Members Choice Award Winners - PhoneGap won for best Cross Platform Dev Tool
Building PhoneGap applications powered by Database.com by Andy Trice
PhoneGap Android Application Preferences Plugin by Simon MacDonald
EVENTS
June 5, BootStrap week- PhoneGap (online), Steve Gill
June 10, CSnextLA - Adobe Creative Suite 6 Launch (Los Angeles), Steve Gill
June 11, Girl Geeks Toronto - Intro to PhoneGap & PhoneGap Build, Matthew Fabb
June 12, Dev:Mobile - Getting Started with PhoneGap (Sweden), Mihai Corlan
June 12, Beyond demo code -- How to build real applications for mobile devices using web, PhoneGap SF Meetup Group
June 14, Getting Started With PhoneGap, South Bay Mobile Meetup Group
June 20, Mobile Application Development with PhoneGap, Pamela Fox
June 20, Cross-Platform Mobile Apps with HTML, JavaScript and PhoneGap, Christophe Coenraets
June 21, Responsive Design and PhoneGap Facebook Plugin, PhoneGap SF Meetup Group
June 27, Cross-Platform Apps with PhoneGap & A Better Web, Christophe Coenraets


Why Step Up Tutors?
Some children find it difficult to concentrate in a busy classroom, and can really benefit from going over the topics with calm, patient, individual support.
Step Up Tutors:
- Is tailored to your child’s individual needs
- Builds confidence, introducing new ideas at the right time for your child
- Provides one-to-one sessions with an experienced teacher
- … and it’s fun!
COVID update: remote sessions via Zoom
I have specialist educational software that works well over Zoom, to provide interactive remote learning that is both rigorous and fun. As well as providing child-centred benefits, this reduces taxiing around for parents.
About me
Based in Denmead, Hampshire, UK - I am a qualified teacher (B.Ed. Hons) with 20+ years of experience and have a specialist diploma in teaching children who have dyslexia.


ARJUNDEEP
RESTAURANT
FIND YOUR PERFECT RESTAURANT
THE BEST PLACES TO EAT
4.3 MILLION RESTAURANTS — EVERYTHING FROM STREET FOOD TO FINE DINING
A restaurant is a business which prepares and serves food and drinks to customers in exchange for money. Meals are generally served and eaten on the premises, but many restaurants also offer take-out and food delivery services. Restaurants vary greatly in appearance and offerings, including a wide variety of cuisines and service models ranging from inexpensive fast food restaurants and cafeterias, to mid-priced family restaurants, to high-priced luxury establishments.[NANDED]
In Western countries, most mid- to high-range restaurants serve alcoholic beverages such as beer and wine. Some restaurants serve all the major meals, such as breakfast, lunch, and dinner (e.g., major fast food chains, diners, hotel restaurants, and airport restaurants). Other restaurants may serve only a single meal (for example, a pancake house may only serve breakfast) or they may serve two meals (e.g., lunch and dinner).


?[1;31m
Start test 1?[0m
null
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 2?[0m
null
[menu] Enter action (add, list, search, count, exit): > count
The Phone Book has 0 records.
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 3?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > count
The Phone Book has 1 records.
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 4?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > list
1. John Smith
[list] Enter action ([number], back): > 1
Name: John
Surname: Smith
Birth date: [no data]
Gender: [no data]
Number: 123 456 789
Time created: 2020-09-01T18:21:23.236481
Time last edit: 2020-09-01T18:21:23.247481400
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 5?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > Pizza Shop
Enter the address: > Wall St. 1
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > list
1. Pizza Shop
[list] Enter action ([number], back): > 1
Organization name: Pizza Shop
Address: Wall St. 1
Number: +0 (123)<PHONE_NUMBER>
Time created: 2020-09-01T18:21:23.269482100
Time last edit: 2020-09-01T18:21:23.272482100
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 6?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > list
1. John Smith
[list] Enter action ([number], back): > 1
Name: John
Surname: Smith
Birth date: [no data]
Gender: [no data]
Number: 123 456 789
Time created: 2020-09-01T18:21:23.288481900
Time last edit: 2020-09-01T18:21:23.302482200
[record] Enter action (edit, delete, menu): > edit
Select a field (name, surname, birth, gender, number): > gender
Enter gender: > M
Name: John
Surname: Smith
Birth date: [no data]
Gender: M
Number: 123 456 789
Time created: 2020-09-01T18:21:23.288481900
Time last edit: 2020-09-01T18:21:23.307481
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > list
1. John Smith
[list] Enter action ([number], back): > 1
Name: John
Surname: Smith
Birth date: [no data]
Gender: M
Number: 123 456 789
Time created: 2020-09-01T18:21:23.288481900
Time last edit: 2020-09-01T18:21:23.307481
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 7?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > Pizza Shop
Enter the address: > Wall St. 1
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > list
1. Pizza Shop
[list] Enter action ([number], back): > 1
Organization name: Pizza Shop
Address: Wall St. 1
Number: +0 (123)<PHONE_NUMBER>
Time created: 2020-09-01T18:21:23.339482100
Time last edit: 2020-09-01T18:21:23.342480800
[record] Enter action (edit, delete, menu): > edit
Select a field (name, address, number): > address
Enter address: > Wall St 2
Organization name: Pizza Shop
Address: Wall St 2
Number: +0 (123)<PHONE_NUMBER>
Time created: 2020-09-01T18:21:23.339482100
Time last edit: 2020-09-01T18:21:23.347482700
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > list
1. Pizza Shop
[list] Enter action ([number], back): > 1
Organization name: Pizza Shop
Address: Wall St 2
Number: +0 (123)<PHONE_NUMBER>
Time created: 2020-09-01T18:21:23.339482100
Time last edit: 2020-09-01T18:21:23.347482700
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 8?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > Pizza Shop
Enter the address: > Wall St. 1
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the organization name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > PizzaNuts
Enter the address: > Wall St. 6
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > search
Enter search query: > pizz
Found 2 results:
1. Pizza Shop
2. PizzaNuts
[search] Enter action ([number], back, again): > 1
Organization name: PizzaNuts
Address: Wall St. 6
Number: +0 (123)<PHONE_NUMBER>
Time created: 2020-09-01T18:21:23.383482800
Time last edit: 2020-09-01T18:21:23.384479800
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 9?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > Pizza Shop
Enter the address: > Wall St. 1
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the organization name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > PizzaNuts
Enter the address: > Wall St. 6
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > search
Enter search query: > s
Found 3 results:
1. Pizza Shop
2. John Smith
3. PizzaNuts
[search] Enter action ([number], back, again): > 1
Name: John
Surname: Smith
Birth date: [no data]
Gender: [no data]
Number: 123 456 789
Time created: 2020-09-01T18:21:23.412481800
Time last edit: 2020-09-01T18:21:23.418480800
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit
?[1;31m
Start test 10?[0m
null
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > Pizza Shop
Enter the address: > Wall St. 1
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > person
Enter the organization name: > John
Enter the surname: > Smith
Enter the birth date: >
Bad birth date!
Enter the gender: >
Bad gender!
Enter the number: > 123 456 789
A record created!
[menu] Enter action (add, list, search, count, exit): > add
[add] Enter the type (person, organization): > organization
Enter the organization name: > PizzaNuts
Enter the address: > Wall St. 6
Enter the number: > +0 (123)<PHONE_NUMBER>
A record created!
[menu] Enter action (add, list, search, count, exit): > search
Enter search query: > 789
Found 2 results:
1. Pizza Shop
2. John Smith
[search] Enter action ([number], back, again): > 1
Name: John
Surname: Smith
Birth date: [no data]
Gender: [no data]
Number: 123 456 789
Time created: 2020-09-01T18:21:23.458480
Time last edit: 2020-09-01T18:21:23.465481500
[record] Enter action (edit, delete, menu): > menu
[menu] Enter action (add, list, search, count, exit): > exit


Lua Environments
Environments Tutorial
lua-users home wiki
Unlike local variables, which are stored in a special data structure in the interpreter, global variables are just stored in a table. A useful feature in Lua is the ability to change this table per-function, so the function sees a different set of global variables.
The default global table is stored inside itself under the key “_G”, this is useful if you want to get an actual reference to it.
The way environments work in Lua 5.2 is very different from 5.1. Both ways will be explained here.
Environments in Lua 5.2
A function’s environment is stored in an upvalue, named _ENV. As an example, here’s a function that sets its environment to a custom one and uses variables from it:
print(_ENV == _G) -- prints true, since the default _ENV is set to the global table
a = 1
local function f(t)
local print = print -- since we will change the environment, standard functions will not be visible
local _ENV = t -- change the environment. without the local, this would change the environment for the entire chunk
print(getmetatable) -- prints nil, since global variables (including the standard functions) are not in the new env
a = 2 -- create a new entry in t, doesn't touch the original "a" global
b = 3 -- create a new entry in t
end
local t = {}
f(t)
print(a, b) --> 1 nil
print(t.a, t.b) --> 2 3
When loading a chunk, the top-level function gets a new _ENV upvalue, and any nested functions inside it can see it. You can pretend that when loading works something like this:
local _ENV = _G
return function (...) -- this function is what's returned from load
-- code you passed to load goes here, with all global variable names replaced with _ENV lookups
-- so, for example "a = b" becomes "_ENV.a = _ENV.b" if neither a nor b were declared local
end
Now you can see that _ENV is an ordinary local variable, how all the functions have access to the _ENV, and why if one function changes _ENV all other functions in the loaded chunks will see the change. That’s why if you want a function to only change its own environment, you need to make a new _ENV local that shadows the original one.
In most cases, you don’t need to use environments, unless you want to sandbox a loaded chunk, to give it convenient access to certain functions by making them look global, or to prevent it from seeing unsafe functions for security reasons. This is why 5.2’s load function takes a parameter that lets you set the chunk’s _ENV to a custom table, instead of _G.
local sandbox_env = {
print = print,
}
local chunk = load("print('inside sandbox'); os.execute('echo unsafe')", "sandbox string", "bt", sandbox_env)
chunk() -- prevents os.execute from being called, instead raises an error saying that os is nil
If you actually want to make a sandbox to run untrusted code, remember that it’s easy to overlook a lot of things that can be exploited, and that you would need some kind of way to limit CPU usage and memory.
Environments in Lua 5.1
In Lua 5.1, environments are their own thing, not related to locals or upvalues. Instead, each function has an environment table associated with it, that can be manipulated with the getfenv/setfenv standard functions.
getfenv and setfenv both take a function or stack level (where 1 is the current function, 2 is the function that called the current function, etc.). setfenv has a second parameter that takes the new env table, and getfenv returns the functions’s current env table.
The previous example rewritten for 5.1:
print(getfenv(1) == _G) -- prints true, since the default env is set to the global table
a = 1
local function f(t)
local print = print -- since we will change the environment, standard functions will not be visible
setfenv(1, t) -- change the environment
print(getmetatable) -- prints nil, since global variables (including the standard functions) are not in the new env
a = 2 -- create a new entry in t, doesn't touch the original "a" global
b = 3 -- create a new entry in t
end
local t = {}
f(t)
print(a, b) --> 1 nil
print(t.a, t.b) --> 2 3
And the sandbox example rewritten for 5.1:
local sandbox_env = {
print = print,
}
local chunk = loadstring("print('inside sandbox'); os.execute('echo unsafe')")
setfenv(chunk, sandbox_env)
chunk() -- prevents os.execute from being called, instead raises an error saying that os is nil
The 5.1 way is sometimes considered simpler and more versatile, but it also requires special treatment of environments (instead of using the existing local variable system). Also, the 5.2 way is designed with the idea that a function’s environment is supposed to be private, instead of being accessible from everywhere without the debug library, so it can be considered safer. RecentChanges · preferences edit · history Last edited June 25, 2014 11:48 pm GMT (diff)
- Previous
- Next


---
layout: post
title: Conterfeit metro fare cards
date: '2008-07-22T10:06:00.000-07:00'
author: Jason R. Coombs
tags:
- None
modified_time: '2011-07-17T13:45:34.469-07:00'
blogger_id: tag:blogger.com,1999:blog-3597351713969111277.post-2628575060096304157
blogger_orig_url: http://blog.jaraco.com/2008/07/conterfeit-metro-fare-cards.html
---
I was offered one of these about 5 days ago. I wondered what the scam was. I think on the same day I overheard some victims of the scam who had bought a card and then weren't allow to use it. I definitely heard the word "counterfeit" while they were talking within station attendants.
When's metro 2.0 coming?


Including clouds¶
Powerlaw cloud models¶
Let’s initialize an atmosphere in the usual way, see “Getting Started”:
[1]:
import numpy as np
from petitRADTRANS import Radtrans
atmosphere = Radtrans(line_species = ['H2O', 'CO_all_iso', 'CH4', 'CO2', 'Na', 'K'], \
rayleigh_species = ['H2', 'He'], \
continuum_opacities = ['H2-H2', 'H2-He'], \
wlen_bords_micron = [0.3, 15])
pressures = np.logspace(-6, 2, 100)
atmosphere.setup_opa_structure(pressures)
Read CIA opacities for H2-H2...
Read CIA opacities for H2-He...
Done.
Units in petitRADTRANS: remember that all units in petitRADTRANS are in cgs, except for pressure, which is in bars, and the mean molecular weight (MMW), which is in units of atomic mass units.
Next we set up the atmospheric parameters, with a parameter selection identical to the “Getting Started” case.
[2]:
from petitRADTRANS import nat_cst as nc
R_pl = 1.838*nc.r_jup_mean
gravity = 1e1**2.45
P0 = 0.01
kappa_IR = 0.01
gamma = 0.4
T_int = 200.
T_equ = 1500.
temperature = nc.guillot_global(pressures, kappa_IR, gamma, gravity, T_int, T_equ)
mass_fractions = {}
mass_fractions['H2'] = 0.74 * np.ones_like(temperature)
mass_fractions['He'] = 0.24 * np.ones_like(temperature)
mass_fractions['H2O'] = 0.001 * np.ones_like(temperature)
mass_fractions['CO_all_iso'] = 0.01 * np.ones_like(temperature)
mass_fractions['CO2'] = 0.00001 * np.ones_like(temperature)
mass_fractions['CH4'] = 0.000001 * np.ones_like(temperature)
mass_fractions['Na'] = 0.00001 * np.ones_like(temperature)
mass_fractions['K'] = 0.000001 * np.ones_like(temperature)
MMW = 2.33 * np.ones_like(temperature)
Abundances in petitRADTRANS: remember that abundances in pRT are in units of mass fractions, not number fractions (aka volume mixing ratio, VMR). You can convert between mass fractions and VMRs by using \begin{equation} X_i = \frac{\mu_i}{\mu}n_i, \end{equation} where \(X_i\) is the mass fraction of species \(i\), \(\mu_i\) the mass of a single molecule/atom/ion/… of species \(i\), \(\mu\) is the atmospheric mean molecular weight, and \(n_i\) is the VMR of species \(i\).
Now, let’s calculate cloudy spectra! The first available mode is the so-called power law cloud. In this case the following opacity is added to the scattering cross-section: \begin{equation} \kappa = \kappa_0\left(\frac{\lambda}{\lambda_0}\right)^\gamma \end{equation} Where \(\kappa_0\) is the opacity in units of cm\(^2\)/g, at \(\lambda_0=0.35 \ {\rm \mu m}\). The power law index \(\gamma\) fixes the wavelength dependence, Rayleigh-like scattering would be obtained for \(\gamma=-4\). Hence \(\kappa_0\) and \(\gamma\) are free parameters.
We now calculate a clear atmosphere, and then four power law cloudy models, with \(\kappa_0 = 0.01\) cm\(^2\)/g, and four different \(\gamma\) values.
Clear model:
[3]:
import pylab as plt
plt.rcParams['figure.figsize'] = (10, 6)
# Clear
atmosphere.calc_transm(temperature, mass_fractions, \
gravity, MMW, R_pl=R_pl, P0_bar=P0)
clear = atmosphere.transm_rad/nc.r_jup_mean
First, \(\gamma = -4\) (Rayleigh-like):
[4]:
kappa_zero = 0.01
gamma_scat = -4.
atmosphere.calc_transm(temperature, mass_fractions, \
gravity, MMW, R_pl=R_pl, P0_bar=P0, \
kappa_zero = kappa_zero, gamma_scat = gamma_scat)
m4 = atmosphere.transm_rad/nc.r_jup_mean
Second, \(\gamma = -2\) (weaker scattering power law):
[5]:
kappa_zero = 0.01
gamma_scat = -2.
atmosphere.calc_transm(temperature, mass_fractions, \
gravity, MMW, R_pl=R_pl, P0_bar=P0, \
kappa_zero = kappa_zero, gamma_scat = gamma_scat)
m2 = atmosphere.transm_rad/nc.r_jup_mean
Third, \(\gamma = 0\) (flat opacity):
[6]:
kappa_zero = 0.01
gamma_scat = 0.
atmosphere.calc_transm(temperature, mass_fractions, \
gravity, MMW, R_pl=R_pl, P0_bar=P0, \
kappa_zero = kappa_zero, gamma_scat = gamma_scat)
m0 = atmosphere.transm_rad/nc.r_jup_mean
Fourth, the exoctic case of, \(\gamma = 1\) (positive opacity slope):
[7]:
kappa_zero = 0.01
gamma_scat = 1.
atmosphere.calc_transm(temperature, mass_fractions, \
gravity, MMW, R_pl=R_pl, P0_bar=P0, \
kappa_zero = kappa_zero, gamma_scat = gamma_scat)
p1 = atmosphere.transm_rad/nc.r_jup_mean
# Make plot
plt.plot(nc.c/atmosphere.freq/1e-4, clear, label = 'Clear')
plt.plot(nc.c/atmosphere.freq/1e-4, \
m4, \
label = r'Powerlaw cloud, $\gamma = -4$')
plt.plot(nc.c/atmosphere.freq/1e-4, \
m2, \
label = r'Powerlaw cloud, $\gamma = -2$')
plt.plot(nc.c/atmosphere.freq/1e-4, \
m0, \
label = r'Powerlaw cloud, $\gamma = 0$')
plt.plot(nc.c/atmosphere.freq/1e-4, \
p1,\
label = r'Powerlaw cloud, $\gamma = 1$')
plt.xscale('log')
plt.xlabel('Wavelength (microns)')
plt.ylabel(r'Transit radius ($\rm R_{Jup}$)')
plt.legend(loc = 'best')
plt.show()
plt.clf()
<Figure size 720x432 with 0 Axes>
Gray cloud deck and/or scaled Rayhleigh scattering¶
In addition to power law clouds, petitRADTRANS can also simply add a gray cloud deck, or scale the Rayleigh scattering opacities of the gas by a factor specified by the user. For these examples we will reuse the Radtrans object from the demonstration of the power law cloud above, there’s no need to intialize it again.
Let’s calculate three spectra: - A clear model - A cloudy model with a gray cloud deck at 0.01 bar - A haze-like model, mimicked by scaling the Rayleigh scattering of the gas by a factor 10 - A combination of the two above cloud models: gray cloud deck plus haze
[8]:
import pylab as plt
plt.rcParams['figure.figsize'] = (10, 6)
# Clear
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, R_pl=R_pl, P0_bar=P0)
plt.plot(nc.c/atmosphere.freq/1e-4, \
atmosphere.transm_rad/nc.r_jup_mean, label = 'Clear')
# Gray cloud deck at 0.01 bar
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, R_pl=R_pl, P0_bar=P0, \
Pcloud = 0.01)
plt.plot(nc.c/atmosphere.freq/1e-4, \
atmosphere.transm_rad/nc.r_jup_mean, label = 'Gray cloud deck at 0.01 bar')
# Haze (10 x gas Rayleigh scattering)
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, R_pl=R_pl, P0_bar=P0, \
haze_factor = 10)
plt.plot(nc.c/atmosphere.freq/1e-4, \
atmosphere.transm_rad/nc.r_jup_mean, label = 'Rayleigh haze')
# Haze + cloud deck
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, R_pl=R_pl, P0_bar=P0, \
haze_factor = 10, Pcloud = 0.01)
plt.plot(nc.c/atmosphere.freq/1e-4, \
atmosphere.transm_rad/nc.r_jup_mean, label = 'Rayleigh haze + cloud deck')
plt.xscale('log')
plt.xlabel('Wavelength (microns)')
plt.ylabel(r'Transit radius ($\rm R_{Jup}$)')
plt.legend(loc = 'best')
plt.show()
plt.clf()
<Figure size 720x432 with 0 Axes>
Condensate clouds from real optical constants¶
Let’s calculate some spectra using opacities derived from optical constants of various materials. In this example we will start of with forsterite, that is \(\rm Mg_2SiO_4\). For the list of available cloud species see “Available opacity species”.
Choose your favorite particle setup: petitRADTRANS offers multiple opacity versions for every given condensate, assuming either spherical (Mie scattering) or irreagularly shaped (DHS method = distribution of hollow spheres) particles. Moreover, opacities assuming a crystalline and/or amorphous internal structure can be used, where available.
We set up the atmosphere like before, this time loading the opacity of crystalline (c
), irregularly shaped particles (DHS method, abbreviated d
). The mode identifier for the \(\rm Mg_2SiO_4\) opacity therefore is Mg2SiO4(c)_cd
. (c)
stands for condensed. These are all possible modes, note that for some species only crystalline or amorphous cross-sections are available.
Opacity code |
Description |
|---|---|
Species(c)_cm |
crystalline Mie opacity of Species |
Species(c)_cd |
crystalline DHS opacity of Species |
Species(c)_am |
amorphous Mie opacity of Species |
Species(c)_ad |
amorphous DHS opacity of Species |
But now, let’s start! We simply give one additional cloud_species
list to the Radtrans object, containing the name of the opacity species we want to use.
[9]:
import numpy as np
from petitRADTRANS import Radtrans
atmosphere = Radtrans(line_species = ['H2O', 'CO_all_iso', 'CH4', 'CO2', 'Na', 'K'], \
cloud_species = ['Mg2SiO4(c)_cd'], \
rayleigh_species = ['H2', 'He'], \
continuum_opacities = ['H2-H2', 'H2-He'], \
wlen_bords_micron = [0.3, 15])
pressures = np.logspace(-6, 2, 100)
atmosphere.setup_opa_structure(pressures)
Read CIA opacities for H2-H2...
Read CIA opacities for H2-He...
Done.
Units in petitRADTRANS: remember that all units in petitRADTRANS are in cgs, except for pressure, which is in bars, and the mean molecular weight (MMW), which is in units of atomic mass units.
Next we set up the atmospheric parameters, with a parameter selection almost identical to the “Getting Started” case. We now also add the mass fraction of the cloud species we are interested in. Note that the mass fractions only contains the name Mg2SiO4(c)
now, the _cd
suffix has to be omitted.
[10]:
from petitRADTRANS import nat_cst as nc
R_pl = 1.838*nc.r_jup_mean
gravity = 1e1**2.45
P0 = 0.01
kappa_IR = 0.01
gamma = 0.4
T_int = 200.
T_equ = 1500.
temperature = nc.guillot_global(pressures, kappa_IR, gamma, gravity, T_int, T_equ)
mass_fractions = {}
mass_fractions['H2'] = 0.74 * np.ones_like(temperature)
mass_fractions['He'] = 0.24 * np.ones_like(temperature)
mass_fractions['H2O'] = 0.001 * np.ones_like(temperature)
mass_fractions['CO_all_iso'] = 0.01 * np.ones_like(temperature)
mass_fractions['CO2'] = 0.00001 * np.ones_like(temperature)
mass_fractions['CH4'] = 0.000001 * np.ones_like(temperature)
mass_fractions['Na'] = 0.00001 * np.ones_like(temperature)
mass_fractions['K'] = 0.000001 * np.ones_like(temperature)
mass_fractions['Mg2SiO4(c)'] = 0.0000005 * np.ones_like(temperature)
MMW = 2.33 * np.ones_like(temperature)
Abundances in petitRADTRANS: remember that abundances in petitCODE are in units of mass fractions, not number fractions (aka volume mixing ratio, VMR). You can convert between mass fractions and VMRs by using \begin{equation} X_i = \frac{\mu_i}{\mu}n_i, \end{equation} where \(X_i\) is the mass fraction of species \(i\), \(\mu_i\) the mass of a single molecule/atom/ion/… of species \(i\), \(\mu\) is the atmospheric mean molecular weight, and \(n_i\) is the VMR of species \(i\).
Setting the cloud particle size¶
We have to define a few additional parameters for the clouds, to start the calculation. We can give the mean particle size and width of the log-normal particle distribution:
[11]:
radius = {}
radius['Mg2SiO4(c)'] = 0.00005*np.ones_like(temperature) # I.e. a 0.5-micron particle size (0.00005 cm)
sigma_lnorm = 1.05
Now, let’s calculate a clear and cloudy spectrum to compare:
[12]:
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, \
R_pl=R_pl, P0_bar=P0, \
radius = radius, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.transm_rad/nc.r_jup_mean, label = 'cloudy', zorder = 2)
mass_fractions['Mg2SiO4(c)'] = np.zeros_like(temperature)
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, \
R_pl=R_pl, P0_bar=P0, \
radius = radius, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.transm_rad/nc.r_jup_mean, label = 'clear', zorder = 1)
plt.xscale('log')
plt.xlabel('Wavelength (microns)')
plt.ylabel(r'Transit radius ($\rm R_{Jup}$)')
plt.legend(loc='best')
plt.show()
plt.clf()
<Figure size 720x432 with 0 Axes>
Here one sees that there is a lot of additional absorption in the optical and near-IR. Also note the silicate (Si-O stretching mode) becoming visible at 10 micron.
Calculating the particle size¶
Alternatively, one can specify an eddy diffusion parameter (\(K_{zz}\), with units of cm\(^2\)/s), which expresses how strongly atmospheric mixing is. The cloud particle size is then controlled by specifying \(K_{zz}\), and the unitless settling parameter \(f_{\rm sed}\), which expresses the particles’ mass averaged settling velocity, when compared to the local atmospheric mixing speed. Also, a width for the log-normal particle size distribution must be specified:
[13]:
Kzz = np.ones_like(temperature)*1e1**7.5
fsed = 2.
sigma_lnorm = 1.05
Again, let’s calculate a clear and cloudy spectrum to compare:
[14]:
mass_fractions['Mg2SiO4(c)'] = 0.0000005 * np.ones_like(temperature)
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, \
R_pl=R_pl, P0_bar=P0, \
Kzz = Kzz, fsed=fsed, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.transm_rad/nc.r_jup_mean, label = 'cloudy', zorder = 2)
mass_fractions['Mg2SiO4(c)'] = np.zeros_like(temperature)
atmosphere.calc_transm(temperature, mass_fractions, gravity, MMW, \
R_pl=R_pl, P0_bar=P0, \
Kzz = Kzz, fsed=fsed, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.transm_rad/nc.r_jup_mean, label = 'clear', zorder = 1)
plt.xscale('log')
plt.xlabel('Wavelength (microns)')
plt.ylabel(r'Transit radius ($\rm R_{Jup}$)')
plt.legend(loc='best')
plt.show()
plt.clf()
<Figure size 720x432 with 0 Axes>
The resulting mean particle sizes can be accessed like this:
[15]:
plt.yscale('log')
plt.xscale('log')
plt.ylim([1e2,1e-6])
plt.ylabel('P (bar)')
plt.xlabel('Average particle size (microns)')
plt.plot(atmosphere.r_g[:,atmosphere.cloud_species.index('Mg2SiO4(c)')]/1e-4, pressures)
plt.show()
plt.clf()
<Figure size 720x432 with 0 Axes>
Minimum particle size: the opacity of particles smaller than 1 nm is set to zero.
Emission spectra¶
We can use the Radtrans object created above to calculate emission spectra as well. Here we will also generate an instance of pRT with scattering turned on, (see “Scattering for Emission Spectra” for an example on how to do this in detail).
[16]:
mass_fractions['Mg2SiO4(c)'] = 0.0000005 * np.ones_like(temperature)
atmosphere.calc_flux(temperature, mass_fractions, gravity, MMW, \
Kzz = Kzz, fsed=fsed, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.flux/1e-6, \
color = 'black', label = 'cloudy, no scattering', zorder = 1)
# Load scattering version of pRT
atmosphere = Radtrans(line_species = ['H2O', 'CO_all_iso', 'CH4', 'CO2', 'Na', 'K'], \
cloud_species = ['Mg2SiO4(c)_cd'], \
rayleigh_species = ['H2', 'He'], \
continuum_opacities = ['H2-H2', 'H2-He'], \
wlen_bords_micron = [0.3, 15], \
do_scat_emis = True)
pressures = np.logspace(-6, 2, 100)
atmosphere.setup_opa_structure(pressures)
atmosphere.calc_flux(temperature, mass_fractions, gravity, MMW, \
Kzz = Kzz, fsed=fsed, sigma_lnorm = sigma_lnorm, \
add_cloud_scat_as_abs = True)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.flux/1e-6, \
label = 'cloudy, including scattering', zorder = 2)
mass_fractions['Mg2SiO4(c)'] = np.zeros_like(temperature)
atmosphere.calc_flux(temperature, mass_fractions, gravity, MMW, \
Kzz = Kzz, fsed=fsed, sigma_lnorm = sigma_lnorm)
plt.plot(nc.c/atmosphere.freq/1e-4, atmosphere.flux/1e-6, '-', \
color = 'red', label = 'clear', zorder = 0)
plt.legend(loc='best')
plt.xscale('log')
plt.xlabel('Wavelength (microns)')
plt.ylabel(r'Planet flux $F_\nu$ (10$^{-6}$ erg cm$^{-2}$ s$^{-1}$ Hz$^{-1}$)')
plt.show()
plt.clf()
Read CIA opacities for H2-H2...
Read CIA opacities for H2-He...
Done.
<Figure size 720x432 with 0 Axes>
Here we plotted the clear spectrum, neglecting the cloud opacity, the cloudy spectrum only considering the absorption of the cloud particles, and the cloudy spectrum with scattering, using the scattering version of pRT.
Scattering and petitRADTRANS: remember that scattering is included for emission spectra in petitRADTRANS only if requested specifically when generating the Radtrans object, as it increases the runtime (see “Scattering for Emission Spectra” for an example how to do this).