I've been using Pythonista for about a week now; primarily as a learning tool while I'm on the go. With that in mind, my terminology might be a little off so I apologise if I sound like I have no idea what I'm talking about.
Basically, I've been playing around with making little 2D games with the app and I want to delve into some of the functions a bit more. I was hoping to be able to see some of the definitions for functions so I can get a glimpse of how they perform. I'd also like to implement my own action functions similar to "move_to" and "rotate_by".
Is it possible to view these definitions somewhere? Either within the app or online etc. I believe Visual Studio allows you to highlight a function call and right-click to view its definition but I'm struggling to find anything similar in Pythonista.
Any help would be much appreciated! :)
If you click on the title of the file at the top of the editor, you will get a popup menu of all functions in that file.
If you tap and hold on a standard library function name in the editor and then select 'help', you will be taken to the Python docs.
Thanks for taking the time to reply. Sadly, I don't think I've worded myself very well so I'll try specifying a bit more carefully.
In the Scene module, there are Action objects with methods such as "move_to" and "rotate_by", I'd like to be able to view the code that defines these built-in methods so I can get a better understanding of them.
So I'm assuming there's code somewhere within the app under the Action class that includes a function definition beginning "def move_to(x, y[, duration, timing_mode])" and containing the code which is executed when this method is called.
I might have my assumptions wrong, or this code might be inaccessible to view, so apologies if I'm asking a silly question. Viewing the definitions for built-in methods would just be quite convenient for me, as a learner, to better understand how things work.
Short version: It depends on the function - for some functions you can see the source code easily, for others it takes some work, and sometimes it's not possible at all. For the methods of
scene.Action, you cannot see the source code at all.
Long version: In Python there are two types of functions:
- Python functions (type
types.FunctionType), which are functions that were written in Python code using a
lambda. If you print out a Python function, it looks like
<function python_func at 0x596f752077696e21>. Because they are written in Python, the source file and code can usually be found automatically using the
inspect.getsourcefunctions. If the source code doesn't exist for some reason, you can at least use
dis.disto disassemble the Python bytecode - which is much less readable than normal Python code, but not impossible to understand.
- "Built-in" functions (type
types.BuiltInMethodType), which are functions that were implemented in a language that compiles to native code, usually C, C++, Objective-C, or assembly. If you print out a built-in function, it looks like
<built-in function builtin_func>. Because they are written in a compiled language, the source code is not needed or available at runtime. If the function is from an open source library (such as CPython itself, numpy, or Pillow), you can search for the source code there, however you need to do this by hand. For functions from a closed source library (such as Pythonista's own modules) this is not possible of course.
Note that very few libraries are pure native code. Many libraries are written in both Python and native code, usually split into a public Python and an internal native module. You can see this with
scene: The main
scenemodule that you get with
import sceneis actually written in Python (see
Modules & Templates>
Standard Library (3.5)>
scene.py), but it imports many classes and functions from an internal
_scene2module that is written in (Objective-)C. This means that you can see the source code for the parts of
scenethat are written in Python, but not the parts written in (Objective-)C.
- Python functions (type
If your aim is to implement your own actions, you can use update or custom_action. Here is an example that implements move_to action using either update or custom_action.
# action move_to example import scene class MyScene(scene.Scene): def setup(self): self.label_node = scene.LabelNode('A', position=(100,400), parent=self) self.animate_action = scene.Action.move_to(340, 400, 2) def touch_ended(self, touch): self.label_node.run_action(self.animate_action) scene.run(MyScene()) ''' # action move_to example implemented using update import scene class MyScene(scene.Scene): def setup(self): self.label_node = scene.LabelNode('A', position=(100,400), parent=self) #self.animate_action = scene.Action.move_to(340, 400, 2) self.start_flag = False def update(self): if self.start_flag: x,y = self.label_node.position if x < 340: self.label_node.position = (x+2, y) else: self.start_flag = False def touch_ended(self, touch): self.start_flag = True #self.label_node.run_action(self.animate_action) scene.run(MyScene()) ''' ''' # action move_to example implemented using custom_action import scene def custom_action(node, progress): x,y = node.initial_position node.position = (x+240*progress, y) class MyScene(scene.Scene): def setup(self): self.label_node = scene.LabelNode('A', position=(100,400), parent=self) x,y = self.label_node.position self.label_node.initial_position = (x,y) self.animate_action = scene.Action.call(custom_action, 2) def touch_ended(self, touch): self.label_node.run_action(self.animate_action) scene.run(MyScene()) '''
@enceladus Thanks for the in-depth reply! I quite like the custom_action implementation, I'm just playing around with it now and wondered if it was possible to add parameters to the custom actions. I can get a custom action to function if it takes no parameters, but I'm struggling with ones that do take parameters.
As an example, I have a function which rotates one object around another by a specified amount of degrees:
def rotate_around(self, point, centre, angle): p = point.position #point c = centre.position #centre a = ((angle)*(math.pi/180)) #angle x = math.cos(a)*(p.x-c.x)-math.sin(a)*(p.y-c.y)+c.x y = math.sin(a)*(p.x-c.x)+math.cos(a)*(p.y-c.y)+c.y point.position = (x,y)
How would I go about translating this into a custom action so that it could be used in a sequence or group etc?
Again, thanks for the help! :)
@dgelessus Thanks for being so thorough in your answer. I'd read somewhere that source code is often split between various languages and compiled differently, but your answer has cleared up a few things for me. That
scene.pyfile is also interesting to look at; thanks for pointing me to it :)
You can not add extra parameters to custom_action but you can put the desired information in the node. In the example, initial_position is the information passed to custom_action.
Look at the Animation class in the scene_drawing.py. Action implementation is similar to that. (Scene_drawing.py is the old implementation . It is there mainly for compatibility with old scene code)
@enceladus Thank you! I was trying to create an enemy movement that spiralled toward the centre of the screen and I've finally cracked it with the help from the replies in this post! :)
Much appreciated! I'm delighted!