From 2422e4717d1067768305e25a56510cc58d4b792d Mon Sep 17 00:00:00 2001 From: Michael Ashley Date: Wed, 28 Aug 2019 07:04:27 -0700 Subject: [PATCH] fix: incorrect parsing on medium.com (#477) * fix: medium extractor now pulls content * fix: remove youtube caption if no preview available * fix: remove youtube node if no image * fix: removing dek from medium.com extractor --- fixtures/medium.com/1477523363921.html | 2 +- fixtures/medium.com/1485902752952.html | 2 +- src/extractors/custom/medium.com/index.js | 34 ++++++++++--------- .../custom/medium.com/index.test.js | 9 ++--- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/fixtures/medium.com/1477523363921.html b/fixtures/medium.com/1477523363921.html index 6936b758d..75a7211f2 100644 --- a/fixtures/medium.com/1477523363921.html +++ b/fixtures/medium.com/1477523363921.html @@ -1 +1 @@ -WTF? What’s The Future? – What’s The Future? – Medium
What’s The Future?
Never miss a story from What’s The Future?, when you sign up for Medium. Learn more
Never miss a story from What’s The Future?

Video of WTF? My talk at the White House Frontiers Conference

WTF? What’s The Future?

My talk at the White House Frontiers Conference

Last Thursday, I had the honor to be one of the warmup acts for President Obama at the White House Frontiers Conference at Carnegie Mellon University in Pittsburgh. Here is the prepared text and slides from the talk I delivered there. As you’ll see if you watch the video, what I ended up saying isn’t exactly what I had written out in advance, but it is reasonably close. (Video is above, slides and text interspersed below, with a link to the actual deck on slideshare at the end. Let me know if you like this format for sharing talks.)

Hearing that Bob Dylan just won the Nobel Prize for Literature, how could I not begin this talk with his famous line, “Something is happening here, but you don’t know what it is, do you, Mr. Jones?” The future is full of amazing things. On my way here, I spoke out loud to a $200 device in my kitchen, and asked it to call a Lyft to take me to the airport. And in a few years, that car might well be driving itself. Someone seeing this for the first time would have every excuse to say “WTF?” That of course is an expression of surprise and delight that stands for What’s the Future?

But many lot of people are reading the news about Artificial Intelligence and are feeling a profound sense of unease. They are also asking themselves “WTF? What’s the Future?” but in a very different tone of voice.

We heard recently from researchers at Oxford University that up to 47% of human tasks, including many white collar jobs, could be eliminated by automation within the next 20 years.

New study shows nearly half of US jobs are susceptible to computerisation

We’ve heard stories about how self driving cars and trucks will put millions of Americans out of work.

Self-Driving Trucks Are Going to Hit Us Like a Human-Driven Truck

I’d like to provide an alternate perspective.

Back in 1811 and 1812, a group of weavers led by Ned Ludd staged a rebellion, smashing the machine looms that were threatening their livelihood. Ludd and his compatriots were right to be afraid. The decades ahead were grim, as machines replaced human labor, and it took time for society to adjust.

Source: Wikimedia Commons

But those weavers couldn’t imagine that their descendants would have more clothing than the kings and queens of Europe, that ordinary people would eat the fruits of summer in the depths of winter. They couldn’t imagine that we’d tunnel through mountains and under the sea, we’d fly through the air, crossing continents in hours, we’d build cities in the desert with buildings a half mile high, that we’d put spacecraft in orbit around Jupiter, that we would eliminate so many scourges of disease! And they couldn’t imagine that their children would find meaningful work bringing all of these things to life!

Photo composite by Tim O’Reilly and Edie Freedman

To understand the future, it often helps to look backwards.

I want to start here, with one of the world’s most heralded inventions. Can you imagine the first woman (I imagine it was a woman) who built a controlled fire? How amazed her companions were. Perhaps afraid at first. But soon warmed and fed by her boldness. But even more important than fire itself was the ability to tell others about it! It was language that was our first great invention, the ability to pass fire from mind to mind.

Neanderthals. Source: Wikimedia Commons

The invention of movable type and the book led to a remarkable flowering in the economy, as the discoverers of the new could pass the fire of knowledge to people not yet born and to those living thousands of miles away.

The War Department Library in the Eisenhower Executive Office Building. Photo: Tim O’Reilly

The internet was the next great leap. But the web browser — words and pictures online — was only a halfway house.

I was recently reminded just how access to knowledge has changed when riding on San Francisco’s 14 Mission bus. I was sitting between two old men. I pulled out my phone to check where to get off. The old man on my right was agog. He’d never seen Google Maps before. The other jumped in eagerly, explaining that the blue dot followed our progress. I left them, one still in wonder, the other confident in the new reality, now demoing Google Maps on his phone to the other, who had never seen it.

Getting to the Bill Gates building on the CMU campus with Google Maps. Source: Microsoft, composite Edie Freedman

Think about it for a moment. Over a billion people can pull out their phone and see where they are and how to get where they want to go in real time. And that capability underlies new kinds of services like Uber, and remarkable startups like Zipline, which is delivering blood and critical medicines on demand by drone in countries without good roads or accessible hospital infrastructure.

A Zipline drone delivering blood or medicine.

GPS and Google maps illustrate what I call “the arc of knowledge.” We’ve gone from the spoken to the written word, to mass production of writing, to electronic dissemination via the internet, to embedding knowledge into services and devices. AI is simply the next step in that arc, feeding massive amounts of data into Machine Learning models to find new meaning in it and to enable new kinds of services.

“The Arc of Knowledge” — from representation to embedding in services and devices

AI is not some kind of radical discontinuity. AI is not the machine from the future that is hostile to human values and will put us all out of work. AI is the next step in the spread and usefulness of knowledge, which is the true source of the wealth of nations.

It’s easy to blame technology for the problems that occur in periods of great economic transition. But, both the problems and the solutions are the result of human choices. As we saw during the first industrial revolution, when the fruits of automation are used solely to enrich the owners of the machines and treat workers as a cost to be eliminated, or as cogs in the machine, to be used up and thrown away, society suffers. But Victorian England figured out how to do without slavery, without child labor, with reduced working hours, and guess what, their society became more prosperous.

An early auto assembly line. Source: Library of Congress

We saw the same thing here in the US during the 20th century. We look back now on those good middle class jobs of the post-war era as something of an anomaly. But as my friend, the labor organizer David Rolf, frequently points out, “God did not make an auto worker a good job!” We made choices as a society to share the fruits of productivity more widely.

David Rolf at my 2015 Next:Economy Summit

We also made choices to invest in the future. That golden age of postwar productivity was the result of massive investments in in roads and bridges, universal power, water, sanitation, and communications. Louis Hyman, author of Borrow: The American Way of Debt, pointed out that we went from 10% of homes in the US having electricity in 1930 to 60% ten years later, simply by putting idle capital and human ingenuity to work. After World War II, we committed enormous resources to rebuild the lands destroyed by war, but we also invested in basic research. We invested in new industries: aerospace, chemicals, and yes, computers and telecommunications.

Image montage adapted from PRI: What the Gig Economy Means for the American Dream

And education. Education. One of the most memorable moments for me during the Markle Rework America task force meetings that we were both a part of was a remark from sociologist and author Robert Putnam, who said “All of the great advances in our society have come when we have made investments in other people’s children.”

Image: iStock

In the age of AI, we are faced again with that choice to invest in the future. Technology investor Nick Hanauer said “Technology is the solution to human problems. We won’t run out of work till we run out of problems.” Are we done yet?

AI has the potential to turbocharge the productivity of all our industries. But making what we do now more productive, and sharing the fruits of that productivity, is just the beginning. If we let machines put us out of work, it will be because of a failure of imagination and a lack of will to make a better future! What is impossible today, but will become possible with the technology we are now afraid of?

We won’t run out of work till we run out of problems.” Are we done yet? Are we done yet?

Nick Hanauer at my Next:Economy Summit 2015

Mark Zuckerberg and Priscilla Chan’s announcement a few weeks ago to fund an initiative that aims to cure all disease within their children’s lifetime is a great example of bold dreams. It’s hard to imagine that AI and Machine Learning won’t play a major role in achieving that ambitious goal. Already AI is being used to analyze millions of radiology scans at a level of resolution and precision impossible for humans, as well as helping doctors to keep up with the flood of medical research at a level that can’t be accomplished by a human practitioner.

Priscilla Chan and Mark Zuckerberg’s bold dream

And the White House Precision Medicine Initiative has already helped blaze that trail, with a vision of tailoring treatment to each individual patient. AI will play a huge role in precision medicine. We contribute our data; machines will help us interpret it. I heard recently from one startup that of the over 1 million full human genomes that have been sequenced, only 49,000 have been interpreted. That’s a job for AI.

Perhaps even more exciting, we’re studying the brain and how it works, with the prospect of creating prosthetics that give their users a sense of touch, that allow direct brain control of devices, and even “brain prosthetics” to deal with neurological diseases!

How about Climate Change? Climate change is for our generation what World War II was for our parents and grandparents, a challenge that we must rise to or suffer dire consequences.

Already in data centers, AI is radically increasing power efficiency. How do we rethink and rebuild our electric grid to be decentralized and adaptive? How do we use autonomous vehicles to rethink the layout of our cities, making them greener, healthier, better places to live? How do we use AI to anticipate ever more unpredictable weather, protecting our agriculture, our cities, and our economy?

Hurricane Matthew. Source: NASA

Cybersecurity is another of our great challenges. And we are rising to it with the aid of Machine Learning. The DARPA Cyber Grand Challenge asked for the development of AI to find and automatically patch software vulnerabilities that corporate IT teams just aren’t able to keep up with. The problem is that an increasing number of cyber attacks are being automated, and as one knowledgeable friend of mine, who wishes to remain anonymous, remarked, “It takes a machine to get inside the OODA loop of another machine.” (OODA: Observe, Orient, Decide, Act.)

Source: DARPA Cyber Grand Challenge

And as with every new technology, one of our grand challenges is governing our own creations. John Mattison, the Chief Medical Information Officer at Kaiser, once said to me, “The great question of the 21st century will be ‘Whose black box do you trust?’” As more and more systems are run by AI, we have to ensure that we know what it takes to understand what is going on in the black box. We have to ensure that AI is not controlled by only a few giant corporations but becomes the common heritage of mankind. And we have to ensure that every data/CS training program has ethics and security embedded throughout the curriculum.

The Connection Machine, the first computer optimized for AI. © Thinking Machines Corporation, 1989. Photo: Steve Grohe.

AI is a tool for human purpose, the next step in a long line that goes back through the ox and plough, the sawmill and the factory, the steam engine and the automobile, the airplane and the communications satellite.

Are we done yet? Are we done yet?

What challenges lie ahead that only AI can help us solve?

We must return again and again to the perpetual challenge: Can we hand off a better world to our children?

Source: Shutterstock

The slides from my talk can be downloaded from slideshare. For more of my thinking about technology and the Next:Economy, see my Economy topic page on oreilly.com.

\ No newline at end of file +WTF? What’s The Future? - From the WTF? Economy to the Next Economy
Video of WTF? My talk at the White House Frontiers Conference

WTF? What’s The Future?

Tim O'Reilly
Oct 19, 2016 · 10 min read

My talk at the White House Frontiers Conference

Last Thursday, I had the honor to be one of the warmup acts for President Obama at the White House Frontiers Conference at Carnegie Mellon University in Pittsburgh. Here is the prepared text and slides from the talk I delivered there. As you’ll see if you watch the video, what I ended up saying isn’t exactly what I had written out in advance, but it is reasonably close. (Video is above, slides and text interspersed below, with a link to the actual deck on slideshare at the end. Let me know if you like this format for sharing talks.)

Hearing that Bob Dylan just won the Nobel Prize for Literature, how could I not begin this talk with his famous line, “Something is happening here, but you don’t know what it is, do you, Mr. Jones?” The future is full of amazing things. On my way here, I spoke out loud to a $200 device in my kitchen, and asked it to call a Lyft to take me to the airport. And in a few years, that car might well be driving itself. Someone seeing this for the first time would have every excuse to say “WTF?” That of course is an expression of surprise and delight that stands for What’s the Future?

But many lot of people are reading the news about Artificial Intelligence and are feeling a profound sense of unease. They are also asking themselves “WTF? What’s the Future?” but in a very different tone of voice.

We heard recently from researchers at Oxford University that up to 47% of human tasks, including many white collar jobs, could be eliminated by automation within the next 20 years.

New study shows nearly half of US jobs are susceptible to computerisation

We’ve heard stories about how self driving cars and trucks will put millions of Americans out of work.

Self-Driving Trucks Are Going to Hit Us Like a Human-Driven Truck

I’d like to provide an alternate perspective.

Back in 1811 and 1812, a group of weavers led by Ned Ludd staged a rebellion, smashing the machine looms that were threatening their livelihood. Ludd and his compatriots were right to be afraid. The decades ahead were grim, as machines replaced human labor, and it took time for society to adjust.

Source: Wikimedia Commons

But those weavers couldn’t imagine that their descendants would have more clothing than the kings and queens of Europe, that ordinary people would eat the fruits of summer in the depths of winter. They couldn’t imagine that we’d tunnel through mountains and under the sea, we’d fly through the air, crossing continents in hours, we’d build cities in the desert with buildings a half mile high, that we’d put spacecraft in orbit around Jupiter, that we would eliminate so many scourges of disease! And they couldn’t imagine that their children would find meaningful work bringing all of these things to life!

Photo composite by Tim O’Reilly and Edie Freedman

To understand the future, it often helps to look backwards.

I want to start here, with one of the world’s most heralded inventions. Can you imagine the first woman (I imagine it was a woman) who built a controlled fire? How amazed her companions were. Perhaps afraid at first. But soon warmed and fed by her boldness. But even more important than fire itself was the ability to tell others about it! It was language that was our first great invention, the ability to pass fire from mind to mind.

Neanderthals. Source: Wikimedia Commons

The invention of movable type and the book led to a remarkable flowering in the economy, as the discoverers of the new could pass the fire of knowledge to people not yet born and to those living thousands of miles away.

The War Department Library in the Eisenhower Executive Office Building. Photo: Tim O’Reilly

The internet was the next great leap. But the web browser — words and pictures online — was only a halfway house.

I was recently reminded just how access to knowledge has changed when riding on San Francisco’s 14 Mission bus. I was sitting between two old men. I pulled out my phone to check where to get off. The old man on my right was agog. He’d never seen Google Maps before. The other jumped in eagerly, explaining that the blue dot followed our progress. I left them, one still in wonder, the other confident in the new reality, now demoing Google Maps on his phone to the other, who had never seen it.

Getting to the Bill Gates building on the CMU campus with Google Maps. Source: Microsoft, composite Edie Freedman

Think about it for a moment. Over a billion people can pull out their phone and see where they are and how to get where they want to go in real time. And that capability underlies new kinds of services like Uber, and remarkable startups like Zipline, which is delivering blood and critical medicines on demand by drone in countries without good roads or accessible hospital infrastructure.

A Zipline drone delivering blood or medicine.

GPS and Google maps illustrate what I call “the arc of knowledge.” We’ve gone from the spoken to the written word, to mass production of writing, to electronic dissemination via the internet, to embedding knowledge into services and devices. AI is simply the next step in that arc, feeding massive amounts of data into Machine Learning models to find new meaning in it and to enable new kinds of services.

“The Arc of Knowledge” — from representation to embedding in services and devices

AI is not some kind of radical discontinuity. AI is not the machine from the future that is hostile to human values and will put us all out of work. AI is the next step in the spread and usefulness of knowledge, which is the true source of the wealth of nations.

It’s easy to blame technology for the problems that occur in periods of great economic transition. But, both the problems and the solutions are the result of human choices. As we saw during the first industrial revolution, when the fruits of automation are used solely to enrich the owners of the machines and treat workers as a cost to be eliminated, or as cogs in the machine, to be used up and thrown away, society suffers. But Victorian England figured out how to do without slavery, without child labor, with reduced working hours, and guess what, their society became more prosperous.

An early auto assembly line. Source: Library of Congress

We saw the same thing here in the US during the 20th century. We look back now on those good middle class jobs of the post-war era as something of an anomaly. But as my friend, the labor organizer David Rolf, frequently points out, “God did not make an auto worker a good job!” We made choices as a society to share the fruits of productivity more widely.

David Rolf at my 2015 Next:Economy Summit

We also made choices to invest in the future. That golden age of postwar productivity was the result of massive investments in in roads and bridges, universal power, water, sanitation, and communications. Louis Hyman, author of Borrow: The American Way of Debt, pointed out that we went from 10% of homes in the US having electricity in 1930 to 60% ten years later, simply by putting idle capital and human ingenuity to work. After World War II, we committed enormous resources to rebuild the lands destroyed by war, but we also invested in basic research. We invested in new industries: aerospace, chemicals, and yes, computers and telecommunications.

Image montage adapted from PRI: What the Gig Economy Means for the American Dream

And education. Education. One of the most memorable moments for me during the Markle Rework America task force meetings that we were both a part of was a remark from sociologist and author Robert Putnam, who said “All of the great advances in our society have come when we have made investments in other people’s children.”

Image: iStock

In the age of AI, we are faced again with that choice to invest in the future. Technology investor Nick Hanauer said “Technology is the solution to human problems. We won’t run out of work till we run out of problems.” Are we done yet?

AI has the potential to turbocharge the productivity of all our industries. But making what we do now more productive, and sharing the fruits of that productivity, is just the beginning. If we let machines put us out of work, it will be because of a failure of imagination and a lack of will to make a better future! What is impossible today, but will become possible with the technology we are now afraid of?

We won’t run out of work till we run out of problems.” Are we done yet? Are we done yet?

Nick Hanauer at my Next:Economy Summit 2015

Mark Zuckerberg and Priscilla Chan’s announcement a few weeks ago to fund an initiative that aims to cure all disease within their children’s lifetime is a great example of bold dreams. It’s hard to imagine that AI and Machine Learning won’t play a major role in achieving that ambitious goal. Already AI is being used to analyze millions of radiology scans at a level of resolution and precision impossible for humans, as well as helping doctors to keep up with the flood of medical research at a level that can’t be accomplished by a human practitioner.

Priscilla Chan and Mark Zuckerberg’s bold dream

And the White House Precision Medicine Initiative has already helped blaze that trail, with a vision of tailoring treatment to each individual patient. AI will play a huge role in precision medicine. We contribute our data; machines will help us interpret it. I heard recently from one startup that of the over 1 million full human genomes that have been sequenced, only 49,000 have been interpreted. That’s a job for AI.

Perhaps even more exciting, we’re studying the brain and how it works, with the prospect of creating prosthetics that give their users a sense of touch, that allow direct brain control of devices, and even “brain prosthetics” to deal with neurological diseases!

How about Climate Change? Climate change is for our generation what World War II was for our parents and grandparents, a challenge that we must rise to or suffer dire consequences.

Already in data centers, AI is radically increasing power efficiency. How do we rethink and rebuild our electric grid to be decentralized and adaptive? How do we use autonomous vehicles to rethink the layout of our cities, making them greener, healthier, better places to live? How do we use AI to anticipate ever more unpredictable weather, protecting our agriculture, our cities, and our economy?

Hurricane Matthew. Source: NASA

Cybersecurity is another of our great challenges. And we are rising to it with the aid of Machine Learning. The DARPA Cyber Grand Challenge asked for the development of AI to find and automatically patch software vulnerabilities that corporate IT teams just aren’t able to keep up with. The problem is that an increasing number of cyber attacks are being automated, and as one knowledgeable friend of mine, who wishes to remain anonymous, remarked, “It takes a machine to get inside the OODA loop of another machine.” (OODA: Observe, Orient, Decide, Act.)

Source: DARPA Cyber Grand Challenge

And as with every new technology, one of our grand challenges is governing our own creations. John Mattison, the Chief Medical Information Officer at Kaiser, once said to me, “The great question of the 21st century will be ‘Whose black box do you trust?’” As more and more systems are run by AI, we have to ensure that we know what it takes to understand what is going on in the black box. We have to ensure that AI is not controlled by only a few giant corporations but becomes the common heritage of mankind. And we have to ensure that every data/CS training program has ethics and security embedded throughout the curriculum.

The Connection Machine, the first computer optimized for AI. © Thinking Machines Corporation, 1989. Photo: Steve Grohe.

AI is a tool for human purpose, the next step in a long line that goes back through the ox and plough, the sawmill and the factory, the steam engine and the automobile, the airplane and the communications satellite.

Are we done yet? Are we done yet?

What challenges lie ahead that only AI can help us solve?

We must return again and again to the perpetual challenge: Can we hand off a better world to our children?

Source: Shutterstock

The slides from my talk can be downloaded from slideshare. For more of my thinking about technology and the Next:Economy, see my Economy topic page on oreilly.com.

From the WTF? Economy to the Next Economy

How work, business, and society face massive, technology-driven change. A conversation growing out of Tim O’Reilly’s book WTF? What’s the Future and Why It’s Up To Us, and the Next:Economy Summit.

Tim O'Reilly

Written by

Founder and CEO, O'Reilly Media. Watching the alpha geeks, sharing their stories, helping the future unfold.

From the WTF? Economy to the Next Economy

How work, business, and society face massive, technology-driven change. A conversation growing out of Tim O’Reilly’s book WTF? What’s the Future and Why It’s Up To Us, and the Next:Economy Summit.

Welcome to a place where words matter. On Medium , smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade
\ No newline at end of file diff --git a/fixtures/medium.com/1485902752952.html b/fixtures/medium.com/1485902752952.html index ed7e62d36..e29645fc3 100644 --- a/fixtures/medium.com/1485902752952.html +++ b/fixtures/medium.com/1485902752952.html @@ -1 +1 @@ -Flag Attributes in Android — How to Use Them – Jakob Ulbrich – Medium

Flag Attributes in Android — How to Use Them

I’m sure you have seen something like the following line very often while writing the XML attributes for your views or layouts.

attribute="option1|option2"

Notice the | between the options. It is not only a fancy separator, it is a bitwise operator merging the two options into one single value.

The following will explain what exactly Bit Flags are, how to declare custom XML flag attributes and how to read and work with them in the code.


What Are Bit Flags?

Generally you can see Bit Flags as a number of boolean values stored in one single value.

In the binary system a bit has two states: on and off. Now think about a row of bits where every bit is an indicator for one of your options. When the option is set, the bit has the value 1. If not, it has the value 0.

110

We read this from right to left.
The bit for our first option is 0. That means the option is not set. Whereas the bits for the second and third options are 1. This means they are set.

Every integer value has a representation in the binary system and and vice versa.

0 = 0*2³ + 0*2² + 0*2¹ + 0*2⁰ = 0000
1 = 0*2³ + 0*2² + 0*2¹ + 1*2⁰ = 0001
2 = 0*2³ + 0*2² + 1*2¹ + 0*2⁰ = 0010
4 = 0*2³ + 1*2² + 0*2¹ + 0*2⁰ = 0100
8 = 1*2³ + 0*2² + 0*2¹ + 0*2⁰ = 1000

This means we can store our Bit Flag value as a plain integer value. And we can use the bitwise operators (more about them later) directly on integer values.


Declaring XML Flag Attributes

Now, let’s assume that we want to create a custom view called MyView which can draw a border around itself, and that we want to specify on which sites (top, right, bottom, left) it should draw the borders using an XML flag attribute.
I will not explain how to actually draw something, I will only explain how to work with flags.

We can declare XML flag attributes like any other attribute. You can find an official documentation here.

In our values/attrs.xml file we declare the new attribute called drawBorder for our view called MyView.

<resources>
<declare-styleable name="MyView">
<attr name="drawBorder">
<flag name="none" value="0" />
<flag name="top" value="1" />
<flag name="right" value="2" />
<flag name="bottom" value="4" />
<flag name="left" value="8" />
<flag name="all" value="15" />
</attr>
...
</declare-styleable>
</resources>

Look exactly at the values we have set for the options.
We essentially have 4 options (top, right, bottom, left). The other two options are used to specify that no option is set or that all options are set.
The values for the 4 options are chosen, so that when you write them in the binary system, these two statements are fulfilled:

  • Every value has exactly one bit which is set to 1. All other bits are 0.
  • None of the values have the same bit set to 1.

The option none is used to indicate that none of the 4 options is set. And the option all is the sum of the values of the 4 options and indicates that all of the 4 options are set.

We can now use our custom attribute like this in our custom View:

<my.package.name.MyView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawBorder="bottom|top" />

Read XML Flag Attributes

Let’s start with the basic class for our custom View. We should declare a constant for each of our options with an equal value as declared above. And a variable for the value that we get from reading the XML attribute. You can have a look about how to read attributes here.

public MyView extends View{
    // Constants for the flags
private static final int BORDER_NONE_DEFAULT = 0;
private static final int BORDER_TOP = 1;
private static final int BORDER_RIGHT = 2;
private static final int BORDER_BOTTOM = 4;
private static final int BORDER_LEFT = 8;
    // Variable for the current value
private int mDrawBorder = BORDER_NONE_DEFAULT;
    public MyView(Context context){
// Delegate to next constructor
this(context, null);
}
    public MyView(Context context, AttributeSet attrs){
// Delegate to next constructor
this(context, attrs, 0);
}
    public MyView(Context context, AttributeSet attrs,
int defStyleAttr){
super(context, attrs, defStyleAttr);
        // Read attributes
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.PieChart);
        try {
mDrawBorder = a.getInteger(
R.styleable.MyView_drawBorder,
BORDER_NONE_DEFAULT);
} finally {
a.recycle();
}

}
...
}

We have now assigned the value specified in the XML layout file to the mDrawBorder variable. If the attribute does not exists in the layout the BORDER_NONE_DEFAULT value is used.


Working With Bit Flags

Okay, how do we know which of our options were set when we only get one value? That’s why we have defined the constants for our options.

There are bitwise operators we can use to check if an option is contained in the current mDrawBorder value and to enable or disable or toggle an option. Let’s have a look at them:

| (bitwise logically or)
Example: 100 | 001 = 101
The result has a 1 on the position where at least one value has a 1.
& (bitwise logically and)
Example: 100 & 101 = 100
The result has a 1 on the position where both values have a 1.
~ (bitwise inverse)
Example: ~100 = 011
All bits get inverted.
^ (bitwise exclusive or)
Example: 100^101 = 001
The result has a 1 on the position where one value has a 1 whereas the other value has a 0.

Let’s assume we have used the attribute in the following two ways. Yes, technically they are correct, but they may look weird 😵.

Example 1: app:drawBorder="none|top"

In this first example the values of none (0 = 000) and top (1 = 001) get combined by the logically or-operator | to the value (001 = 1). The result still contains the flag value for top (which is 1). And also for none (which is 0) because every flag-set contains the 0-flag at every time.

Example 2: app:drawBorder="bottom|all"

In this second example the values of bottom (3 =0011) and all (15 = 1111) get combined to (1111 = 15). The result still contains the flag for bottom since all enables the bits for all of the 4 options.

Check If a Flag is Contained in The Set

Now we need to check which option is contained in the value of the mDrawBorder variable. We do this by calling the following method:

private boolean containsFlag(int flagSet, int flag){
return (flagSet|flag) == flagSet;
}
// Method call
boolean drawBorderTop = containsFlag(mDrawBorder, BORDER_TOP);

We try to add the flag to the existing flag-set and if the value of the flag-set does not change, we can combine that the flag was already contained.

Add a Flag to The Set

Adding a flag is pretty simple. We use the same operator (The logically or-operator) like in the XML attributes:

private int addFlag(int flagSet, int flag){
return flagSet|flag;
}
// Method call
mDrawBorder = addFlag(mDrawBorder, BORDER_LEFT);

We do not need to check if the flag-set already contains the flag that we want to add. When it is already contained, the value simply stays the same.

Toggle a Flag in The Set

Toggling is also very simple.

private int toggleFlag(int flagSet, int flag){
return flagSet^flag;
}
// Method call
mDrawBorder = toggleFlag(mDrawBorder, BORDER_LEFT);

Since the exclusive or-operator ^ only keeps the bits where both bits are different, it will remove the bits that are set in the flag when they are also already set in the flag-set. And it will add them if they are not set in the flag-set.

Example 1: 110^010 = 100 (Binary)
6 ^ 2 = 4 (Decimal)
Example 2: 100^010 = 110 (Binary)
4 ^ 2 = 6 (Decimal)

Remove a Flag From the Set

Removing a flag is a bit more complicated (we need two bitwise operators), but still easy.

private int removeFlag(int flagSet, int flag){
return flagSet&(~flag);
}
// Method call
mDrawBorder = removeFlag(mDrawBorder, BORDER_LEFT);

First we invert the flag that we want to remove. Then we combine this with the current flag-set. This means only where the bit in the flag was set, we now have a 0. And that’s why we also have a 0 at this position in the final result. The rest of the result is the same as in the original flag-set. Have a look at this example:

110&(~010) = 110&101 = 100 (Binary)
6 &(~ 2 ) = 6 & 5 = 4 (Decimal)

Bit Flags are also a good alternative if you have a lot of boolean values and especially if you want to store them somehow. Instead of saving a lot of booleans you only need to save one integer value.

You should now be able to define your own flag attributes and work with them in your application. You should also be able to use Bit Flags as an alternative to a number of booleans.
When you found this tutorial useful feel free to hit the 💚.


If you have any suggestions on how to improve this tutorial or found a mistake, you can leave a private note at the specific position.

Happy coding 💻.

  • Share
Go to the profile of Jakob Ulbrich
Never miss a story from Jakob Ulbrich, when you sign up for Medium. Learn more
Never miss a story from Jakob Ulbrich
\ No newline at end of file +Flag Attributes in Android — How to Use Them - Jakob Ulbrich - Medium

Flag Attributes in Android — How to Use Them

JakobUlbrich
Follow

I’m sure you have seen something like the following line very often while writing the XML attributes for your views or layouts.

attribute="option1|option2"

Notice the | between the options. It is not only a fancy separator, it is a bitwiseoperator merging the two options into one single value.

The following will explain whatexactly Bit Flags are, how to declare custom XML flag attributes and how to read and work with them inthe code.


What Are Bit Flags?

Generally you can see Bit Flags asa number of boolean values stored in one single value.

In the binary system a bit has twostates:on and off. Now think about a rowof bits where every bit is an indicator for one of your options. When the option is set, the bit has thevalue 1. If not, it has the value 0.

110

We read this from right to left.
The bit for our first option is 0. That means the option is not set. Whereas thebits for the second and third options are 1. This means they are set.

Every integer value has arepresentation in the binary system and and vice versa.

0 = 0*2³ + 0*2² + 0*2¹ + 0*2⁰ = 0000
1 = 0*2³ + 0*2² + 0*2¹ + 1*2⁰ = 0001
2 = 0*2³ + 0*2² + 1*2¹ + 0*2⁰ = 0010
4 = 0*2³ + 1*2² + 0*2¹ + 0*2⁰ = 0100
8 = 1*2³ + 0*2² + 0*2¹ + 0*2⁰ = 1000

This means we can store our BitFlag value as a plain integer value. And we can use the bitwise operators (more about them later)directly on integer values.


Declaring XML Flag Attributes

Now, let’s assume that we want tocreate a custom view called MyView which can draw a border around itself,and that we want to specify on which sites (top, right, bottom, left) it should draw the borders usingan XML flag attribute.
I will not explain how to actually drawsomething, I will only explain how to work with flags.

We can declare XML flag attributeslike any other attribute. You can find an official documentation here.

In our values/attrs.xml file we declare the new attribute called drawBorder for our view called MyView.

<resources>
<declare-styleable name="MyView">
<attr name="drawBorder">
<flag name="none" value="0" />
<flag name="top" value="1" />
<flag name="right" value="2" />
<flag name="bottom" value="4" />
<flag name="left" value="8" />
<flag name="all" value="15" />
</attr>
...
</declare-styleable>
</resources>

Look exactly at the values we haveset for the options.
We essentially have 4 options (top, right, bottom, left). The other twooptions are used to specify that no option is set or that all options are set.
The values for the 4options are chosen, so that when you write them in the binary system, these two statements arefulfilled:

  • Every value has exactlyone bit which is set to 1. All other bits are 0.
  • None of the values havethe same bit set to 1.

The option none is used to indicate that none of the 4 options is set.And the option all is the sum of the values of the 4options and indicates that all of the 4 options are set.

We can now use our custom attributelike this in our custom View:

<my.package.name.MyView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawBorder="bottom|top" />

Read XML Flag Attributes

Let’s start with the basic classfor our custom View. We should declare a constant for each of our options with an equal value asdeclared above. And a variable for the value that we get from reading the XML attribute. You can have alook about how to read attributes here.

public MyView extends View{// Constants for the flags
private static final int BORDER_NONE_DEFAULT = 0;
private static final int BORDER_TOP = 1;
private static final int BORDER_RIGHT = 2;
private static final int BORDER_BOTTOM = 4;
private static final int BORDER_LEFT = 8;
// Variable for the current value
private int mDrawBorder = BORDER_NONE_DEFAULT;
public MyView(Context context){
// Delegate to next constructor
this(context, null);
}
public MyView(Context context, AttributeSet attrs){
// Delegate to next constructor
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs,
int defStyleAttr){
super(context, attrs, defStyleAttr);
// Read attributes
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.MyView);
try{
mDrawBorder = a.getInteger(
R.styleable.MyView_drawBorder,
BORDER_NONE_DEFAULT);
} finally{
a.recycle();
}

}
...
}

We have now assigned the valuespecified in the XML layout file to the mDrawBordervariable. If the attribute does not exists in the layout the BORDER_NONE_DEFAULT value is used.


Working With Bit Flags

Okay, how do we know which of ouroptions were set when we only get one value? That’s why we have defined the constants for our options.

There are bitwise operators we canuse to check if an option is contained in the current mDrawBorder valueand to enable or disable or toggle an option. Let’s have a look at them:

| (bitwise logically or)
Example:100 | 001 = 101
The result has a 1 on the position where at least one value has a 1.
& (bitwise logically and)
Example:100 & 101 = 100
The result has a 1 on the position where both values have a 1.
~ (bitwise inverse)
Example:~100 = 011
All bits get inverted.
^ (bitwise exclusive or)
Example:100^101 = 001
The result has a 1 on the position where one value has a 1 whereas the other value has a 0.

Let’s assume we have used theattribute in the following two ways. Yes, technically they are correct, but they may look weird 😵.

Example 1: app:drawBorder="none|top"

In this first example the values ofnone (0 = 000) and top (1 = 001) get combined by the logically or-operator | to the value (001 = 1). The result still contains the flag value for top (which is 1). And also for none (which is 0) because every flag-set contains the 0-flag at every time.

Example 2: app:drawBorder="bottom|all"

In this second example the valuesof bottom (3 =0011) and all (15 = 1111) get combined to (1111 = 15). The result still contains theflag for bottom since all enables the bits for all of the 4 options.

Check If a Flag is Contained inThe Set

Now we need to check which optionis contained in the value of the mDrawBordervariable. We do this by calling the following method:

private boolean containsFlag(int flagSet, int flag){
return (flagSet|flag) == flagSet;
}
// Method call
boolean drawBorderTop = containsFlag(mDrawBorder, BORDER_TOP);

We try to add the flag to theexisting flag-set and if the value of the flag-set does not change, we can combine that the flag wasalready contained.

Add a Flag to The Set

Adding a flag is pretty simple. Weuse the same operator (The logically or-operator) like in the XML attributes:

private int addFlag(int flagSet, int flag){
return flagSet|flag;
}
// Method call
mDrawBorder = addFlag(mDrawBorder, BORDER_LEFT);

We do not need to check if theflag-set already contains the flag that we want to add. When it is already contained, the value simplystays the same.

Toggle a Flag in The Set

Toggling is also very simple.

private int toggleFlag(int flagSet, int flag){
return flagSet^flag;
}
// Method call
mDrawBorder = toggleFlag(mDrawBorder, BORDER_LEFT);

Since the exclusive or-operator^ only keeps the bits where both bits are different, it will remove thebits that are set in the flag when they are also already set in the flag-set. And it will add them ifthey are not set in the flag-set.

Example 1: 110^010 = 100 (Binary)
6 ^ 2=4(Decimal)
Example 2: 100^010 = 110 (Binary)
4 ^ 2=6(Decimal)

Remove a Flag From the Set

Removing a flag is a bit morecomplicated (we need two bitwise operators), but still easy.

private int removeFlag(int flagSet, int flag){
return flagSet&(~flag);
}
// Method call
mDrawBorder = removeFlag(mDrawBorder, BORDER_LEFT);

First we invert the flag that wewant to remove. Then we combine this with the current flag-set. This means only where the bit in theflag was set, we now have a 0. And that’s why we also have a 0 at this position in the final result. Therest of the result is the same as in the original flag-set. Have a look at this example:

110&(~010) = 110&101 = 100 (Binary)
6 &(~ 2 ) =6 & 5=4(Decimal)

Bit Flags are also a goodalternative if you have a lot of boolean values and especially if you want to store them somehow.Instead of saving a lot of booleans you only need to save one integer value.

You should now be able to defineyour own flag attributes and work with them in your application. You should also be able to use BitFlags as an alternative to a number of booleans.
When you found this tutorial useful feel free tohit the 💚.


If you have any suggestions on howto improve this tutorial or found a mistake, you can leave a private note at the specific position.

Happy coding 💻.

Thanks to

Written by

Follow
See responses (5)

Discover

Welcome to a place where words matter. Onhref="https://medium.com/about?autoplay=1&source=post_page-----ac4ec8aee7d1----------------------"class="bb bc bd be bf bg bh bi bj bk bn bo hr hs ia">Watch

Make

Follow all the topics you care about, and we’lldeliver the best stories for you to your homepage and inbox.class="bb bc bd be bf bg bh bi bj bk bn bo hr hs ia">Explore

Become a member

Get unlimited access to the best stories onhref="https://medium.com/membership?source=post_page-----ac4ec8aee7d1----------------------"class="bb bc bd be bf bg bh bi bj bk bn bo hr hs ia">Upgrade
AboutHelpLegal
\ No newline at end of file diff --git a/src/extractors/custom/medium.com/index.js b/src/extractors/custom/medium.com/index.js index c21236150..01fc94007 100644 --- a/src/extractors/custom/medium.com/index.js +++ b/src/extractors/custom/medium.com/index.js @@ -1,10 +1,8 @@ export const MediumExtractor = { domain: 'medium.com', - supportedDomains: ['trackchanges.postlight.com'], - title: { - selectors: ['h1'], + selectors: ['h1', ['meta[name="og:title"]', 'value']], }, author: { @@ -12,11 +10,7 @@ export const MediumExtractor = { }, content: { - selectors: [ - ['.section-content'], - '.section-content', - 'article > div > section', - ], + selectors: ['article'], // Is there anything in the content you selected that needs transformed // before it's consumable content? E.g., unusual lazy loaded images @@ -25,14 +19,18 @@ export const MediumExtractor = { iframe: $node => { const ytRe = /https:\/\/i.embed.ly\/.+url=https:\/\/i\.ytimg\.com\/vi\/(\w+)\//; const thumb = decodeURIComponent($node.attr('data-thumbnail')); + const $parent = $node.parents('figure'); if (ytRe.test(thumb)) { const [_, youtubeId] = thumb.match(ytRe); // eslint-disable-line $node.attr('src', `https://www.youtube.com/embed/${youtubeId}`); - const $parent = $node.parents('figure'); const $caption = $parent.find('figcaption'); $parent.empty().append([$node, $caption]); + return; } + + // If we can't draw the YouTube preview, remove the figure. + $parent.remove(); }, // rewrite figures to pull out image and caption, remove rest @@ -42,29 +40,33 @@ export const MediumExtractor = { const $img = $node.find('img').slice(-1)[0]; const $caption = $node.find('figcaption'); + $node.empty().append([$img, $caption]); }, + + // Remove any smaller images that did not get caught by the generic image + // cleaner (author photo 48px, leading sentence images 79px, etc.). + img: $node => { + const width = parseInt($node.attr('width'), 10); + if (width < 100) $node.remove(); + }, }, // Is there anything that is in the result that shouldn't be? // The clean selectors will remove anything that matches from // the result - clean: [], + clean: ['span', 'svg'], }, date_published: { - selectors: [['time[datetime]', 'datetime']], + selectors: [['meta[name="article:published_time"]', 'value']], }, lead_image_url: { selectors: [['meta[name="og:image"]', 'value']], }, - dek: { - selectors: [ - // enter selectors - ], - }, + dek: null, next_page_url: { selectors: [ diff --git a/src/extractors/custom/medium.com/index.test.js b/src/extractors/custom/medium.com/index.test.js index 2f08c9f6e..fc704d786 100644 --- a/src/extractors/custom/medium.com/index.test.js +++ b/src/extractors/custom/medium.com/index.test.js @@ -44,7 +44,7 @@ describe('MediumExtractor', () => { it('returns the date_published', async () => { const { date_published } = await result; - assert.equal(date_published, '2016-10-19T14:24:20.323Z'); + assert.equal(date_published, '2016-10-19T14:30:56.529Z'); }); it('returns the dek', async () => { @@ -62,7 +62,7 @@ describe('MediumExtractor', () => { // the article. assert.equal( lead_image_url, - 'https://cdn-images-1.medium.com/max/1200/1*3Gzaug9mRc8vvx1cuQWkog.png' + 'https://miro.medium.com/max/540/1*3Gzaug9mRc8vvx1cuQWkog.png' ); }); @@ -78,12 +78,9 @@ describe('MediumExtractor', () => { 13 ); - // testing that youtube video transform is working - assert.equal(/IAoy3ia2ivI/.test(content), true); - assert.equal( first13, - 'Video of WTF? My talk at the White House Frontiers ConferenceLast Thursday, I' + 'Last Thursday, I had the honor to be one of the warmup acts' ); }); });