Donnerstag, 24. Juli 2014

Scene Kit dragging / picking demo for OS X / iOS

I just published this little demo of Scene Kit, where we can drag around a 3d model and select individual parts. For OS X and iOS using Swift.




The code in probably self explanatory (if not, I'm sorry...). The 3d program needs to give each object a name, which we use to identify what we picked - in the case of this example, we use it to show the label at the bottom "Right foot" etc. The model has to be exported to .dae.

In Blender the name of the object is here:





Code:

OS X:
https://github.com/i-schuetz/scene_kit_pick

iOS:
https://github.com/i-schuetz/scene_kit_pick_ios

The iOS version is laggy, at least in the simulator, don't think it's related with the code or my super complex 3d model ;). It might be a bug of the beta.

Donnerstag, 3. Juli 2014

Items drag & drop iOS exercise

This is a little exercise I did to practice gesture recognizers, collection view, and snapping effect effect using UIDynamicAnimator (iOS 7).
We can drag and drop views from the bottom selector to top view. The views can be clicked to see more info. When view is dragged to invalid place it snaps back. Placed views can be removed by dragging back to the bottom.
This can be useful for e.g. placing furniture in a room, dressing a person, etc.
It needs refactoring, right now everything is in a view controller.


Code

Freitag, 27. Juni 2014

Donnerstag, 19. Juni 2014

Tamagotchi example in Clojure

A basic example of a command-line Tamagotchi game, in Clojure!

Completely functional - doesn't mantain any state (besides the "state" in the functions itself, of course).

Start:
Lein run
This is how it looks:
create <name> ::: creates a new tamagotchi
show ::: shows tamagotchi
feed ::: feeds tamagotchi
quit ::: exit
create Max
Tamagotchi Max created!
show
Max has 10 health points. Last feed time: 19.06.2014 11:51:28, You have 17 seconds to feed it before health is reduced.
show
Max has 10 health points. Last feed time: 19.06.2014 11:51:28, You have 9 seconds to feed it before health is reduced.
feed
Feed!, updated health: 12
show
Max has 12 health points. Last feed time: 19.06.2014 11:51:42, You have 15 seconds to feed it before health is reduced.

Project url: https://github.com/i-schuetz/tamagotchi_clojure/blob/master/README.md

Sonntag, 1. Juni 2014

Clojure shop project

I created Clojure shop, an open source project, with basic functionality of an online shop:

- Product list
- Authentication
- Cart
- User account
- Payment
- Image resolutions management
- md5

For the full description, please check the Github repository.

I also wrote an open source client application for iOS.


Hope this is useful, it's a learning project, everything working so far, a good start if you're interested in developing online shop / mobile REST api with Clojure. Also, contributions welcome!


*I Had to create a Clojure only blog to add a feed to Planet Clojure: http://clojurestuff.blogspot.de/
For now duplicating the entries...

Mittwoch, 28. Mai 2014

Clojure protocols example 2: Extending existing classes

In my past post "Clojure protocols example" I gave an example about using protocols on new types. But protocols also can be used to extend existing types.

A real world example of this can be found in this library, used to generate message digest (md5, etc) for different input types.

More specifically this file.

Here we see existing data types (Collection, String, File, etc) are extended to implement Digestible protocol. So we can call digest on them - a method which they don't support natively.

This is a different, simplified version, with just what we need to understand:
(defprotocol Digestible
  (digest [digestible]))

(extend-protocol Digestible

  clojure.lang.PersistentVector
  (digest [digestible]
    (str "vector-md5-" digestible))

  clojure.lang.PersistentArrayMap
  (digest [digestible]
    (str "map-md5-" digestible))

  java.lang.String
  (digest [digestible]
    (str "string-md5-" digestible)))


;test
(digest {:a 1 :b 2}) ;map-md5-{:a 1 :b 2} 
(digest [1 2 3]) ;vector-md5-[1 2 3]
(digest "hellooo") ;string-md5-"hellooo"


In this case, we could say, explaining it in object oriented fashion, that we are extending the existing map, vector and string classes in Clojure to support the digest function. A more functional explanation, and thus suitable for this context, would be that we are defining a function, which will execute implementation according to the type of the parameter.
Either way, we call digest with these types, and get the correct hash. In this example, probably needless to say, for demonstrative purposes, we don't return a hash but a text that helps us to see which method was called.

Note that in this example I'm using "digestible" instead of "this" to name the parameter (contrary to the first example I posted about protocols). There's no reason for this, besides I consider "this" maybe to be too engrained into object oriented world and misleading in this context. I may change the other post to use "data-provider" instead of "this". The source of the GitHub project I mentioned uses "message". I consider "digestible" better, since if we pass anything here that's not "digestible", we will get an error. It seems there is no (well known) convention about the naming of this parameter yet, since all the examples I have found use something different.

On a different note, this functionality can also be achieved using multimethods. This is the multimethod version of our example:

(defmulti digest class)

(defmethod digest clojure.lang.PersistentVector [digestible]
  (str "vector-md5-" digestible))

(defmethod digest clojure.lang.PersistentArrayMap [digestible]
  (str "map-md5-" digestible))

(defmethod digest java.lang.String [digestible]
  (str "string-md5-" digestible))

;test
(digest {:a 1 :b 2})
(digest [1 2 3])
(digest "hellooo")


More info on when to use protocol or multimethod e.g. here.

Dienstag, 27. Mai 2014

Clojure protocols example

Task: create a data provider with different implementations e.g. database / memory

;We start with a basic in-memory implementation:
(defprotocol DataProvider
  ;We pass the instance to the functions as "this" (the name is arbitrary)
  (find-user [this id]))

(deftype MemoryDataProvider []
  DataProvider

  (find-user [this id]
    (first (filter #(= (:id %) id)
                   [
                    {:id 1 :name "betty"}
                    {:id 2 :name "mike"}]))))

;Test: create an instance and find user with id 2
(def my-data-provider (MemoryDataProvider.))
(find-user my-data-provider 2)

;In the database implementation we need to pass e.g. host and port
;in order to establish a connection. We do this using the constructor
;function of the type (see DBDataProvider below). 
;We also need to add a function to establish the connection. We have to
;do add it also to the protocol, since the client has to call it and doesn't know 
;the implementation. We add a generic method "init" to the protocol, 
;for this purpose.
;(Note that "init" means side effects, so this doesn't really make
;sense in the in-memory implementation, but don't see a better solution).
(defprotocol DataProvider
  (init [this])
  (find-user [this id]))

;We have to add the method to MemoryDataProvider. Not doing this will
;not cause compiler error, but will throw runtime error if init is
;called on this type
(deftype MemoryDataProvider []
  DataProvider

  (init [this])
  
  (find-user [this id]
    (first (filter #(= (:id %) id)
                   [
                    {:id 1 :name "betty"}
                    {:id 2 :name "mike"}]))))


;Test
(def my-data-provider (MemoryDataProvider.))
(init my-data-provider) ;nil
(find-user my-data-provider 2)


;This is the database data provider type
(deftype DBDataProvider [host port]
  DataProvider

  (init [this]
    (println "host: " host ", port: " port)
    ;connect...
    )
  
  (find-user [this id]
    ;get it from database...
    {:id 0 :name "test"}
    )
  )

(def my-data-provider (DBDataProvider. "127.0.0.1" "1234"))
(init my-data-provider) ;nil
(find-user my-data-provider 2)


;We can also make init return the type:
(deftype DBDataProvider [host port]
  DataProvider

  (init [this]
    (println "host: " host ", port: " port)
    ;connect...
    this
    )
  
  (find-user [this id]
    ;get it from database...
    {:id 0 :name "test"}
    )
  )

;then we can do:
(def my-data-provider (init (DBDataProvider. "127.0.0.1" "1234")))
(find-user my-data-provider 2)


Note: I'm new to Clojure, glad to receive corrections or suggestions in the case something can be improved.
These snippets can be found (together with others) here.

Sonntag, 18. Mai 2014

Practical Clojure partials introduction

Today I found myself practicing a bit the concept of partials in Clojure, and ended writing a tutorial -like script. Here it is, maybe it helps someone else to learn how to use them.

;assume we have a function that does something with a list of numbers
;in this case, it adds a value to each number:
(defn add-value [value numbers]
(map (fn [number] (+ number value)) numbers))

;test
(add-value 2 [1 2 3]) ;(3 4 5)

;now we put this logic in a function "foo":
(defn foo []
  (add-value 2 [1 2 3])

;test
(foo) ;(3 4 5)

;now imagine that besides of add-value we have a mult-value function:
(defn mult-value [value numbers]
  (map (fn [number] (* number value)) numbers))

;or any other function that accept a value and numbers vector as
;parameters, and does something with them!

;we want to customise the
;behaviour - so we pass the behaviour as parameter:
(defn foo [some-function]
  (some-function 2 [1 2 3]))


;now we can call foo with add-value:
(foo add-value) ;(3 4 5)
;or mult-value:
(foo mult-value) ;(2 4 6)


;now imagine a situation where foo passes the vector
;but not the value. Instead, we want to pass the value
;together with some-function

;we could do:
(defn foo [some-function value]
  (some-function value [1 2 3]))

;test
(foo add-value 2) ;(3 4 5)

;this works but it's ugly, and in more complex use cases can quickly
;become a mess - we are altering the signature of foo with
;values which belong rather to some-function.
;so how can we pass the value to some-function instead of passing it
;to foo, despite we don't have all the parameters to call
;some-function yet?
;this is were a partial comes to help

;with a partial we can pass only a part of the parameters to a function,
;letting it "on hold" until the rest is passed.

;we revert to our old signature of foo:
(defn foo [some-function]
  ;note: value is "captured" (see call below) in some-function so we don't pass it here anymore
  (some-function [1 2 3]))

;and we call foo using a partial, which captures the value:
(foo (partial add-value 2)) ;(3 4 5)
(foo (partial mult-value 2)) ;(2 4 6)


;an alternative would be to use partial in the definition of the function
;this would make sense if we are certain that the function is going to be always used as partial:
(defn add-value [value]
  (partial map (fn [number] (+ number value))))

;and call it like this:
(foo (add-value 2)) ;(3 4 5)

;note that, with this implementation, (forgetting about foo for a moment) we can't do this anymore:
(add-value 2 [1 2 3]) ;error
;we would have to use this syntax in order to call add-value will all parameters:
((add-value 2) [1 2 3]) ;(3 4 5)

;if we want to be more flexible, meaning we have the options to use the function
;both as partial or passing all the parameters, we can use multiple arities 
;(like before, it depends on the use case if this makes sense):
(defn add-value
([value] (partial add-value value))
([value numbers]
  (map (fn [number] (+ number value)) numbers)))

;we also use it like this:
(foo (add-value 2)) ;(3 4 5)

;without foo, we can do this, like before:
((add-value 2) [1 2 3]) ;(3 4 5)
;but now we also can do:
(add-value 2 [1 2 3]) ;(3 4 5)


Note: I'm new to Clojure, glad to receive corrections or suggestions in the case something can be improved.
These snippets can be found (together with others) here.

Sonntag, 5. Januar 2014

Maps v2 circles library for Android!

I published a library to create circles using gestures in Android's maps v2.

Github: https://github.com/i-schuetz/map_areas



I remember back on maps v1, that I actually invented the basic functionality (create circle with long press and drag to resize) - together with a college in a company I was working at. It was quite complicated to implement in v1. I published the functionality in my homepage.

With maps v2 this code was not usable anymore. And surprisingly, Google added this functionality to maps v2 / a sample demo (coincidence...?). Though with some differences, like using markers to do the gestures, or the possibility to change the position of the circles.

Anyway, the provided sample is relatively raw, possibly not usable out of the box. I created the library to ease the usage and provide some additional features.