Import csv to list of dictionaries in utf-8

125 views
Skip to first unread message

Pulli Noobi

unread,
Sep 14, 2016, 10:46:44 AM9/14/16
to Kivy users support
Hello!

I'm writing my first Kivy-App, so please treat my like a child :-)

I want my app to import a csv (in.csv) to a list of dictionaries (result) every time it starts. My problem come by my requirement of symbols like ä, ö, ü.

On strackoverflow someone helped me with this python-code:
import codecs
import csv

def utf_8_encoder(unicode_csv_data):
   
for line in unicode_csv_data:
       
yield line.encode('utf-8')

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
   
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader
= csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect
=dialect, **kwargs)
   
for row in csv_reader:
       
# decode UTF-8 back to Unicode, cell by cell:
       
yield [unicode(cell, 'utf-8') for cell in row]

with codecs.open('in.csv', encoding='utf-8') as f:
    reader
= unicode_csv_reader(f)
    keys
= [k.strip() for k in reader.next()]
    result
= []
   
for row in reader:
        d
=dict(zip(keys, row))
        result
.append(d)

   
for d in result:
       
for k, v in d.iteritems():
           
print k, v
   
print result

This code works fine in a standalone file. My question now is:

How do I paste this code in my main.py?

I tried it like this:
class TestApp(App):

   
def build(self):
       
self.load_csv()

   
def utf_8_encoder(unicode_csv_data):
       
for line in unicode_csv_data:
           
yield line.encode('utf-8')

   
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
       
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
        csv_reader
= csv.reader(utf_8_encoder(unicode_csv_data),
                                dialect
=dialect, **kwargs)
       
for row in csv_reader:
           
# decode UTF-8 back to Unicode, cell by cell:
           
yield [unicode(cell, 'utf-8') for cell in row]

   
def load_csv(self):
       
with codecs.open('in.csv', encoding='utf-8') as f:
            reader
= unicode_csv_reader(f)
            keys
= [k.strip() for k in reader.next()]
            result
= []
           
for row in reader:
                d
=dict(zip(keys, row))
                result
.append(d)
           
print (result)

But I've got the "NameError: global name 'unicode_csv_reader' is not defined". So I added a "self":

            reader = self.unicode_csv_reader(f)

That seems to work. But now I've got the "Name Error: global name 'utf_8_encoder' is not defined". So I tried with another "self":

        csv_reader = csv.reader(self.utf_8_encoder(unicode_csv_data),

That doesn't work. I've got the " "Name Error: global name 'self' is not defined". Same result if I'm writing

    @property
   
def utf_8_encoder(unicode_csv_data):
       
for line in unicode_csv_data:
           
yield line.encode('utf-8')

I think I've got a lack of basic understanding. Maybe someone can help me!?

Andreas Ecker

unread,
Sep 14, 2016, 11:16:44 AM9/14/16
to kivy-...@googlegroups.com
You were near to solve your problem but missed the self parameter in your class methods.

FYI: Python is passing to any normal method of a class always the object instance as the first parameter, which is normally (but not have to be) named as self.

I did some corrections to your example to demonstrate this (could not run/test it because don't have no csv module on my machine, but on your machine it should now run further):
class TestApp(App):

    
def build(self):
        
self.load_csv()


    
def utf_8_encoder(self, unicode_csv_data):

        
for line in unicode_csv_data:
            
yield line.encode('utf-8')


    
def unicode_csv_reader(self, unicode_csv_data, dialect=csv.excel, **kwargs):

        
# csv.py doesn't do Unicode; encode temporarily as UTF-8:

        csv_reader 
= csv.reader(self.utf_8_encoder(unicode_csv_data),

                                dialect
=dialect, **kwargs)
        
for row in csv_reader:
            
# decode UTF-8 back to Unicode, cell by cell:
            
yield [unicode(cell, 'utf-8') for cell in row]

    
def load_csv(self):
        
with codecs.open('in.csv', encoding='utf-8') as f:

            reader 
= self.unicode_csv_reader(f)

            keys 
= [k.strip() for k in reader.next()]
            result 
= []
            
for row in reader:
                d
=dict(zip(keys, row))
                result
.append(d)
            
print (result)

Recommending to you to do first some basic python tutorials before you go further with a kivy - especially on how to write classes in python.

HTH and have fun with lovely python,
Andi


--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Pulli Noobi

unread,
Sep 14, 2016, 3:49:28 PM9/14/16
to kivy-...@googlegroups.com
Yeah! Thank you a lot, Andreas! And you are right that I should learn more basics, and I will! But I'm enthusiastic how far you can come with Kivy without!

The code you gave me works great on my pc. But I've got a problem on my phone: my app isn't running any more. Is it possible, that the launcher can't handle the import csv? The log on my android tells me that their is "no module named _csv". Or do I have to find another mistake in my code?
I've seen this forum entry, but if I understand it right, they only discuss buildozer and not the launcher itself.

Or maybe their is an alternative code without the csv module? All code here and here needs this module or can't handle UTF-8.

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/p7pzzf8DVGg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+unsubscribe@googlegroups.com.

Andreas Ecker

unread,
Sep 15, 2016, 4:43:53 AM9/15/16
to kivy-...@googlegroups.com
I think you'll find the answer to your question by first going to the forum link you provided in your last email and then moving on to the stackoverflow item in the last forum entry from Alexander Taylor (http://stackoverflow.com/questions/32875139/buildozer-cant-load-csv-module-after-removing-it-from-blacklist).

So it looks like csv is a built-in module and you only need to remove it from your the requirements entry of your buildozer spec file to get it working on your android phone.

Pulli Noobi

unread,
Sep 15, 2016, 8:57:37 AM9/15/16
to kivy-...@googlegroups.com
It's nice to read that I can use the csv module when packaging an apk.
My app is still under progress so it would be nice to use the Kivy Launcher and if I'm right, their are no settings like this in Packaging for Kivy Launcher, right?
Reply all
Reply to author
Forward
0 new messages