flags_iso3166
Rolf presents:
Fun with Flags - A homage to The Big Bang Theory.
flags_iso3166.py is a series of base64 encoded png images of Country's Flags and Regional Flags, with a small set of country details, capital, languages etc and standard UTC timezone information, designed to work with wxPython.
They accessed via their ISO 3166 country codes
See: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes
The images are small. They have been standardised to 23x15 pixels and are aimed at being used in Menus, BitmapComboBox, ListCtrl etc. wherever a small bitmap can be inserted, to add some clarity and va-va-voom!
The original purpose of a standardised size was to enable conformity with wx.ImageList (used with wx.ListCtrl and wx.TreeCtrl) which demands all images be a single size.
wx.ImageList is now being superceded by wx.BitmapBundle but it still makes sense to have a uniform size.
If you require larger or scaleable images, see flags_iso3166svg, which utilises SVG images.
Developed and tested on Linux, wxPython 4.2.1 gtk3 wxWidgets 3.2.2.1
These images are aimed at being used in Menus, BitmapComboBox, ListCtrl, TreeCtrl etc. wherever a bitmap can be inserted, to add some clarity and Va-Va-Voom, to your code.
There are currently 249 Country flags and 315 Regional flags (at last count) in flags_iso3166.py.
Regional flags are currently for Australia, Canada, Germany, Spain, France, India, Italy, Great Britain, Japan, Russia and the USA
You simply need to import flags_iso3166 and you will be able to access the flag images.
For those that do not want to access, or to load all the flags, there are versions by continent, that only contain countries within that continental area, namely:
flags_iso3166_Africa.py
flags_iso3166_Americas.py
flags_iso3166_Asia.py
flags_iso3166_Europe.py
flags_iso3166_Oceania.py
flags_iso3166_NoRegions.py (is world flags but omits the regional flags)
The decision on which country belongs in which continent is based on the United Nations geoscheme:
https://en.wikipedia.org/wiki/United_Nations_geoscheme
Russia straddling 2 continents, is divided, roughly, by the Ural mountain range <= UTC+04:00 is Europe whilst > UTC+04:00 is Asia
I'll admit now, the majority of the images were originally pinched from wikipedia.org, so cheers Wiki.
It is based on the ISO 3166-1 country codes.
The images are stored under 'b64_' and the ISO 3166-1 alpha-2 code and that code is linked to it, so:
b64_ES = b'iVBORw0KGgoAAAANSUhEUgAAABcAAAAPCAMAAAA4caRkAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAgVBMVEXGCx7UORb/xAD6wgLklBHNhhXchRH5vQblqATXfwvKfBrSnzjwtQv0vAH9vwHVmD67YRPFgE7anrbcqE3rsiD4tgLWlVG8aSd5UVrGjHPZn1Dknyj8vwHevkK9bCG7Yja0SxLdqT3rux77wgbcuSr2vQznwTbzuhvqvBrsvhX///9KgMvKAAAAAWJLR0QqU77UngAAAAd0SU1FB+cJAgsVC8y++x0AAABOSURBVBjTY2CgEmDEDhiYIICZCRVAxVlY2dixiHNwcnHz8GKI8/ELCAoJi2CIi4qJS0hKSWOIy8jKySsoKmGIK6uoqqlraKKI43I/lQAAwI8EfW8R2sAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDktMDJUMTE6MjA6NTUrMDA6MDBuKtP9AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA5LTAyVDExOjIwOjU1KzAwOjAwH3drQQAAAABJRU5ErkJggg=='
would be the entry for Spain's national flag.
Where the data is the PNG in base64.
Access to the Flag of Spain would be via flags_iso3166.ES which would provide the following properties:
• Bitmap,
• Data,
• Icon,
• Image,
and methods:
• GetBitmap()
• GetData()
• GetIcon()
• GetImage()
flags_iso3166 also contains a list of entries called:
index
and 6 dictionaries:
• catalog,
• country,
• lookup,
• regional,
• details,
• languages,
• timezone
The index allows a simple check if an entry exists e.g,:
>>> if "USA" in flags_iso3166.index: True
True
>>> if "United States of America" in flags_iso3166.index: True
True
________________________________________________________________________________
*** Warning: you made need to brush up on list comprehension over dictionaries ***
There is built in redundancy, to provide multiple ways to access the data
________________________________________________________________________________
flags_iso3166.catalog iso2 = image
catalog["ES"] = ES
iso3 = image
catalog["ESP"] = ES (Not regional entries)
name = image
catalog["Spain"] = ES
flags_iso3166.country name = (iso2, is03, regional(True/False)
country["Spain"] = ('ES', 'ESP', 0)
flags_iso3166.lookup iso2 = (iso2, iso3, name, regional(True/False)
lookup["ES"] = ('ES', 'ESP', 'Spain', 0)
iso3 = (iso2, iso3, name, regional(True/False)
lookup["ESP"] = ('ES', 'ESP', 'Spain', 0)
name = (iso2, iso3, name, regional(True/False)
lookup["Spain"] = ('ES', 'ESP', 'Spain', 0)
capital = (iso2, iso3, name, regional(True/False)
lookup["Madrid Spain"] = ('ES', 'ESP', 'Spain', 0)
and rarely
altname = (iso2, iso3, name, regional(True/False)
For regional entries in the above, the iso2 entry is a concatenation of country, underscore "_" and region code
e.g. US_AL = United State of America Alabama and there is no iso3 code, it is blank
flag_iso3166.regional regional_iso = (region_iso, region_name, regional(True))
flags_iso3166.regional["US_AL"] =
('US_AL', 'United States of America Alabama', 1)
flags_iso3166.regional['United States of America Alabama'] =
('US_AL', 'United States of America Alabama', 1)
flag_iso3166.details iso2 = {"continent": continent name,
"capital": city name,
"currency": currency name",
"web": country's Top-Level domain,
"lang": list of language codes
"tz": timezone using UTC standard time offset,
"altname": Alternate name, mainly for Russian oblasts e.g. Severnaya Osetiya Respublika = North Ossetia
}
See: https://en.wikipedia.org/wiki/Country_code_top-level_domain (“web”)
https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes ("lang")
Timezone may differ if it is a regional code or a main entry
Where a main entry has multiple time zones, this value may be a range e.g.
"-08:00 | -03:30" for Canada from British Columbia in the West to Newfoundland in the East the regional entry should contain just the timezone appropriate for the region.
Where a region has more than one timezone, the main one is listed e.g.
most of British Columbia is in -08:00 whilst it's South East is in -07:00
flags_iso3166.languages language code = language description
There are 489 language entries
flags_iso3166.timezone iso2 = iana timezone name
There are 542 timezone entries
links the country's alpha-2 code, the alpha-3 code and the country's name to the PyEmbeddedImage(..)
links the country name with the alpha-2 code, the alpha-3 and a final country/region parameter False (0) if this is a main country or True (1) if this is a regional entry
links the alpha-2 code, the alpha-3 code and the country's name and contains a final country/region parameter False (0) if this is a main country or True (1) if this is a regional entry
It includes entries for the capital city and rarely any alternative name.
(These are included to extend search facilities.)
links the iso3166-2 regional code with the country region name.
The dictionary key is the iso3166-1 alpha-2 code and the additional regional code, which may be 2 or 3 chars
For example the code for Andalucia, Spain is ES-AN ES for Spain and AN for Andalucia, this is stored as ES_AN in the catalog.
The code for England, Great Britain is GB-ENG GB for Great Britain and ENG for England, this would be stored as GB_ENG
links the country's alpha-2 code with another dictionary of country details, namely:
which continent it is on;
the name of the capital;
the name of the currency;
the Top_level domain code;
timezone
alternate name
and the codes of languages used in the country.
The language codes conform ISO 639-1 and ISO 639-3
See: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
https://en.wikipedia.org/wiki/List_of_ISO_639-3_codes
The timezones are the iana timezone names
See: https://www.iana.org/time-zones
Links the iso country/regional code to the iana timezone name, or my best attempt :)
________________________________________________________________________________
A full entry for Spain would look like this:
b64_ES = b'iVBORw0KGgoAAAANSUhEUgAAABcAAAAPCAMAAAA4caRkAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAgVBMVEXGCx7UORb/xAD6wgLklBHNhhXchRH5vQblqATXfwvKfBrSnzjwtQv0vAH9vwHVmD67YRPFgE7anrbcqE3rsiD4tgLWlVG8aSd5UVrGjHPZn1Dknyj8vwHevkK9bCG7Yja0SxLdqT3rux77wgbcuSr2vQznwTbzuhvqvBrsvhX///9KgMvKAAAAAWJLR0QqU77UngAAAAd0SU1FB+cJAgsVC8y++x0AAABOSURBVBjTY2CgEmDEDhiYIICZCRVAxVlY2dixiHNwcnHz8GKI8/ELCAoJi2CIi4qJS0hKSWOIy8jKySsoKmGIK6uoqqlraKKI43I/lQAAwI8EfW8R2sAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDktMDJUMTE6MjA6NTUrMDA6MDBuKtP9AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA5LTAyVDExOjIwOjU1KzAwOjAwH3drQQAAAABJRU5ErkJggg=='
ES = PyEmbeddedImage(b64_ES)
index.append("ES")
index.append("ESP")
index.append("Spain")
catalog["ES"] = ES
catalog["ESP"] = ES
catalog["Spain"] = ES
country["Spain"] = ('ES', 'ESP', 0)
lookup["ES"] = ('ES', 'ESP', 'Spain', 0)
lookup["Madrid Spain"] = ('ES', 'ESP', 'Spain', 0)
lookup["ESP"] = ('ES', 'ESP', 'Spain', 0)
lookup["Spain"] = ('ES', 'ESP', 'Spain', 0)
details["ES"] = {"continent":"Europe","capital":"Madrid","currency":"Euro","web":".es","lang":"es-ES | ca | gl | eu | oc","tz":"+01:00","altname":""}
Regions are a limited effort to include the flags of the major regions of key countries included for example would be the flags of US states and the regions of Spain.
The images are stored under the ISO 3166-1 alpha-2 code and the ISO 3166-2 code,
so US_AL = PyEmbeddedImage(..)
There is no alpha-3 code so that is left blank and in both the country dictionary and missing in the regional dictionary.
Both contain a 1 (True) as the final parameter, denoting this is a regional flag
The full entry for the flag of Alabama, USA for example is this:
b64_US_AL = b'iVBORw0KGgoAAAANSUhEUgAAABcAAAAPCAMAAAA4caRkAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAilBMVEWxACG7IT7qu8T////tw8u9JkK+KkaxASLQZnr68PL9+vvbiJezBia5GTfmrrjptr+6HTqyBCTVd4n9+Pnx0tjBNU/LVWv56u367vC/L0rvzNP++/zdkJ60Cyu4FjTioa3nsry5GjizCCjYf5Dz2N3DPFXJUGfwzdP//v7gmaa1DSy0Cir+/Pzrv8eAq3BtAAAAAWJLR0QDEQxM8gAAAAd0SU1FB+cJAgsVDSXdXigAAACKSURBVBjTfdDrDoIwDAXggwdlgIoTlYsXUAHxwvu/ngWiwYTZH0v3pWu6ArAm/A17CmAGOModqKucVj1/DiyWXw5WgF6HIDdbebaLOo2V5ElKinN/OAKnTLL8DFyuHnsni1LKqlslZ1l00jvr+wNtPP0Xh042Wlg3n+v/+vH+hnnG5zf917Qfwz7fENoLeQstKLAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDktMDJUMTE6MjA6NTUrMDA6MDBuKtP9AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA5LTAyVDExOjIwOjU1KzAwOjAwH3drQQAAAABJRU5ErkJggg=='
US_AL = PyEmbeddedImage(b64_US_AL)
index.append("US_AL")
index.append("United States of America Alabama")
catalog["US_AL"] = US_AL
catalog["United States of America Alabama"] = US_AL
country["United States of America Alabama"] = ('US_AL', '', 1)
lookup["US_AL"] = ('US_AL', '', 'United States of America Alabama', 1)
lookup["Montgomery United States of America Alabama"] = ('US_AL', '', 'United States of America Alabama', 1)
lookup["United States of America Alabama"] = ('US_AL', '', 'United States of America Alabama', 1)
details["US_AL"] = {"continent":"Americas","capital":"Montgomery","currency":"","web":"","lang":"","tz":"-06:00","altname":""}
regional["US_AL"] = ('US_AL', 'United States of America Alabama', 1)
regional["United States of America Alabama"] = ('US_AL', 'United States of America Alabama', 1)
Other than:
>>> flags_iso3166.ES
<wx.lib.embeddedimage.PyEmbeddedImage object at 0x7fd7f4a95de0>
Access via properties using the catalog via the iso alpha-2 code, iso alpha-3 code or the country's name:
>>> flags_iso3166.catalog['ES'].Bitmap
<wx._core.Bitmap object at 0x7fd7f4a2d090>
>>> flags_iso3166.catalog['ESP'].Bitmap
<wx._core.Bitmap object at 0x7fd7f4a2cdc0>
>>> flags_iso3166.catalog['Spain'].Bitmap
<wx._core.Bitmap object at 0x7fd7f4a2cee0>
ditto for Image:
flags_iso3166.catalog['Spain'].Image
<wx._core.Image object at 0x7fd7f4a2d090>
or Icon:
>>> flags_iso3166.catalog['Spain'].Icon
<wx._core.Icon object at 0x7fd7f4a2cee0>
or Data:
>>> flags_iso3166.catalog['Spain'].Data
b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x17\x00\x00\x00\x0f\x08\x03\x00\x00\x008q\xa4d\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x00\x81PLTE\xc6\x0b\x1e\xd49\x16\xff\xc4\x00\xfa\xc2\x02\xe4\x94\x11\xcd\x86\x15\xdc\x85\x11\xf9\xbd\x06\xe5\xa8\x04\xd7\x7f\x0b\xca|\x1a\xd2\x9f8\xf0\xb5\x0b\xf4\xbc\x01\xfd\xbf\x01\xd5\x98>\xbba\x13\xc5\x80N\xda\x9e\xb6\xdc\xa8M\xeb\xb2 \xf8\xb6\x02\xd6\x95Q\xbci'yQZ\xc6\x8cs\xd9\x9fP\xe4\x9f(\xfc\xbf\x01\xde\xbeB\xbdl!\xbbb6\xb4K\x12\xdd\xa9=\xeb\xbb\x1e\xfb\xc2\x06\xdc\xb9*\xf6\xbd\x0c\xe7\xc16\xf3\xba\x1b\xea\xbc\x1a\xec\xbe\x15\xff\xff\xffJ\x80\xcb\xca\x00\x00\x00\x01bKGD*S\xbe\xd4\x9e\x00\x00\x00\x07tIME\x07\xe7\t\x02\x0b\x15\x0b\xcc\xbe\xfb\x1d\x00\x00\x00NIDAT\x18\xd3c`\xa0\x12`\xc4\x0e\x18\x98 \x80\x99\t\x15@\xc5YX\xd9\xd8\xb1\x88sprq\xf3\xf0b\x88\xf3\xf1\x0b\x08\n\t\x8b`\x88\x8b\x8a\x89KHJIc\x88\xcb\xc8\xca\xc9+(*a\x88+\xab\xa8\xaa\xa9kh\xa2\x88\xe3r?\x95\x00\x00\xc0\x8f\x04}o\x11\xda\xc0\x00\x00\x00%tEXtdate:create\x002023-09-02T11:20:55+00:00n*\xd3\xfd\x00\x00\x00%tEXtdate:modify\x002023-09-02T11:20:55+00:00\x1fwkA\x00\x00\x00\x00IEND\xaeB`\x82"
The same is true of access via the methods:
>>> flags_iso3166.catalog['Spain'].GetBitmap()
<wx._core.Bitmap object at 0x7fd7f4a2d090>
>>> flags_iso3166.catalog['ES'].GetImage()
<wx._core.Image object at 0x7fd7f4a2cee0>
Use the lookup dictionary to get iso2, iso3, country name and if it's a main entry or a regional map e.g. ES ESP Spain 0
>>> flags_iso3166.lookup.get("ES")
('ES', 'ESP', 'Spain', 0)
>>> flags_iso3166.lookup.get("ESP")
('ES', 'ESP', 'Spain', 0)
>>> flags_iso3166.lookup.get("Spain")
('ES', 'ESP', 'Spain', 0)
This also works for Regional entries (although you will notice the missing iso3 code and the 1 at the end, indicating a regional map):
>>> flags_iso3166.lookup.get("ES_AN")
('ES_AN', '', 'Spain Andalucia', 1)
>>> flags_iso3166.lookup.get("Spain Andalucia")
('ES_AN', '', 'Spain Andalucia', 1)
Access is the same:
>>> flags_iso3166.regional.get("ES_AN")
('ES_AN', 'Spain Andalucia', 1)
>>> flags_iso3166.regional.get("Spain Andalucia")
('ES_AN', 'Spain Andalucia', 1)
>>> flags_iso3166.ES_AN
< wx.lib.embeddedimage.PyEmbeddedImage object at 0x7f7cb21ada80>
>>> flags_iso3166.catalog['ES_AN']
<wx.lib.embeddedimage.PyEmbeddedImage object at 0x7f7cb21ada80>
>>> flags_iso3166.catalog['ES_AN'].GetBitmap()
<wx._core.Bitmap object at 0x7f7cb167c280>
>>> flags_iso3166.catalog['Spain Andalucia'].GetBitmap()
<wx._core.Bitmap object at 0x7f7cb167c310>
>>> flags_iso3166.catalog['Spain Andalucia'].GetImage()
<wx._core.Image object at 0x7f7cb167c280>
>>> flags_iso3166.details["ES"]
{'continent': 'Europe', 'capital': 'Madrid', 'currency': 'Euro', 'web': '.es', 'lang': 'es-ES | ca | gl | eu | oc', 'tz': '+01:00', 'altname': ''}
>>> flags_iso3166.details["ES"].get("currency")
'Euro'
>>> flags_iso3166.details["ES"].get("lang")
'es-ES | ca | gl | eu | oc'
>>> flags_iso3166.details["ES"].get("tz")
'+01:00'
>>> flags_iso3166.language.get('es')
['Spanish - Castilian']
>>> flags_iso3166.language.get('wa')
['Walloon']
>>> flags_iso3166.language.get('wol')
['Wolof']
>>> flags_iso3166.language.get('oc')
['Occitan (post 1500)']
The zoneinfo module was introduced with python3.9
https://docs.python.org/3.9/library/zoneinfo.html#module-zoneinfo
>>> flags_iso3166.timezone.get('AF')
['Asia/Kabul']
>>> flags_iso3166.timezone.get('US_IL')
['America/Chicago']
>>> flags_iso3166.timezone.get('AU_NSW')
['Australia/Sydney']
The timezone dictionary is a clumsy attempt to tie the iso3166-1 and iso3166-2 country and region codes to the iana timezone names.
Where there is no direct link, I attempt to tie the iso3166-2 code to the nearest or most appropriate name.
I fully expect that somewhere in there, I will have made an error.
For countries with multiple timezones, that I didn't get around to subdividing, I've selected the commonest or the capital region.
Country entries that are unused, for whatever reason, have been retained but given a number as a suffix to keep them out of the way but still available for future use.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
zone = flags_iso3166.timezone.get('AU_NSW')
datetime.now(ZoneInfo(zone[0]))
datetime.datetime(2023, 9, 11, 2, 48, 19, 153133, tzinfo=zoneinfo.ZoneInfo(key='Australia/Sydney'))
For clarity with many of the examples below, the import statement for flags_iso3166 will have been:
import flags_iso3166 as flags
A list of countries excluding regions (the last entry is False (0) indicating it's not a regional entry)
countries = [item for item in flags.country.items() if not item[1][-1]]
('Andorra', ('AD', 'AND', 0))
('United Arab Emirates', ('AE', 'ARE', 0))
('Afghanistan', ('AF', 'AFG', 0))
('Antigua and Barbuda', ('AG', 'ATG', 0))
('Anguilla', ('AI', 'AIA', 0))
...
A list of regions for a country: e.g. for the US
us_regions = [item for item in flags.regional.items() if item[0].startswith('US')]
('US_AK', ('US_AK', 'United States of America Alaska', 1))
('US_AL', ('US_AL', 'United States of America Alabama', 1))
('US_AR', ('US_AR', 'United States of America Arkansas', 1))
...
A list of regions for a country: e.g. for the US excluding the individual iso3166-2 entries like USAK
us_regions = [item for item in flags.regional.items() if item[0].startswith('United States ')]
('United States of America Alaska', ('US_AK', 'United States of America Alaska', 1))
('United States of America Alabama', ('US_AL', 'United States of America Alabama', 1))
('United States of America Arkansas', ('US_AR', 'United States of America Arkansas', 1))
...
Alternatively you could use the country dictionary: (the last entry if True indicating it's a regional entry)
us_regions = [item for item in flags.country.items() if item[0].startswith("United States") and item[1][-1]]
for i in us_regions: print(i)
('United States of America Alaska', ('US_AK', '', 1))
('United States of America Alabama', ('US_AL', '', 1))
('United States of America Arkansas', ('US_AR', '', 1))
...
flags_iso3166.Regional_Entries
returns a list of all entries in the country dictionary that are regional entries
So len(flags_iso3166.Regional_Entries) would tell you how many Regional entries there are
flags_iso3166.Country_Entries
returns a list of all entries in the country dictionary that are NOT regional entries
So len(flags_iso3166.Country_Entries) would tell you how many Countries there are
function lookupiso2(value) will return the iso2 code for any value
>>> flags.lookupiso2('Japan')
'JP'
>>> flags.lookupiso2('JPN')
'JP'
>>> flags.lookupiso2('JP')
'JP'
function lookupiso3(value) will return the iso2 code for any value
function lookupname(value) will return the country or region name for any value
function isregional(value) will return True/False for any value
function lookupbasecountry(value) will return the iso2 code for any value (if isregional returns True for example)
>>> import flags_iso3166 as flags
>>> flags.lookupbasecountry('United States of America Alabama')
('US', 'USA', 'United States of America', 0)
>>> flags.lookupbasecountry('US_AL')
('US', 'USA', 'United States of America', 0)
>>> flags.lookupbasecountry('JP_22')
('JP', 'JPN', 'Japan', 0)
>>> if flags.isregional('JP_17'):
flags.lookupname('JP_17')
flags.lookupbasecountry('JP_17')
'Japan Ishikawa'
('JP', 'JPN', 'Japan', 0)
The demonstration programs (flagsdemo.py, flagsdemo2.py, flagsdemo3.py and flagsdemo4.py) attempt to give an example of many of the methods and properties, so even if much of the above, is gobbledigook, hopefully you will see how it can be used.
Flag images are demonstrated for Menus, Comboboxes, a Button, StaticBitmaps, a ListCtrl, a TreeCtrl and SuperToolTips.
Have fun with Flags!
Dear dear, will Sheldon ever forgive me? :)
Regards,
Rolf
As always, errors, bugs and insults, on a postcard please.
Demo 1
Demo 2
Demo 3
Demo 4