Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A tale of two cellphones: Python on Android and iOS

A tale of two cellphones: Python on Android and iOS

Python is enjoying a surge in popularity due to it's features as a language. However, over the last 10 years, mobile platforms have increased in importance, and Python doesn't have a good story on these platforms.

In this talk, Dr Russell Keith-Magee will give a technical dive into the work the BeeWare project has been doing to make Python as simple to use on Mobile as it is on other platforms.

Video: https://www.youtube.com/watch?v=NqdpK9KjGgQ

Russell Keith-Magee

May 31, 2016
Tweet

More Decks by Russell Keith-Magee

Other Decks in Programming

Transcript

  1. A tale of two cellphones Python on Android and iOS

    Dr Russell Keith-Magee @freakboy3742 PyCon US 2016
  2. A tale of two cellphones Python on Android and iOS

    Dr Russell Keith-Magee @freakboy3742 PyCon US 2016
  3. What is currently possible? You can: Write a native iOS

    application Write a native Android application Write a cross-platform application
  4. iOS

  5. Objective C in C Class nsstring = objc_getClass("NSString"); SEL alloc

    = sel_registerName("alloc"); id str = objc_msgsend(nsstring, alloc); SEL init = sel_registerName( "initWithCharacters:length:"); str = objc_msgsend( str, init, "http://pybee.org", 16); Class nsurl = objc_getClass("NSURL"); SEL urlwithstring = sel_registerName( "URLWithString:"); id url = objc_msgsend( nsurl, urlwithstring, str);
  6. ctypes from ctypes import * libc = cdll.LoadLibrary("libc.so.6") libc.strchr.argtypes =

    [c_char_p, c_char] libc.strchr.restype = c_char_p >>> print(libc.strchr(b"abcdef", b"d")) 'def'
  7. ctypes and Objective C from ctypes import * lib =

    util.find_library(b'objc') objc = cdll.LoadLibrary(lib) objc.objc_getClass.argtypes = [c_char_p] objc.objc_getClass.restype = c_void_p NSString = objc.objc_getClass(b'NSString')
  8. Descriptors class ObjCInstance: def __getattr__(self, name): print("Getting attribute", name) def

    __setattr__(self, name, value): print("Set", name, "to", value) >>> obj = ObjCInstance() >>> obj.spam Getting attribute spam >>> obj.pork = "ham" Set attribute pork to ham
  9. Callables class Method: def __call__(self, *args) print("Invoke method with args",

    args) ... >>> method = Method() >>> method(1,2,3) Invoke method with args (1, 2, 3)
  10. Rubicon from ctypes import cdll, util from rubicon.objc import ObjCClass

    cdll.LoadLibrary(util.find_library('Foundation')) NSURL = ObjCClass('NSURL'); NSURL.URLWithString_("http://pybee.org/")
  11. Rubicon from rubicon.objc import * NSObject = ObjCClass(NSObject) class Handler(NSObject):

    @objc_method def initWithValue_(self, v: int): self.value = v return self @objc_method def pokeWithValue_(self, v: int) -> None: print ("Poking with", v)
  12. An iOS application in Python class PythonAppDelegate(UIResponder): @objc_method def application_didFinishLaunchingWithOptions_(

    self, application, launchOptions) -> bool: ... class MyViewController(UIViewController): @objc_method def loadView(self) -> None: self.title = 'Add item'
  13. Inside Python def sing(): for i in range(100, 0, -1):

    print("%d bottles of beer on the wall" %i) print()
  14. Bytecode 2 0 SETUP_LOOP 47 (to 50) 3 LOAD_GLOBAL 0

    (range) 6 LOAD_CONST 1 (100) 9 LOAD_CONST 2 (0) 12 LOAD_CONST 5 (-1) 15 CALL_FUNCTION 3 (3 positional, 0 keyword pair) 18 GET_ITER >> 19 FOR_ITER 27 (to 49) 22 STORE_FAST 0 (i) 3 25 LOAD_GLOBAL 1 (print) 28 LOAD_CONST 4 ('%d bottles of beer on the wall') ...
  15. Java package com.example; public class Sing { public static void

    main(String [] args) { for (int i = 100; i < 0; i--) { System.out.println(i + " bottles of beer on the wall"); } } }
  16. Bytecode Max stack: 3 Max locals: 2 Bytecode: (39 bytes)

    0: BIPUSH 100 2: ISTORE_1 3: ILOAD_1 4: IFGE 34 7: GETSTATIC java/lang/System.out 10: NEW java/lang/StringBuilder 13: DUP 14: INVOKESPECIAL java/lang/StringBuilder.<init> 17: ILOAD_1 ...
  17. VOC

  18. An Android application in Python from android.widget import ListView class

    MainActivity( extends=android.app.Activity): def onCreate(self, state: android.os.Bundle ) -> void: super().onCreate(state) Log.i("MyApp", "Create new app") listview = ListView(self) ...
  19. A Toga App import toga class TodoApp(toga.App): def startup(self): self.list

    = toga.List( data=[...], on_delete=self.remove_entry, on_refresh=self.refresh ) ...
  20. A Toga App (pt II) ... container = toga.NavigationView( title="Todo

    List", content=self.list, on_action=self.show_add_dialog ) self.main_window.content = container
  21. A Toga App (pt III) ... self.input = toga.TextInput(placeholder="thing to

    do...") self.add_item_dialog = toga.Dialog( title="Add item", content=toga.Container( self.input ), on_accept=self.add_entry ) ...
  22. A Toga App (pt IV) def show_add_dialog(self, widget): self.input.clear() self.show_dialog(self.add_item_dialog)

    def add_entry(self, widget): if self.input.value: self.list.add({'description': self.input.value}) def remove_entry(self, widget): ... def refresh(self, list_widget): ...
  23. It is the best of times, it is the worst

    of times, it is the age of wisdom, it is the age of foolishness, it is the epoch of belief, it is the epoch of incredulity...