Showing posts with label potentiallyUsefulInfo. Show all posts
Showing posts with label potentiallyUsefulInfo. Show all posts

Monday, November 30, 2020

Acknowledging that the available evidence may be limited and not representative of the complete evidence

It's good to use evidence to make judgments, but there's a common mistake in the way this is done. This is to assume that the available evidence is sufficient for making a judgment. It may well be sufficient, but the mistake is to assume that it is.

The limitations of the available evidence need to be assessed. Until relatively-recently, we didn't have telescopes capable of detecting exoplanets (planets orbiting other stars). Then we started to get that ability but initially could only detect very large exoplanets. Back then, it would have have been a mistake to look at the available evidence and make the judgment that no exoplanets exist, or that only very large exoplanets do.

We can ask questions like: what are the limitations of our ability to gather the relevant evidence? Has all the relevant evidence been collected, keeping in mind that resources are required to gather evidence (time and money, and people who have prioritised gathering it)? Is it possible that we could obtain more evidence in the future that could support a different judgment? Do we have good reason to believe that the evidence we have gathered so far is representative of all the possible cases?

The mistake is in assuming that a judgment being consistent with the available evidence is evidence that the judgment is correct.

So not only do we need to do more than just consider the nature of the available evidence (like its limitations). We need to consider what different judgments could be consistent with the available evidence. And we need to consider what the different possibilities could be for the missing evidence, and what judgments could be consistent with each of those different possibilities. 

In the exoplanet example, back when we didn't have the technology for detecting them, we needed to consider that the missing evidence could include exoplanets. And, obviously, that the judgment "exoplanets exist" is consistent with that possibility.

We need to be honest with ourselves if this consideration of different possibilities for the missing evidence (and the judgments they would support) shows that that are multiple different (and incompatible) judgments that could be made, like both "exoplanets don't exist" and "exoplanets exist". Being honest with ourselves means admitting it when we don't currently know the answer, and holding an agnostic attitude on this matter. It means not jumping to conclusions.

It can be difficult to do this. Having an agnostic attitude to something doesn't tend to be encouraged in our society. And we tend to have a bias towards information that we have, and against potential information that we don't yet have. We tend to privilege the information we have. It's tangible, whereas the other possibilities are not.

This bias can be subtle, such as if we take the available evidence -- from which we are prematurely forming judgments -- as evidence against possibilities that are incompatible with those judgments. If the available evidence does not include exoplanets, we may take this as evidence against the possibility that further evidence will include exoplanets.

We can't use the available evidence in this fashion. The fact that certain information is available, while certain other information is not currently available, (in general) tells us nothing of how representative the available information is of the unavailable information. What information is currently available is simply an artifact of our current abilities to gather relevant information.


When I talk of 'judgments' in the above, these are often judgments about what explains some evidence. There is one type of explanation that is routinely overlooked. When there is some apparent phenomenon in the outside world, we tend to assume that the explanation of it simply exists in the outside world. But a component of the explanation may be due to the nature of ourselves and our perception.

For example, the coloured bow-shape that we see (and the position we see it at) when we perceive a rainbow is due to the character of the light that reaches the position where we are. The actual explanation has to do with light rays interacting with water droplets over a larger area than where we see the rainbow, and the light there being scattered in a large range of directions -- and thus there is light reaching many different positions, at which different rainbows would be perceived.

There can be details that we think exist in the world but which are in fact phenomena that our brains have subconsciously invented to explain other phenomena in the world. Belief in ghosts, for example. The point is that we may think we have evidence for them, we may think that we can perceive them, and not realise that actually they're kinds of explanations for other details that our brains came up with, without us clearly understanding that this is what has happened.

I would argue (and will argue, in my PhD) that belief in an intangible 'information' is an example of such a phenomena, where part of the explanation is to do with an explanation our brains construct.

When we consider what judgments (including explanations) are supported by some evidence, we need to also consider that the apparent evidence and explanation of it may have to do with the character of ourselves (such as our perception). Doing so may expand the set of possible explanations that could be consistent with the evidence.

Sunday, November 22, 2020

How to help learners develop the subconscious knowledge that is the substance of our understanding

This post is a preliminary attempt to express some ideas about how to teach knowledge.

I imagine these ideas wouldn't always be applicable. To apply them you'd probably need to have a very good grasp on the material you want to teach, and you don't always have that (especially for difficult topics). It also seems like it'd be much more difficult to apply for more abstract knowledge.

Even though this post is itself an attempt to convey some knowledge, it doesn't follow its own dictates, for the two reasons given above.


We can distinguish between subconscious and conscious parts of our knowledge. The conscious parts of our knowledge are the parts you can consciously access. You can interrogate them with introspection, and they're what you can verbalise. There's also the subconscious knowledge that underlies those consciously-accessible details.

Think about what that knowledge enables a person to do. It may let them think about certain topics, draw certain conclusions, solve certain problems and so on. What we can verbally articulate of that knowledge is likely to be a pale shadow what is actually there in our brains that enable us to do all those things. There's a lot of subconscious knowledge that we can't consciously interrogate or articulate.

This subconscious knowledge is a big part of why AI and robotics is so difficult. Sophisticated AI or robotic systems would need to embody such knowledge, but we don't have a good enough grasp on such knowledge to be able to embody it (or much of it) in such systems.

The conscious knowledge, which we can verbalise, seems to "sit on top of" the subconscious knowledge, which is the foundation and main substance of our knowledge.

The subconscious knowledge seems to be what we primarily use when we actually apply the knowledge. When we're applying knowledge we're usually not explicitly thinking it through in verbal terms, and we couldn't verbalise those details if we wanted to.

Our understanding of the conscious knowledge (the knowledge we can verbalise) is grounded in the subconscious knowledge. We can create verbal definitions of concepts that are in our conscious knowledge, but our understanding of those concepts is primarily a matter of our subconscious knowledge. It is notoriously difficult to articulate your understanding of the meaning of concepts.


Despite this, it's easy to think that our knowledge equates to our conscious knowledge. For that's the knowledge that we can access. When we consider our conscious knowledge (for something we understand well), there's no obvious deficits to it. We can define the concepts that form it in terms of other concepts, and these in terms of other concepts, and so on. In this way, we can break down verbal descriptions of the knowledge into simpler and simpler elements. Once we've described the simplest concepts related to the top-level concepts for this bit of knowledge, we seem to have completed the task. Those simplest concepts seem to ground that task of describing the concepts.

But actually, as described above, there is subconscious knowledge underlying our understanding of all of those concepts in that hierarchy. It is because we have that subconscious knowledge that we can look at that description of the hierarchy of concepts in conscious knowledge and understand them. It's because of that subconscious knowledge that there doesn't appear to be anything missing when we describe the conscious knowledge.


Typically, when knowledge is presented in material like lectures, lecture notes, and textbooks, the focus is on communicating the conscious (verbalisable) knowledge. The overarching structure is to define the concepts. Within this structure there may be illustrations (examples) and exercises.

This is a problem because the subconscious knowledge is the substance of understanding. That's what we really want people to learn. Teaching them in a way that's focused around defining concepts is not a good way to get them to develop that subconscious knowledge.

While the person doing the teaching will already have the subconscious knowledge to understand those definitions, the learners will not. That makes it difficult for the learners to learn the conscious knowledge. And it's not what they should be learning in the first place -- the learning should be focused on them developing the subconscious knowledge.

This limitation of the teaching material won't be apparent to the teacher, because they already have the subconscious knowledge that makes the definitions understandable to them. (The distinction between conscious and subconscious knowledge, by the way, explains a lot of "the curse of knowledge", in which someone who understands some material is poor at communicating it because they can't see what it's like for someone who doesn't already understand the material).


But there's an obvious question here. What other option do we have but to try to communicate our conscious knowledge as best we can? By definition, we can't access our subconscious knowledge.

(We can't access it via introspection, nor do have knowledge of it from fields like neuroscience. We don't understand enough about how our brains work. If we were to eventually obtain such knowledge in an area like neuroscience, that might help in developing learning strategies, but it's not like if we could give someone a description of the subconscious knowledge they could learn it by reading that description.)

What I'm suggesting is not that we could or should try to directly communicate the subconscious knowledge. It is that the aim of the teaching should be, first and foremost, to present material to the learners that will best help them develop the subconscious knowledge. And this is not to present them the verbalisable conscious knowledge (definitions of concepts).


Here's how I think we can help people develop the subconscious knowledge.

The key is to recognise that knowledge is a problem-solving tool.

I mean "problem" and "problem solving" in very broad terms. I don't mean just things we'd usually label as problems or problem-solving. I mean that knowledge is there to help us do things. To figure things out, to achieve goals, to understand some issue, to draw conclusions, and so on.

Under the view that knowledge is a problem-solving tool, the bulk of our knowledge, which is the subconscious knowledge, is there for solving problems.

That means, to help learners develop the subconscious knowledge, we need to convey to them what the problems being solved are, and how the knowledge solves those problems.

The problem provides the motivation for the particular bit of knowledge. It lets the learner understand what that knowledge is there to enable. And we can show them how that knowledge solves the problem.

So we should always start with a motivating problem, and then present the relevant concept(s) for solving that problem. We should never introduce a concept without having first presented a motivating problem.


We should start with the most core of the problems and concepts. To do this, we can examine dependencies between the problems (and thus between their corresponding concepts). Those that don't depend on others are core ones. Ones that depend on others are not core ones. There may be multiple levels of non-core concepts.

And, we want to start with the simplest version of each problem/concept, and then progressively add wrinkles (special cases, or exception to the general rules) to those.

We should convey those details through concrete example scenarios that demonstrate the relevant issues we want to communicate (the problem and the means to solve it). And we should use a use a variety of situations to flesh out the learner's picture of them.

After we've demonstrated the problem and solution to the learner, such they have a concrete understanding, we can provide the names for the relevant concepts in that understanding. We should not provide their names until this point. 

It's less of a mental burden on the learner to do it this way. If you present the concept names up-front, the learners need to remember a name for something they don't yet understand.


The goal is to help the learner develop an understanding of the material. Teaching that's focused on concept definitions isn't communicating the bulk of an understanding (the subconscious knowledge). That sort of teaching puts more of a burden on the students' memories. The 'learning' becomes more of a matter of memorising and regurgitating information. The more extreme version of this is the "information dump". And not only is this the way students are taught material, but this broken picture of learning is built-into how students tend to be assessed, as well. So much assessment is oriented around recall of the conscious (verbal) knowledge. Like being able to remember facts and definitions.

If you can teach in a way that focuses on developing the student's understanding, it should put much less of a burden on their memory. Understanding will fix the relevant subconscious details in their heads.


The approach just outlined may seem inferior to the usual approach of describing the verbalisable knowledge (defining concepts).

Compared to presenting concrete problem scenarios first, as motivations for concepts, the usual approach of defining concepts may feel far more orderly, pure, objective and precise. Our approach may seem messier, less objective, and getting less at the heart of the knowledge.

I believe this is an illusion, that primarily comes from equating knowledge with the consciously-accessible, verbalisable knowledge. If you think knowledge equates to defining concepts, then defining concepts will appear to be how we should teach knowledge. But if you think that knowledge is primarily the subconscious knowledge, then we see the task differently.


Here's a brief example outlining how these ideas could be applied. It's not an example of the actual teaching material we'd present, but a high-level description of what such teaching material would contain.

This example concerns teaching people about relational databases. Unfortunately, if you're not familiar with relational databases, the following might not make a lot of sense. I chose them as a topic because they're something I have a bit of familiarity with, with respect to teaching about them.

The first thing we'd do is determine how 'core' each of the problems (and associated concepts) are. We'll use this information to determine what order to introduce them to the learners. We want to start first with the most core of the problems.

The most core problem that databases address is storing information. There's retrieving information, but first of all you need to store the information. And the most core problem to do with storing information that relational databases are designed to address is to do with unambiguous identification of information and the associated issue of redundancy of information. 

So we would start with some example scenarios that concretely demonstrate these problems. I'll go into some details of this in a moment.

After those problems associated with storing information, the next most core problem is that of retrieving information. Like of wanting to get different sorts of 'answers' about what is there in the stored information.

Retrieving information is less core than the first problem of dealing with redundancy, as the first problem has to do with storing the information, which needs to be done before we can retrieve information.

Perhaps the next most central problem is the need to be able to design a database to fit some situation. The sorts of situations we might face, and how we want to develop a design that avoids the redundancy potentially present in the information there.

Then there are many less core problems, associated with various more advanced or specific details that could be gone into after those.

(As an example of more specific details, in relation to database design there is the point that the abundance of Nulls in a table often indicates poor design. For the motivation for this we would provide an example demonstrating the issue. There's also issues like efficiency, accessing database information from within programs, security, and so on).

Now that we've determined how core each of the problems (and their associated concepts are), we know what order to present them to the learners, and we can figure out the details of how to present them. In the following, I'll go into more detail about how we could teach the knowledge associated with that first set of core problems, to do with storing the information. I won't go into similar detail for the other problems.


We could start by giving some example scenarios of information that may be stored. I.e. we would write down some of the information that might be stored. One of these might be information that a shop keeps about customers' purchase histories.

Then we would introduce the relevant concept names, like 'entity', 'field', 'table', and 'columns'.

We could give a couple more illustrations to help reinforce the concept names.


Then we could give some example scenarios that demonstrate the problem of being able to determine which real-world entity some information is about.

There could be an example of where there's customer information and where there's issues of determining which actual person the customer information is about.

For example, there are entries about customers and their purchases, which have the following customer names:

- Edward Henderson

- Ed Henderson

- E Henderson

it could be that the one employee added all of these bits of information, and they remember who these entries refer to (perhaps they all refer to the same person). But maybe they will forget these details in a few months. Or maybe a different employee is looking at the data and trying to figure out who each of those entries refers to. Is it the same person, or different people?

Being able to determine which person the information is about is important for being able to find all the information about a particular person. That may be just to see that information, or it may be for if we need to change that information (e.g. if that person decides to change their name, and we want to change all occurrences of their name that we've stored) or something associated with it.


Then we can give example scenarios demonstrating that, by ensuring that all entities have a unique identity, these problems are avoided. We can illustrate some of the different ways entities can have unique identity (e.g. a combination of existing fields they might have, or giving them a new field like an identification number).


Then we can illustrate why it is that information about the same entity may occur multiple times in the information we've stored.

In our example we can see it's because the one customer may make multiple purchases (on different days). So we record information about that customer for each of those purchases.

We can give other examples to show that each time an entity occurs multiple times, it's because it is related in some way to multiple instances of some other kind of entity (e.g. if a library tracks all the book borrowings of a person, that person will occur once for each borrowing).

After having illustrated this concept, we can introduce the name 'one-to-many relationship' for it.


We can present scenarios that demonstrate that where there's one-to-many relationships and there's duplication of data (like if for each purchase we stored the customers first and last names and postcode) we run into problems similar to the ones we mentioned at the start where the person's name was entered multiple times and potentially spelled in multiple different ways. Difficulties in finding all the cases you want, and in updating them, and where errors can be introduced.

Then we can show examples illustrating how this problem can be addressed by having a separate table for the 'one' entities (like customer), where all the information about the 'one' entities is stored. We've established that each entity should have unique identifier (say that each customer is given a 5 digit identifier). Thus we can just include this identifier in the 'many' table (purchases) and not have to include any other information about the customer in the purchases table.

So the only customer information that gets duplicated is its identity. The identity is something that shouldn't change, so we don't have the issues of needing to make changes to all occurrences of that same information (but even still, since it is unique, we can have the software easily find all instances of it and thus change them if we needed to).


Once we have a table that's just for the 'one' entities (in one-to-many relationships), the computer software can do things automatically for us

  • check that each entity has a unique identity (and not let us add one that doesn't have a unique identity)
  • check that a reference to an identity (in a 'many' table) is to one that actually exists (actually, and also that it's of the right type of entity, as we'll get to).
  • we can also set up the software to automatically create a unique identity (like an ID number) for new entities 

(Having a separate table for the 'one' entity in a 'one-to-many relationship' creates issue of having to cross reference the customer table if we're looking at a purchase and want to find out details about the customer (like their postcode), which adds some complexity, but later we'll see how the software can automate this).


After having illustrated these details about identities, and referencing identities where there's one-to-many relationships, we can introduce the following names for the concepts
- primary keys (what uniquely identities entities)
- foreign keys (the references to these entities)

To reinforce the understanding of these concepts we've just named, we would then further illustrate them with examples.

.

Related: Being able to explicitly reason about a concept is a skill. That post argues that learning how to reason about a concept is learning a skill, which means it requires practice. That relates to the present post in that when you provide the concrete scenarios presenting the problems and how the concepts can be used to solve them, you want to present multiple varied scenarios such that the learner can practice seeing things in these terms. And you'd want to give them exercises to do along the way, and feedback, as well.

Wednesday, November 18, 2020

"Be kind because you never know what someone is going through" is a nice sentiment but fairly useless advice

You might have heard the advice "Be kind, because you never know what someone is going through". I think that's a nice sentiment, but at the same time I think that, as advice, it's pretty useless.

This advice is meant to apply to situations where you might negatively judge someone. Perhaps they seem grumpy, or scruffy, or vague, or are exhibiting some other negative behavior or trait.

The advice sounds good -- instead of jumping to conclusions about that person, acknowledge that they might have some hidden struggles that are causing them to be that way. By following this advice you can be more compassionate.

But I think the advice is fairly useless in practice, in that it doesn't make people more compassionate.

It's predicated on the idea that people observe the behavior of the other person, and then formulate a negative judgment of the person. The advice is meant to short-circuit the second-step of that process.

Forming that negative judgment is in effect developing an explanation of the reason for the person's behavior: they're acting that way because they're a jerk, or a loser. The explanation is usually that there's some defect in the person's character.

But I don't think that two-step process (perceive, then draw conclusions) exists in reality. In reality, people's observations are the judgments. They perceive a person who is a jerk, a lazy arsehole, or a grumpy mofo. Their perception inherently contains the explanation. And that explanation appears to them to be an objective part of what they're observing.

The advice to "Be kind, because you never know what someone is going through" requires you to think that you don't actually know what the cause of someone's behavior is. But in real life we tend to always think we do, objectively, know why the person is behaving in that way (because they're a jerk, and so on).

We might appreciate the point about being kind in the abstract, but we're not likely to think it applies in the cases where it actually does.

What would better advice look like? It would acknowledge that our perceptions inherently involve explanations of what is being perceived, and that doing this is the problem.

It might look something like the following (but ideally more concise and punchy): Remember that, though your perceptions of people seem objective, your brain is subconsciously making assumptions about people's character in order to explain their behavior, and these assumptions can be wrong. Their behavior might not be because of their character, but because of what they're going through.

Saturday, November 14, 2020

Walking is good for working out the structure of some writing

During the pandemic, I've been going for a lot of afternoon walks, and I've found that walking is a great way to work out what I want to say with some writing.

It helps me work out the overall structure of the writing. I can figure out that structure from scratch, and something about walking frees up my mind for that task. And I can't use some external representation of the details as a crutch. I'm forced more to justify the structure to myself.

I find it helps to speak out loud while I'm walking. I wear a pair of headphones with a microphone and record what I'm saying using my phone's voice recorder. Having it actually recorded seems to impose a bit of discipline, that aids in figuring things out.

When I'm sitting at the computer, I tend to be much more constrained by the existing content I've written. Even though I often create new documents as I'm drafting the material. It's just more difficult to figure out what the overall structure of the material should be.

In the past I've tried using whiteboards and paper-based notes to work out the structure of the material, and neither of those were as good as walking.

What working at the computer is better for is getting into the nitty-gritty of my argument and how I'm expressing that.

Monday, December 31, 2012

Books I read in 2012


The best:

Wool - Omnibus edition, by Hugh Howey
Great bit of storytelling


.


Ones that were decent:

We Are All Weird, by Seth Godin
A touch wishy-washy but an interesting, brief look at broad cultural currents.

Rainbows End, by Vernor Vinge
Fairly good, but mainly as a plausible near-future (c 2025) world of pervasive augmented reality & wearable computers.


A number of Kindle Singles, all of which were decent:

My Seinfeld Year, by Fred Stoller
Memoir. A couple of interesting insights into how the writing process for Seinfeld worked.

Gutenberg the Geek, by Jeff Jarvis
A look at Gutenberg as an entrepreneur

Cautionary Tales, by Stephen Tobolowsky
Memoir of bad (but funny) mistakes the author made.

The First Light of Evening, by Mark Ernest Pothier
A day in the life of a guy 3 years after divorce and still dealing with it. Pretty nicely done.

Shakedown, by James Ellroy
Pretty sharply written. Somewhat salicious.


A number of books on ancient Rome, all pretty decent. Working on slowly building up my understanding of history.

Ancient Rome: The Rise and Fall of an Empire, by Simon Baker.
Decent, readable basic overview. Focus mainly on politics and major political figures

The World of Rome, by Michael Grant
This one was a bit less readable than the others, but fairly informative.

Rubicon: The Triumph and the Tragedy of the Roman Republic, by Tom Holland

Julius Caesar, by Philip Freeman

Cicero: The Life and Times of Rome's Greatest Politician, by Anthony Everitt

Antony and Cleopatra, by Adrian Goldsworthy

Augustus: The Life of Rome's First Emperor, by Anthony Everitt


.


Ones I really didn't like. I'd avoid these: 


The Metamorphosis of Prime Intellect, by Roger Williams

Accelerando, by Charles Stross


.


And several that I read bits of but didn't around to finishing. Not because I didn't like them, just didn't get time:

Stop Stealing Dreams, Seth Godin

The Mammoth Book of Best New Science Fiction 23, by Gardner Dozois
I read about 5 stories from this, and didn't think much of most of them.

Pro Git, by Scott Chacon

Poems of Emily Dickinson, series 1, by Emily Dickinson

Monday, April 11, 2011

Making Vim copy all yanked text to the system clipboard

In addition to the usual cut and paste operations found in most other editors, Vim has a 'yank' command that can be followed by a motion operator.

So you can type yw to copy a word to the clipboard, or y3w to copy three words, or yip to copy the current paragraph to the clipboard, and so on.

Which is useful. But by default the text copied by the yank command is only accessible from within that same instance of Vim.

So if you've opened another instance of Vim in a new window[1] and you want to paste the text into that, or you want to paste it into another program, you can't.

An IMO problematic solution is to set 'unnamed' in the 'clipboard' option in your .vimrc / _vimrc, like so

set clipboard+=unnamed

this works but it has a downside - it also means all deleted text gets sent to the system clipboard.

Most of the time I delete text because I just want to get rid of it. When I tried setting this option I kept overwriting the clipboard contents (that I did want) with the deleted text that I didn't want.

And if you do actually want to delete text _and_ copy it to the clipboard you can use a cut command - i.e. C-x. So set clipboard+=unnamed doesn't seem like a good idea.

Here's a better solution, that just ensures yanked text is copied to the system clipboard. Just add the following line to your .vimrc / _vimrc:

nnoremap y "+y

The "+ tells Vim to yank into the + register, which is the system register.




[1] I know many people like to work within one Vim instance and use splits/buffers and tabs to arrange their files, and may want to suggest this as an alternative, but I find it very useful to work with multiple Vim instances. It's a long story, but I like to be able to spatially arrange the (OS)windows in a certain way that reflects the relationship between the files in them, and you can't achieve what I want with a single Vim instance.

Monday, February 22, 2010

My Vim setup

[updated: 02.03.14; 11.4.10; 23.2.10; 17.1.10; 29.8.09; 31.8.09]
vimrc
(UNIX/Mac: ~/.vimrc; Windows: $VIM/_vimrc)

" vim:fo-=a


set nocompatible


"== pathogen
call pathogen#runtime_append_all_bundles() 


filetype plugin indent on 



set autowriteall   " auto save the file on things like :next

set switchbuf=usetab,newtab


" Make shift-insert work like in Xterm
map  
map!  

if version >= 500

  " highlight strings inside C comments
  let c_comment_strings=1

  " Switch on syntax highlighting if it wasn't on yet.
  if !exists("syntax_on")
    syntax on
  endif

  " Switch on search pattern highlighting.
  set hlsearch

endif



set shiftwidth=4
set softtabstop=4
set expandtab

set linebreak      " dont linebreak inside words
set mousehide    " hide the mouse when typing text
set splitbelow


"== search related
set ignorecase smartcase
set incsearch
function! NoHLSearch(pat)
   call search(a:pat)
   set nohls
   set hls
endfunction
" command -nargs=1 S :call NoHLSearch()
" F5 - toggle highlight search
map  :set hls!set hls?


" unicode - for hars pasted from web-pages, PDFs etc (see usr_45.txt)
set encoding=utf-8


" ** actualyl these sould be defined in vimrc and called in there to set
" the default that is set when vim is run.
function! NormalWritingModeLinesAndLinespace()
    set lines=36
    set linespace=4
endfunction

function! DraftingWritingModeLinesAndLinespace()
    set lines=21
    set linespace=13
endfunction


"== syntax/display
set columns=75
" set lines=38
" now setting it to less as i've increased linespace
" set lines=32
" set linespace=5
call NormalWritingModeLinesAndLinespace()
set ch=2  " Make command line two lines high
set laststatus=2   " so last remaining window always has a statusline
" make closed folds less visually prominent
highlight Folded guifg=LightBlue
function! MyFoldText()
    let leadingSpaces = "                                                                   "
    return leadingSpaces . "\\" . (v:foldend - v:foldstart)
endfunction
set foldtext=MyFoldText()
" note that the following has a backslash followed by one space
set fillchars=fold:\ 
highlight statusline guibg=LightGray guifg=DarkGray gui=none
set statusline=
set statusline+=%{getline(search(\"^[:#]\",\ \"bnW\"))}   " show curr heading
set statusline+=%=                                     " show rest right justified.
set statusline+=\ \ %c\,\ %l\ (%L)                     " col, line (tot lines)
highlight CursorLine guibg=#D9D9D9
"colorscheme morning
"set background=light " dark   " for solarized
if has("gui_macvim")
    colorscheme solarized
else
    colorscheme morning
endif



set backup          " turn on backup
set backupdir=/Temp/vimFileBackups    " dir for tilde files
set dir=/Temp/vimSwapFiles     " dir for swap files 
" mustn't have trailing slash. otherwise subsequent additions wont work 
set path+=~/Notes
set path+=~/PhD


set autoindent


set browsedir=current       " open file browser in current dir 

set selectmode=key



"== snipmate options
let g:snips_author = "James Cole" 


"== taglist options
let g:Tlist_Auto_Open=1
set updatetime=100
let Tlist_WinWidth = 40
let tlist_text_settings  = 'text;h:headings'
nnoremap   :TlistToggle
" To not display the Vim fold column in the taglist window
let g:Tlist_Enable_Fold_Column = 0
" only show contents of the current file in current tab
let g:Tlist_Show_One_File = 1

" weird, my computer crashed and after restarting it would no longer 
" generate the tags. it'd say 
" Taglist: Failed to generate tags for /my/path/to/file
"   ctags: illegal option -- -^@usage: ctags [-BFadtuwvx] [-f tagsfile] file ...
" Taglist FAQ says this is coz its not using the exuberant ctags file.
" if i type ctags in shell it gets exuberant one...
" but anyway i recently installed oh-my-zsh, which might be somehow the 
" problem.  setting the following var fixes the prob
" This seems to be about this problem (though I didn't it all):
" http://vim.1045645.n5.nabble.com/MacVim-and-PATH-td3388705.html
let Tlist_Ctags_Cmd = '/usr/local/bin/ctags'



" assume it gets a valid filename and path 
function! GetMarkdownHtmlFilename()
    let b:htmlFileNameForMarkdownDoc = expand('%:t:r') . ".html"
    let dialogPrompt = "Name and location for HTML file"
    let b:htmlFileNameForMarkdownDoc = 
        \ inputdialog( dialogPrompt, expand('%:p:h') .  "/" .  b:htmlFileNameForMarkdownDoc) 
    let menuTypeAndLoc = "amenu 900.107 "
    let menuItemName = "&Personal.A&uto\\-generate\\ HTML\\ on\\ save"
    let menuCall = ":silent call GetMarkdownHtmlFilename()"
    let menuDef = menuTypeAndLoc . menuItemName . menuCall
    execute(menuDef)
endfunction

" let markdownUtilName = "multimarkdown"
let markdownUtilName = "peg-markdown"
function! SaveFile()
    w
    TlistUpdate
    if exists("b:htmlFileNameForMarkdownDoc")
        execute("!" . g:markdownUtilName . " % > " . b:htmlFileNameForMarkdownDoc)
    endif
endfunction

nnoremap   :silent call SaveFile()
inoremap   :silent call SaveFile()
vnoremap   :silent call SaveFile()gv


"== tabbar options
let g:tagbar_expand = 1
let g:tagbar_updateonsave_maxlines = 7000



"== scrolling 
imap  
set sidescroll=1   " smooth horizontal scrolling - 1 char at a time
set scrolloff=1


"== cut and paste
" set clipboard+=unnamed    " copy yanks and deletions to system clipboard 
" send all yanked text to the system clipboard
nnoremap y "+y
" a 'cut' operator that can be used with text-objects, where cut text
" is placed on the system clipboard.
nmap \u "+d


" F4 - show list of headings in document
map  :g/^:/

" F6 - change all the non-displayed chars to plain-text equivs
"    (note how have to escape pipes between commands, and
"     double escape pipes within replace commands)
map  :%s/—/--/ge \| %s/…/.../ge  \| %s/“\\|”/"/ge  \|  %s/‘\\|’/'/ge


" F7 - to condense selected lines
" very quick a dirty way to do it, should put all the words in a datastructure
" and handle words and their variants ending with s better
map   :s/\/\&/ge  \| '<,'>s/\/tt/ge \| '<,'>s/\/b\/ween/ge \| '<,'>s/\/w\//ge \| '<,'>s/\/info/ge \| '<,'>s/\/compu/ge \| '<,'>s/\/r/ge \| '<,'>s/\/pic/ge \| '<,'>s/\/2/ge \| '<,'>s/\/in2/ge \| '<,'>s/\/b/ge \| '<,'>s/\/defn'd/ge \| '<,'>s/\/4/ge \| '<,'>s/\/Howevr/ge \| '<,'>s/\/defn /ge \| '<,'>s/\/partic/ge \| '<,'>s/\/thng/ge \| '<,'>s/\/thngs/ge \| '<,'>s/\/whch/ge \| '<,'>s/\/prt/ge \| '<,'>s/\/arg/ge \| '<,'>s/\/u/ge\| '<,'>s/\/wnt/ge \| '<,'>s/\/othr/ge \| '<,'>s/\/corresp/ge \| '<,'>s/\/4/ge\| '<,'>s/\/reps/ge \| '<,'>s/\/abve/ge \| '<,'>s/\/char/ge \| '<,'>s/\/chars/ge \| '<,'>s/\/req'd/ge \| '<,'>s/\/undef'd/ge \| '<,'>s/\/replacemnt/ge \| '<,'>s/\/dest/ge \| '<,'>s/\/src/ge \| '<,'>s/\/ure/ge \| '<,'>s/\/langs/ge \| '<,'>s/\/frm/ge \| '<,'>s/\/orig/ge \| '<,'>s/\/abt/ge \| '<,'>s/\/prop/ge \| '<,'>s/\/attrib/ge \| '<,'>s/\/qu/ge \| '<,'>s/\/diff/ge \| '<,'>s/\/philos/ge \| '<,'>s/\/impl/ge \| '<,'>s/\/req'd/ge \| '<,'>s/\/elems/ge \| '<,'>s/\/elem/ge


" insert '.x' at the start of the line - i've got syntax highlighting so
" that this line is 'crossed off' (as a plain text equiv so strikethrough)
" i use it for my planning docs and the 'to do' sorts of items in it
map  I.x 


" pump out lines below the cursor 
" orig ver: nnoremap  ok
" newer ver that supports counts - see http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_2)
" nnoremap  @='ok'


" execute the selected lines on the ex-line 
" e.g. if those lines contain a function you're coding, or a map
" so you don't have to copy those lines then type ':@"' 
vnoremap x "xy:@x





" note that we may have already deleted some of the files created today..... 
"   e.g. the files from today left might be 
"          100423.txt
"          100423--3.txt
"          100423--4.txt
" and we don't really want to just find the first available sequence num....
" but actually the first one after the current greatest sequence num
function! SaveNewPhdFile()    
    let today = strftime("%y%m%d") 
    let newFileName = today
    let theFileNames = glob(newFileName . "*.txt")
    let suffixes = []
    for fileName in split(theFileNames, "\n")
        let res = matchlist(fileName, "--\\(\\d\\+\\)")
        if res != []
            call add(suffixes, res[1]) 
        " assume it is the unsuffixed file for this date
        else 
            call add(suffixes, 1)        
        endif
    endfor
    " note: max rets 0 on an empty list, which will be case when none of the files had suffixes
    let suffix = max(suffixes) + 1  
    if (suffix > 1)
        let newFileName = newFileName . "--" . suffix . ".txt"
        " ^ for some reason += isnt working  ??
    else
        let newFileName = newFileName . ".txt"
    endif
    exec "w " . newFileName
endfunction

command CreatePhdDocument :call SaveNewPhdFile()

" improvement: hmm, i think i could exec both of these in the one command... and
" whatever is used to separate two commands.. like an ampersand i
" think...thatd guarntee that one only happens after the other and that
" only a single window is used.
function! AddFileToGit()
    exec "silent !git add " . expand("%:p")
    exec "silent !git commit " . expand("%:p") . " -m 'added'"
endfunction
command AddFileToGit :call AddFileToGit()



" @nextAvailable - if '1' attempt to delete the next block of whitespace lines
"   in the given direction, not just any immediately above current line
function! DeleteBlankLinesAboveOrBelow(direction, nextAvailable)
    let currLineNum = getpos(".")[1]
    if (a:nextAvailable == 1)
        let currLineNum = GetNextWhiteSpaceLine(currLineNum, a:direction)
    else
        let currLineNum = Next(currLineNum, a:direction)
    endif
    while (WithinDocument(currLineNum))
        if getline(currLineNum) =~ "^\\s*$"
            exec currLineNum . "delete"
            " note that if we're deleting lines below (direction == 0)
            " then the line numbers below will be one less each time we
            " delete a line
            if (a:direction == 1)
                let currLineNum = Next(currLineNum, a:direction)
            endif
        else
            break
        endif
    endwhile
endfunction

    "  ^ the problem i was having was coz i wasnt reading the documentation of
    "   delete closely enough. i thought you put the line number (or rather,
    "   range) /after/ the delete text. 
    

" the maps stand for 'delete blanks above/below' 
nmap  dba :call DeleteBlankLinesAboveOrBelow(1, 0)
nmap  dbA :call DeleteBlankLinesAboveOrBelow(1, 1)
nmap  dbb :call DeleteBlankLinesAboveOrBelow(0, 0)
nmap  dbB :call DeleteBlankLinesAboveOrBelow(0, 1)

" ^ hmm, if you have these maps as 
"       dsa     (delete space above, etc etc)
"       dsA
"       dsb
"       dsB
"   then for some unknonw reason when you 
"   type 'dd' it pauses before doing it, as if you could be typing 
"   some other thing after it - but none of these start with 'dd' ??
"   but then why can surround.vim not have this effect??


    " @direction:  1 - up, 0 - down
    function! Next(item, direction)
        if (a:direction == 1)
            return a:item - 1
        else
            return a:item + 1
        endif
    endfunction


    function! WithinDocument(lineNum)
        return a:lineNum >= 1 && a:lineNum <= getpos("$")[1]
    endfunction


    function! GetNextWhiteSpaceLine(currLineNum, direction)
        " cases (just in the upwards direction)
        "     - 1. next line above *is* whitespace
        "     - 2. next line above isnt whitespace
        "         - 2.1 whitespace line is N lines above
        "         - 2.2 there are *no* lines of whitespace above
        " 
        "     - 1 & 2 r both handled coz it is passed the line the cursor was
        "       on when deletion command was called, and it just starts looking
        "       from that line 
        "     - the code in general handles 2.1
        "     - the uses of WithinDocument handle 2.2
        let newLineNum = Next(a:currLineNum, a:direction) 
        while ( getline(newLineNum) !~ "^\\s*$" && WithinDocument(newLineNum) )
            let newLineNum = Next(newLineNum, a:direction)
        endwhile
        if !WithinDocument(newLineNum)
            return a:currLineNum
        else
            return newLineNum
        endif
    endfunction
     " *** should really put the regex for whitespace lines into a var!
    " testing map  :echo(GetNextWhiteSpaceLine(getpos(".")[1], 1))


function! FormatXml()
   % !xmllint.exe % --format
endfunction
command FormatXml :call FormatXml()



function! SOnPlural(num)
    if a:num == 1 || a:num == -1
        return ""
    else
        return "s"
endfunction


cd ~/PhD/working/2013/

" show the 'cued-up' keys as you type them, eg as you type 3d
set showcmd

" Highlight from start of fileEdit
" most accurate but slowest 
" see http://vim.wikia.com/wiki/Fix_syntax_highlighting 
" autocmd BufEnter * :syntax sync fromstart

set textwidth=9000
set formatoptions-=a

autocmd FileType text set textwidth=75
" auto-format as you insert text
autocmd FileType text set formatoptions+=a
" With this, a linebreak means a new para, unless trailing whitespace at 
" end of line.  It means that the 'a' option doesn't auto join lines 
" separated by a linebreak.
autocmd FileType text set formatoptions+=w

set hidden
set switchbuf=useopen,usetab

set tabpagemax=35

let g:gitgutter_enabled = 0

set foldmethod=manual


gvimrc
(UNIX/Mac: ~/.gvimrc; Windows: $VIM/_gvimrc)
" vim:fo-=a if has("win16") || has("win32") || has("win64")|| has("win95") " get normal ALT-SPACE behavior map :simalt ~ set gfn=Lucida_Sans_Typewriter:h18:cANSI elseif has("gui_macvim") set gfn=Menlo:h15 endif set cursorline " highlight line cursor is on set guioptions-=T " no toolbar " must be set in vimrc rather than vimrc - they're values are reset when " gvim starts set vb t_vb= function! SubsituteTildeForHomeDir(path) " " want the trailing slash to avoid case of a file in " parent of homedir starting with homedir's name " e.g. if homedir is /users/James " if there was a file called /users/JamesNotex.txt " let homeDir = expand("~") . "/" let newPath = substitute(a:path, "^" . homeDir, "~/", "") return newPath endfunction " sets window title that shows, in this order, these details: " - for unnamed files " - '[No Name]' " - a '+' if buffer has been modified " - current working directory " - vim server instance name " - for named files " - filename " - a '+' if buffer has been modified " - path " - if we're currently auto-generating HTML for this markup, " indicate name+path of that file " - vim server instance name " in any paths, a tilde is substituted for the home directory " function! JamesTitleString() " get list of nums of the buffers assoc'd w/ each window in curr tab page. let l:bufnrlist = tabpagebuflist() let fileNameAndPath = bufname(l:bufnrlist[tabpagewinnr(tabpagenr()) - 1]) " show only the filename (get rid of all the path details) let fileName = substitute(fileNameAndPath, ".*/", "", "") " 'escape' ampersands, so they 1) aren't hidden " & 2) make character following them underlined let fileName = substitute(fileName, "&", "&&", "g") if fileNameAndPath == "" let title = "[No Name]" else let title = fileName endif " Add '+' if the current buffer in the tab page is modified if getbufvar(l:bufnrlist[tabpagewinnr(tabpagenr()) - 1], "&modified") let title = title . ' +' endif if fileNameAndPath == "" let title = title . " (CWD: " . SubsituteTildeForHomeDir(getcwd()) . ")" endif if fileNameAndPath != "" let title = title . " (" let title = title . SubsituteTildeForHomeDir(expand("%:h")) let title = title . ")" endif " if we're currently auto-generating HTML for this markup, indicate name+path of that file if exists("b:htmlFileNameForMarkdownDoc") let title = title . " [->" . b:htmlFileNameForMarkdownDoc . "]" endif let title = title . " - " . v:servername return title endfunction set title set titlestring=%{JamesTitleString()} " max size of titlestring set titlelen=100 function! JamesTabLabel() let label = '' let bufnrlist = tabpagebuflist(v:lnum) " Add '+' if one of the buffers in the tab page is modified for bufnr in bufnrlist if getbufvar(bufnr, "&modified") let label = '+' break endif endfor " Append the number of windows in the tab page if more than one " let wincount = tabpagewinnr(v:lnum, '$') " if wincount > 1 " let label .= wincount " endif " if label != '' " let label .= ' ' " endif " ^ commented out because it includes taglist window in count " an enhancement would be to filter it out let fileName = bufname(bufnrlist[tabpagewinnr(v:lnum) - 1]) " show only the filename (get rid of all the path details) let fileName = substitute(fileName, ".*/", "", "") " 'escape' ampersands, so they 1) aren't hidden " & 2) make character following them underlined let fileName = substitute(fileName, "&", "&&", "g") " don't show '.txt' extensions let fileName = substitute(fileName, "\\.txt$", "", "") let label = label . fileName return label endfunction set guitablabel=%{JamesTabLabel()} function! OpenMyFiles() " note that for filepaths, must use forwards-slashes let notesDir = "~/Notes" let phdWorkingDir = "~/PhD/working" let dropBoxDir = "~/Dropbox" let fileList = [ \ notesDir . "/2014-plan.txt", \ notesDir . "/2014-days.txt", \ dropBoxDir . "/Apps/PlainText\\ 2/plan.txt", \ notesDir . "/vim.txt", \ notesDir . "/biograph.txt", \ notesDir . "/food&drinks.txt", \ notesDir . "/artsRelated.txt", \ phdWorkingDir . "/phdNotesInclSources.txt", \ notesDir . "/projectsToWorkOn.txt", \ notesDir . "/doAndGet-ideas.txt", \ notesDir . "/media-ideas.txt", \ notesDir . "/presents-ideas.txt" \ ] " \ notesDir . "/compu.txt", " \ notesDir . "/aiya,univData.txt", " \ notesDir . "/thinking&Knowl.txt", " \ notesDir . "/writing.txt", " \ notesDir . "/postQueue.txt", " \ notesDir . "/otherIdeas.txt", " \ notesDir . "/I-F&Games.txt", for fileName in fileList exec "e " . fileName exec "tabe" endfor exec "tabc" exec "tabdo :TlistToggle" " now, put the focus on the days file exec "normal! 2gt" set columns=135 endfunction " dev notes: " originally I didnt have the command there to join the lines, and it " didnt work properly. the reason was that you can't call exec like that " when there are a range of lines specified on the command line, as there " will be because there is a selection - and that sucks. the only " reasonable option would be if i could just put the 's' command there " without putting it as an arg to the exec...which i tried but it didnt " seem to work. if you use the substitute function, it only works on a " per-line basis, which'd be a pain. " could ask vim-use if there's a better way to do this. function! ConvertStringToFileName() normal! gv normal! J exec "s#\\<\\l#\\u&#ge" normal! gv exec "s/ //ge" exec "s/:/-/ge" endfunction " kinda silly way to impl this - I dont know how to define it as a string " and just insert that string. dont know how to encode the linebreaks. but " it works. function! InsertNotesFileFields() let oldFo = &fo set fo-=a normal! O normal! otitle= normal! oauthor= normal! otype= normal! oyear= normal! otopics= normal! oread= normal! o normal! o normal! o---------- normal! o let &fo = oldFo endfunction " requires the input text to be visual selection function! CleanTranslinkResult() let stringsToRemove = "Take Bus\\|\\t\\|(.\\{-})\\|daily timetable\\|trip timetable\\|Departing\\|Arriving\\|Zones travelled in:.*$\\|Fares for this journey.*$\\|Fare included in the next trip.*$" normal! gv exec "'<,'>s/" . stringsToRemove . "//ge" endfunction function! WrapAllLines() let oldTw = &tw let &tw = 9000 normal! gg normal! gqG let &tw = oldTw endfunction function! CloseTlistAndSetColumns() TlistClose set columns=76 endfunction function! GetLevel(theLine) if a:theLine =~ "^:" return 0 else return 1 endif endfunction function! FoldOnColonHeadings() setlocal foldmethod=expr " Make all the text within each section a fold " note that you dont call that func you just spec the func name setlocal setlocal foldexpr=GetLevel(getline(v:lnum)) " set columns=77 " setlocal foldcolumn=2 normal! zR endfunction "== menus function! OpenMyFiles_MenuItem() call OpenMyFiles() amenu disable &Personal.&Open\ Standard\ Files endfunction amenu 900.100 &Personal.&Open\ Standard\ Files :silent call OpenMyFiles_MenuItem() amenu 900.105 &Personal.C&lose\ Tlist\ and\ Set\ Columns :silent call CloseTlistAndSetColumns() amenu 900.107 &Personal.A&uto\-generate\ HTML\ on\ save :silent call GetMarkdownHtmlFilename() amenu 900.109 &Personal.Toggle\ GitGutter :GitGutterToggle amenu 900.110 &Personal.&Format\ XML :silent call FormatXml() amenu 900.120 &Personal.&Convert\ String\ To\ File\ Name :silent call ConvertStringToFileName() amenu 900.140 &Personal.Clean\ &Translink\ Result :silent call CleanTranslinkResult() amenu 900.150 &Personal.&Insert\ Notes\ File\ Fields :silent call InsertNotesFileFields() amenu 900.160 &Personal.&Wrap\ All\ Lines :silent call WrapAllLines() " eventually i want to put ticks next to the selected ones ✓ amenu 900.170 &Personal.W&riting\ Mode.&Normal :silent call NormalWritingModeLinesAndLinespace() amenu 900.180 &Personal.W&riting\ Mode.&Drafting :silent call DraftingWritingModeLinesAndLinespace() colorscheme solarized set background=light " for solarized " its set to dark in vimrc, as light is unreadable in terminal " make the highlighting of search terms less prominent " this is a lighter shade of brown " highlight Search guifg=#cbac4c highlight Search guifg=#dac47f


Autocommand for setting filetype of .txt files
(UNIX/MAC: ~/.vim/bundle/myadditions/ftdetect/txt.vim; Windows: $VIM/vimfiles/bundle/myadditions/ftdetect/txt.vim)
au BufNewFile,BufRead *.txt setf txt


$HOME/ctags.cnf (unix/mac: $HOME/.ctags. ctags website).
--langdef=txt
--langmap=txt:.txt
--txt-kinds=+h
--regex-txt=/^(:.*)$/\1/h,headings/

($HOME is an environment variable ctags uses; that's where it looks for the configuration file - I've set mine to same dir as $VIM)


$VIM/vimfiles/syntax/txt.vim
syntax match lvl1Heading /^:[^:].*$/
syntax match lvl2Heading /^::[^:].*$/
syntax match lvl3Heading /^:::[^:].*$/
syntax match lvl4Heading /^::::[^:].*$/
syntax match lvl5Heading /^:::::.*$/

highlight lvl1Heading guifg=#0000FF
highlight lvl2Heading guifg=#0075FF
highlight lvl3Heading guifg=#0095FF
highlight lvl4Heading guifg=#60B9FF
highlight lvl5Heading guifg=#90DCFF


syntax match crossedOutLine /^\s*\.x.*$/
highlight crossedOutLine guifg=#AAAAAA



Add-on scripts
  • matchit
  • three related ones by Tim Pope
  • snipMate - TextMate-style snippets for Vim
    • though i haven't used this one much yet
  • taglist
    • for this i've installed ctags, and put it in my PATH environment variable (in my case in c:\programs\ctags58)
    • to get it to work properly with tabs (the 'tabs' for selecting different files, not the 'tabs' for indenting) apply the following patch
      --- plugin/taglist.vim 2008-08-13 19:04:48 +0000
      +++ plugin/taglist.vim 2008-08-27 19:24:49 +0000
      @@ -4097,6 +4097,12 @@
      " window. Used after entering a tab. If this is not done, then the folds
      " are not properly created for taglist windows displayed in multiple
      tabs.
      function! s:Tlist_Refresh_Folds()
      +
      + " Not needed when one file is displayed.
      + if g:Tlist_Show_One_File
      + return
      + endif
      +
      let winnum = bufwinnr(g:TagList_title)
      if winnum == -1
      return
  • renamer - rename multiple files by editing a text document
    • Allows you to use the familiar editing techniques like regexs and using visual-block mode to rename multiple files, and also not have to deal with the escaping you have to do with a shell
    • I came across this in a discussion thread about the editor-agnostic massren util, which allows you to do a similar thing. I ended up using renamer as I couldn't get massren running properly on my system.



How I've dealt with Vim's temp files

Details here.

Thursday, July 23, 2009

How to backup Winamp song ratings and playcounts, and media library playlists

If you want to backup your Winamp song ratings and playcounts, as well as the playlists you create within the Media Library, this is how you can do it. You can back it up so you don't lose the information when you get a new computer and reinstall Winamp onto it.

I got this information from here and here

The files are in this directory:

%appdata%\Winamp\Plugins\ml
(On Win2k/XP, %appdata% is
    C:\Documents and Settings\(username)\Application Data\
On Vista, it is
    C:\Users\(username)\AppData\Roaming\)


The files are:
main.dat       # ratings and play counts
main.idx # ratings and play counts index file
recent.dat # play history
recent.idx # play history index file
*.m3u8 # playlists stored in the media library
playlists.xml # list of the playlists stored in the media library

The first of the source pages also suggests some alternative strategies for saving this information.

Sunday, June 07, 2009

Rough notes on getting things done

Doing an assignment, writing a book, losing weight -- whatever the task is, there's no doubt that it can be hard to get things done. Here's some rough notes -- that I'd like to clean up sometime -- on ideas to make it a bit easier.

  • Build habits. Habits have momentum, and they can suck you into a task without you trying.
  • Associate a place with a task (if you can). That's one good way to build a habit. I go to a local coffeeshop to do PhD writing. That's all I do there, and I don't go there otherwise. I find it quite useful. If it's a place you don't do any other tasks at, it's less likely to trigger habits associated with them.
  • Make the habits generic, so you can always invoke them. If you make the initial task "start writing" (start writing anything - it doesn't matter what), then this applies regardless of what you are writing or what you are writing it for.
  • Minimised the (perceived) next task. Make it easy to start.
  • Doing has momentum. Make the initial task very simple. Simply by continuing to work on it, it can gather momentum and snowball and if that happens you don't have to even think about trying to do next thing.
  • Impose non-negotiable constraints (where possible). The coffeeshop I do my PhD writing at doesn't have any internet access, so I can't stuff around on the net even if I wanted to. (I understand that many tasks require internet access - this is just an example of the general principle). I also don't have Freecell or Solitare etc installed on my computer.
  • Have others around who can see you. That's another thing I suspect is an benefit of writing in a public place... it feels harder to slack off. May not work for some sorts of tasks.
  • Be prepared for initial Suck when getting into any new sort of task / setup. Basically it’s like developing a skill - it's going to take a while to get into it.
  • Learn to recognise and acknowledge when you’re refusing to consider doing something or how to do it, and just pushing it back. and that if you can do this, this could be all that’s required to actually get your major goals done.
  • We seem to have a tendancy to try to figure things out in our heads before starting. This tends to make the task seem to big, and you just end up staring at a blank page or screen. So learn to recognise when you’re doing this.
  • Related to this, there's a tendancy to want to go into a ‘perceptual response’ mode of thinking – you get stuck. (need to do more work to explain this).
  • As a longer-term proposition, try building up desire to achieve what you want to achieve.
  • Try to have “definite critiera” (I need to do more work here to explain what I mean) -– like writing something that reads from start to finish, rather than just a bunch of notes.

Sunday, December 14, 2008

Wikipedia's list of common misconceptions

Wikipedia's long list of common misconceptions (along with details of the truth of the matter in each case). Misconceptions such as that

  • Napoleon Bonaparte was especially short.
  • searing meat "seals in the juices"
  • seasons are caused by the Earth being closer to the sun in summer than in winter.
  • shaving causes hair to grow back thicker or coarser.
  • earthworms become two worms when cut in half.
  • Inuits have a large number of words for snow.
...and many many more (though the list is far from complete).

Tuesday, November 25, 2008

How to save SMSs from a Sony-Ericsson w7000i phone to your computer

Just as you might want to save letters or emails you send and receive, I like to save my SMSs to my computer.

But that didn't seem possible with my Sony-Ericsson w7000i phone. You can't with the software the comes with it, and I seem to remember talking to a phone guy a few years ago who said you couldn't do it.

But I discovered today that you can use the My Phone Explorer software (Softpedia, Wikipedia). Works great. It's freely downloadable.

(found via this page, via this forum discussion page, via this google search).

Monday, October 27, 2008

How to get rid of Vim's temp files

The default behavior in Vim when you save a file is to also put temporary files in the save directory. I'll explain how you can stop it from doing this. (I don't know Vim that well, but the following works).

What happens is that if you save a file called 'weeklyReport.txt' it also stores a temporary file with the same name appended with a tilde 'weeklyReport.txt~'. It also stores a swapfile there.

I found this really annoying, as it makes it awkward to scan the list of files in the directory (and the files were getting into my version control system - and yes, I'm sure I could find a way to avoid them getting in there, but I think the better solution is to not have them in the directory in the first place).

Here's a solution I found (I'm using it on Windows, but the only difference on other systems should be the file system syntax for specifying directories).

Open or create your settings file.

Here's some deails if you're not familiar with doing this.

When you install Vim, you've effectively installed two programs: Vim (the terminal version), and gVim (the GUI version), and each has its own settings file. For Vim, it's <VimDirectory>/_vimrc. For gVim it's <VimDirectory>/_gvimrc.

A note on what I mean by <VimDirectory>: the actual exectuable files are stored in a directory containing the vim version number - on my computer it is C:\Program Files\Vim\vim72. This is not the <VimDirectory> I'm referring to - the one I'm referring to is the parent directory of that, in my case C:\Program Files\Vim
Add the following lines to it (it shouldn't matter where):
" turn on backup
set backup

" Set where to store backups
set backupdir=c:\temp

" Set where to store swap files
set dir=c:\temp
This will store the tilde and swap files in c:\temp - you can change the directory location to wherever you want.



I found this soultion here, via this, and that via a google search.

Thursday, March 27, 2008

Reader's Digest: 23 ways to avoid catching a cold or the flu

The seems to be a lot colds going around lately -- I've got one now. Reader's Digest has an interesting list of things you can do to prevent catching a cold or the flu.

Here are some of the interesting ones I hadn't heard of. Some might sound strange, but they make sense after you read the explanation for them.

  • Wash your hands twice every time you wash them.
  • Run your toothbrush through the microwave on high for 10 seconds to kill germs that can cause colds and other illnesses.
  • Leave the windows in your house open a crack in winter.
  • Speaking of which, buy a hygrometer.
  • Sit in a sauna once a week.
  • Inhale air from your blow-dryer.
  • Wipe your nose -- don't blow.

Here's another bit from it
3. Use this hand-drying strategy in public restrooms. Studies find a shockingly large percentage of people fail to wash their hands after using a public restroom. And every single one of them touches the door handle on the way out. So after washing your hands, use a paper towel to turn off the faucet. Use another paper towel to dry your hands, then open the door with that paper towel as a barrier between you and the handle. It sounds nuts, but it's an actual recommendation from the Centers for Disease Control to protect you from infectious diseases like cold and flu.
I've always found it strange how many people don't wash their hands... I wonder why exactly?

Monday, November 19, 2007

A nice information-graphics example – baseball pitches

[Update: the page can now be found here]

Here’s a nice example of information graphics done well.


So you know there's many different types of baseball pitches, but can't tell your cutter from your slider or changeup? Well help is at hand in this visual catalogue, showing each type in a simple graphic that intuitively captures it essential character.

Tuesday, October 30, 2007

Phil Greenspun's suggestions for philianthropy

If you've got a bit of money and want to put some of it to good use, Philip Greenspun has some suggestions. He explains the benefit each suggestion could bring, how it could be done, and it's approximate cost.

  • Donate money to Wikipedia
  • Internet Content Prizes - for content such as novels, poems, plays, non-fiction books, textbooks that is published on-line. At present, serious awards for such content is -- by and large -- only when they're published on traditional media.
  • Internet Classical Music Free Library
  • English-language School in Peru's Urubamba Valley
  • Computer Science University in Africa

Thursday, October 25, 2007

Richard Hamming's advice on doing research - "You and Your Research"

In "You and Your Research", Richard Hamming gives his advice on -- not surprisingly -- doing research. For some reason most research advice seems to be pretty elementary with what they say being fairly obvious, but his advice is actually quite good.

If you're wondering who Richard Hamming is, he worked on the Manhattan project, was a founder and president of the Association for Computing Machinery, and was a recipient of the Turing Award (which is like the Nobel prize for computing).

Thursday, July 19, 2007

Video of impressive statistics visualisation - Hans Rosling using Trandalyzer

If you want to make sense of statistics for people, this is how you do it, as shown in this very interesting and impressive video.

In it, Hans Rosling uses UN statistics to demonstrate that many common beliefs about the modern-day world, such as on the nature of the divide between first and third-world countries, are wrong.

But more than the content (and whether you would agree with it or not), what it's about is how he presents it. The software he uses, Trendalyzer, seems pretty impressive. I don't mean from a technical standpoint -- though no doubt it is -- but from what it is able to do. This is futuristic software, like science-fiction films try to portray.

Graphs are animated to show how the data changes over the years, highlighting the trends. They're morphed to show a different, but related perspective. Details are drilled down into, for example to go from showing data for a particular country to data for its consitutent states. It's all interactive, and it leads to a very impressive flow: one perspective raises certain questions, so he modifies the view to try and get insight into them.

What I think is important about this kind of software is that it allows you to really demonstrate points, directly from the data -- very much showing rather than telling.

Tuesday, July 17, 2007

Effective analogy for showing what prosopagnosia is like

[Update: the linked page can now be accessed here]

Prosopagnosia is 'face-blindness' - the inability to recognize other humans by their faces. This page is a very effective description of what it's like, written by a sufferer.

They say good writing shows rather than tells, and that's what that pages does, using a very effective analogy -- to show you what it's like to have prosopagnosia.

If individuals were rocks, then it's like having to remember the characteristics of each rock, and try to realise when you come across this rock again, from your memories. The page uses photos of different rocks so you can see for yourself the sorts of difficulties involved.

There's a lot of complications you probably wouldn't think of, which the page demonstrates well. E.g. when someone gets a haircut - as demonstrated by the rock being obscured by a bit of foliage.

Thursday, July 12, 2007

Some presentation-skills lessons from Job's iPhone talk

[Update: the article can now be found here]

Giving good presentations - five lessons drawn from Steve Job's iPhone presentation. The lessons the article goes into are: Build Tension, Stick to One Theme Per Slide, Add Pizzazz to Your Delivery, Practice, Be Honest and Show Enthusiasm.

Monday, June 18, 2007

Ishkur's Guide to Electronic Music

Ishkur's Guide to Electronic Music. After a quick look, seems interesting. Maps out the myriads of genres and sub-genres of electronic music, giving a short desc of each -- and the author is not afraid to give their opinion of it -- along with some musical samples of it (usefully giving the artist and track name).