text:
Venture Capital: why AUM is the wrong metric
The Bridge 2021.11.29
This guest post is authored by Mark Bivens. Mark is a Silicon Valley native and former entrepreneur, having started three companies before "turning to the dark side of VC."
He is a venture capitalist that travels between Paris and Tokyo (aka the RudeVC). He is the Managing Partner of Shizen Capital (formerly known as Tachi.ai Ventures) in Japan. You can read more on his blog at http://rude.vc or follow him @markbivens. The Japanese translation of this article is available here.
Image credit: Pixnio
There's an old dig that venture capitalists like to make about private equity professionals: private equity folks boast about the size of their ego in AUM, whereas VCs know that what really matters is their IRR.
Now let's define these three-letter words. First, I'm using the word ego as a euphemism here to be gender agnostic (albeit in reality it's usually only men who tend to make this brag). AUM means assets under management (i.e. the total amount of money in the funds managed by the general partner team). IRR means internal rate of return (i.e. the cash returns distributed to a fund's investors, annualized).
Asset managers care about AUM because it directly translates into guaranteed revenue. Closed-end investment funds typically follow a "2 and 20 model," meaning annual management fees of 2% and a share of 20% of the capital gains generated by the fund (aka carried interest). The annual management fees are a direct function of AUM, i.e. 2% of total AUM each year. They are contractually established for the life of the fund, usually 10 years. The carried interest is a direct function of fund performance, i.e. 20% of the capital gains generated by the fund.
Accordingly, a large AUM directly translates into a significant guaranteed revenue stream for the entire life of the fund. A fund manager with $1 billion in AUM is probably receiving around $20 million per year in recurring revenue. A micro VC fund of say $10 million is receiving only $200k per year in recurring revenue via its management fees.
Risk of misalignment
Since management fees are meant to cover the operations of the fund, excessively high management fees can translate into high salaries for the managing partners, luxurious offices, and lavish parties. Even if the fund's financial performance is lackluster, a guaranteed annual revenue stream in the double-digit millions for several years makes for a fairly comfortable lifestyle. Do you see where a potential misalignment can emerge?
In contrast, a small VC fund can afford no such excesses. The managers of a small VC fund cannot become wealthy on management fees alone. They must perform. Only by generating significant capital gains on the funds they manage will they be able to generate wealth for themselves via the carried interest mechanism. IRR represents each fund's financial performance.
For LP investors in private equity or VC funds who care about financial return, IRR is the metric that reflects their financial return, not AUM. So I submit that when a fund manager brags about their AUM, the appropriate rebuttal would be to ask their IRR.
Full disclosure: I too used to be guilty of the AUM flex. As a former GP in a fund that managed nearly $1 billion in AUM, I would often open my introduction at conferences by citing this figure. But over time, I learned that IRR represents my true KPI as a fund manager. IRR is the indicator of how well or how poorly I perform my job. It is not a mathematical anomaly that my best-performing funds have been those with smaller fund sizes, hence lower AUM.
In many ways actually, a propensity to chatter more about AUM than IRR is an indication of the stage of an ecosystem. When the venture market in a given region is still nascent, track records are limited, so the nearest metric people can look for is assets under management. However, once a fund manager has progressed beyond their first vintage, the more the relevant question to ask is, "So what is your IRR?"
Why I tend to prefer equity rounds over notes
Movida Japan opening up startup program under new chief accelerator
Japan's Brazil Venture Capital announces first close of $9M second fund
2022 predictions from insightful investors
Commmune, customer success support platform from Japan, announces US expansion
Japanese sneaker marketplace reaches $340M valuation after raising funds from SoftBank
Japan's space debris remover Astroscale secures $109M, brings valuation to $295M
Top 5: Japanese Online Dating Sites
Meet 5 of Japan's top photo apps
Top 5: Japan's cutest Kaomoji apps
5 cute Japanese apps that let you customize your mobile's homescreen
Japanese government unveils downloadable 3D topographical map of the country
Japan's Ookami, offering social network app for sports fans, secures series A round
Japan's sticker character production Quan to merge with cartoonist agency Wwwaap
Base: The Japanese freemium e-commerce platform that's following Shopify's lead
HRTech startup SmartHR becomes Japan's 6th unicorn after raising $110M+: Nikkei
Astroscale
Tokyo-based Astroscale Holdings, the Japanese startup offering space debris removal services, has secured approximately 12.4 billion yen (about $109 million) in a Series F round, which brought the startup's valuation to 33.4 billion yen (about $295 million). This follows their series E round back in October of last year. Investors participating in the latest round are: DNCA Invest Beyound Global Leaders Environmental Energy Investment Siniphian AXA Life Insurance Innovation Engine OPS Seraphim Space Investment Trust Solaris ESG Master Fund Chiba Dojo Nomura Sparks Investment Prelude Structured Alternatives Master Fund Yamauchi-No.10 Family Office (the family office of Nindendo's founder) Y's Investment According to the company, the funding will enable the company's global growth, including the development of technology for safe and cost-effective on-orbit services and the expansion of its own facilities for mass production in Japan, the UK and the US. Since its Series E round back in October of last year, the company's workforce has grown by more than 60 percent, reaching about 250 employees globally. The company successfully launched and put into orbit the ELSA-d space debris removal satellite in March, and this month, followed by introducing its docking plate this month, which is designed to be pre-loaded onto…
ELSA-d
Image credit: Astroscale Holdings
Tokyo-based Astroscale Holdings, the Japanese startup offering space debris removal services, has secured approximately 12.4 billion yen (about $109 million) in a Series F round, which brought the startup's valuation to 33.4 billion yen (about $295 million). This follows their series E round back in October of last year.
Investors participating in the latest round are:
DNCA Invest Beyound Global Leaders
Environmental Energy Investment
Siniphian
AXA Life Insurance
Innovation Engine
Seraphim Space Investment Trust
Solaris ESG Master Fund
Chiba Dojo
Nomura Sparks Investment
Prelude Structured Alternatives Master Fund
Yamauchi-No.10 Family Office (the family office of Nindendo's founder)
Y's Investment
According to the company, the funding will enable the company's global growth, including the development of technology for safe and cost-effective on-orbit services and the expansion of its own facilities for mass production in Japan, the UK and the US.
Since its Series E round back in October of last year, the company's workforce has grown by more than 60 percent, reaching about 250 employees globally.
The company successfully launched and put into orbit the ELSA-d space debris removal satellite in March, and this month, followed by introducing its docking plate this month, which is designed to be pre-loaded onto low-Earth orbit satellites, one of the main possible sources of space debris.
Singapore / Japan space-debris removal startup Astroscale raises $35M in series B
Singapore / Japan space-debris removal startup Astroscale raises $25M in series C
Synspective nabs $100M in 17 months since founding, targets 6 mini-sats launch by 2022
Japan music marketplace Audiostock secures $5.8M for global subscription service
Okayama, Japan-based Audiostock, the Japanese startup behind a marketplace for music composers and sound creators under the same name, has secured 670 million yen (about $5.8 million) in its latest round, according to Nikkei's report on Wednesday. Participating investors include Susquehanna International Group, Ceres (TSE:3696), and HBCC Technology Investment. This follows the company's series B round back in July of 2020 and previous funding from Link-U and CiP Council in April of 2020 as well as previous rounds in March of 2018 and October of 2012. The company has partnered with overseas companies to sell foreign-branded background music and sound effects to the Japanese market. With the latest round, the company is planning to sell Japanese music and sound effects to the global market on a subscription basis. Previously known as Cleoguga, Audiostock was founded in October of 2007 and subsequently launched the music marketplace in 2013. The company claims that it has attracted over 10,000 amateur composers and has helped promote games and music artists.
Image credit: Audiostock
Okayama, Japan-based Audiostock, the Japanese startup behind a marketplace for music composers and sound creators under the same name, has secured 670 million yen (about $5.8 million) in its latest round, according to Nikkei's report on Wednesday. Participating investors include Susquehanna International Group, Ceres (TSE:3696), and HBCC Technology Investment.
This follows the company's series B round back in July of 2020 and previous funding from Link-U and CiP Council in April of 2020 as well as previous rounds in March of 2018 and October of 2012.
The company has partnered with overseas companies to sell foreign-branded background music and sound effects to the Japanese market. With the latest round, the company is planning to sell Japanese music and sound effects to the global market on a subscription basis.
Previously known as Cleoguga, Audiostock was founded in October of 2007 and subsequently launched the music marketplace in 2013. The company claims that it has attracted over 10,000 amateur composers and has helped promote games and music artists.
Japanese music composer community Creofuga launches crowdsourcing platform
What Japanese computer vision startup Edison.ai takes away from Techstars Music
KDDI to migrate its music service to Kkbox, joining Asia's largest music network
Blogging as a recruiting tool
This guest post is authored by Mark Bivens. Mark is a Silicon Valley native and former entrepreneur, having started three companies before "turning to the dark side of VC." He is a venture capitalist that travels between Paris and Tokyo (aka the RudeVC). He is the Managing Partner of Shizen Capital (formerly known as Tachi.ai Ventures) in Japan. You can read more on his blog at http://rude.vc or follow him @markbivens. The Japanese translation of this article is available here. During a return visit to France last month, I caught up with a successful French entrepreneur (whom I wish I would have backed on his first venture, but that's another story). Anyway, he opened the conversation with flattery, claiming that I had inspired him. So of course I'm growing suspicious at this point, either expecting a punch line or reconsidering my assessment of his sound judgment. But he wasn't joking. Rather, he stated that a blog post I wrote several years ago inspired him to adopt a habit which has now given his company a competitive advantage in recruiting talent. Specifically, he was referring to something that I had written way back in 2013: The importance of blogging for entrepreneurs….
Image credit: Pxfuel
During a return visit to France last month, I caught up with a successful French entrepreneur (whom I wish I would have backed on his first venture, but that's another story). Anyway, he opened the conversation with flattery, claiming that I had inspired him. So of course I'm growing suspicious at this point, either expecting a punch line or reconsidering my assessment of his sound judgment. But he wasn't joking. Rather, he stated that a blog post I wrote several years ago inspired him to adopt a habit which has now given his company a competitive advantage in recruiting talent.
Specifically, he was referring to something that I had written way back in 2013: The importance of blogging for entrepreneurs.
As I posited back then, regular blogging is about far more than shameless self-promotion; it's about communication of thoughts, transparency in opinions, and beta-testing ideas with the sounding board of your readers. Regular blogging exercises the muscles of intuition and creativity. It facilitates achieving clarity in your mind's eye, and it establishes you as a thought leader in your domain.
The fifth benefit I had cited in particular has proven especially relevant to this French entrepreneur I caught up with. Consistent blogging over the years is paying dividends to him now as his most effective recruiting tool.
The market for hiring talent, especially software developers, is insanely competitive right now across Europe, he told me. Startups are finding themselves outbid for developers by deep-pocketed incumbent companies, or increasingly, by other startups who have recently closed on massive fundraising rounds.
By having established his voice over the years through blogging, this guy inadvertently compiled a loyal following of readers who subscribe to the narrative of his ambition. Now, when he posts a job opening, he benefits from a ready-made audience. Better yet, candidates from this audience often prove to fit well culturally, because they've already been indoctrinated into his company's vision over the years.
Blogging is playing a long game. The fruits of it do not appear immediately, causing many people to abandon it prematurely. Yet this entrepreneur is now reaping the rewards of his long-term investment. Given today's war for talent, by accelerating the recruiting process and attracting individuals who are already on board with his project, the returns are astronomical.
Granted, the world has changed in the 8 years since I originally wrote that piece on the powers of blogging. There are other ways to evangelize and build a following as an entrepreneur. Podcasting, for example.
Creating something that does not rely on the approval of others can offer limitless upside. Naval Ravikant refers to this concept as permissionless leverage.
Code and media are permissionless leverage. They're the leverage behind the newly rich. You can create software and media that works for you while you sleep.
— Naval (@naval) May 31, 2018
I like this articulation and will adopt it too.
From Monozukuri Hub Meetup: DFM and prototype experts meet hardware startups
In conversation with WordPress.com parent Automattic CEO Matt Mullenweg
Japan's Lancers raises $9M from HR giant and bank, offers loans to freelance workers
Wwwaap
See the original story in Japanese. Tokyo-based Quan, the Japanese startup producing characters like Betakkuma and Business Fish for messaging stickers, has announced that it will merge with Wwwaap (pronounced 'warp'), an agency of cartoonists and influencers. The two companies will be merged by January of 2022 to establish a new company called Minto. Quan's CEO Kazuhiro Mizuno will be appointed as the CEO of the new company while Wwwaap's CEO Genta Nakagawa, Wwwaap's director Nobuyuki Takahashi, and Quan's director Jun Oagawa will join the new company's director board. In the U.S., influencing creators such as YouTubers, Instagramers, and Tiktokers are expanding their fan base all over the world, which has grown the creator economy up to over $104 billion US. Meanwhile, Japan's creator economy is centered on two-dimensional content, mainly on manga and anime illustration. Webtoons originally from South Korea has recently spread into the Japanese market, which lets Kakao Japan operating the Piccolo manga app become valued over $7 billion US by riding on the wave. We won't go into detail about Quan's business here because we've covered them many times while Wwwaap was founded in 2016 by Nakagawa, who started a manga editing team and an app…
Nobuyuki Takahashi (Co-CEO of Wwwaap), Kazuhiro Mizuno (CEO of Quan), Genta Nakagawa (Co-CEO of Wwwaap)
Image credits Quan, Wwwaap
See the original story in Japanese.
Tokyo-based Quan, the Japanese startup producing characters like Betakkuma and Business Fish for messaging stickers, has announced that it will merge with Wwwaap (pronounced 'warp'), an agency of cartoonists and influencers. The two companies will be merged by January of 2022 to establish a new company called Minto. Quan's CEO Kazuhiro Mizuno will be appointed as the CEO of the new company while Wwwaap's CEO Genta Nakagawa, Wwwaap's director Nobuyuki Takahashi, and Quan's director Jun Oagawa will join the new company's director board.
In the U.S., influencing creators such as YouTubers, Instagramers, and Tiktokers are expanding their fan base all over the world, which has grown the creator economy up to over $104 billion US. Meanwhile, Japan's creator economy is centered on two-dimensional content, mainly on manga and anime illustration. Webtoons originally from South Korea has recently spread into the Japanese market, which lets Kakao Japan operating the Piccolo manga app become valued over $7 billion US by riding on the wave.
We won't go into detail about Quan's business here because we've covered them many times while Wwwaap was founded in 2016 by Nakagawa, who started a manga editing team and an app marketing team at a major digital ad agency. With more than 250 creators, mainly manga and anime creators attracting fans through social network channels, the company has successfully monetized their content by making companies to use them for promotion. It claims that 80 to 90% of the manga illustrations used in Twitter ads in Japan are created by them. In other words, they can be called a multi-channel network for manga artists.
Nakagawa says,
In this industry, even if you are extremely talented (as an artist), you can't make a living. While there are many people quitting, we have succeeded in monetizing their works to tell them how much we can pay them if they have a certain number of followers. We have over than 250 manga artists having 10,000 followers, and some of them are housewives earning 10 million yen ($8.8 million US) a year.
By joining forces, the two companies are expected to create several complementary relationships. It allows Quan to distribute Wwwaap's creators' works through Quan's vast region-wide network in Asia while Wwwaap will be able to expand its sales channels. In addition to their own characters, Quon will be able to play a trader role in the distribution of third-party content.
Mizuno says,
Whether it's webtoon or animation, there are so many small productions are working here. It is true that this has created diversity, but in order to be strategic and dynamic business, a certain level of scale is necessary. If we only had our own characters, we would not be able to cover all the demands form clients. After subsiding the pandemic, it would be especially difficult to differentiate ourselves from other competitors from the rest of the world.
Some of characters and manga titles by Quan and wwwaap
Image credit: Quan, Wwwaap
Mizuno's and Nakagawa's different areas of expertise will complementary work. Despite several business models in hand Quan has been focused on monetizing by character merchandising as well as promotion use for companies in Asia after gaining popularity of unique characters through the use of free messaging stickers. Having successfully established his own business in Japan, Nakagawa expressed confidence in the business potential after the merger in terms of diversifying revenue stream in the region.
Allied Asia Pacific launches crowdsourced Facebook ad design platform ReFUEL4
YouTube opens its third global space for video creators in Tokyo
Japanese service brings manga characters to life with 3D printing
Japan's Flatt Security nabs $1.8M to help developers fix security issues in codes
Flatt Security
Kenro
Shisho
Tokyo-based cybersecurity startup Flatt Security announced on Monday that it has secured about 200 million yen (about $1.8 million US) in equity and loans from B Dash Ventures, FinTech Global, and an unnamed business company. For the startup, this follows their $2 million funding back in July of 2019. The latest round brought their total sum of funding up to date to 450 million yen (about $4 million). Under its previous name of Flatt, the company was founded in May of 2017 with most of its members from millennials attending the University of Tokyo. Initially, they had been developing a live commerce app called PinQul but subsequently pivoted to the cybersecurity business and rebranded themselves in 2019. Flatt Security currently provides vulnerability assessment service as well as a secure coding learning platform for web engineers called Kenro. The company is launching a new product called Shisho for the global market, aiming to eliminate the gap between product development and cybersecurity measure within a team. In the app development, we see sometimes a trade-off between security and usability, and also that between ensuring safety and enriching functionality. The company's solutions are designed to bridge the gap between app development engineers and…
The Flatt Security team
Image credit: Flatt Security
Tokyo-based cybersecurity startup Flatt Security announced on Monday that it has secured about 200 million yen (about $1.8 million US) in equity and loans from B Dash Ventures, FinTech Global, and an unnamed business company. For the startup, this follows their $2 million funding back in July of 2019. The latest round brought their total sum of funding up to date to 450 million yen (about $4 million).
Under its previous name of Flatt, the company was founded in May of 2017 with most of its members from millennials attending the University of Tokyo. Initially, they had been developing a live commerce app called PinQul but subsequently pivoted to the cybersecurity business and rebranded themselves in 2019.
Flatt Security currently provides vulnerability assessment service as well as a secure coding learning platform for web engineers called Kenro. The company is launching a new product called Shisho for the global market, aiming to eliminate the gap between product development and cybersecurity measure within a team.
In the app development, we see sometimes a trade-off between security and usability, and also that between ensuring safety and enriching functionality. The company's solutions are designed to bridge the gap between app development engineers and security management engineers, who are often completely separated in doing their jobs each other.
In addition to general cloud configuration and app diagnostics, Flatt Security offers diagnostics specific to the users of Firebase, one of popular no-code backend environment tools. When Japanese accounting company Freee acquired bookkeeping app Taxnote in June, Flatt Security's diagnostics were adopted for evaluation upon acquisition and throughout subsequent operations.
The company has been focused on consulting and a learning platform but is aiming to expand its business with greater scalability by launching a security product for developers around the world.
In Bridge's interview with Flatt Security's Chief Creative Officer Keijiro Toyoda, he says,
Shisho's goal is to create security tools that are easy for developers to use. Previous tools did not support modern technology stacks and did not support the latest diagnostic methods. […]
We would like to eliminate the gap between operating companies and security vendors which we have seen in the system development. First of all, we will closely work with ecosystems of developers, and eventually create a system that can suggest code fixes with just a single click.
Flatt Security hopes to expand Shisho's global reach by penetrating the developer community. In order to achieve this, the company has released the vulnerability detection and correction engine, which is the technical core of Shisho, as open source software, and also released the SaaS-based beta version of the product earlier this month. They plan to use the revenue from existing businesses and the funds from the latest round to accelerate the launch of the new product.
Japan's in-car security startup Trillium secures series A funding from Global Brain
Japanese startup unveils AI-powered rule sets solution to secure AWS-hosted websites
TalentEx offers online course for Russian developers to work with Japanese IT firms
(C) PR TIMES, Inc. All Rights Reserved.


Brie Williams, Anna Chang et al.
Python is a friendly and flexible programming language in widespread use everywhere from Fortune 500 companies to large-scale open-source projects. Python is an interpreted language: It translates code into bytecode (page 1087) at runtime and executes the bytecode within the Python virtual machine. Contrast Python with the C language, which is a compiled language. C differs from Python in that the C compiler compiles C source code into architecture-specific machine code. Python programs are not compiled; you run a Python program the same way you run a bash or Perl script. Because Python programs are not compiled, they are portable between operating systems and architectures. In other words, the same Python program will run on any system to which the Python virtual machine has been ported.
While not required to use the language, Python supports the object-oriented (OO) paradigm. It is possible to use Python with little or no understanding of object-oriented concepts, and this chapter covers OO programming minimally while still explaining Python's important features.
Python comes with hundreds of prewritten tools that are organized into logical libraries. These libraries are accessible to Python programs, but not loaded into memory at runtime because doing so would significantly increase startup times for Python programs. Entire libraries (or just individual modules) are instead loaded into memory when the program requests them.
This section discusses the methods you can use to run a Python program.
While you are using the Python interactive shell, you can give Python a command by entering the command and pressing RETURN. Use CONTROL-D to exit the shell.
Implied display does not work unless you are running the Python interactive shell (i.e., Python does not invoke an implicit display action when it is run from a file).
Most of the time a Python program is stored in a text file. Although not required, the file typically has a filename extension of .py. Use chmod (page 759) to make the file executable. As explained on page 297, the #! at the start of the first line of the file instructs the shell to pass the rest of the file to /usr/bin/python for execution.
You can also run a Python program by specifying the name of the program file as an argument or as standard input to python.
Because the shell interprets an exclamation point immediately followed by a character other than a SPACE as an event number (page 341), the final command includes a SPACE after the exclamation point.
Using the python –c option, you can run a program from the shell command line. In the preceding and following commands, the double quotation marks keep the shell from removing the single quotation marks from the command line before passing it to Python.
$ python -c "print 'Good morning! '"
You can use single quotation marks and double quotation marks interchangeably in a Python program, and you can use one to quote the other. When Python displays quotation marks around a string it uses single quotation marks.
From the Python interactive shell give the command help() to use the Python help feature. When you call it, this utility displays information to help you get started using it. Alternatively, you can give the command help('object') where object is the name of an object you have instantiated or the name of a data structure or module such as list or pickle.
Python makes it easy to write to standard output and read from standard input, both of which the shell (e.g., bash) connects to the terminal by default. The raw_input() function writes to standard output and reads from standard input. It returns the value of the string it reads after stripping the trailing control characters (RETURN-NEWLINE or NEWLINE).
In the following example, raw_input() displays its argument (Enter your name:) and waits for the user. When the user types something and presses RETURN, Python assigns the value returned by raw_input(), which is the string the user entered, to the variable my_in.
Additional downloadable libraries hold more functions. For more information refer to "Using Libraries" on page 599. Table 12-1 lists a few of the most commonly used functions.
Functions and methods are very similar. The difference is that functions stand on their own while methods work on and are specific to objects. You will see the range() function used by itself [range(args)] and the readall() method used as an object method [f.readall(args), where f is the object (a file) readall() is reading from]. Table 12-2 on page 585 and Table 12-4 on page 593 list some methods.
This section discusses some of the Python builtin data types. Scalar data types include number and string types. Compound data types include dictionary and list types.
A Python list is an object that comprises one or more elements; it is similar to an array in C or Java. Lists are ordered and use zero-based indexing (i.e., the first element of a list is numbered zero). A list is called iterable because it can provide successive elements on each iteration through a looping control structure such as for; see page 586 for a discussion.
You can access an element of a list by specifying its index (remember—the first element of a list is numbered zero). The first of the following commands displays the value of the third element of a; the next assigns the value of the first element of a to x and displays the value of x.
When you specify a negative index, Python counts from the end of the array.
You can replace an element of a list by assigning a value to it.
If you omit the number that follows the colon, Python displays from the element with the index specified before the colon through the end of the list. If you omit the number before the colon, Python displays from the beginning of the list up to the element with the number specified after the colon.
You can use negative numbers when slicing a list. The first of the following commands displays element 1 up to the last element of the list (element –1); the second displays from the next-to-last element of the list (element –2) through the end of the list.
The append(x) method appends an element whose value is x to the list, and increases the length of the list by 1.
reverse() The reverse() method does not take an argument. It is an efficient method that reverses elements of a list in place, overwriting elements of the list with new values.
sort() The sort() method does not take an argument. It sorts the elements in a list in place, overwriting elements of the list with new values.
sorted() If you do not want to alter the contents of the list (or other iterable data structure) you are sorting, use the sorted() function. This function returns the sorted list and does not change the original list.
len() The len() function returns the number of elements in a list or other iterable data structure.
Table 12-2 lists some of the methods that work on lists. The command help(list) displays a complete list of methods you can use with a list.
Python passes all objects, including lists, by reference. That is, it passes an object by passing a pointer to the object. When you assign one object to another, you are simply creating another name for the object; you are not creating a new object. When you change the object using either name, you can view the change using either name. In the following example, names is instantiated as a list that holds the values sam, max, and zach; copy is set equal to names, setting up another name for (reference to) the same list. When the value of the first element of copy is changed, displaying names shows that its first element has also changed.
When you use the syntax b = a[:] to copy a list, each list remains independent of the other. The next example is the same as the previous one, except copy2 points to a different location than names because the list was copied, not passed by reference: Look at the difference in the values of the first element (zero index) of both lists.
An important feature of lists is that they are iterable, meaning a control structure such as for (page 591) can loop (iterate) through each item in a list. In the following example, the for control structure iterates over the list a, assigning one element of a to item each time through the loop. The loop terminates after it has assigned each of the elements of a to item. The comma at the end of the print statement replaces the NEWLINE print normally outputs with a SPACE. You must indent lines within a control structure (called a logical block; page 588).
The next example returns the largest element in a list. In this example, the list is embedded in the code; see page 602 for a similar program that uses random numbers. The program initializes my_rand_list as a list holding ten numbers and largest as a scalar with a value of –1. The for structure retrieves the elements of my_rand_list in order, one each time through the loop. It assigns the value it retrieves to item. Within the for structure, an if statement tests to see if item is larger than largest. If it is, the program assigns the value of item to largest and displays the new value (so you can see how the program is progressing). When control exits from the for structure, the program displays a message and the largest number. Be careful when a logical block (a subblock) appears within another logical block: You must indent the subblock one level more than its superior logical block.
See page 603 for an easier way to find the maximum value in a list.
The following example instantiates and displays a telephone extension dictionary named ext. Because dictionaries are unordered, Python does not display a dictionary in a specific order and usually does not display it in the order it was created.
The items() method returns key–value pairs as a list of tuples (pairs of values). Because a dictionary is unordered, the order of the tuples returned by items() can vary from run to run.
Because dictionaries are iterable, you can loop through them using for.
Using this syntax, the dictionary returns just keys; it is as though you wrote for i in ext.keys(). If you want to loop through values, use for i in ext.values().
Control flow statements alter the order of execution of statements within a program. Starting on page 430, Chapter 10 discusses bash control structures in detail and includes flow diagrams of their operation. Python control structures perform the same functions as their bash counterparts, although the two languages use different syntaxes. The description of each control structure in this section references the discussion of the same control structure under bash.
In this section, the bold italic words in the syntax description are the items you supply to cause the structure to have the desired effect; the nonbold italic words are the keywords Python uses to identify the control structure. Many of these structures use an expression, denoted as expr, to control their execution. The examples in this chapter delimit expr using parentheses for clarity and consistency; the parentheses are not always required.
In most programming languages, control structures are delimited by pairs of parentheses, brackets, or braces; bash uses keywords (e.g., if...fi, do...done). Python uses a colon (:) as the opening token for a control structure. While including SPACEs (or TABs) at the beginning of lines in a control structure is good practice in other languages, Python requires these elements; they indicate a logical block, or section of code, that is part of a control structure. The last indented line marks the end of the control structure; the change in indent level is the closing token that matches the opening colon.
As with all Python control structures, the control block, denoted by ..., must be indented.
In the following example, my_in != '' (if my_in is not an empty string) evaluates to true if the user entered something before pressing RETURN. If expr evaluates to true, Python executes the following indented print statement. Python executes any number of indented statements that follow an if statement as part of the control structure. If expr evaluates to false, Python skips any number of indented statements following the if statement.
Program running, with or without your input.
If expr evaluates to true, Python executes the statements in the if control block. Otherwise, it executes the statements in the else control block. The following example builds on the previous one, displaying an error message and exiting from the program if the user does not enter something.
Program running with your input.
Program requires input to continue.
This control structure can include as many elif control blocks as necessary. In the following example, the if statement evaluates the Boolean expression following it within parentheses and enters the indented logical block below the statement if the expression evaluates to true. The if, elif, and else statements are part of one control structure and Python will execute statements in only one of the indented logical blocks.
The if and elif statements are each followed by a Boolean expression. Python executes each of their corresponding logical blocks only if their expression evaluates to true. If none of the expressions evaluates to true, control falls through to the else logical block.
The while control structure (page 447) evaluates a Boolean expression and continues execution while the expression evaluates to true. The following program, run using the Python interactive shell, displays 0 through 9. As you enter the command, Python displays its secondary prompt (...) when it requires more input to complete a statement; you must still enter SPACE or TAB characters to indent the logical block.
First, the program initializes count to 0. The first time through the loop, the while expression evaluates to true and Python executes the indented statements that make up the while control structure logical block. The comma at the end of the print statement causes print to output a SPACE instead of a NEWLINE after each string, and the count += 1 statement increments count each time through the loop. When control reaches the bottom of the loop, Python returns control to the while statement, where count is now 1. The loop continues while count is less than or equal to 10. When count equals 11, the while statement evaluates to false and control passes to the first statement after the logical block (the first statement that is not indented; there is none in this example).
It is easy to accidentally create an infinite loop using a while statement. Ensure that a reachable exit condition exists (e.g., a counter is compared to a finite value and the counter is incremented each time through the loop).
The for control structure (page 445) assigns values from a list, string, or other iterable data structure (page 586) to a loop index variable each time through the loop.
In the following example, lis is a list that holds the names of four types of animals. The for statement iterates through the elements of lis in order, starting with turkey, and assigning a value to nam each time it is called. The print statement in the logical block displays the value of nam each time through the loop. Python exits from the logical block when it runs out of elements in lis.
The next example demonstrates that strings are iterable. The string named string holds My name is Sam. and the for statement iterates through string, assigning one character to char each time through the loop. The print statement displays each character; the comma causes print to put a SPACE after each character instead of a NEWLINE.
M y   n a m e   i s  S a m .
The range() function returns a list that holds the integers between the two values specified as its arguments, including the first but excluding the last. An optional third parameter defines a step value.
The next example shows how to use range() in a for loop. In this example, range() returns a list comprising 0, 3, 6, and 9. The for control structure loops over these values, executing the indented statement each time through the loop.
The range() function is useful for generating short lists, but because it stores the list it returns in memory, it takes up a lot of system resources when it generates longer lists. In contrast, xrange() has a fixed memory footprint that is independent of the length of the list it returns; as a consequence, it uses fewer system resources than range() when working with long lists.
The two functions work differently. Whereas range() fills a list with values and stores that list in memory, xrange() works only when you iterate through the values it returns: The entire list is never stored in memory.
Python allows you to work with files in many ways. This section explains how to read from and write to text files and how to preserve an object in a file using pickle.
The open() function opens a file and returns a file object called a file handle; it can open a file in one of several modes (Table 12-3). Opening a file in w (write) mode truncates the file; use a (append) mode if you want to add to a file. The following statement opens the file in Max's home directory named test_file in read mode; the file handle is named f.
Read only Error if file does not exist.
Write only File is created if it does not exist. File is truncated if it exists.
Read and write File is created if it does not exist.
Append File is created if it does not exist.
Append and read File is created if it does not exist.
Binary Append to r or w to work with binary files.
Once the file is opened, you direct input and output using the file handle with one of the methods listed in Table 12-4. When you are finished working with a file, use close() to close it and free the resources the open file is using.
The following example reads from /home/max/test_file, which holds three lines. It opens this file in read mode and assigns the file handle f to the open file. It uses the readlines() method, which reads the entire file into a list and returns that list. Because the list is iterable, Python passes to the for control structure one line from test_file each time through the loop. The for structure assigns the string value of this line to ln, which print then displays. The strip() method removes whitespace and/or a NEWLINE from the end of a line. Without strip(), print would output two NEWLINEs: the one that terminates the line from the file and the one it automatically appends to each line it outputs. After reading and displaying all lines from the file, the example closes the file.
The next example opens the same file in append mode and writes a line to it using write(). The write() method does not append a NEWLINE to the line it outputs, so you must terminate the string you write to the file with a \n.
It is more efficient to iterate over the file handle directly because this technique does not store the file in memory.
An exception is an error condition that changes the normal flow of control in a program. Although you can try to account for every problem your code will need to deal with, it is not always possible to do so: Unknown circumstances might arise. What if the file the previous programs opened does not exist? Python raises an IOError (input/output error) number 2 and displays the message No such file or directory.
Instead of allowing Python to display what might be an incomprehensible error message and quit, a well-written program handles exceptions like this one gracefully. Good exception handling can help you debug a program and can also provide a nontechnical user with clear information about why the program failed.
The next example wraps the open statement that failed with an exception handler in the form of a try...except control structure. This structure attempts to execute the try block. If execution of the try block fails (has an exception), it executes the code in the except block. If execution of the try block succeeds, it skips the except block. Depending on the severity of the error, the except block should warn the user that something might not be right or should display an error message and exit from the program.
...     print "Error on opening the file."
Error on opening the file.
You can refine the type of error an except block handles. Previously, the open statement returned an IOError. The following program tests for an IOError when it attempts to open a file, displays an error message, and exits. If it does not encounter an IOError, it continues normally.
The pickle module allows you to store an object in a file in a standard format for later use by the same or a different program. The object you store can be any type of object as long as it does not require an operating system resource such as a file handle or network socket. The standard pickle filename extension is .p. For more information visit wiki.python.org/moin/UsingPickle.
The pickle module is not secure against maliciously constructed data. When you unpickle an object, you are trusting the person who created it. Do not unpickle an object if you do not know or trust its source.
It is critical that you open the file in binary mode (wb and rb). The load() method returns the object; you can assign the object the same name as or a different name from the original object. Before you can use pickle, you must import it (page 601).
The next example calls the Python interactive shell and pickle.load() reads the pres.p file in rb (read binary) mode. This method returns the object you originally saved using dump(). You can give the object any name you like.
The Python re (regular expression) module handles regular expressions. Python regular expressions follow the rules covered in Appendix A and are similar to Perl regular expressions, which are covered starting on page 562. This section discusses a few of the tools in the Python re library. You must give the command import re before you can use the re methods. To display Python help on the re module, give the command help() from the Python interactive shell and then type re.
where regex is the regular expression and string is the string you are looking for a match in.
Because findall() returns a list (it is iterable), you can use it in a for statement. The following example uses the period (.) special character, which, in a regular expression, matches any character. The regex (hi.) matches the three occurrences of hi followed by any character in the string.
search() The search() re method uses the same syntax as findall() and looks through string for a match to regex. Instead of returning a list if it finds a match, however, it returns a MatchObject. Many re methods return a MatchObject (and not a list) when they find a match for the regex in the string.
The group() method allows you to access the match a MatchObject holds.
When no match exists, search() returns a NoneType object [as shown by the type() function], which evaluates to None or in a Boolean expression evaluates to false.
Because a re method in a Boolean context evaluates to true or false, you can use a re method as the expression an if statement evaluates. The next example uses search() as the expression in an if statement; because there is a match, search() evaluates as true, and Python executes the print statement.
The match() method of the re object uses the same syntax as search() but looks only at the beginning of string for a match to regex.
You can pass arguments to a function in three ways. Assume the function place_stuff is defined as follows. The values assigned to the arguments in the function definition are defaults.
This section discusses the Python standard library, nonstandard libraries, and Python namespace, as well as how to import and use a function.
The Python standard library, which is usually included in packages installed with Python, provides a wide range of facilities, including functions, constants, string services, data types, file and directory access, cryptographic services, and file formats. Visit docs.python.org/library/index.html for a list of the contents of the standard library.
In some cases a module you want might be part of a library that is not included with Python. You can usually find what you need in the Python Package Index (PyPI; pypi.python.org), a repository of more than 22,000 Python packages. You can find lists of modules for the distribution you are using by searching the Web for distro package database, where distro is the name of the Linux distribution you are using, and then searching one of the databases for python.
Two popular libraries are SciPy and NumPy. The SciPy ("Sigh Pie"; scipy.org) library holds Python modules for mathematics, science, and engineering. It depends on NumPy (numpy.scipy.org), a library of Python modules for scientific computing.
You must download and install the package that holds NumPy before you can use any of its modules. Under Debian/Ubuntu/Mint and openSuSE, the package is named python-numpy; under Fedora/RHEL, it is named numpy. If you are running macOS, visit www.scipy.org/Installing_SciPy/Mac_OS_X. See Appendix C for instructions on downloading and installing packages. Alternatively, you can obtain the libraries from scipy.org or pypi.python.org. Once you import SciPy (import scipy), help(scipy) will list the functions you can import individually.
Although it is not good programming practice, later on in the program you could assign planets a string value. It would then be an object of type string.
You could make planets a function, a list, or another type of object. Regardless, there would always be only one object named planets (identifiers in a namespace must be unique).
The next section discusses different ways you can import objects from a library and steps you can take to avoid the preceding problem.
You can import a module in one of several ways. How you import the module determines whether Python merges the namespace of the module with that of your program.
The simplest thing to do is to import the whole module. In this case Python does not merge the namespaces but allows you to refer to an object from the module by prefixing its name with the name of the module. The following code imports the random module. Using this syntax, the function named sample is not defined: You must call it as random.sample.
This setup allows you to define your own function named sample. Because Python has not merged the namespaces from your program and the module named random, the two functions can coexist.
Another way to import a module is to specify the module and the object.
When you import an object using this syntax, you import only the function named sample; no other objects from that module will be available. This technique is very efficient. However, Python merges the namespaces from your program and from the object, which can give rise to the type of problem illustrated in the previous section.
You can also use from module import *. This syntax imports all names from module into the namespace of your program; it is generally not a good idea to use this technique.
The my_max.py program on page 586 finds the largest element in a predefined list. The following program works the same way, except at runtime it fills a list with random numbers.
The following command imports the sample() function from the standard library module named random. You can install an object from a nonstandard library, such as NumPy, the same way.
where list is a list holding the population, or values sample() can return, and number is the number of random numbers in the list sample() returns.
The algorithm used in this example is not the most efficient way of finding the maximum value in a list. It is more efficient to use the max() builtin function.
You can use a list comprehension to perform the same task neatly and efficiently. The syntax is similar, but a list comprehension is enclosed within square brackets and the operation (x + 10) precedes the iteration [for x in range(10)].
The next list comprehension fills a list with even numbers. The if clause returns values only if the remainder after dividing a number by 2 is 0 (if x % 2 == 0).
The final example shows nested list comprehensions. It nests for loops and uses x + y to catenate the elements of both lists in all combinations.
Python is an interpreted language: It translates code into bytecode at runtime and executes the bytecode within the Python virtual machine. You can run a Python program from the Python interactive shell or from a file. The Python interactive shell is handy for development because you can use it to debug and execute code one line at a time and see the results immediately. Within the Python interactive shell, Python displays output from any command line that does not have an action. From this shell you can give the command help() to use the Python help feature or you can give the command help('object') to display help on object.
Functions help improve code readability, efficiency, and expandability. Many function are available when you first call Python (builtin functions) and many more are found in libraries that you can download and/or import. Methods are similar to functions except they work on objects whereas functions stand on their own. Python allows you to define both normal functions and nameless functions called Lambda functions.
Python enables you to read from and write to files in many ways. The open() function opens a file and returns a file object called a file handle. Once the file is opened, you direct input and output using the file handle. When you are finished working with a file, it is good practice to close it. The pickle module allows you to store an object in a file in a standard format for later use by the same or a different program.
A Python list is an object that comprises one or more elements; it is similar to an array in C or Java. An important feature of lists is that they are iterable, meaning a control structure such as for can loop (iterate) through each item in a list. A Python dictionary holds unordered key–value pairs in which the keys are unique. Like lists, dictionaries are iterable.
Python implements many control structures, including if...else, if...elif...else, while, and for. Unlike most languages, Python requires SPACEs (or TABs) at the beginning of lines in a control structure. The indented code marks a logical block, or section of code, that is part of the control structure.
Python regular expressions are implemented by the Python re (regular expression) module. You must give the command import re before you can use the re methods.
1. What is meant by implied display? Is it available in the Python interactive shell or from a program file? Provide a simple example of implied display.
2. Write and run a Python program that you store in a file. The program should demonstrate how to prompt the user for input and display the string the user entered.
3. Using the Python interactive shell, instantiate a list that holds three-letter abbreviations for the first six months of the year and display the list.
5. Using the Python interactive shell, put the elements of the list you instantiated in exercise 3 in alphabetical order.
6. Instantiate a dictionary in which the keys are the months in the third quarter of the year and the values are the number of days in the corresponding month. Display the dictionary, the keys, and the values. Add the tenth month of the year to the dictionary and display the value of that month only.
7. What does iterable mean? Name two builtin objects that are iterable. Which control structure can you use to loop through an iterable object?
8. Write and demonstrate a Lambda function named stg() that appends .txt to its argument. What happens when you call the function with an integer?
11. Create a list that has four elements. Make a copy of the list and change one of the elements in the copy. Show that the same element in the original list did not change.
12. Why does the following assignment statement generate an error?
14. Use a list comprehension to display the numbers from 1 through 30 inclusive that are divisible by 3.
15. Write a function that takes an integer, val, as an argument. The function asks the user to enter a number. If the number is greater than val, the function displays Too high. and returns 1; if the number is less than val, the function displays Too low. and returns –1; if the number equals val, the function displays Got it! and returns 0. Call the function repeatedly until the user enters the right number.
The string "The rain in Spain" has  17 characters in it.
Enter some words: Go East young man!
The string "Go East young man!" has  6 vowels in it.
Enter some words: The sun rises in the East and sets in the West.
13 letters in 47 are vowels.
One way or another you are sitting in front of a screen that is connected to a computer running Linux. You might be working with a graphical user interface (GUI) or a textual interface. This book is about the textual interface, also called the command-line interface (CLI). If you are working with a GUI, you will need to use a terminal emulator such as xterm, Konsole, GNOME Terminal, Terminal (under macOS), or a virtual console (page 44) to follow the examples in this book.
This chapter starts with a discussion of the typographical conventions used in this book, followed by a section about logging in on the system. The next section introduces the shell and explains how to fix mistakes on the command line and repeat previous command lines. Next come a brief reminder about the powers of working with root privileges and suggestions about how to avoid making mistakes that will make your system inoperable or hard to work with. The chapter continues with a discussion about where to find more information about Linux. It concludes with additional information on logging in, including how to change your password.
Be sure to read the warning on page 32 about the dangers of misusing the powers of working with root privileges. While heeding that warning, feel free to experiment with the system: Give commands, create files, follow the examples in this book, and have fun.
This book uses conventions to make its explanations shorter and clearer. The following paragraphs describe these conventions.
References to macOS refer to version 10.12 (Sierra). Because the book focuses on the underlying operating system, which changes little from one release of macOS to the next, the text will remain relevant through several future releases.
Everything you enter at the keyboard is shown in a bold typeface. Within the text, this bold typeface is used; within examples and screens, this one is used. In the previous example, the dollar sign ($) on the first line is a prompt that Linux displays, so it is not bold; the remainder of the first line is entered by a user, so it is bold.
Names of utilities are printed in this sans serif typeface. This book references the emacs text editor and the ls utility or ls command (or just ls) but instructs you to enter ls –a on the command line. In this way the text distinguishes between utilities, which are programs, and the instructions you enter on the command line to invoke the utilities.
Filenames appear in a bold typeface. Examples are memo5, letter.1283, and reports. Filenames might include uppercase and lowercase letters; however, Linux is case sensitive (page 1088), so memo5, MEMO5, and Memo5 name three different files.
The default macOS filesystem, HFS+, is not case sensitive; under macOS, memo5, MEMO5, and Memo5 refer to the same file. For more information refer to "Case Sensitivity" on page 1070.
Within the text, characters and character strings are marked by putting them in a bold typeface. This convention avoids the need for quotation marks or other delimiters before and after a string. An example is the following string, which is displayed by the passwd utility: Sorry, passwords do not match.
• Keyboard keys, such as the SPACE bar and the RETURN,1 ESCAPE, and TAB keys.
• The characters that keys generate, such as the SPACEs generated by the SPACE bar.
Most examples include the shell prompt—the signal that Linux is waiting for a command—as a dollar sign ($), a hashmark (#), or sometimes a percent sign (%). The prompt does not appear in a bold typeface in this book because you do not enter it. Do not type the prompt on the keyboard when you are experimenting with examples from this book. If you do, the examples will not work.
To use this example as a model for running the vim text editor, enter the command vim memo.1204 (some systems use vim.tiny in place of vim) and press the RETURN key. (Press ESCAPE ZZ to exit from vim; see page 167 for a vim tutorial.) This method of displaying commands makes the examples in the book correspond to what appears on the screen.
Online Dictionary of Computing (foldoc.org), and are used with permission. This site is an ongoing work containing definitions, anecdotes, and trivia.
1. Different keyboards use different keys to move the cursor (page 1093) to the beginning of the next line. This book always refers to the key that ends a line as the RETURN key. The keyboard you are using might have a RET, NEWLINE, ENTER, RETURN, or some other key. Use the corresponding key on your keyboard each time this book asks you to press RETURN.
Passages marked as optional appear in a gray box. This material is not central to the ideas presented in the chapter and often involves more challenging concepts. A good strategy when reading a chapter is to skip the optional sections and then return to them when you are comfortable with the main ideas presented in the chapter. This is an optional paragraph.
Web addresses, or URLs, have an implicit http:// prefix, unless ftp:// or https:// is shown. You do not normally need to specify a prefix when the prefix is http://, but you must use a prefix in a browser when you specify an FTP or secure HTTP site. Thus you can specify a URL in a browser exactly as it is shown in this book.
This book uses the output of ls –l commands, such as produced by including the option –-time-style=iso. This option produces shorter lines, making the examples more readable.
The following boxes highlight information that might be helpful while you are using or administrating a Linux system.
A tip box might help you avoid repeating a common mistake or might point toward additional information.
A caution box warns you about a potential pitfall.
A security box highlights a potential security issue. These notes are usually intended for system administrators, but some apply to all users.
The issue message is followed by a prompt to log in. Enter your username and password in response to the system prompts. Make sure you enter your username and password as they were specified when your account was set up; the routine that verifies the username and password is case sensitive. Like most systems, Linux does not display your password when you enter it. By default macOS does not allow remote logins (page 1076).
If you are using a terminal (page 1128) and the screen does not display the login: prompt, check whether the terminal is plugged in and turned on, and then press the RETURN key a few times. If login: still does not appear, try pressing CONTROL-Q (Xon).
Security: Did you log in last?
As you are logging in to a textual environment, after you enter your username and password, the system displays information about the last login on this account, showing when it took place and where it originated. You can use this information to determine whether anyone has accessed the account since you last used it. If someone has, perhaps an unauthorized user has learned your password and logged in as you. In the interest of maintaining security, advise the system administrator of any circumstances that make you suspicious and change your password.
If you are using a Mac, PC, another Linux system, or a workstation (page 1133), open the program that runs ssh (secure; page 980), telnet (not secure; page 1001), or whichever communications/emulation software you use to log in on the system, and give it the name or IP address (page 1104) of the system you want to log in on.
One of the reasons telnet is not secure is that it sends your username and password over the network in cleartext (page 1090) when you log in, allowing someone to capture your login information and log in on your account. The ssh utility encrypts all information it sends over the network and, if available, is a better choice than telnet. The ssh program has been implemented on many operating systems, not just Linux. Many user interfaces to ssh include a terminal emulator.
In the example Max mistyped his password, received an error message and another prompt, and then retyped the password correctly. If your username is the same on the system you are logging in from and the system you are logging in on, you can omit your username and the following at sign (@). In the example, Max could have given the command ssh tiny.
After you log in, the shell prompt (or just prompt) appears, indicating you have successfully logged in; it shows the system is ready for you to give a command. The first shell prompt might be preceded by a short message called the message of the day, or motd, which is stored in the /etc/motd file.
The usual prompt is a dollar sign ($). Do not be concerned if you have a different prompt; the examples in this book will work regardless of which prompt the system displays. In the previous example, the $ prompt (last line) is preceded by the username (max), an at sign (@), the system name (tiny), and the name of the directory Max is working in (max). For information on how to change the prompt, refer to page 319 (bash) or page 403 (tcsh).
The TERM shell variable establishes the pseudographical characteristics of a character-based terminal or terminal emulator. Typically TERM is set for you—you do not have to set it manually. If things on the screen do not look right, refer to "Specifying a Terminal" on page 1050.
Before the introduction of the graphical user interface, UNIX and then Linux provided only a textual (command-line) interface. Today, a textual interface is available when you log in from a terminal, a terminal emulator, or a textual virtual console, or when you use ssh or telnet to log in on a system.
Although the concept might seem antiquated, the textual interface has a place in modern computing. In some cases an administrator might use a command-line tool either because a graphical equivalent does not exist or because the graphical tool is not as powerful or flexible as the textual one. For example, chmod (pages 102 and 759) is more powerful and flexible than its GUI counterpart. Frequently, on a server system, a graphical interface might not even be installed. The first reason for this omission is that a GUI consumes a lot of system resources; on a server, those resources are better dedicated to the main task of the server. Additionally, security considerations mandate that a server system run as few tasks as possible because each additional task can make the system more vulnerable to attack.
You can also write scripts using the textual interface. Using scripts, you can easily reproduce tasks on multiple systems, enabling you to scale the tasks to larger environments. When you are the administrator of only a single system, using a GUI is often the easiest way to configure the system. When you act as administrator for many systems, all of which need the same configuration installed or updated, a script can make the task go more quickly. Writing a script using command-line tools is frequently easy, whereas the same task can be difficult to impossible using graphical tools.
Before the introduction of GUIs, resourceful programmers created textual interfaces that included graphical elements such as boxes, borders outlining rudimentary windows, highlights, and, more recently, color. These textual interfaces, called pseudographical interfaces, bridge the gap between textual and graphical interfaces. The Midnight Commander file management utility (mc; page 902) is a good example of a utility with a well-designed pseudographical interface.
Either way, this output shows you are running bash. If you are running a different shell, the shell will display appropriate output.
This section explains how to correct typographical and other errors you might make while you are logged in on a textual display. Because the shell and most other utilities do not interpret the command line or other text you enter until you press RETURN, you can readily correct a typing mistake before you press RETURN.
You can correct such mistakes in several ways: Erase one character at a time, back up a word at a time, or back up to the beginning of the line in one step. After you press RETURN, it is too late to correct a mistake: At that point, you must either wait for the command to run to completion or abort execution of the program (next page).
While entering characters from the keyboard, you can back up and erase a mistake by pressing the erase key once for each character you want to delete. The erase key backs over as many characters as you wish. It does not, in general, back up past the beginning of the line.
2. The command stty is an abbreviation for set teletypewriter, the first terminal UNIX ran on. Today stty is commonly thought of as meaning set terminal.
Alternatively, you can give the next command to reset most terminal parameters to a sane value. If the RETURN key does not move the cursor to the next line, press CONTROL-J instead.
See page 989 for more examples of using stty.
You can delete a word you entered by pressing CONTROL-W. A word is any sequence of characters that does not contain a SPACE or TAB. When you press CONTROL-W, the cursor moves left to the beginning of the current word (as you are entering a word) or the previous word (when you have just entered a SPACE or TAB), removing the word.
Although it is not a way of correcting a mistake, you might press the suspend key (typically CONTROL-Z) by mistake and wonder what happened. If you see a message containing the word Stopped, you have just stopped your job using job control (page 151). If you give the command fg to continue your job in the foreground, you should return to where you were before you pressed the suspend key. For more information refer to "bg: Sends a Job to the Background" on page 306.
Sometimes you might want to terminate a running program. For example, you might want to stop a program that is performing a lengthy task such as displaying the contents of a file that is several hundred pages long or copying a large file that is not the one you meant to copy.
To terminate a program from a textual display, press the interrupt key (CONTROL-C or sometimes DELETE or DEL). When you press this key, the Linux operating system sends a TERM (termination) signal to the program you are running and to the shell. Exactly what effect this signal has depends on the program. Some programs stop execution immediately, some ignore the signal, and some take other actions. When the shell receives a TERM signal, it displays a prompt and waits for another command.
If these methods do not terminate the program, try sending the program a QUIT signal (CONTROL-\). If all else fails, try pressing the suspend key (typically CONTROL-Z), giving a jobs command to verify the number of the job running the program, and using kill to abort the job. The job number is the number within the brackets at the left end of the line displayed by jobs (). In the next example, the kill command (pages 152 and 866) uses –TERM to send a TERM signal to the job specified by the job number, which is preceded by a percent sign (%1). You can omit –TERM from the command, as kill sends a TERM signal by default. Table 10-5 on page 496 lists some signals.
When the termination signal does not work, use the KILL signal (specify –KILL in place of –TERM in the example). A running program cannot ignore a KILL signal; it is sure to abort the program.
Because a program receiving a KILL signal has no chance to clean up its open files before being terminated, using KILL can corrupt application data. Use the KILL signal as a last resort. Before using KILL, give a termination (TERM) or quit (QUIT) signal a full ten seconds to take effect.
The kill command returns a prompt; you might need to press RETURN again to see the confirmation message. For more information refer to "Running a Command in the Background" on page 150.
To repeat a previous command, press the UP ARROW key. Each time you press this key, the shell displays an earlier command line. Press the DOWN ARROW key to browse through the command lines in the other direction. To reexecute the displayed command line, press RETURN.
The RIGHT ARROW and LEFT ARROW keys move the cursor back and forth along the displayed command line. At any point along the command line, you can add characters by typing them. Use the erase key (page 29) to remove characters from the command line. Press RETURN to execute the modified command.
You can also repeat the previous command using !!. This technique is useful if you forgot to use su (next page) to prefix a command. In this case, if you type su –c "!!", the shell will run the previous command with root privileges. Or, if the local system is set up to use sudo (next page), you can type sudo !! and the shell will run the previous command with root privileges.
The command ^old^new^ reruns the previous command, substituting the first occur-rence of the string old with new. Also, on a command line, the shell replaces the characters !$ with the last token (word) on the previous command line. The following example shows the user correcting the filename meno to memo using ^n^m^ and then printing the file named memo by giving the command lpr !$. The shell replaces !$ with memo, the last token on the previous command line.
This is the memo file.
For information about more complex command-line editing, see page 338.
UNIX and Linux systems have always had a privileged user named root. When you are working as the root user ("working with root privileges"), you have extraordinary systemwide powers. A user working with root privileges is sometimes referred to as Superuser or administrator. When working with root privileges, you can read from or write to almost any file on the system, execute programs that ordinary users cannot, and more. On a multiuser system you might not be permitted to gain root privileges and so might not be able to run certain programs. Nevertheless, someone—the system administrator—can, and that person maintains the system.
Feel free to experiment when you are not working with root privileges. When you are working with root privileges, do only what you have to do and make sure you know exactly what you are doing. After you have completed the task at hand, revert to working as yourself. When working with root privileges, you can damage the system to such an extent that you will need to reinstall Linux to get it working again.
The first command in the preceding example shows that a user who is not working with root privileges is not permitted to list the files in the /lost+found directory: ls displays an error message. The second command uses su with the –c (command) option to execute the same command with root privileges. Single quotation marks enclose the command to ensure the shell interprets the command properly. When the command finishes executing (ls shows there are no files in the directory), the user no longer has root privileges.
Without any arguments, su spawns a new shell running with root privileges. Typically the shell displays a hashmark (#) prompt when you are working with root privileges. Give an exit command to return to the normal prompt and nonroot privileges.
With an argument of –s, sudo spawns a new shell running with root privileges. Typically the shell displays a hashmark (#) prompt when you are working with root privileges. Give an exit command to return to the normal prompt and nonroot privileges.
Distributions of Linux typically do not come with hardcopy reference manuals. However, its online documentation has always been one of Linux's strengths. The man (or manual) and info pages have been available via the man and info utilities since early releases of the operating system. Not surprisingly, with the ongoing growth of Linux and the Internet, the sources of documentation have expanded as well. This section discusses some of the places you can look for information on Linux. See also Appendix B.
To find out more about a utility, give the command man, followed by the name of the utility. Figure 2-1 shows man displaying information about itself; the user entered a man man command.
• Press the SPACE bar to display another screen of text.
• Press PAGE UP, PAGE DOWN, UP ARROW, or DOWN ARROW to navigate the text.
• Press h (help) to display a list of less commands.
• Press q (quit) to stop less and cause the shell to display a prompt.
You can search for topics covered by man pages using the apropos utility (next page).
This layout closely mimics the way the set of UNIX manuals has always been divided. Unless you specify a manual section, man displays the earliest occurrence in the manual of the word you specify on the command line. Most users find the information they need in sections 1, 6, and 7; programmers and system administrators frequently need to consult the other sections.
The preceding command instructs man to look only in section 5 for the man page. In documentation you might see this man page referred to as passwd(5). Use the –a option (see the adjacent tip) to view all man pages for a given subject (press qRETURN to display each subsequent man page). For example, give the command man –a passwd to view all man pages for passwd.
An option modifies the way a utility works. Options are usually specified as one or more letters that are preceded by one or two hyphens. An option typically appears following the name of the utility you are calling and a SPACE. Other arguments (page 1083) to the command follow the option and a SPACE. For more information refer to "Options" on page 131.
When you do not know the name of the command required to carry out a particular task, you can use apropos with a keyword to search for it. This utility searches for the keyword in the short description line of all man pages and displays those that contain a match. The man utility, when called with the –k (keyword) option, provides the same output as apropos.
The database apropos uses, named mandb or makewhatis, is not available when a system is first installed but is built automatically by cron or crond (see crontab on page 781 for a discussion of cron/crond).
The following example shows the output of apropos when you call it with the who keyword. The output includes the name of each command, the section of the manual that contains it, and the short description from the man page. This list includes the utility you need (who) and identifies other, related tools you might find useful.
w (1)              - Show who is logged on and what they are doing.
The textual info utility (www.gnu.org/software/texinfo) is a menu-based hypertext system developed by the GNU project (page 3) and distributed with Linux. It includes a tutorial on itself (give the command info info) and documentation on many Linux shells, utilities, and programs developed by the GNU project. Figure 2-2 shows the screen that info displays when you give the command info coreutils (the coreutils soft-ware package holds the Linux core utilities).
The info utility displays more complete and up-to-date information on GNU utilities than does man. When a man page displays abbreviated information on a utility that is covered by info, the man page refers to info. The man utility frequently displays the only information available on non-GNU utilities. When info displays information on non-GNU utilities, it is frequently a copy of the man page.
The notation info uses to describe keyboard keys is the same notation emacs uses and might not be familiar to you. For example, the notation C-h is the same as CONTROL-H.
Similarly, M-x means hold down the META or ALT key and press x. (On some systems you need to press ESCAPE and then x to duplicate the function of META-X.) For more information refer to "Keys: Notation and Use" on page 231.
After giving the command info coreutils, press the SPACE bar a few times to scroll through the display. Type /sleepRETURN to search for the string sleep. When you type /, the cursor moves to the bottom line of the window and displays Regexp search [string]:, where string is the last string you searched for. Press RETURN to search for string or enter the string you want to search for. Typing sleep displays sleep on that line, and pressing RETURN displays the next occurrence of sleep.
The pinfo utility is similar to info but is more intuitive if you are not familiar with emacs editor commands. This utility runs in a textual environment, as does info. When it is available, pinfo uses color to make its interface easier to use. If pinfo is not installed on the system, install the pinfo package as explained in Appendix C.
Now type /RETURN (or /sleepRETURN) to search for the next occurrence of sleep as shown in Figure 2-3. The asterisk at the left end of the line indicates that this entry is a menu item. Following the asterisk is the name of the menu item and a description of the item.
Each menu item is a link to the info page that describes the item. To jump to that page, search for or use the ARROW keys to move the cursor to the line containing the menu item and press RETURN. With the cursor positioned as it is in Figure 2-3, press RETURN to display information on sleep. Alternatively, you can type the name of the menu item in a menu command to view the information: To display information on sleep, for example, you can give the command m sleep, followed by RETURN. When you type m (for menu), the cursor moves to the bottom line of the window (as it did when you typed /) and displays Menu item:. Typing sleep displays sleep on that line, and pressing RETURN displays information about the menu item you specified.
Figure 2-5 shows the top node of information on sleep. A node groups a set of information you can scroll through by pressing the SPACE bar. To display the next node, press n. Press p to display the previous node.
As you read through this book and learn about new utilities, you can use man or info to find out more about those utilities. If the local system can print PostScript documents, you can print a manual page by using the man utility with the –t option. For example, man –t cat | lpr prints information about the cat utility. You can also use a Web browser to display the documentation at one of the sites listed in Appendix B and then print the desired information from the browser.
Another tool you can use in a textual environment is the ––help option. Most GNU utilities provide a ––help option that displays information about the utility. A nonGNU utility might use a –h or –help option to display information about itself.
otherwise the list of help topics is printed.
Execute commands as long as a test succeeds.
This section describes several methods you can use to get help with a Linux system and lists some helpful Web sites. See also Appendix B.
The Internet provides many helpful sites related to Linux and macOS. Aside from sites that offer various forms of documentation, you can enter an error message from a program you are having a problem with in a search engine such as Google (www.google.com). The search will likely yield a post concerning your problem and suggestions about how to solve it. See Figure 2-5.


I often dream about snakes wanting to attack me. In my dream I'm very scared, but there are also other people trying to get rid of those snakes and trying to protect me. But interesting is those snakes feel I'm scared and going only after me.
Dreams have been mentioned in our religion's Holy Book. Therefore I believe in their interpretation. But few of them are Divine others may or may not be from Satan. & it's not at all necessary that every dream has meaning. The one you've mentioned might be due to some fear that resides in you & that's it.
Hi Sebastian, thank you for your comment.
I only know if dog attacks you in dream it means a fight or end of friendship with a friend. Can't say about snakes. Maybe something similar.
I am a firm believer that dreams have meanings, especially objects that you see in dreams such as the snakes that you see or umbrellas or staircases for example. In regards to your dream, snakes are known to have many different meanings. These meanings can range from fear you have in your life all the way to a person in your life who is acting like a "snake" meaning they are sneaky and manipulative.
Thank you so much, someone told me snakes can mean enemy, just wanted to know more about it. Thank you again.
Thank you for your comment. I was reading your post while having my coffee, very interesting and helpful. Actually I'm gonna read it one more time, it is a great hub. Well done!
Well being big on dreams, I do believe that there is such a thing as dream interpretation. I actually wrote a hub relating to my experiences on dreams. My thoughts and opinions.
The reality of my dreams are never to a tee of my dream, they always symbolize a sign or message. As most do.
However I have had dreams that I never had before and am usually guided to the place where I can find the answer.
I believe God/angels give us dreams to warn us of a hidden message. I do not myself really believe in trying to rack your brain trying to remember the dream. IF you are given the dream for a hidden message you will remember it. If not then it wasnt important as of yet.
However what one dream means to someone may not be the same definition to someone else. It all depends on what is going on in our lives. Sometimes it depends on your days activity.
Two people can have the same dream and it will mean entirely different things to each person.
I always have pre cognitive dreams and always always remember them for years.
I know the future is not written in stone however in general my dreams have always been messages to me about my life.


text:
Q: how to create a dynamic port forwarding with several hops? If we have a following situation:
[laptop] ---- [host1] ---- [host2] ----[target]
where host1 is reachable from the my laptop machine, host2 from host1 and the target from host2 only. We have ssh credentials to both host1 and host2.
We can use the dynamic port forwarding with the following command:
ssh -N -D 127.0.0.1:8282 host1_account@host1
and that will basically create a SOCKS4 that we can use with proxychains so that command will work from the kali device:
proxychains ssh host2_account@host2
How we can make a similar (additional?) dynamic tunnel from host2 to target?

A: Make sure you're on OpenSSH 7.3 or later, and use SSH's ProxyJump feature: ssh -J host1_account@host1 -D 127.0.0.1:8282 host2_account@host2. That will give you an SSH session on host2, and 127.0.0.1:8282 will proxy traffic out through host2.

redpajama_set_name: RedPajamaStackExchange


text:
Roma Hall, Club Indigo, and Jazz
by Kim Rush, John Russo, and Martin Starr
Dances and floorshows held at Roma Hall commonly featured African-American entertainers. Herman Curtis was probably the first African-American musician to reside in and perform jazz music in Grand Rapids, as early as 1920. Curtis was a South Bend conservatory trained musician, playing both violin and upright bass. He was introduced in 1935 Roma Hall ads as "The Clown Prince of Jazz." This was definitely a derivative title, yet accurately foreshadows his humorous personality and comical stage performances. The band names, which he used over the course of his career, such as Curtis Satonic 9-Piece Band of Grand Rapids, the Dusky Devastators of the Depression, Chocolate Vagabonds, NBC (Nobody But Curtis), and Herman Curtis and the Jazz Hounds also display his playfulness. During his lifetime he served as an auto mechanic, chauffeur, a boat captain, and had a truck body repair and painting business. For his truck-related business he utilized the last name of Curtisma in order that his advertising would appeal to the predominant Dutch community!
In the late 1930s, Mrs. Floyd H. Skinner composed a column that covered social events staged by Grand Rapids' African-American community. Her column was posted regularly in the Chicago Defender newspaper. Her 9.26.36 article announced the opening of "The Club Indigo, Inc. …organized for the social, athletic, and civic advancement of our group. It is intended that a first class nightclub will be opened in the near future where its members and their guests may enjoy meals, beer, mixed drinks, and dancing in a refined atmosphere. Mr. Milo M. Brown, popular local undertaker, is president and manager of said Club, and announces that the club, located at 746 South Division Avenue, will be open for business in the very near future." [1]
The entertainment provided at Club Indigo's frequent dances resembled popular "floor shows" of that time period, similar to Idlewild's presentations or other venues located on the "chitlin circuit." Grand Rapid's Pierson Smith served shortly as their first M.C. Johnny Edwards, from Idlewild's Paradise Club eventually served in this same capacity. They booked talent from Lansing, Saginaw, Battle Creek, Texas, Chicago, Kansas City, Detroit, St. Louis, and New York City, though not nationally renowned acts. At that time, Roma Hall was less than 2,000 square feet, and could not have accommodated a huge crowd. This venue was generally open three to four nights per week, and was operated by the Club Indigo, not the Russo family. Jenny Russo: "Club Indigo paid my father rent for the hall. They brought in entertainment, and had their own cook."
An African American theatrical company from Chicago performed a musical comedy entitled "Shuffle Along" at Keith Theater located at 113-121 Lyon N.W. in Grand Rapids on 1.19.37. Later that evening, the entire cast was invited to Club Indigo and provided entertainment for the audience. One member of the cast was an eighteen-year-old pianist from Chicago named Nat ("King") Cole. His band also played that night, though this was well before he enjoyed his highly successful recording career. [2]
As late as 4.1.39, Mrs. Skinner's column spoke of Club Indigo being "beautifully redecorated and remodeled and open nightly under new management." It appears to have operated at Roma Hall until at least February of 1940. Their listings in the Grand Rapids city directories disappear in 1940. According to a Crisis magazine article from April of 1939, Club Indigo sponsored a charity dance for the Grand Rapids Youth Council, although the specific location of this event was not mentioned.[3] Music for this event was furnished by the Club Indigo Orchestra and the Federal Music Project (WPA) band.
Gene Seals performed with the local WPA (Works Project Administration) band and served temporarily as leader of the Club Indigo house band. Arnold Allen and Bennie Carew also assumed the role of house bandleader, though it has not been documented that they were members of the WPA band. From 1935-1943 the WPA created both an African-American and white jazz band in Grand Rapids under the auspices of the FMP (Federal Music Project). Numerous quality jazz musicians were drawn to Grand Rapids to apply for these paying positions. One objective of the FMP was to eliminate segregation of workers based on race. The original intent of the program was to create only one band in various designated cities. Inter-racial bands generally worked well together, but it was found that establishments in some regions refused to hire black musicians. As a result, in markets such as Detroit and Grand Rapids, a separate African American band was created. A few of the members of the Grand Rapids WPA African-American band were Gene Seals, Burt Benton, Burt Brasier, Bernie Peacock, and Ham Allen.
[1] Chicago Defender 9.26.1936. Mrs. Floyd Skinner columns, located in the Chicago Defender newspaper from 1936 to 1939, are the most complete and informative documents concerning Club Indigo history that I have located so far.
[2] Chicago Defender 2.6.37.
[3] Crisis Magazine April 1939
Related Items displaying 3 out of 16 total, view all
Russo's Roma Hall
Club Indigo
Frank Lamar and his Dog
Jerry Lamar at Club Indigo, Roma Hall
Chicky Candy Bar Giants with Frank Lamar
Women with Sport Trophies
Floyd Skinner at Roma Hall/Club Indigo
Band at Crispus Attucks Post
Herman Curtis Orchestra
Beginning of Roma Hall
Roma Hall and Prohibition
Widening South Division Avenue
Genoa Cafe and Roma Hall
Club Indigo (Roma Hall)
"Chitlin' Circuit" Performers Come to Roma Hall
G.B.'s Brother, Joe, Carries on the Tradition

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: AppWidgetManager.ACTION_APPWIDGET_BIND always returns Activity.RESULT_CANCELED I am building a custom launcher. I have followed the steps
mentioned in the Android documentation for hosting App Widgets as well as browsing
the default Launcher source code. But when I call startActivityForResult using the intent action as AppWidgetManager.ACTION_APPWIDGET_BIND, it is always returning Activity.RESULT_CANCELED even though the user is accepting from the dialog prompt shown on the UI.
Here's the code snippet
    appWidgetManager = AppWidgetManager.getInstance(this);
    appWidgetHost = new AppWidgetHost(this, 7772);
    int appWidgetId = appWidgetHost.allocateAppWidgetId();
    Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
    pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    startActivityForResult(pickIntent, REQUEST_PICK);

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, " onActivityResult " + requestCode + " res " + resultCode);
        if (requestCode == REQUEST_PICK && resultCode == Activity.RESULT_OK)
        {
            int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
            AppWidgetProviderInfo info = appWidgetManager.getAppWidgetInfo(appWidgetId);

            boolean hasPermission = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.provider);
            if (!hasPermission)
            {
                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider);
                startActivityForResult(intent, REQUEST_BIND);
            }

        }else if (requestCode == REQUEST_BIND) {
            // Here the resultCode is always returning Activity.RESULT_CANCELED
        }
    }

Can someone please help me out as to what I may be doing incorrectly?
I have also added android:name="android.permission.BIND_APPWIDGET"
in the Manifest file.
And finally, through the Android logs, I can see errors like
1567-1940/system_process E/AppWidgetServiceImpl: Widget id 34 already bound to: ProviderId{user:0, app:10025, cmp:ComponentInfo{com.android.deskclock/com.android.alarmclock.AnalogAppWidgetProvider}}

A: Found the problem. Answering it here in case anyone else faces the same issue.
If you use the AppWidgetManager.ACTION_APPWIDGET_PICK inten to pick the intent from the chooser displayed by the Android OS, there is no need to bind as the framework automatically binds the widget.
If you implement a custom chooser (for example, something which shows the preview images of widgets which is implemented in lots of custom launchers), then binding is necessary.


text:
Dodd's Consumer Financial Protection Plan
Nick Baumann
President Barack Obama meets with Rep. Barney Frank, (D-Mass), Sen. Dick Durbin, (D-Ill), and Sen. Chris Dodd, (D-Conn), in the Green Room of the White House prior to a financial regulatory reform announcement June 17, 2009. | White House photo/Pete Souza (Government Work)
Mother Jones has obtained a copy of Sen. Chris Dodd's plan to house a consumer financial protection office within the Department of the Treasury rather than creating an independent agency. Several other news sources have received copies, but none have made the leaked document publicly available. We're posting Chris Dodd's consumer financial protection plan here (PDF). It seems certain to disappoint experts and progressives who had called for a powerful new agency. (Andy Kroll has more on this.) This is the document's top-line summary:
Create a [Bureau of Financial Protection] inside of Treasury with a Presidentially-appointed director; a dedicated budget (through assessments on large banks, non-banks, and with the Fed making up the shortfall); autonomous rule-writing authority with the regulations to apply across-the-board to all entities offering financial services or products; and examination and enforcement authority for large banks and mortgage companies, small banks in a back-up capacity, and other non-banks on a risk basis, as described below.
The independent agency proposal would be dropped.
As Andy explained Saturday afternoon, Dodd's decision to move financial protection inside an existing agency is an effort to gain Republican votes for financial reform. But it's unclear whether either of the Republicans Dodd has negotiated with to date—Sen. Richard Shelby (R-Al.) and Sen. Bob Corker (R-Tenn.)—will support the new plan. There hasn't been any hint of GOP backing for the proposal in newspaper articles on Dodd's leaked plan.
Even if Dodd can convince Republicans to back the notion of a Treasury-based consumer protection office, this proposal could have problems passing the House. Multiple members of the House Financial Services Committee, including its chair, Rep. Barney Frank (D-Mass.), told Andy last week that they were worried about the Senate watering down consumer protection. (Frank said that if the Senate's financial reform plan did not include a standalone agency, it would be a potential "dealbreaker.") Now House Dems' worst fears are already being realized—and as far as anyone knows, Dodd hasn't even won any Republican votes.
Dodd Guts Consumer Protection
Is the Senate Bungling Its Wall Street Crackdown?