emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* My Python solution to generating unique Ids in headlines
@ 2009-03-04 23:20 Charles Cave
  2009-03-04 23:59 ` Nick Dokos
  2009-03-05  8:39 ` Ian Barton
  0 siblings, 2 replies; 6+ messages in thread
From: Charles Cave @ 2009-03-04 23:20 UTC (permalink / raw)
  To: emacs-orgmode

Recently I asked about a method of inserting a unique number in a
headline. My requirement is to be able to uniquely identify a
particular headline when exporting data to another system
(ListPro on Palm/Windows).     

I settled on using a small Python script, since I am not
a Lisp programmer.

1.  I created a text file todononum.txt which contains
the next number to use.

2.  I created the following script to read this file, return the
next available number formatted in a unique, easy to find string,
for example [#310].

# script next_todo.py 
import sys
nextnum_file = "C:/charles/gtd/todonum.txt"

try:
   f = open(nextnum_file, 'r')
except IOError:
   print "Unable to open %s. Program terminating." % nextnum_file
   sys.exit(1)

val = int(f.readline()) + 1
f.close()

of = open(nextnum_file, 'w')
of.write("%d\n"  % val)
of.close()

print "[#%s]" % val


3. I created a one line batch file nextnum.bat (I'm on Windows!) 
containing:

python c:/charles/gtd/next_todo.py


4. In org-mode I insert the  unique id by positioning the
cursor at the end of the headline text, then entering the command

ESC-1 ESC-! nextnum RET   Ctl-D

The Ctrl D is needed to remove a carriage return (not sure why it is
there.

Can someone give me Lisp code equivalent of
the command sequene above? I know it is something to do
with (shell command .... )


The end result now looks like 

*** Post  to org-mode list about next sequential [#315]  :COMPUTER:

Once I have  Lisp code to implement the command sequence I will have
a satisfactory solution to generating the unique id when I need it.


-------------------------------------------
Charles Cave
Sydney, NSW, Australia
Email:  charles_cave@optusnet.com.au
Follow me on Twitter:  www.twitter.com/ozcaveman
-------------------------------------------

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: My Python solution to generating unique Ids in headlines
  2009-03-04 23:20 My Python solution to generating unique Ids in headlines Charles Cave
@ 2009-03-04 23:59 ` Nick Dokos
  2009-03-05  2:40   ` Charles Cave
  2009-03-05  8:39 ` Ian Barton
  1 sibling, 1 reply; 6+ messages in thread
From: Nick Dokos @ 2009-03-04 23:59 UTC (permalink / raw)
  To: charles_cave; +Cc: emacs-orgmode

Charles Cave <charles_cave@optusnet.com.au> wrote:

> ... 
> print "[#%s]" % val
> 
> 
> ...
> 
> ESC-1 ESC-! nextnum RET   Ctl-D
> 
> The Ctrl D is needed to remove a carriage return (not sure why it is
> there.

Try

      import sys
      sys.stdout.write("[%d]" % val)

instead of print. It should work on Windows as well (but I have not
tested it there).

> 
> Can someone give me Lisp code equivalent of
> the command sequene above? I know it is something to do
> with (shell command .... )
> 

(shell-command "nextnum" t)

It may be necessary to specify a complete path to the command.

> 
> The end result now looks like 
> 
> *** Post  to org-mode list about next sequential [#315]  :COMPUTER:
> 
> Once I have  Lisp code to implement the command sequence I will have
> a satisfactory solution to generating the unique id when I need it.
> 

But I still don't understand why you need an external program: what is
wrong with (insert (format "[%s]" (org-id-new)))? Are the IDs too ugly
or is there some other problem?

The trouble with unique IDs in files is that it's easy for them to get
out of sync (leading to non-uniqueness), e.g. if there are two processes
trying to get a unique id at the same time.

Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: My Python solution to generating unique Ids in headlines
  2009-03-04 23:59 ` Nick Dokos
@ 2009-03-05  2:40   ` Charles Cave
  2009-03-05  9:37     ` Carsten Dominik
  0 siblings, 1 reply; 6+ messages in thread
From: Charles Cave @ 2009-03-05  2:40 UTC (permalink / raw)
  To: emacs-orgmode

Nick Dokos <nicholas.dokos <at> hp.com> writes:
 
> Try
>       import sys
>       sys.stdout.write("[%d]" % val)

Thanks. That works fine.

> (shell-command "nextnum" t)

This worked fine.
> 
> It may be necessary to specify a complete path to the command.

I diodnt need to because the .BAT file was in a directory which is
part of the PAHT list.  By the way, I had to include a beginning
line of @ECHO OFF in the bat file.

> But I still don't understand why you need an external program: what is
> wrong with (insert (format "[%s]" (org-id-new)))? Are the IDs too ugly
> or is there some other problem?

I'm struggling to find documentation or installing and using org-id.
I added the line (require 'org-id) to my .eamcs file
then discovered a variable to customise the method to internal
or to use an external command uuidgen which doesnt exist on Windows.

How do I change the name of the external command from uuidgent
to nextnum

> The trouble with unique IDs in files is that it's easy for them to get
> out of sync (leading to non-uniqueness), e.g. if there are two processes
> trying to get a unique id at the same time.

This shouldnt be a problem as I am the only user.

Thanks for your help,
Charles

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: My Python solution to generating unique Ids in headlines
  2009-03-04 23:20 My Python solution to generating unique Ids in headlines Charles Cave
  2009-03-04 23:59 ` Nick Dokos
@ 2009-03-05  8:39 ` Ian Barton
  1 sibling, 0 replies; 6+ messages in thread
From: Ian Barton @ 2009-03-05  8:39 UTC (permalink / raw)
  To: emacs-orgmode


> I settled on using a small Python script, since I am not
> a Lisp programmer.
> 
> 1.  I created a text file todononum.txt which contains
> the next number to use.
> 
> 2.  I created the following script to read this file, return the
> next available number formatted in a unique, easy to find string,
> for example [#310].
> 
> # script next_todo.py 
> import sys
> nextnum_file = "C:/charles/gtd/todonum.txt"
> 
> try:
>    f = open(nextnum_file, 'r')
> except IOError:
>    print "Unable to open %s. Program terminating." % nextnum_file
>    sys.exit(1)
> 
> val = int(f.readline()) + 1
> f.close()
> 
> of = open(nextnum_file, 'w')
> of.write("%d\n"  % val)
> of.close()
> 
> print "[#%s]" % val
> 
> 
Charles,

If you don't need human readable numbers, you could try something like 
the following to generate a hash:

import hashlib
from time import strftime

timestamp = strftime("%Y-%m-%d %H:%M:%S")
s = myorg_item + timestamp
myhash = hashlib.sha224(s).hexdigest()

This combines your org text with the current timestamp to generate a 
hash. Since it's unlikely that you will try to create a hash from two 
identical org items at the same moment in time, this should be unique.

Ian.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re: My Python solution to generating unique Ids in headlines
  2009-03-05  2:40   ` Charles Cave
@ 2009-03-05  9:37     ` Carsten Dominik
  2009-03-06  2:13       ` Samuel Wales
  0 siblings, 1 reply; 6+ messages in thread
From: Carsten Dominik @ 2009-03-05  9:37 UTC (permalink / raw)
  To: Charles Cave; +Cc: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 4506 bytes --]

Hi Charles,

if you want a pure Emacs solution for this, here is one

(defvar charles-num-file "C:/charles/gtd/todonum.txt")
(defun charles-add-id ()
   "Add ID number to headline."
   (interactive)
   (save-excursion
     (org-back-to-heading t)
     (when (looking-at ".*\\[#[0-9]+\\]")
       (error "ID number already present"))
     (when (looking-at org-complex-heading-regexp)
       (goto-char (match-end 4))
       (insert (format " [#%s]" (charles-next-num)))
       (org-set-tags nil 'align))))

(defun charles-next-num ()
   "Get next number"
   (let (num)
     (with-temp-buffer
       (if (file-exists-p charles-num-file)
	  (insert-file-contents-literally charles-num-file))
       (goto-char (point-min))
       (setq num (1+ (or (ignore-errors (read (current-buffer))) 0))))
     (with-temp-file charles-num-file
       (insert (number-to-string num)))
     num))

However:

It really depends on how much you want to depend on these numbers.
In fact, my first implementation of IDs in org did use numbers just
like yours, but I moved away from them because they are simply not
reliable.

1. If you ever sit on a different computer and would like
    to create a task, you will mess up the numbering.
2. If you forget to backup and restore the numbering file, you will
    run into trouble.
3. No good way to collaborate with others.

But if you are convinced that you alone will use this, with a
single computer, it might work OK.  The one advantage of numbers
as IDs is that they are better readable with the eye, and that you
can even remember "Oh yes, this was task 136".  However, if it is
a computer that is looking at the IDs, there are much better
alternatives:

1. Of course, as Nick proposes, the IDs created by uuidgen.
    Globally unique, they will never ever give you any trouble.
    They are long, though, if you want to store them in the
    headline - that's why Org has them in a property.

2. Instead of (charles-next-num), you could use

      (org-id-time-to-b36)

    This will give you an encoding of the current time, to
    microsecond accuracy, in just 12 characters, good enough
    for multiple computers and even for large collaborations.
    Even if 2 people are trying to make an ID at exactly the
    same time, chances are still 1 in 100000 or so that they
    would actually get the same ID.

3. If you are sure the you never make 2 IDs in the same second,
    you can nibble off the last digits, like

      (substring (org-id-time-to-b36) 0 -4)

    which is an 8 character encoding of the creation time,
    accurate to a second.  Quite safe for yourself, unless
    you use a program like org-map-entries to create these
    IDs for many entries in very short time.
    You could even nibble away the first digit which will
    not become significant for another 100 years or so.

      (substring (org-id-time-to-b36) 1 -4)

    7 characters, one second accuracy, hard to beat.

HTH

- Carsten

On Mar 5, 2009, at 3:40 AM, Charles Cave wrote:

> Nick Dokos <nicholas.dokos <at> hp.com> writes:
>
>> Try
>>      import sys
>>      sys.stdout.write("[%d]" % val)
>
> Thanks. That works fine.
>
>> (shell-command "nextnum" t)
>
> This worked fine.
>>
>> It may be necessary to specify a complete path to the command.
>
> I diodnt need to because the .BAT file was in a directory which is
> part of the PAHT list.  By the way, I had to include a beginning
> line of @ECHO OFF in the bat file.
>
>> But I still don't understand why you need an external program: what  
>> is
>> wrong with (insert (format "[%s]" (org-id-new)))? Are the IDs too  
>> ugly
>> or is there some other problem?
>
> I'm struggling to find documentation or installing and using org-id.
> I added the line (require 'org-id) to my .eamcs file
> then discovered a variable to customise the method to internal
> or to use an external command uuidgen which doesnt exist on Windows.
>
> How do I change the name of the external command from uuidgent
> to nextnum
>
>> The trouble with unique IDs in files is that it's easy for them to  
>> get
>> out of sync (leading to non-uniqueness), e.g. if there are two  
>> processes
>> trying to get a unique id at the same time.
>
> This shouldnt be a problem as I am the only user.
>
> Thanks for your help,
> Charles
>
>
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode


[-- Attachment #1.2: Type: text/html, Size: 6897 bytes --]

[-- Attachment #2: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re: My Python solution to generating unique Ids in headlines
  2009-03-05  9:37     ` Carsten Dominik
@ 2009-03-06  2:13       ` Samuel Wales
  0 siblings, 0 replies; 6+ messages in thread
From: Samuel Wales @ 2009-03-06  2:13 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: emacs-orgmode, Charles Cave

I have a related idea in the thread, "IDs on anything".

-- 
Myalgic encephalomyelitis denialism is causing death (decades early;
Jason et al. 2006) and severe suffering (worse than nearly all other
diseases studied; e.g. Schweitzer et al. 1995) and *grossly*
corrupting science.
http://www.meactionuk.org.uk/What_Is_ME_What_Is_CFS.htm

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-03-06  2:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-04 23:20 My Python solution to generating unique Ids in headlines Charles Cave
2009-03-04 23:59 ` Nick Dokos
2009-03-05  2:40   ` Charles Cave
2009-03-05  9:37     ` Carsten Dominik
2009-03-06  2:13       ` Samuel Wales
2009-03-05  8:39 ` Ian Barton

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).