4

How can I rewrite following clause:

if u'января' in date_category['title']:
    month = 1
elif u'февраля' in date_category['title']:
    month = 2
elif u'марта' in date_category['title']:
    month = 3
elif u'апреля' in date_category['title']:
    month = 4
elif u'мая' in date_category['title']:
    month = 5
elif u'июня' in date_category['title']:
    month = 6
elif u'июля' in date_category['title']:
    month = 7
elif u'августа' in date_category['title']:
    month = 8
elif u'сентября' in date_category['title']:
    month = 9
elif u'октября' in date_category['title']:
    month = 10
elif u'ноября' in date_category['title']:
    month = 11
elif u'декабря' in date_category['title']:
    month = 12

It just looks ugly.

evgeniuz
  • 2,599
  • 5
  • 30
  • 36
  • 1
    @Marcin Of course. It is a parser, I have a string with russian dates. I `strptime()` won't work for these. `date-util` package too won't work for it. I'm parsing day with simple regexp and now I need to parse month somehow. The next string just takes parsed month and day and creates datetime object. – evgeniuz Apr 08 '12 at 11:04
  • Howcome you are checking if the month is in the date_category['title'], is it possible for you to just check the index of the month in a month list? – jamylak Apr 08 '12 at 11:07
  • @Marcin In russian %B for january would be `'январь'`, and `'January, 23'` would be `'23 января'`, so this just won't work. – evgeniuz Apr 08 '12 at 11:08
  • @jamylak date_category['title'] contains not only month, but some other information. – evgeniuz Apr 08 '12 at 11:11
  • @Shark I'm fairly certain you don't understand how python date parsing works. `%B` refers *only* to the month, and will deal with russian dates if you set your locale correctly. – Marcin Apr 08 '12 at 11:11
  • @Shark alright makes sense then :D – jamylak Apr 08 '12 at 11:12
  • @Marcin The genitive case of russian month differs from nominative. `datetime.now().strftime('%d %B')` returns `08 Апрель` but should return `08 Апреля`. That's would be gramatically correct. Because of this, most locales just contains `'Апр.'`, but unfortunately, I have full month in my strings. – evgeniuz Apr 08 '12 at 11:17
  • @Shark I bet you could more cleanly create locale settings to also recognise genitive forms, rather than writing your own date parser. Alternatively, map the genitive forms to the nominative and back, and use strptime to do the heavy lifting. – Marcin Apr 08 '12 at 11:19

7 Answers7

7

To solve this, parse your date information using the python datetime module. It has support for locales, and will sort this out. If genitive forms are really the issue, then just map those forms to the dative, then map back on output.

To answer your actual question -

Consider that you are pairing up data with integers. If you can transform your data into the format (month, integer), you can drive your code with data.

for (n, month) in enumerate(u'января, feb, mar, apri, may, jun, jul, aug, sep, oct, nov, декабря'.split(', '), 1):# the parameter 1 specifies to start counting from 1. h/t @san4ez
    if month in date_category['title']: return n
Marcin
  • 48,559
  • 18
  • 128
  • 201
  • Consider adding some sort of type check, e.g. `return d[title] if d in title else None` – Adam Matan Apr 08 '12 at 11:04
  • 1
    `enumerate(iterable, 1)` starts enumerating from 1. So no need to increment `n` when return value – San4ez Apr 08 '12 at 11:07
  • @AdamMatan (a) That is not in OP's code (b) This is a loop. It only returns if something is found. If you fall off the end of the function, you get `None` anyway. – Marcin Apr 08 '12 at 11:08
  • @Marcin Perhaps, but IMO explicit is better than implicit. A matter of taste. – Adam Matan Apr 08 '12 at 11:15
  • I meant creating the dictionary separately, and querying it. It's a different approach. @Marcin – Adam Matan Apr 08 '12 at 11:25
  • @AdamMatan An approach that tries to find a `dict` in a string. Do look at your own code. – Marcin Apr 08 '12 at 11:26
  • @Marcin Correct, it should be the full string within the dict. However, building a class with a static method that parses the string and returns a month object seems cleaner to me. – Adam Matan Apr 08 '12 at 12:02
4

Get system support for Russian internationalization: OS locale support for use in Python

Use the locale module to set the locale: How to get unicode month name in Python?

Use strptime: Handling international dates in python

Demonstration: Locale troubles


Alternatively, just do:

months = ['Jan', 'Feb', 'Mar', ...]
monthToNumber = dict((name,i+1) for i,name in enumerate(months))

monthToNumber[date_category['title']]
Community
  • 1
  • 1
ninjagecko
  • 88,546
  • 24
  • 137
  • 145
2
months = (u'января', u'февраля', u'марта', u'апреля', u'мая', u'июня', u'июля', u'августа', u'сентября', u'октября', u'ноября', u'декабря')
month = next(i for i,name in enumerate(months,1) if name in date_category['title'])
jamylak
  • 128,818
  • 30
  • 231
  • 230
1

You may also use the index function in list to get a mapping of months to months number

months = (u'января', u'февраля', u'марта', u'апреля', u'мая', u'июня', u'июля', u'августа', u'сентября', u'октября', u'ноября', u'декабря')
month = months.index(date_category['title'])+1
Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • The problem is that the `date_category['title']` also contains other information so it can't be used as an index. – jamylak Apr 08 '12 at 11:21
  • 1
    @jamylak: Never came to my mind. In that case if OP mentions about the format, it can most possibly be reduced to the month name. – Abhijit Apr 08 '12 at 11:22
  • Any one who is down-voting, please leave a comment. – Abhijit Apr 08 '12 at 11:40
  • @Abhijit: couple of errors in your answer. namely `month = moths` and the fact that you index `index`. It should be `months.index(round brackets)`. – Joel Cornett Apr 08 '12 at 12:38
  • @jamylak: I didn't realize that `date_category['title']` contained more than the names of the months. I guess I'm going to have to revise my answer as well. – Joel Cornett Apr 08 '12 at 12:40
1

Create a dict of the months, with corresponding indices:

months = [u'января', u'февраля', u'марта', u'апреля', u'мая', u'июня', u'июля', u'августа', u'сентября', u'октября', u'ноября', u'декабря']

Then you can simply do:

month = max(enumerate((date_category['title'].find(month) for month in months), start = 1), key = lambda x: x[1])[0]
Joel Cornett
  • 24,192
  • 9
  • 66
  • 88
  • I think you haven't read another answers and comments. I cannot use date_category['title'] as index, because month name is just little part of it. – evgeniuz Apr 08 '12 at 12:40
0

Simply create a hash array which maps your string to corresponding month number, then you can simply iterate through it, check where the key is in date_category['title'], and in all cases, set month to the corresponding value. Good luck.

Thiem Nguyen
  • 6,345
  • 7
  • 30
  • 50
0

Here's something a bit more perverse, because I enjoy proving the futility of saying "there should be only one way to do it":

pattern = re.compile(u'(января)|(февраля)|(марта)|(апреля)|(мая)|(июня)|(июля)|(августа)|(сентября)|(октября)|(ноября)|(декабря)')

month = map(bool, x.search(date_category['title']).groups()).index(True) + 1
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153