Text Input
Technology Solutions for Increased Student Motivation Player Experience Design in Software-Based Learning Systems by Stephen Burgess Submitted to the Board of Mathematics/Computer Science School of Natural Sciences in partial fulfillment of the requirements for the degree of Bachelor of Arts Purchase College State University of New York December 2014 Sponsor: Jeanine Meyer Second Reader: Irina Shablinsky 2 Introduction As the widespread adoption of the Internet changes the way information is distributed and consumed, emergent digital media platforms provide new modes for skill training and education. Software-Based Learning Systems (SBLS) provide cost-effective solutions to allow teachers to spend more time with students. I have implemented several design schemes during my career at Purchase College using free and often open-source platforms. In this paper I will share my work exploring the potential of software for learning and skill-training using examples of designs I have created. Software interface designs for learning I have done for software that relates to learning are: • Interactive visualizations of mathematical and logical concepts • Instructional videos presented in a web environment • Student Loans, challenge-based educational application • Search interface Bibliofy with accompanying auto-generated keyword cloud • User interface design for Moodle-style classroom web software • Games, ones which include cultural, conceptual, and historical information The ‘Learning’ in ‘Software-Based Learning Systems’ is important to define as the intended goal of an educational platform. Learning is broadly defined as the ability to acquire new or transform existing knowledge, skills, or behaviors (Pereira). More specifically, learning is “a process which leads to the modification of behaviour or the acquisition of new abilities or responses, and which is additional to natural development by growth or maturation” (Oxford-English Dictionary). ‘Pedagogy’ is “The art, occupation, or practice of teaching. Also: the theory or principles of education; a method of teaching based on such a theory” (OED). ‘E-learning’ is: any form of education or training that uses computer technology as an essential part of the teaching process. The term covers a broad range of goals and methodologies, but two features frequently found are that computerized data and programs substitute partly or completely for the human teacher; and that students engage with all or part of the course remotely, for example over the 3 Internet from their homes. (Daintith) SBLS categorically encompass educational games, electronic learning (elearning), and mobile learning (m-learning). One subset of SBLS is ‘Digital Game-Based Learning’ (Lothian, Ryoo), referred to hereafter by the acronym DGBL, which uses fictional narratives to immerse and motivate students (Beserra, Annetta, Malone, Lothian). More broadly, SBLS do not necessarily depend on participant immersion in a fictional world to maintain participant engagement and motivation, as do games. Likewise, they are not necessarily used outside of the classroom as is implied by the terms ‘e-learning’ and ‘m-learning.‘ Figure 1: Visualizing Calculus In the example of Visualizing Calculus (Figure 1: Visualizing CalculusFigure 1), I created an interactive graph to help students understand what a derivative is. In this example, students could input any formula that falls in the range of the graph, then can trace along with their input devices the derivative along any point on the line. Being able to see how the derivative changes from point to point in an interactive graph on any inputted formula is just one powerful way that software can aid in learning and subject comprehension. Software-based learning enjoys a valuable characteristic after the process of 4 design and implementation is complete: immediate individualized feedback. Other benefits include processing and tracking numerous data points about student performance, responsive and flexible frameworks that allow for continual improvement and adaptation, and access asynchronicity providing expanded options for engagement outside the classroom. “Asynchronous mechanisms allow players to freely choose when they play, and they do not have arrange [sic] a time before playing.” (Chien-Hung) The modularity and capability of randomness inherent in SBLS especially lend themselves towards designing learning exercise of rote, such as math homework or French vocabulary training with randomly generated problems. Immediate feedback provides motivation and lets students know right away if they are able to grasp the concept of a topic. With less busy work of grading homework or exercises, teachers can spend more one-on-one time with students already knowing what topics to address. Survey of Literature Studies have concluded that games can be an effective pedagogical tool: “The use of computer games favors the development of complex thinking skills related to problem solving, strategic planning, and self-regulated learning” (Beserra). Since “97% of students between the ages of 12 and 17 years old play video games” (Lothian and Ryoo), it is a form with near-universal appeal. However, the use of educational games does not result in higher subject comprehension compared to equivalent non-narrative digital instruction. Digitally-assisted instruction in a physical classroom setting, whether constructed as a game or not, produced higher subject comprehension than typical instruction methods that didn’t use software (Beserra). Considering that fact, this paper will discuss software-based learning systems as a whole and not be limited exclusively to software with narratives, or software intended to be accessed outside of the classroom. SBLS do not need to have a narrative component, nor must they be used outside of a classroom setting. If the ecosystem of apps intended to be used in a classroom setting grows, this technology would be more available to under-supported school. Therefore, while initial investments are comparable or slightly more than 5 textbook-based instruction, software does not become completely obsolete in two years or less as do some textbooks. This is because software can be changed, whereas books end up in landfills. Lacking a term to sufficiently encompass all of these software options, I will discuss software-based learning as a whole using the acronym SBLS. However I will relate the finds on studies done on DGBL game learning to SBLS. For instance, Ryoo found that "[digital] games have also been demonstrated as an effective way to close learning gaps among previously underperforming students.” Considering that studies did not find significant differences in learning outcomes between the two, besides a higher motivation to play DGBL games over other SBLS applications, I will hold Ryoo’s observations on games to also hold for non-narrative instructional software. Continual development in this field, and expansion upon existing offerings is necessary in order for SLBS to be most effective and well understood. “In game-based learning [DGBL], if the same system is used continuously, long time use would result in lowered curiosity or even annoyance at the system, resulting in decreased learning motivation“ (Lai). Once systems are developed, they must be continually expanded upon and updated in order to maintain the advantage of student engagement. So while there are many effective offerings already extant, the process of continual investment and development must be emphasized for most effective results. Though SBLS as a category do encompass Massive Open Online Courses (MOOCs), and though software is often an integral part of MOOCs, the fact that they are online and intended to be used massively (in other words, with many users who have minimal to no interaction with a teacher) puts them outside of the scope of what other literature I cite. MOOCs have faced serious and increased criticism as their use has grown (Fischer, Parry). The essential separation of teacher and student a serious of this system due do the primary role of guidance that teachers play in students’ learning experience. In the use of interpersonal computers for instance, engagement with software allows more time for a teacher to give individualized attention to students. In the video “This Will Revolutionize Education” by popular online educational video-maker Veritasium, Muller 6 makes the point that many technologies have offered the potential to revolutionize education without delivering in the end. This is due to the powerful role of teachers in a role of learning guide and diminishing returns of an increased classroom size enabled by technology options. As such my argument is not to increase classroom sizes significantly, but simply to allow teachers to spend more time in a guidance and advisory role to students. The United States is consistently given scores of average or below average for quality of education and is often ranked around 20th in the world (OECD, Pearson) despite spending the most on post-secondary students ($25,576) in relation to grossdomestic product per capita (NCES). Worldwide, literary rates are around 84% as of 2010. The largest concentrations of the world illiterate are located in India, China, and Pakistan (CIA) and three-quarters are women. In the United States, states spend an average of $10,608 per pupil each year for public elementary-secondary schools (Dixon). Further development of educational regimens is needed in the United States in order to achieve more cost-efficient education as well as universal literacy worldwide. If the cost-efficiency of education improved following the integration of software into the learning process, increased accessibility could only promote educational equality. Beserra found in 2014 that the learning impact of technology-based exercises “was significantly greater among students who were initially in the less knowledgeable half” of the groups in the study. ****On the other hand, in the implementation of Massive Open Online Classrooms (MOOCs) showed that the students who succeeded from this form were the same ones who were already motivated to succeed. As such, adoption of SBLS depends on situation, and may only be a benefit for students already enrolled in classes. However in a classroom setting, SBLS promise to most benefit underperforming students, the same ones who have a greater need for individualized feedback. Overall, adoption would expand educational opportunities and increase the efficacy of educational regimens in struggling and underfunded schools. One especially cost-effective model is the interpersonal computer. In this setup, a group of students all have input to a single computer and a single shared screen. 7 “With an interpersonal computer, multiple users located in the same space share one output device, like a computer screen, but each user has their own input device that they use to interact simultaneously with the virtual world” (Beserra). Having to purchase a set of input devices rather than individual computers for a classroom could provide many of the benefits of software-assisted learning while keeping the cost low per student. Pereira found that “a team-based game can lead to better performance results, a better learning process, and better cognitive development.” Attracting and maintaining student engagement through active, social engagement in learning activities could serve to alleviate some of the strain of passive learning experienced in secondary education as outlined by Strauss in her 2014 article “Teacher Spends Two Days as a Student and Is Shocked at What She Learns” in the Washington Post. Of course this would not completely replace traditional chalkboard instruction. Software would be just another tool to use in pedagogical settings, but it would be an important one. If buying a full-set of computers for one classroom is unrealistic then the interpersonal computer offers a more cost-effective model. Existing SBLS technologies such as Khan Academy, Lynda, Code Academy, Code School et al. already provide opportunities for subject training for free or at low cost. Khan Academy, the most well known of online learning platforms, enjoys 10 million unique viewers per month as of February 2014 (SRI International). The microtutorial videos Salman Khan produces are a low-cost resource for independent learners. Kolås (2012) explores in greater depth the use of Easy Production Educational (EPE) videos as a cost-effective pedagogical tool. EPE videos only need minimal equipment to produce, using a computer with a microphone and using inexpensive screen capture software can record a short pedagogical video. Filming an instructor at a chalkboard or a white board is another kind of EPE video since it requires very little to produce beyond a computer and a camera. Kolås’ study found that “it is more efficient to work with the subjects based on an inquiry-based approach, making the students ask questions and wonder about why different mathematical formulas are defined the way they are.” This is in contrast to the 8 traditional format of a chalkboard lecture. In m-learning (mobile learning), such as the style of the flipped classroom, students can access EPE videos remotely, and can watch them on their phones while commuting or at home. Then, when they get to the classroom, students focus on exercises, what would traditional be homework, with the teacher on hand to provide support at the very moment the student is struggling. In this case, the transmission of knowledge takes place when it is most convenient for everyone involved. Then, when students are in class they have access to teachers to provide guidance. The unusual style of the flipped classroom is made possible by the use of EPE videos. Now imagine if students could also do practice exercises without having to go to another page. Then, more classroom time could be dedicated towards students practicing exercises or more social learning activities generally. Looking forward, e-learning and m-learning both offer new possibilities to reshaping the educational experience. Bring-Your-Own-Device (BYOD) offers one of the most cost-effective models, but requires strict control of device use in classrooms that would present its own challenges (Bruder). With BYOD learning, students navigate to web software with their mobile devices and use them in class. This way, the school does not need to purchase computers for students. However without a healthy and robust ecosystem of existing software platforms for mobile devices, BYOD and m-learning models will struggle to gain traction. The relationship between instructional content and its motivational appeal is important in building an effective SBLS platform. Motivational appeal can be built through contextual understanding of a subject’s importance, but it can also be built through creating engaging experiences. “Intrinsically motivated learning [emphasis added] is learning that occurs in a situation in which the most narrowly defined activity from which the learning occurs would be done without any external reward or punishment.” (Malone and Lapper). One SBLS site, Khan Academy, has 10 million unique visitors a month. This speaks highly of how successfully the platform has created an intrinsically motivating learning experience through their videos and challenges. Software that does this most successfully puts students in a state of flow. 9 Csikszentmihalyi (1990) defines flow as “the state in which people are so involved in an activity that nothing else seems to matter, the experience is so enjoyable that people will do it even at great cost, for the sheer sake of doing it.” Flow consists of eight elements (Sweester): 1. a task that can be completed 2. the ability to concentrate on the task 3. that concentration is possible because the task has clear goals 4. that concentration is possible because the task provides immediate feedback 5. the ability to exercise a sense of control over actions 6. a deep but effortless involvement that removes the awareness of the frustrations of everyday life 7. concern for self disappears, but sense of self emerges stronger afterwards 8. the sense of the duration of time is altered The main types of learning—“auditory, visual, and kinesthetic” (Pereira) should be considered when designing educational software, though the brunt of the work will fall in the visual category. Two important considerations are balancing the cognitive load and providing advice and feedback. Annetta created the six “I”’s of educational game design. The six I’s are as follows: 1. Identity 2. Immersion 3. Interactivity 4. Increasing Complexity 5. Informed Teaching 6. Instructional Identity, as discussed in the last section, can be built through such methods as allowing for choice and customization of in-game personas through avatars, name customization, in-game professions and through many other means. “One of the critical issues in designing educational games is to sustain student motivation over time during gameplay“ (Eseryel). Creating a strong in-game identity won’t lead to better test scores; it will put the reins of education into the students hands. SBLS could provide 10 children and learners of all ages with a more active role in their own education. Identity is a factor of becoming immersed in a virtual world, as are interactivity and increasing complexity. Greater immersion leads to finding a flow state, thus greater engagement in the learning process. Incorporating fictional narratives into a learning module is intended primarily to elicit student immersion in the game and student identification with their in-game avatar (Chien-Hung, Sweetser). This immersion is intended to promote motivation and engagement with the material in game, and to make the learning module intrinsically motivating. “Informed Teaching” and “Instructional” are two factors that are applicable outside of the scope of educational software design that feature a narrative element. Utilize strong feedback cycles to tune the learning experience to address specific needs. Student Loans In my Student Loans application (Figure 2), I set the task to the learner of having a greater understanding of student loans by the end of the experience. I used minimal design elements to encourage concentration on the subject, one that is usually not a part of general curricula. The key concept with which this application engaged was compound interest. The concept of “Annual Percentage Rate” can be misleading to people unfamiliar with loans. Considering compound periods are generally per month instead of yearly, and can be of any variety of time frames, interest gained on loans is usually functionally higher per year than the stated rate. This application aimed to educate students on concepts such as the loan principal, how often interest compounds, and how much interest will be paid over the life of the loan. These numbers should be part and parcel of any loan agreement, and calculations for cumulative student loans should be done every time the principal amount increases through new loans, which for many students happens every semester. 11 Figure 2: Student Loans Through the use of three quizzes (Figure 3), I engaged students with the concepts presented in each informational section. According to Leemkuil, “learners need to be prompted for reflection to occur.” Without a warning, the pop quiz reinforces the need to do close reading in each section. For those without finance training, I estimate that the entire application would take 20-30 minutes to work through with close reading. One friend who I asked to use the application to learn about student loans commented that the information sections could be rewritten to use clearer and more concise language. While she said the language was grammatically correct and made sense, it could be redone to be less dense. This is a note I’ve received on other writing that I’ve done. Having short, clear sentences lets readers move smoothly through material. 12 Figure 3: Student Loan Quiz Design should be as transparent as possible. That is, the design choices of an interface including layout, buttons, typography, color, and so on should not draw attention to themselves. The less cognitive effort put into understanding an interface, the easier interaction with the software will be. Warde (1956) wrote that typography should be like a crystal goblet, allowing the meaning of the content to be read clearly without being obscured. Extending that concept to interface design means following a strategy of simplicity, clarity, and convention. This was a struggle for me as I developed my design aesthetic. In my earlier projects, I liked to break convention and use bold colors or unusual symbology. In feedback I received for my Student Loan education application (Figure 3), I never received notes that it was hard to understand, slow, or distracting. I view the lack of negative feedback as positive feedback that the design choices were not distracting or garish. Other feedback I received from my professor, Irina Shablinsky, was that the loan calculator could have been standardized to existing loan interfaces such as for mortgage repayment calculators. Having a format that fits in with existing conventions is an easy and simple way to create transparent design. Giving monthly repayment values, monthly interest values, and other information couched in conventional language is most often an ideal way to communicate new information to learners. Although most people who are interested in learning about student loans would not have experience 13 with mortgage interfaces, some way. Even if they don’t, they most likely will later encounter mortgage calculators, and so my role as an interface designer goes even so far as to prepare learners for those later experiences to minimize cognitive overload. Figure 4: JavaScript Sketchpad In some of my previous work at Purchase College such as Bibliofy (Figure 10: ‘Bibliofy’ Search Interface, 2013) and the JavaScript grapher (Figure 4: JavaScript Sketchpad), I made bold color choices that feedback showed distracted from the software’s purpose. While these colors appeal to me personally and I believed would provide an exciting flare to simple flare, I have come to believe through feedback from professors Hakan Topal and Peter Ohring that opting for cleaner and simpler design schemas is the wiser option for user interfaces. Astrablade Game Transparent design is just one component of building player engagement. It prevents confusion and frustration, allowing the content to reach its audience. Interactivity (that the student has agency in the learning environment, and that her actions have measurable effect) is another important motivator. Interactivity is also one of Annetta’s “six I’s of educational game design” as explored in the next section. “Not only has the provision of choice been shown to enhance intrinsic motivation per se, it has also proved a significant variable in a variety of motivational 14 paradigms” (Malone and Lepper). Choice was found to be an effective tool for building student interest even when it only gave the illusion of control to the players without any actual effect in the program. Interestingly, even the false illusion of agency may be more effective at sustaining student interest than when student actions do create change but the effects are imperceptible. Figure 5: Astrablade Name Generator The game Astrablade was designed around the idea of a non-linear experience for players, one determined by the series of choices they made. One of the first choices players are presented with is the choice of what name they would like to use in the game world. For this I wrote a fantasy name generator in JavaScript (Figure 5). After choosing gender and degree of familiarity, this widget generates a name from options of prefixes and suffixes. In the feedback I received on this, most players generated names that sounded strange and unfamiliar, even when using the familiar option. This is an effect of English names inheriting from Germanic as opposed to Romantic languages. In Latin and languages that have evolved from it, names are more often made of a prefix (Jul-) and a gendered suffix (–ia and -ius) in the case of the names Julia and Julius. I built the widget with this in mind, but the effect was not understood as well as it would be for speakers of Romance languages. One key consideration for me in the creation of the name generator was to allow for third-gendered name endings. This was to encourage thought in players of moving beyond the cultural construct of a gender binary (i.e. only male and female) to be inclusive of options outside that range. In this way, choosing a name and being offered a choice for third gender would lead to engagement with broader cultural issues as an ancillary activity in the game world. 15 Figure 6: Astrablade Avatars For the Astrablade game demo, I also created three avatars (Figure 6) for players to choose from. Since this game takes place in a fantasy world, I did not include anything I felt would be an obvious marker of time, place, or another potentially anachronistic features. Players start with a default avatar, and are given the option to change it to any of the above three. The system is easily scalable and would be just a matter of adding another avatar element, in other words the game is not limited to three avatars. Avatars represent a similar level of choice as a chosen in-world game. Annetta found that: …using avatars increased social presence and built a strong community of practice. During game play, students who had a choice of which avatar they would like to represent them reported greater course satisfaction and felt closer to their classmates and instructor than students who could choose only between a standard male or female avatar. Avatars serve as a source of identification with a virtual world increasing a sense of a immersion and making easier a state of flow as described by Csikszentmihalyi. Another feature I explored with Astrablade was hidden information. For instance, at the beginning of the game players can choose a profession such as “Merchant Trader” or “Martial Artist.” Players can view a description of these professions, but when they select one option it provides different starting conditions for their characters in the game world. This information could not be predetermined by anyone unless they had access to, and could read, the code that I’ve written. Hidden information provides an element of the unexpected. In complex systems, this can be even more effective through the process of observation and learning behavior. Actions may have an outcome that is impossible to determine beforehand but after observing 16 the effects of an action, strategy can emerge. While Astrablade was only a proof of concept demonstration, my concept for the finished product included a complex system of non-player characters (NPCs) with which players could engage (Figure 7). In this concept, becoming friends with a morally ambiguous character such as a thief would lead to decreased favor with authority figures. In other words, mutually exclusive choices would result in unforeseen outcomes with an opportunity to adjust behavior for desired results. Still, it is important to not overload players with data outside the primary scope of the experience as that would result in a less immersive experience. Instead, hidden information can be used to effective create interesting and dynamic experiences in a game setting or in any complex simulated environment. Figure 7: Astrablade Game There are some features in Astrablade for which I laid the groundwork but did not have the opportunity to fully implement. One of these features was a time score (Figure 7, top right). For every second players stayed on the page, their time scores incremented by one. In the concept of the final piece, this time score could serve as a kind of in-game currency. After gaining enough time score points, players would be able to ‘spend’ them to reveal new locations or meet new NPCs. Another aspect of the game concept yet to be implemented was to have tiers of goals. Some goals would be small, such as meeting a new character. Other goals would be larger, such as meeting every character in a town. Players could train in different ingame skills, and once a skill was trained could use it to accomplish a task that was previously inaccessible. Malone’s observation on the use of tiered goals was that 17 “Hierarchical goal systems—that simultaneously provide both proximal and distal goals across a wide range of performances—may prove especially effective motivational devices.” In addition, “challenge appears to be intrinsically motivating, in large part, because it engages the learner’s sense of self-esteem.” It seems as though a healthy mix of proximal (e.g. “Get 5 correct in a row,” Figure 8) and distal goals will provide the greatest boon to motivation. Increasing complexity is a strategy to ensure that an appropriate degree of challenge is maintained. Figure 8: Khan Academy Math Challenge Astrablade is the most powerful framework of any I developed during my time at Purchase College. Considering the application is contained within a single page from the player’s perspective, the many links and state changes in the game do not overload the player’s web history. In addition, the use Asynchronous JavaScript and XML (AJAX) allows lightning-fast page returns for short load times and therefore a smoother game experience. Astrablade was built in a way inspired by the representational state transfer 18 (RESTful) style of web architecture. REST web applications feature modularity, minimal calls to the web server, and scalability among other qualities (Fielding). Like a RESTful application, Astrablade is lightning fast, functions well even without a fast web connection, and is inherently scalable. As other demands required my attention during my final year at Purchase College, I was unable to expand upon the original demo. Indeed, much of the most impressive work I did in this application is invisible to players in its current form. However, I have created a framework that could easily be adaptable for a number of purposes beyond this game per se. Within the context of this game, next steps would be to develop the scenes of the narrative story as well as challenges. The modularity of this structure creates a form that lends itself towards “scenes.” Each scene contains narrative information as well as a selection of options of where to go next (Figure 7: Astrablade Game). A combination of third person narration and character dialogue uses conventions of prose fiction, while the Uniform Resource Identifiers (URIs, or links in common speech) (Fielding) brings the power of web architecture to create an interactive narrative experience. The potential for interactive engagement with text is one of the most attractive qualities of web frameworks. The next step is to put to use the modular framework of Astrablade. The concept I have had for that game was to create a series of proximal and distal goals within the game that involve learning skills that may also be applicable within real-world contexts. For instance, the player could choose to work as an “editor” within the game world. After getting a primer on grammar, the player would be presented with text with grammatical errors. Identifying the errors would earn the player in-game achievements and points. After attempting this task enough times, the player would gain a badge indicating their success at editing, opening up new challenge options. In this way, learning about grammar could be an active process and its situation within a challenge environment would provide motivation. While having a page to boast of achievements and badges has not yet been integrated into the game, the framework already exists to implement the challenge of providing a selection of random grammar challenges with UI elements to input answers and client-side scripts to check for correctness. 19 Pen +ool In my project Pen +tool (Error! Reference source not found.), I embedded EPE videos on a website to provide some basic instruction on how to trace a raster image in Adobe Illustrator and make a vector image out of it. A raster image is one that it made out of a grid of squares or dots with per-pixel information about color. Digital photographs are stored in raster format. Vector format images on the other hand are created from a set of mathematical instructions given to the computer, which process to draw lines and colors as defined by the image creator. This creates a scalable illustration that is especially useful in printing and digital animation. Pen +ool provides EPE videos that show how to trace a raster image in order to create a vector representation. Figure 9: Pen +ool Coupling EPE videos with challenge prompts not only takes the pressure of basic instruction and grading off teachers, it is more efficient and engaging. Interactivity with 20 learning software would give agency to students in becoming active participants in learning and move us away from the poor results of the dominant passive learning model. If I were to implement challenges in Pen +ool they would use the HTML5 canvas element, and be a basic simulation of using the pen tool in Adobe Illustrator. Once the student arranged the elements on the canvas to match some certain criteria, the exercise would be complete and the student will have achieved a proximal goal. For a distal goal in this case, it would be that the student successfully completes three simulations of vector manipulation, thus finishing the section. With both proximal and distal goals, students would be motivated to learn this useful skill and be participating actively in kinesthetic learning. Bibliofy Figure 10: ‘Bibliofy’ Search Interface, 2013 Bibliofy (Figure 10) was a concept I explored for an integrated application in a library setting. The idea was that students and researchers could approach an integrated touch screen unit that would be constantly cycling through popular search keywords. This would engage those without a clear idea of what interesting topics they wanted to look into. In this way, this library interface could become a more engaging place for casual readers. If a reader did have a clear idea of a topic to research in coming to the search interface, the word cloud would dynamically regenerate based on whatever terms were entered into the field without needing to search. These words clouds would be informed through a dynamically updated database. In other words, as searchers click terms of a word cloud, the words that are clicked would gain priority of 21 association. Likewise, searching related terms in succession would give a stronger relationship between those terms for future users. This algorithm would evolve, and become better as the user base increased. Considering that this interface would be embedded, I felt the keyboard could easily be eliminated utilizing existing jQueryUI keyboard interface elements. Isolating this application from its hardware and providing an keyboard interface not dependent on a tablet or physical keyboard would give it a modularity allowing for use in a variety of settings and with a variety of hardware options. For this semi-functional mockup, feedback from fellow students focused on the distracting and bright color and not understanding the function of the emerging words. Conclusion Software has many as-yet unexplored possibilities for integration into learning environments. These possibilities could be cost saving for educational institutions, but that is not the strongest case for increased use. Instead, the possible use of software in freeing up the time of professors to work closely with students has yet to be explored in public education in the United States. With the U.S. trailing behind other developed countries in education despite spending more than any other country, it’s clear that decisive action is needed and options should be explored. While SBLS have specific limitations and should not be seen as replacing the powerful relationship of student and teacher, it could open up time for teachers to engage individually with students. Following principles of design, powerful and simple software could help transition education from a passive experience that fails to engage restless students. Making education an active experience could serve to address the problems of motivation and attention in U.S. schools. Feedback on my work consistently shows that working within the framework of convention and depending on transparent design are essential to successful interface design.
Word Counts
Word Frequency


--- layout: post status: publish published: true title: "[Android] intent for sdcard ready" author: display_name: hojunbaek login: hojunbaek email<EMAIL_ADDRESS>url: '' author_login: hojunbaek author_email<EMAIL_ADDRESS>wordpress_id: 757 wordpress_url: http://ezcocoa.com/?p=757 date: '2011-06-02 06:49:03 +0900' date_gmt: '2011-06-02 06:49:03 +0900' categories: - Android tags: - intent - filter - sdcard comments: [] ---
출처 : http://stackoverflow.com/questions/3417161/android-intent-for-sdcard-ready
I have an application that uses a file on the SD card, the application runs when the phone boots, and it has become apparent that the file cannot be accessed when the program is first run as it starts working before SD card is avaliable.
Is there an broadcast receiver I can use to tell when the SD card is ready?
Update
Just to summarise the answer to register the intent do:
[sourcecode language="java"]
IntentFilter filter = new IntentFilter (Intent.ACTION_MEDIA_MOUNTED);
filter.addDataScheme("file");
registerReceiver(this.mSDInfoReceiver, new IntentFilter(filter));
[/sourcecode]
and create a broadcast receiver to react to it:
[sourcecode language="java"]
private BroadcastReceiver mSDInfoReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent intent) {
// Code to react to SD mounted goes here
}
};
[/sourcecode]


04/18/14 Stereotypes
I am glad that I have not experienced a situation in which I felt that negative stereotyping dramatically impacted the outcome of my work or led me to decisions that I regretted afterwards. Of course, I am completely aware of specific stereotypes and as a woman, I especially sense women-related stereotyping.
Thinking back to school, I sensed I am part of the group that is supposed to be great at literature and art, but not in math. It is a part of our society to be socialised in a certain way. As a result, we think to have knowledge about how certain things are structured (and have to be), like boys like blue and play with cars and girls like pink and play with dolls.
 It is a negative stereotype but I remember some less successful tests were thinking of this stereotype gave me some comfort and kept me from being too upset: I just told myself something like 'this is not the end of the world and besides, being a girl, people do not expect you to be perfect in math'. To be honest, this gave me comfort in the first place but after a short while, feeling a stereotype apply (I stereotyped myself..) also made me stubborn and fight even more to prove the opposite.
Another moment I felt being stereotyped was a visit at a hair cutter shortly after I moved to the US. My hair is cut short, nothing specially meaningful in Germany. But based on what the hair cutter chatted I learned that girls with short hair are not as common in the US and some people link short hair to being homosexual. I felt a irritated. Not because I felt uncomfortable with being counted into that group, but because I felt misjudged and 'rated' by the society without any personal knowledge of myself.
That feeling wasn't good and first I felt a little bit 'watched' and certainly misunderstood. But my anger about such a stereotyped-thinking of some people was bigger than being upset about it. That helped me to get over it quickly, to continue having short hair and not to bother. I have to admit that a feeling that being stereotyped in this way does not happen too often, especially not in the cities I live(d), helped me to ignore it.
And what would I do if I suspected a colleague to feel a stereotype threat? I would not address him or her directly and ask whether my suspicsion is true. I don't think that would do any good as my asking could be wrongly (negatively) interpreted . But in a conversation, I would address possible stereotype fears by highlighting what the basis for this conversation is and starting with positive feedback. The most important thing is to really know what you want the other person to give feedback about. And then I would do the best I could to give him/her the feeling of being in a friendly and constructive environment.


Atom feeds for new packages
from
popular
ELPA
archives
.
-
GNU ELPA
-
Marmalade
-
MELPA
-
MELPA Stable


Here you will see few of my projects, and also some exercises done by me during the programming and web development classes. They are available to be accessed by anyone and you are welcome to contribute.
Exercises from the HTML course, which is a markup language used to create the context of a website, and CSS course, which is a markup language used to create the design of a website.
Exercises from the Python course, which is a high level programming language.


--- layout: paper title: Publications --- Identification and Verification of Simple Claims about Statistical Properties, , Proceedings of the Conference on Empirical Methods in Natural Language Processing 2015 [pdf]
@inproceedings{vlachos2015fact, month={September}, year={2015}, author={Vlachos, Andreas and Riedel, Sebastian}, title={Identification and Verification of Simple Claims about Statistical Properties}, booktitle={Proceedings of the Conference on Empirical Methods in Natural Language Processing}, }


|
|
By using string access shims, strings, or those things that are expressible ( as String types, or
These classes are used to wrap instances of fundamental types in order to pass them into the Pantheios diagnostic logging functions, as in:
short s = 123; int i = 456; long l = 789; float f = static_cast<float>(0.123); double d = 0.456; long double ld = 0.789; void* p = reinterpret_cast<void*>(0x01230123); unsigned char ar[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; pantheios::log_INFORMATIONAL( "This string contains: " , "some integers (", pantheios::integer(s), ", ", pantheios::integer(i, 4 | pantheios::fmt::zeroPadded), ", ", pantheios::integer(l), "); " , "some real numbers (", pantheios::real(f), ", ", pantheios::real(d), ", ", pantheios::real(ld), "); " , "a pointer (", pantheios::pointer(p, pantheios::fmt::fullHex), "); " , "and a blob (", pantheios::blob(&ar[0], sizeof(ar), ")" );
which will produce the following output:
This string contains: some integers (123, 0456, 789); some real numbers (0.123, 0.456, 0.789); a pointer (0x1230123); and a blob<PHONE_NUMBER>)
Within the scope of a given function, it can be appropriate to use a using directive to reduce the clutter, as in:
using namespace pantheios; short s = 123; int i = 456; long l = 789; float f = static_cast<float>(0.123); double d = 0.456; long double ld = 0.789; void* p = reinterpret_cast<void*>(0x01230123); unsigned char ar[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; log_INFORMATIONAL( "This string contains: " , "some integers (", integer(s), ", ", integer(i, 4 | fmt::zeroPadded), ", ", integer(l), "); " , "some real numbers (", real(f), ", ", real(d), ", ", real(ld), "); " , "and a pointer (", pointer(p, fmt::fullHex), "); " , "and a blob (", blob(&ar[0], sizeof(ar), ")" );
or using declarations, as in:
using pantheios::log_INFORMATIONAL; using pantheios::blob; using pantheios::integer; using pantheios::real; using pantheios::pointer; using pantheios::fmt; short s = 123; int i = 456; long l = 789; float f = static_cast<float>(0.123); double d = 0.456; long double ld = 0.789; void* p = reinterpret_cast<void*>(0x01230123); unsigned char ar[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; log_INFORMATIONAL( "This string contains: " , "some integers (", integer(s), ", ", integer(i, 4 | fmt::zeroPadded), ", ", integer(l), "); " , "some real numbers (", real(f), ", ", real(d), ", ", real(ld), "); " , "and a pointer (", pointer(p, fmt::fullHex), "); " , "and a blob (", blob(&ar[0], sizeof(ar), ")" );
Classes | |
| class | args |
Class for inserting argc+argv arguments into Pantheios diagnostic logging statements. More... | |
| class | b64 |
| Class for inserting binary regions types into Pantheios diagnostic logging statements. More... | |
| class | blob |
| Class for inserting binary regions types into Pantheios diagnostic logging statements. More... | |
| class | boolean |
| Class for inserting Boolean types into Pantheios diagnostic logging statements. More... | |
| class | character |
| Class for inserting characters into Pantheios diagnostic logging statements. More... | |
| struct | fmt |
| Format constants used by Pantheios inserter classes. More... | |
| class | hex_ptr |
| [DEPRECATED] Class for inserting pointers into Pantheios diagnostic logging statements. More... | |
| class | integer |
| Class for inserting integral types into Pantheios diagnostic logging statements. More... | |
| class | pointer |
| Class for inserting pointers into Pantheios diagnostic logging statements. More... | |
| class | real |
| Class for inserting floating-point types into Pantheios diagnostic logging statements. More... | |
| class | variant_bool |
| Class for inserting VARIANT_BOOL variables into Pantheios diagnostic logging statements. More... | |
| class | w2m |
| Class for inserting wide strings into Pantheios diagnostic logging statements. More... | |
Defines | |
| #define | PANTHEIOS_LPAD(var, minWidth) ( ::pantheios::pad(var, minWidth)), (var) |
| Inserts a variable with a minimum width, padding to the left with spaces. | |
| #define | PANTHEIOS_RPAD(var, minWidth) (var), ( ::pantheios::pad(var, minWidth)) |
| Inserts a variable with a minimum width, padding to the right with spaces. | |
Typedefs | |
| typedef character | ch |
| Class for inserting characters into Pantheios diagnostic logging statements. | |
| typedef stlsoft::string_view | m2w |
| Class for inserting wide strings into Pantheios diagnostic logging statements. | |
Variables | |
| struct hostId_t const * | hostId |
| Global instance that may be used to insert a host identity into a log statement. | |
| struct processId_t const * | processId |
| Global instance that may be used to insert a process identity into a log statement. | |
| struct threadId_t const * | threadId |
| Global instance that may be used to insert a thread identity into a log statement. |
| #define PANTHEIOS_LPAD | ( | var, | |||
| minWidth | ) | ( ::pantheios::pad(var, minWidth)), (var) |
Inserts a variable with a minimum width, padding to the left with spaces.
| var | The variable to be inserted | |
| minWidth | The minimum width of the inserted variable |
| #define PANTHEIOS_RPAD | ( | var, | |||
| minWidth | ) | (var), ( ::pantheios::pad(var, minWidth)) |
Inserts a variable with a minimum width, padding to the right with spaces.
| var | The variable to be inserted | |
| minWidth | The minimum width of the inserted variable |
| typedef character ch |
Class for inserting characters into Pantheios diagnostic logging statements.
This class converts a character variable into a string, thereby enabling it to be inserted into a logging statement. Consider the following statement:
char c = '#'; char s[] = "abc"; std::string str("def"); pantheios::log(pantheios::notice, "s=", s, ", c=", pantheios::character(c), ", str=", str);
This will produce the output:
s=abc, c=#, str=def
| typedef stlsoft:: string_view m2w |
Class for inserting wide strings into Pantheios diagnostic logging statements.
This class converts a m2w variable into a string, thereby enabling it to be inserted into a logging statement. Consider the following statement:
char s[] = "abc"; wchar_t ws = L"def"; std::wstring wstr(L"ghi"); pantheios::log(pantheios::notice, L"s=", pantheios::m2w(s), L", ws=", ws, L", wstr=", wstr);
This will produce the output:
s=abc, ws=def, str=ghi
| struct hostId_t const* hostId |
Global instance that may be used to insert a host identity into a log statement.
pantheios::log_NOTICE("host id=", pantheios::hostId);
This will produce output such as the following:
host id=my-system
| struct processId_t const* processId |
Global instance that may be used to insert a process identity into a log statement.
pantheios::log_NOTICE("process id=", pantheios::processId);
This will produce output such as the following:
process id=2436
| struct threadId_t const* threadId |
Global instance that may be used to insert a thread identity into a log statement.
pantheios::log_NOTICE("thread id=", pantheios::threadId);
This will produce output such as the following:
thread id=1310
|
|
|
| pantheios Library documentation © Matthew Wilson & Synesis Software, 2006-2011 |


HC grants 30-day parole to Rajiv Gandhi killer Robert Payas
He has been given parole from November 25 till December 24.
by PTIThe Madras High Court on Thursday granted a 30-day parole to Robert Payas, one of the seven convicts serving a life term for assassination of former Prime Minister Rajiv Gandhi.
A division bench of justices MM Sundresh and RMT Teekaa Raaman gave the order on a plea by Payas seeking parole for making arrangements for his son’s wedding.
He has been given parole from November 25 till December 24.
The conditions of the parole include a bar on him interacting with the media, political parties or personalities and an undertaking to keep good conduct and not disrupt public peace.
The petitioner had in his plea in September, submitted that he has been in prison since August 16, 1991 and has completed actual imprisonment of more than 28 years.
During this period, he said, he had not utilised the emergency or ordinary leave provided to him under Tamil Nadu Suspension of Sentence Rules, 1982 despite his good conduct in the prison.
In July, the court had granted one month parole to Nalini, another convict in the case, after she argued her plea in person for seeking the relief to make arrangements for her daughter’s wedding.
Payas and six other people — Murugan, Santhan, Perarivalan, S. Jayakumar and Nalini — are serving life term in connection with the assassination of Gandhi by a suicide bomber at an election rally in Tamil Nadu on May 21, 1991.


We have dogs!
- deliver value-added e-markets
- integrate plug-and-play architectures
- benchmark cross-platform action-items
- incubate magnetic synergies
- e-enable turn-key infrastructures
- disintermediate interactive relationships
- utilize e-business web services
- harness ubiquitous mindshare
- productize global vortals


Welcome to stream chat!
Experimental distributed chat room build on streams & discovery-network
Join Room
join
send message
send


My phase 0 Blogs!
Links to all my blog posts
Week-1
Week-2
Week-3
Week-4
Week-5
Week-6
Week-7
Week-8


My project for the summer was to create the redesign for napaonline.com store finder page. Below I have included what the page currently looks like.
Why was this important? This page was the mid-point for consumers to look for store locations, understand where they could pick up their items and access the store details pages. To redesign this page meant consumers had an understanding of where to shop for their items, therefore create more revenue.
Some of the main issues with the look and design of the page include
Before redesigning the page, I took a look at what other companies created for their store finders/store locators/store trackers. Whatever it was called...
Stores I analyzed include Advance Auto Parts, AutoZone, O'Reillys, Best Buy, Walmart and Best Buy.
Container Style and Name: After understanding what other companies did, I realized I wanted a modal because the modal didnt disrupt the flow of a user at the PLP or PDP. I also decided to name the button "Change Store" to relfect what it did.
Store Pin Treatement: I made the gps automatically confirm the store, so the user could avoid that extra step. I decided to autopopulate as many stores in a 50 mile radius to provide more stores to see.
Search Bar and Action Treatement: Considering the low number of NAPA stores and the copy limit, I choose the search result to be zipcode. I decided to include filters to help with users search and autofill the search to align with automatic confirmation of stores.
After watching a couple of videos of users actually interacting with the system, I learned a couple things.
Considering all this, I wanted to be sure my new page had
If you look below, I have included a cool graphic about how this new modal works
After some more research of other systems such as the ones I evaluated above, I realized that the best way to display this information was in a webpage.
The reason I decided this is because a modal is more of “step” in a process for a user. The store finder itself is not a “step”.
There is plenty of information within it including
It also allowed the opportunity for responsive design to be more natural, whereas a modal would disrupt a mobile platform more than a page. It also aligned with the user observation videos. Users liked to explore the map and by making this modal -> a full screen would make the map easier to explore.
Here a couple of examples of what I crafted before my final product.
This is the option I went with MAINLY because the store pods hovering over the page allowed for more viewing space on the map.
This is mobile wireframe. I kept in mind what this design would look on a responsive platform and made sure to prioritize the map - to align with user expectations of the desktop view.
After collaboration with a UI designer the final product looks like this


Matrices
Basic Operations
Select a matrix
2 x 2
3 x 3
Select an Operator
Addition
Multiplication
Subtraction
=
c1
c2
c3
c4
c5
c6
c7
c8
c9
Select an Operator
Addition
Multiplication
Subtraction
=
c1
c2
c3
c4
Miscellaneous Operations
Select a matrix
2 x 2
3 x 3
Select an Operator
Transpose
Inverse
Minor
Determinant
Adjoint
Co-factor
c1
c2
c3
c4
Select an Operator
Transpose
Inverse
Minor
Determinant
Adjoint
Co-factor
c1
c2
c3
c4
c5
c6
c7
c8
c9


{% extends "static_section.html" %} {% block content %}
Our upper State St. office in Santa Barbara, CA features two treatment rooms, parking and an alternative medicine lending library.
Dr. Gruver is available Monday through Friday and select evenings.
We accept personal injury and worker's comp insurance cases with a Doctor's prescription.
Featuring an alternative medicine library: over 1,000 categorized books and articles for you to browse or borrow.
Personal injury and worker's comp accepted with prescription.
{% for service in object_list %}{{service.name}}
{{service.description|safe}}
{{service.price|safe}}


public class CategoryDocumentBuilder extends Object
CategoryPath
s or
CategoryAttribute
s to a given document using a taxonomy.
FacetIndexingParams
or
the default implementation
DefaultFacetIndexingParams
.
CategoryAttribute
elements through
setCategories(Iterable)
,
or as
CategoryPath
elements through
setCategoryPaths(Iterable)
.
Note that both
setCategories(Iterable)
and
setCategoryPaths(Iterable)
return this
CategoryDocumentBuilder
, allowing the following pattern:
new
CategoryDocumentBuilder(taxonomy,
params).setCategories(categories).build(doc)
.
| Modifier and Type | Field and Description |
|---|---|
protected
Map
<
String
,
List
<
CategoryAttribute
>>
|
categoriesMap
|
protected
ArrayList
<
Field
>
|
fieldList
A list of fields which is filled at ancestors' construction and used
during
build(Document)
.
|
protected
FacetIndexingParams
|
indexingParams
Parameters to be used when indexing categories.
|
protected
TaxonomyWriter
|
taxonomyWriter
A
TaxonomyWriter
for adding categories and retrieving their
ordinals.
|
| Constructor and Description |
|---|
CategoryDocumentBuilder
(
TaxonomyWriter
taxonomyWriter)
Creating a facets document builder with default facet indexing
parameters.
See:
CategoryDocumentBuilder(TaxonomyWriter, FacetIndexingParams)
|
CategoryDocumentBuilder
(
TaxonomyWriter
taxonomyWriter,
FacetIndexingParams
params)
Creating a facets document builder with a given facet indexing parameters
object.
|
| Modifier and Type | Method and Description |
|---|---|
Document
|
build
(
Document
doc)
Adds the fields created in one of the "set" methods to the document
|
protected void
|
fillCategoriesMap
(
Iterable
<
CategoryAttribute
> categories)
Fills the categories mapping between a field name and a list of
categories that belongs to it according to this builder's
FacetIndexingParams
object
|
protected
CategoryListTokenizer
|
getCategoryListTokenizer
(
TokenStream
categoryStream)
Get a category list tokenizer (or a series of such tokenizers) to create
the
category list tokens
.
|
protected
CategoryTokenizer
|
getCategoryTokenizer
(
TokenStream
categoryStream)
Get a
CategoryTokenizer
to create the
category tokens
.
|
protected
CountingListTokenizer
|
getCountingListTokenizer
(
TokenStream
categoryStream)
Get a
CountingListTokenizer
for creating counting list token.
|
protected
TokenStream
|
getParentsStream
(
CategoryAttributesStream
categoryAttributesStream)
Get a stream of categories which includes the parents, according to
policies defined in indexing parameters.
|
CategoryDocumentBuilder
|
setCategories
(
Iterable
<
CategoryAttribute
> categories)
Set the categories of the document builder from an
Iterable
of
CategoryAttribute
objects.
|
CategoryDocumentBuilder
|
setCategoryPaths
(
Iterable
<
CategoryPath
> categoryPaths)
Set the categories of the document builder from an
Iterable
of
CategoryPath
objects.
|
protected final TaxonomyWriter taxonomyWriter
TaxonomyWriter
for adding categories and retrieving their
ordinals.
protected final FacetIndexingParams indexingParams
protected final ArrayList < Field > fieldList
build(Document)
.
protected Map < String , List < CategoryAttribute >> categoriesMap
public CategoryDocumentBuilder( TaxonomyWriter taxonomyWriter) throws IOException
CategoryDocumentBuilder(TaxonomyWriter, FacetIndexingParams)
taxonomyWriter
- to which new categories will be added, as well as translating
known categories to ordinals
IOException
public CategoryDocumentBuilder( TaxonomyWriter taxonomyWriter, FacetIndexingParams params) throws IOException
taxonomyWriter
- to which new categories will be added, as well as translating
known categories to ordinals
params
- holds all parameters the indexing process should use such as
category-list parameters
IOException
public CategoryDocumentBuilder setCategoryPaths( Iterable < CategoryPath > categoryPaths) throws IOException
Iterable
of
CategoryPath
objects.
categoryPaths
- An iterable of CategoryPath objects which holds the categories
(facets) which will be added to the document at
build(Document)
new
CategoryDocumentBuilder(TaxonomyWriter)
.
setCategoryPaths(Iterable)
.
build(Document)
.
IOException
public CategoryDocumentBuilder setCategories( Iterable < CategoryAttribute > categories) throws IOException
Iterable
of
CategoryAttribute
objects.
categories
- An iterable of
CategoryAttribute
objects which holds
the categories (facets) which will be added to the document at
build(Document)
new
CategoryDocumentBuilder(TaxonomyWriter)
.
setCategories(Iterable)
.
build(Document)
.
IOException
protected TokenStream getParentsStream( CategoryAttributesStream categoryAttributesStream)
categoryAttributesStream
- The input stream
OrdinalPolicy (for policy of adding category tokens for parents)
,
PathPolicy (for policy of adding category
list
tokens for parents)
protected void fillCategoriesMap( Iterable < CategoryAttribute > categories) throws IOException
FacetIndexingParams
object
categories
- Iterable over the category attributes
IOException
protected CategoryListTokenizer getCategoryListTokenizer( TokenStream categoryStream)
categoryStream
- A stream containing
CategoryAttribute
with the
relevant data.
protected CountingListTokenizer getCountingListTokenizer( TokenStream categoryStream)
CountingListTokenizer
for creating counting list token.
categoryStream
- A stream containing
CategoryAttribute
s with the
relevant data.
protected CategoryTokenizer getCategoryTokenizer( TokenStream categoryStream) throws IOException
CategoryTokenizer
to create the
category tokens
.
This method can be overridden for adding more attributes to the category
tokens.
categoryStream
- A stream containing
CategoryAttribute
with the
relevant data.
CategoryTokenizer
to be used in creating category
tokens.
IOException


If you have a laptop, you will be changing the keyboard layout to "laptop". The CAPSLOCK key will become a modifier for the INSERT key. This means that when INSERT is used in a keystroke, the CAPSLOCK can be used to replace the INSERT key. CAPSLOCK is often easier to reach compared with insert. You won't have to move your hands off of homerow to reach CAPSLOCK.
in-context


Global Variables
The following global variables are available globally.
-
get URL from handler.userInfo. the object Class should be URL or NSURL
Declaration
Swift
public let HHRouterURLKey: String
-
get completion handler from handler.userInfo
Declaration
Swift
public let HHRouterCompletionHandlerKey: String
-
Declaration
Swift
public let HHRouterURLWildcardCharacter: String


Configuring Plot Tools¶
Bokeh comes with a number of interactive tools that can be used to report information, to change plot parameters such as zoom level or range extents, or to add, edit, or delete glyphs. Tools can be grouped into four basic categories:
- Gestures
These are tools that respond to single gestures, such as a pan movement. The types of gesture tools are:
For each type of gesture, one tool can be active at any given time, and the active tool is indicated on the toolbar by a highlight next to to the tool icon.
- Actions
- These are immediate or modal operations that are only activated when their
button in the toolbar is pressed, such as the
ResetTool
. - Inspectors
- These are passive tools that report information or annotate plots in some
way, such as the
HoverTool
orCrosshairTool
. - Edit Tools
- These are sophisticated multi-gesture tools that can add, delete, or modify glyphs on a plot. Since they may respond to several gestures at once, an edit tool will potentially deactivate multiple single-gesture tools at once when it is activated.
In addition to information about all the individual tools, this chapter describes how the toolbar may be configured.
Positioning the Toolbar¶
By default, Bokeh plots come with a toolbar above the plot. In this section you will learn how to specify a different location for the toolbar, or to remove it entirely.
The toolbar location can be specified by passing the toolbar_location
parameter to the figure()
function. Valid values are:
"above"
"below"
"left"
"right"
If you would like to hide the toolbar entirely, pass None
.
Below is some code that positions the toolbar below the plot. Try
running the code and changing the toolbar_location
value.
from bokeh.plotting import figure, output_file, show
output_file("toolbar.html")
# create a new plot with the toolbar below
p = figure(plot_width=400, plot_height=400,
title=None, toolbar_location="below")
p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
show(p)
Note that the toolbar position clashes with the default axes, in this case
setting the toolbar_sticky
option to False
will move the toolbar
to outside of the region where the axis is drawn.
from bokeh.plotting import figure, output_file, show
output_file("toolbar.html")
# create a new plot with the toolbar below
p = figure(plot_width=400, plot_height=400,
title=None, toolbar_location="below",
toolbar_sticky=False)
p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
show(p)
Specifying Tools¶
At the lowest bokeh.models
level, tools are added to a Plot
by
passing instances of Tool
objects to the add_tools
method:
plot = Plot()
plot.add_tools(LassoSelectTool())
plot.add_tools(WheelZoomTool())
This explicit way of adding tools works with any Bokeh Plot
or
Plot
subclass, such as Figure
.
Tools can be specified by passing the tools
parameter to the figure()
function. The tools parameter accepts a list of tool objects, for instance:
tools = [BoxZoomTool(), ResetTool()]
Tools can also be supplied conveniently with a comma-separate string containing tool shortcut names:
tools = "pan,wheel_zoom,box_zoom,reset"
However, this method does not allow setting properties of the tools.
Finally, it is also always possible to add new tools to a plot by passing
a tool object to the add_tools
method of a plot. This can also be done
in conjunction with the tools
keyword described above:
from bokeh.models import BoxSelectTool
plot = figure(tools="pan,wheel_zoom,box_zoom,reset")
plot.add_tools(BoxSelectTool(dimensions="width"))
Setting the Active Tools¶
Bokeh toolbars can have (at most) one active tool from each kind of gesture (drag, scroll, tap). By default, Bokeh will use a default pre-defined order of preference to choose one of each kind from the set of configured tools, to be active.
However it is possible to exert control over which tool is active. At the
lowest bokeh.models
level, this is accomplished by using the active_drag
,
active_inspect
, active_scroll
, and active_tap
properties of
Toolbar
. These properties can take the following values:
None
— there is no active tool of this kind"auto"
— Bokeh chooses a tool of this kind to be active (possibly none)- a
Tool
instance — Bokeh sets the given tool to be the active tool
Additionally, the active_inspect
tool may accept:
* A sequence of Tool
instances to be set as the active tools
As an example:
# configure so that no drag tools are active
plot.toolbar.active_drag = None
# configure so that Bokeh chooses what (if any) scroll tool is active
plot.toolbar.active_scroll = "auto"
# configure so that a specific PolySelect tap tool is active
plot.toolbar.active_tap = poly_select
# configure so that a sequence of specific inspect tools are active
# note: this only works for inspect tools
plot.toolbar.active_inspect = [hover_tool, crosshair_tool]
The default value for all of these properties is "auto"
.
Active tools can be specified by passing the these properties as keyword
arguments to the figure()
function. It is also possible to pass any one of
the string names for, ease of configuration:
# configures the lasso tool to be active
plot = figure(tools="pan,lasso_select,box_select", active_drag="lasso_select")
Pan/Drag Tools¶
These tools are employed by panning (on touch devices) or left-dragging (on mouse devices). Only one pan/drag tool may be active at a time. Where applicable, Pan/Drag tools will respect any max and min values set on ranges.
BoxSelectTool¶
The box selection tool allows the user to define a rectangular selection
region by left-dragging a mouse, or dragging a finger across the plot area.
The box select tool may be configured to select across only one dimension by
setting the dimensions
property to width
or height
instead of the
default both
.
Note
To make a multiple selection, press the SHIFT key. To clear the selection, press the ESC key.
BoxZoomTool¶
The box zoom tool allows the user to define a rectangular region to zoom the plot bounds too, by left-dragging a mouse, or dragging a finger across the plot area.
LassoSelectTool¶
The lasso selection tool allows the user to define an arbitrary region for selection by left-dragging a mouse, or dragging a finger across the plot area.
Note
To make a multiple selection, press the SHIFT key. To clear the selection, press the ESC key.
PanTool¶
The pan tool allows the user to pan the plot by left-dragging a mouse or dragging a finger across the plot region.
It is also possible to constrain the pan tool to only act on either just the x-axis or
just the y-axis by setting the dimensions
property to a list containing width
or height
. Additionally, there are tool aliases 'xpan'
and 'ypan'
,
respectively.
Click/Tap Tools¶
These tools are employed by tapping (on touch devices) or left-clicking (on mouse devices). Only one click/tap tool may be active at a time.
PolySelectTool¶
The polygon selection tool allows the user to define an arbitrary polygonal region for selection by left-clicking a mouse, or tapping a finger at different locations.
Note
Complete the selection by making a double left-click or tapping. To make a multiple selection, press the SHIFT key. To clear the selection, press the ESC key.
TapTool¶
The tap selection tool allows the user to select at single points by clicking a left mouse button, or tapping with a finger.
Note
To make a multiple selection, press the SHIFT key. To clear the selection, press the ESC key.
Scroll/Pinch Tools¶
These tools are employed by pinching (on touch devices) or scrolling (on mouse devices). Only one scroll/pinch tool may be active at a time.
WheelZoomTool¶
The wheel zoom tool will zoom the plot in and out, centered on the current mouse location. It will respect any min and max values and ranges preventing zooming in and out beyond these.
It is also possible to constraint the wheel zoom tool to only act on either
just the x-axis or just the y-axis by setting the dimensions
property to
a list containing width
or height
. Additionally, there are tool aliases
'xwheel_zoom'
and 'ywheel_zoom'
, respectively.
WheelPanTool¶
The wheel pan tool will translate the plot window along the specified dimension without changing the window’s aspect ratio. The tool will respect any min and max values and ranges preventing panning beyond these values.
Actions¶
Actions are operations that are activated only when their button in the toolbar is tapped or clicked. They are typically modal or immediate-acting.
ResetTool¶
The reset tool will restore the plot ranges to their original values.
SaveTool¶
The save tool pops up a modal dialog that allows the user to save a PNG image of the plot.
ZoomInTool¶
The zoom-in tool will increase the zoom of the plot. It will respect any min and max values and ranges preventing zooming in and out beyond these.
It is also possible to constraint the wheel zoom tool to only act on either
just the x-axis or just the y-axis by setting the dimensions
property to
a list containing width
or height
. Additionally, there are tool aliases
'xzoom_in'
and 'yzoom_in'
, respectively.
ZoomOutTool¶
The zoom-out tool will decrease the zoom level of the plot. It will respect any min and max values and ranges preventing zooming in and out beyond these.
It is also possible to constraint the wheel zoom tool to only act on either
just the x-axis or just the y-axis by setting the dimensions
property to
a list containing width
or height
. Additionally, there are tool aliases
'xzoom_in'
and 'yzoom_in'
, respectively.
Inspectors¶
Inspectors are passive tools that annotate or otherwise report information about the plot, based on the current cursor position. Any number of inspectors may be active at any given time. The inspectors menu in the toolbar allows users to toggle the active state of any inspector.
CrosshairTool¶
Th crosshair tool draws a crosshair annotation over the plot, centered on
the current mouse position. The crosshair tool draw dimensions may be
configured by setting the dimensions
property to one of the
enumerated values width
, height
, or both
.
HoverTool¶
The hover tool is a passive inspector tool. It is generally on at all times, but can be configured in the inspector’s menu associated with the toolbar.
Basic Tooltips¶
By default, the hover tool will generate a “tabular” tooltip where each row
contains a label, and its associated value. The labels and values are supplied
as a list of (label, value) tuples. For instance, the tooltip below on the
left was created with the accompanying tooltips
definition on the right.
hover.tooltips = [
("index", "$index"),
("(x,y)", "($x, $y)"),
("radius", "@radius"),
("fill color", "$color[hex, swatch]:fill_color"),
("foo", "@foo"),
("bar", "@bar"),
]
|
Field names that begin with $
are “special fields”. These often correspond
to values that are intrinsic to the plot, such as the coordinates of the mouse
in data or screen space. These special fields are listed here:
$index : | index of selected point in the data source |
|---|---|
$name : | value of the name property of the hovered glyph renderer |
$x : | x-coordinate under the cursor in data space |
$y : | y-coordinate under the cursor in data space |
$sx : | x-coordinate under the cursor in screen (canvas) space |
$sy : | y-coordinate under the cursor in screen (canvas) space |
$name : | The name property of the glyph that is hovered over |
$color : | colors from a data source, with the syntax: $color[options]:field_name .
The available options are: hex (to display the color as a hex value),
and swatch to also display a small color swatch. |
Field names that begin with @
are associated with columns in a
ColumnDataSource
. For instance the field name "@price"
will display
values from the "price"
column whenever a hover is triggered. If the hover
is for the 17th glyph, then the hover tooltip will correspondingly display
the 17th price value.
Note that if a column name contains spaces, the it must be supplied by
surrounding it in curly braces, e.g. @{adjusted close}
will display values
from a column named "adjusted close"
.
Sometimes (especially with stacked charts) it is desirable to allow the
name of the column be specified indirectly. The field name @$name
is
distinguished in that it will look up the name
field on the hovered
glyph renderer, and use that value as the column name. For instance, if
a user hovers with the name "US East"
, then @$name
is equivalent to
@{US East}
.
Here is a complete example of how to configure and use the hover tool by setting
the tooltips
argument to figure
:
from bokeh.plotting import figure, output_file, show, ColumnDataSource
output_file("toolbar.html")
source = ColumnDataSource(data=dict(
x=[1, 2, 3, 4, 5],
y=[2, 5, 8, 2, 7],
desc=['A', 'b', 'C', 'd', 'E'],
))
TOOLTIPS = [
("index", "$index"),
("(x,y)", "($x, $y)"),
("desc", "@desc"),
]
p = figure(plot_width=400, plot_height=400, tooltips=TOOLTIPS,
title="Mouse over the dots")
p.circle('x', 'y', size=20, source=source)
show(p)
Hit-testing Behavior¶
The hover tool displays informational tooltips associated with individual
glyphs. These tooltips can be configured to activate in in different ways
with a mode
property:
"mouse" : | only when the mouse is directly over a glyph |
|---|---|
"vline" : | whenever the a vertical line from the mouse position intersects a glyph |
"hline" : | whenever the a horizontal line from the mouse position intersects a glyph |
The default configuration is mode = "mouse"
. This can be observed in the
Basic Tooltips example above. The example below in
Formatting Tooltip Fields demonstrates an example that sets
mode = "vline"
.
Formatting Tooltip Fields¶
By default, values for fields (e.g. @foo
) are displayed in a basic numeric
format. However it is possible to control the formatting of values more
precisely. Fields can be modified by appending a format specified to the end
in curly braces. Some examples are below.
"@foo{0,0.000}" # formats 10000.1234 as: 10,000.123
"@foo{(.00)}" # formats -10000.1234 as: (10000.123)
"@foo{($ 0.00 a)}" # formats 1230974 as: $ 1.23 m
The examples above all use the default formatting scheme. But there are other formatting schemes that can be specified for interpreting format strings:
"numeral" : | Provides a wide variety of formats for numbers, currency, bytes, times,
and percentages. The full set of formats can be found in the
NumeralTickFormatter reference documentation. |
|---|---|
"datetime" : | Provides formats for date and time values. The full set of formats is
listed in the DatetimeTickFormatter reference documentation. |
"printf" : | Provides formats similar to C-style “printf” type specifiers. See the
PrintfTickFormatter reference documentation for complete details. |
These are supplied by configuring the formatters
property of a hover
tool. This property maps column names to format schemes. For example, to
use the "datetime"
scheme for formatting a column "close date"
,
set the value:
hover_tool.formatters = { "close date": "datetime"}
If no formatter is specified for a column name, the default "numeral"
formatter is assumed.
Note that format specifications are also compatible with column names that
have spaces. For example `@{adjusted close}{($ 0.00 a)}
applies a format
to a column named “adjusted close”.
The example code below shows explicitly configuring a HoverTool
with
different formatters for different fields:
HoverTool(
tooltips=[
( 'date', '@date{%F}' ),
( 'close', '$@{adj close}{%0.2f}' ), # use @{ } for field names with spaces
( 'volume'<EMAIL_ADDRESS>a}' ),
],
formatters={
'date' : 'datetime', # use 'datetime' formatter for 'date' field
'adj close' : 'printf', # use 'printf' formatter for 'adj close' field
# use default 'numeral' formatter for other fields
},
# display a tooltip whenever the cursor is vertically in line with a glyph
mode='vline'
)
You can see the output generated by this configuration by hovering the mouse over the plot below:
Using the CustomJSHover
model, it is also possible to use JavaScript
to specify a custom formatter that can display derived quantities in the
tooltip.
Image Hover¶
The hover tool can be used to inspect image glyphs which may contain
layers of data in the corresponding ColumnDataSource
:
import numpy as np
from bokeh.plotting import figure, output_file, show
output_file("tools_hover_tooltip_image.html")
ramp = np.array([np.linspace(0, 10, 200)]*20)
steps = np.array([np.linspace(0, 10, 10)]*20)
bitmask = np.random.rand(25, 10) > 0.5
data = dict(image=[ramp, steps, bitmask],
squared=[ramp**2, steps**2, bitmask**2],
pattern=['smooth ramp', 'steps', 'bitmask'],
x=[0, 0, 25],
y=[5, 20, 5],
dw=[20, 20, 10],
dh=[10, 10, 25])
TOOLTIPS = [
('index', "$index"),
('pattern', '@pattern'),
("x", "$x"),
("y", "$y"),
("value", "@image"),
('squared', '@squared')
]
p = figure( x_range=(0, 35), y_range=(0, 35), tools='hover,wheel_zoom', tooltips=TOOLTIPS)
p.image(source=data, image='image', x='x', y='y', dw='dw', dh='dh', palette="Inferno256")
show(p)
In this example, three image patterns are defined named ramp
,
steps
and bitmask
. The hover tooltip shows the index of the
image, the name of the pattern, the x
and y
position of the
cursor as well as the corresponding value and value squared.
Custom Tooltip¶
It is also possible to supply a custom HTML template for a tooltip. To do
this, pass an HTML string, with the Bokeh tooltip field name symbols wherever
substitutions are desired. All of the information above regarding formats, etc.
still applies. Note that you can also use the {safe}
format after the
column name to disable the escaping of HTML in the data source. An example is
shown below:
from bokeh.plotting import figure, output_file, show, ColumnDataSource
output_file("toolbar.html")
source = ColumnDataSource(data=dict(
x=[1, 2, 3, 4, 5],
y=[2, 5, 8, 2, 7],
desc=['A', 'b', 'C', 'd', 'E'],
imgs=[
'https://bokeh.pydata.org/static/snake.jpg',
'https://bokeh.pydata.org/static/snake2.png',
'https://bokeh.pydata.org/static/snake3D.png',
'https://bokeh.pydata.org/static/snake4_TheRevenge.png',
'https://bokeh.pydata.org/static/snakebite.jpg'
],
fonts=[
'italics',
'
pre
',
'bold',
'small',
'del'
]
))
TOOLTIPS = """

@desc
[$index]

@fonts{safe}

Location
($x, $y)

"""
p = figure(plot_width=400, plot_height=400, tooltips=TOOLTIPS,
title="Mouse over the dots")
p.circle('x', 'y', size=20, source=source)
show(p)
Edit Tools¶
The edit tools provide functionality for drawing and editing glyphs
client-side by adding, modifying and deleting ColumnDataSource
data.
All the edit tools share a small number of key bindings:
- SHIFT
- Modifier key to add to selection or start drawing
- BACKSPACE
- Deletes the selected glyphs
- ESC
- Clear the selection
Note
On MacBooks and some other keyboards the BACKSPACE key is labelled “delete”.
BoxEditTool¶
The BoxEditTool allows drawing, dragging and deleting Rect
glyphs
on one or more renderers by editing the underlying
ColumnDataSource
data. Like other drawing tools, the renderers
that are to be edited must be supplied explicitly as a list:
r1 = p.rect('x', 'y', 'width', 'height', source=source)
r2 = p.rect('x', 'y', 'width', 'height', source=source2)
tool = BoxEditTool(renderers=[r1, r2])
The tool will automatically modify the columns on the data source
corresponding to the x
, y
, width
and height
values of
the glyph. Any additional columns in the data source will be padded
with the declared empty_value
, when adding a new box. When drawing
a new box the data will always be added to the ColumnDataSource
on
the first supplied renderer.
It is also often useful to limit the number of elements that can be
drawn, e.g. when specifying a specific number of regions of interest.
Using the num_objects
property we can ensure that once the limit
has been reached the oldest box will be popped off the queue to make
space for the new box being added.
The animation above shows the supported tool actions, highlighting
mouse actions with a circle around the cursor and key strokes by
showing the pressed keys. The BoxEditTool
can Add, Move
and Delete boxes on plots:
- Add box
- Hold shift then click and drag anywhere on the plot or double tap once to start drawing, move the mouse and double tap again to finish drawing.
- Move box
- Click and drag an existing box, the box will be dropped once you let go of the mouse button.
- Delete box
- Tap a box to select it then press BACKSPACE key while the mouse is within the plot area.
To Move or Delete multiple boxes at once:
- Move selection
- Select box(es) with SHIFT+tap (or another selection tool) then drag anywhere on the plot. Selecting and then dragging on a specific box will move both.
- Delete selection
- Select box(es) with SHIFT+tap (or another selection tool) then press BACKSPACE while the mouse is within the plot area.
FreehandDrawTool¶
The FreehandDrawTool
allows freehand drawing of lines and polygons
using the Patches
and MultiLine
glyphs, by editing the
underlying ColumnDataSource
data. Like other drawing tools, the
renderers that are to be edited must be supplied explicitly as a
list:
r = p.multi_line('xs', 'ys' source=source)
tool = FreehandDrawTool(renderers=[r])
The tool will automatically modify the columns on the data source
corresponding to the xs
and ys
values of the glyph. Any
additional columns in the data source will be padded with the declared
empty_value
, when adding a new point. Any newly added patch or
multi-line will be inserted on the ColumnDataSource
of the first
supplied renderer.
It is also often useful to limit the number of elements that can be
drawn, e.g. when specifying a specific number of regions of interest.
Using the num_objects
property we can ensure that once the limit
has been reached the oldest patch/multi-line will be popped off the
queue to make space for the new patch/multi-line being added.
The animation above shows the supported tool actions, highlighting
mouse actions with a circle around the cursor and key strokes by
showing the pressed keys. The PolyDrawTool
can Draw and
Delete patches and multi-lines:
- Draw patch/multi-line
- Click and drag to start drawing and release the mouse button to finish drawing
- Delete patch/multi-line
- Tap a line or patch to select it then press BACKSPACE key while the mouse is within the plot area.
To Delete multiple patches/lines at once:
- Delete selection
- Select patches/lines with SHIFT+tap (or another selection tool) then press BACKSPACE while the mouse is within the plot area.
PointDrawTool¶
The PointDrawTool
allows adding, dragging and deleting point-like
glyphs (of XYGlyph
type) on one or more renderers by editing the
underlying ColumnDataSource
data. Like other drawing tools, the
renderers that are to be edited must be supplied explicitly as a
list:
c1 = p.circle('x', 'y', 'width', 'height', source=source)
r1 = p.rect('x', 'y', 0.1, 0.1, source=source2)
tool = PointDrawTool(renderers=[c1, r1])
The tool will automatically modify the columns on the data source
corresponding to the x
and y
values of the glyph. Any
additional columns in the data source will be padded with the declared
empty_value
, when adding a new point. Any newly added points will
be inserted on the ColumnDataSource
of the first supplied
renderer.
It is also often useful to limit the number of elements that can be
drawn. Using the num_objects
property we can ensure that once the
limit has been reached the oldest point will be popped off the queue
to make space for the new point being added.
The animation above shows the supported tool actions, highlighting mouse actions with a circle around the cursor and key strokes by showing the pressed keys. The PointDrawTool can Add, Move and Delete point-like glyphs on plots:
- Add point
- Tap anywhere on the plot
- Move point
- Tap and drag an existing point, the point will be dropped once you let go of the mouse button.
- Delete point
- Tap a point to select it then press BACKSPACE key while the mouse is within the plot area.
To Move or Delete multiple points at once:
- Move selection
- Select point(s) with SHIFT+tap (or another selection tool) then drag anywhere on the plot. Selecting and then dragging a specific point will move both.
- Delete selection
- Select point(s) with SHIFT+tap (or another selection tool) then press BACKSPACE while the mouse is within the plot area.
PolyDrawTool¶
The PolyDrawTool
allows drawing, selecting and deleting
Patches
and MultiLine
glyphs on one or more renderers by
editing the underlying ColumnDataSource
data. Like other drawing
tools, the renderers that are to be edited must be supplied explicitly
as a list.
The tool will automatically modify the columns on the data source
corresponding to the xs
and ys
values of the glyph. Any
additional columns in the data source will be padded with the declared
empty_value
, when adding a new point. Any newly added patch or
multi-line will be inserted on the ColumnDataSource
of the first
supplied renderer.
It is also often useful to limit the number of elements that can be
drawn, e.g. when specifying a specific number of regions of interest.
Using the num_objects
property we can ensure that once the limit
has been reached the oldest patch/multi-line will be popped off the
queue to make space for the new patch/multi-line being added.
If a vertex_renderer
with an point-like glyph is supplied the
PolyDrawTool will use it to display the vertices of the
multi-lines/patches on all supplied renderers. This also enables the
ability to snap to existing vertices while drawing.
The animation above shows the supported tool actions, highlighting
mouse actions with a circle around the cursor and key strokes by
showing the pressed keys. The PolyDrawTool
can Add, Move
and Delete patches and multi-lines:
- Add patch/multi-line
- Double tap to add the first vertex, then use tap to add each subsequent vertex, to finalize the draw action double tap to insert the final vertex or press the ESC key.
- Move patch/multi-line
- Tap and drag an existing patch/multi-line, the point will be dropped once you let go of the mouse button.
- Delete patch/multi-line
- Tap a patch/multi-line to select it then press BACKSPACE key while the mouse is within the plot area.
PolyEditTool¶
The PolyEditTool allows editing the vertices of one or more
Patches
or MultiLine
glyphs. The glyphs to be edited can
be defined via the renderers
property and the renderer for the
vertices can be defined via the vertex_renderer
, which must
render a point-like Glyph (of XYGlyph
type).
The tool will automatically modify the columns on the data source
corresponding to the xs
and ys
values of the glyph. Any
additional columns in the data source will be padded with the declared
empty_value
, when adding a new point.
The animation above shows the supported tool actions, highlighting
mouse actions with a circle around the cursor and key strokes by
showing the pressed keys. The PolyEditTool
can Add, Move
and Delete vertices on existing patches and multi-lines:
- Show vertices
- Double tap an existing patch or multi-line
- Add vertex
- Double tap an existing vertex to select it, the tool will draw the next point, to add it tap in a new location. To finish editing and add a point double tap otherwise press the ESC key to cancel.
- Move vertex
- Drag an existing vertex and let go of the mouse button to release it.
- Delete vertex
- After selecting one or more vertices press BACKSPACE while the mouse cursor is within the plot area.
Controlling Level of Detail¶
Although the HTML canvas can comfortably display tens or even hundreds of thousands of glyphs, doing so can have adverse affects on interactive performance. In order to accommodate large-ish (but not enormous) data sizes, Bokeh plots offer “Level of Detail” (LOD) capability in the client.
Note
Another option, when dealing with very large data volumes, is to use the Bokeh Server to perform downsampling on data before it is sent to the browser. Such an approach is unavoidable past a certain data size. See Running a Bokeh Server for more information.
The basic idea is that during interactive operations (e.g., panning or
zooming), the plot only draws some small fraction of data points. This
hopefully allows the general sense of the interaction to be preserved
mid-flight, while maintaining interactive performance. There are four
properties on Plot
objects that control LOD behavior:
-
lod_interval
¶ property type:
Int
Interval (in ms) during which an interactive tool event will enable level-of-detail downsampling.


VANISHING, THE (SPOORLOOS)(director/writer/editor: George Sluizer; screenwriters: from Tim Krabbe's book The Golden Egg; cinematographers: Toni & Tom Kuhn; editor: Lin Friedman; cast: Johanna Ter Steege (Saskia), Gene Bervoets (Rex), Bernard-Pierre Donnadieu (Raymond Lemorne), Gwen Eckhaus (Lieneke), 1988 - Netherlands / France)
Reviewed by Dennis Schwartz
The Vanishing is a challenging psychological thriller about a nightmare that comes true and an obsession that leads to bizarre results. It makes the most of its tale by its vivid dream sequences and the masterly holding off of its inevitable findings until its conclusion, as it relies on the viewer becoming overwhelmed with curiosity to hang on until the end. It is a superbly done suspense yarn relating to what lengths someone will go to find out something that he feels he must know about himself, as this tale is told without the usual horror film special effects. It consists of the real everydayness situations, which makes the mystery seem even scarier.
The theme of disappearance has been attempted by many great directors, such as Hitchcock, in his The Lady Vanishes, but it has never been done as spookily as it is here and from such a simple storyline.
A young couple, Saskia (Johanna Ter Steege) and Rex Hofman (Gene Bervoets), from Amsterdam, are on a vacation to go cycling in the south of France, hoping to go to Bois Vieux. They are driving casually on the highway, being very playful with each other and finally getting on each other's nerves with their teasing, evidently they are still getting to know one another and don't know each other's deadly sore point. Saskia tells him about a recurring dream that she is having about her being lost and lonely in a golden egg forever and another one where both of them are sealed in separate eggs and floating through the universe.
The ominous car ride is halted when their car runs out of gas in the middle of a tunnel and despite her anxious cries of not wanting to be left alone, Rex leaves her there to go to the nearest gas station. Expecting the worst, there is a certain amount of surprise when she turns out to be fine when he returns with a can of gas, though she is irritated at him for treating her so unconscionably. They make up and are glad to stop at a service center and get gas and refreshments. She goes to the toilet and returns to buy a Frisbee and they bury a few coins by a tree to mark the spot as a reminder of their holiday and he makes a promise that she insists on, that he will never abandon her again. When she goes back into the convenience store to get some liquid refreshments, she never returns, seemingly vanishing into thin air.
There are no clues worth pursuing and the police offer little help, and three years go by with Rex becoming obsessed with finding out what happened to her. For him, it is like an intellectual jigsaw puzzle that he must compulsively put back together. He returns to the spot in Nimes with a new girlfriend, Lieneke (Gwen). They go to where the service station is and he puts posters out of Saskia. His campaign results in his receiving 5 different postcards from someone who claims to know what happened to her and who offers to meet him. Each time he goes to the designated spot of the meeting there is no one there, but he feels the presence of that person. Strangely, he starts having the same dream as Saskia had about the golden egg, and he becomes even more obsessed with finding out what happened to her.
The audience is suddenly informed of who the kidnapper is and the film tells the story of Raymond Lemorne (Bernard-Pierre Donnadieu), a middle-class science professor with a wife and two daughters. He says that he can be labeled as a sociopath and is shown to be a very precise and intelligent man, living an ordinary life. He is obsessed with a defect he has in his personality, which he noticed when he was child. He jumped, for no reason at all, from the balcony of his house, breaking his arm and losing two fingers in the fall. He also displayed courage by jumping off a bridge to save a young girl from drowning and became a hero to his family. He is currently interested in exploring the depths of his evil side to balance the good deed he once did, and thereby the viewer sees how he tries to clumsily lure a score of different women into his car without success, until that fateful summer day, when he spotted Saskia.
Rex goes on a French TV program telling about the disappearance and how he had to borrow money to continue the investigation on his own, since the police have uncovered nothing. He pleads with the person who kidnapped her to come forward with some information as to her whereabouts. One day, near his home in Amsterdam, the kidnapper comes to meet him face-to-face, and a cat-and-mouse game develops, as the two tangle with each other, going back to the spot of the crime in France.
The performances are particularly good, with Gene Bervoets being made into a victim, becoming a Kafkaesque figure, trapped in a world that is not of his making. While Johanna Ter Steege gives the film an inner light that captures the prevailing mood of the mystery. She is so sweet, honest, and endearing, that the continuing curiosity Gene shows for what happened to her is very understandable. And, Bernard-Pierre Donnadieu is perfectly credible as a self-absorbed psycho, someone who is devoid of passion, as his crime is not sexually motivated even if he seems to only target pretty woman (he says that he does so because they don't expect to be victims). He becomes an example of how banal evil can be. What is the scariest thing about him, is that his family does not see this evil side of him, as he is a good husband and father to the children, and he fits so well into the community that no one would ever suspect him.
This film is so well-crafted, that it is easy to get carried away and think that more is being said here than what has transpired. But in the simplicity of its story, it becomes easy to identify with the Amsterdam couple and feel caught up in their dreamworld which intermingles with their real-life. A film that is very much in the Hitchcock suspense mode, as a real-chiller.
REVIEWED ON 5/14/2000 GRADE: B+
Dennis Schwartz: "Ozus' World Movie Reviews"
http://www.sover.net/~ozus
<EMAIL_ADDRESS>© ALL RIGHTS RESERVED DENNIS SCHWARTZ
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Beit Shemesh has the largest number of children per family
Children make up 33% of Israel's population, statistics show.
by Arutz Sheva StaffAt the end of 2018, a total of 2.960 million children (0-17) lived in Israel.
These children made up 33% of the country's total population, Israel's Central Bureau of Statistics said Monday morning.
A full 2.131 million of the children (72%) are Jews, while 731,000 were Arabs (24.7%) and another 98,000 (3.3%) were "other" - a label used to include non-Arab Christians and other groups not identified by religion.
Of large cities with over 100,000 residents, Jerusalem had the greatest percentage of children, at 39%. In Haifa, Ramat Gan, Tel Aviv, and Bat Yam, children represented approximately one-fifth of the city's population.
Israel had an average of 2.43 children per household in 2018, and Beit Shemesh had the highest number of children per household, at 3.67. In second place was Bnei Brak, with 3.50 children per household, followed by Jerusalem with 2.99 children per household. Tel Aviv-Yafo came in last, with just 1.87 children per household.
A full 18% of children under age 17 lived in a household with no other children of any age. Nineteen percent of these children were Jews, while 11% were Arabs. Thirty percent of the families were immigrants from the former Soviet Union.
A total 184,370 babies were born in 2018, with an average of 3.09 children per woman.
Eighty-eight percent of children under age 17 live in two-parent homes, while 12% live in one-parent homes. Most of the single-parent homes (87%) were headed by an unattached mother.