• bennr01

    BTW, PyPy (the python JIT which is in many usecases faster than CPython) will continue to support py2 indefinetly and probably forever. So as long as you do not have to use c-dependent modules and are OK with using outdated modules, it is a good way to continue using py2 after its EOL.

    posted in Pythonista read more
  • bennr01

    @mikael You are right. This was only meant as a suggestion for reducing the number of times you have to write my_property (for a complete getter/setter/deleter setup it would be 3 instead of 5 times). Your decorator @prop is indeed neat, but it may still be useful to remember the my_property = property(...) syntax in case you (or anyone else who reads this) may find themself in a situation where you can not use it (due to code style guidelines or other reasons). I had not seen that you actually used this syntax in your example above and thought it may be a nice tip for you.

    would I not still need to maintain 3 names – property, getter and setter?

    I am not sure, but you may be able to use lambda in this case, which could still be usefull for some cases like read-only properties. Also, in some cases the getter and setter may only be calling some other aliases (like getting/setting text labels).

    posted in Pythonista read more
  • bennr01

    I am not sure, but IIRC, you could also use my_property = property(getter, setter) instead of the @property syntax.

    posted in Pythonista read more
  • bennr01

    Hi guys, is anyone interested in beta testing a few new features for StaSh?
    I have spend the last few weeks to port StaSh to PC, but the changes were rather extensive so i may have broken a few things.
    If you are interested in helping, here is a list of stuff which needs to be tested:

    What needs to be tested:

    • [iOS] Check that everything previously working still works (installation, updates, commands, ...)
    • [PC] Check that the port does not contain any bugs.
    • [iOS/PC] Check that StaSh still runs on both py2 and py3. I only had the chances to test the changes on py2.

    What is not working on PC:

    • The telnet and ssh commands will not work on PC. They need ui.measure_string which i am not sure how to implement using tkinter.
    • easy_config uses its own UI, which was not ported.

    How to install:

    • PC: Clone/download the crossplatform branch of bennr01/stash from github and run python setup.py install. Start with the launch_stash.py command.
    • iOS: If you do not already have StaSh installed, install the normal release first, then force quit pythonista. Afterwards, run selfupdate bennr01:crossplatform and force quit pythonista again.

    How to report bugs:
    If you find any bugs, please report them either in this thread or in my StaSh fork. Please do not report them directly to the main repo to reduce the number of issues created there.
    Of course, pull requests are welcome :)

    posted in Pythonista read more
  • bennr01

    A few month ago someone asked a similiar question on reddit.
    Assuming you can run python on both sides, you can use this example. For more details, please see the discussion in the reddit discussion linked above. This example does not use SSH, but the socket & webbrowser modules instead.

    posted in Pythonista read more
  • bennr01

    @danaportenier replace def __ini__(...) with def __init__(...) (notice the t)

    Edit: You can also replace your if-construct with something like this:

    inp = input("What was the month (1-12) ").strip()
    self.month_input = {
       "01": 1,
       "1": 1,
       "Jan": 1,
        "02": 2,
        "2": 2,
        "Feb": 2,
        }.get(inp, None)

    This does the following:

    1. ask the user for input, saving it in the local variable inp
    2. create a dictionary (key-value mapping) containing the inputs and their numeric values, then checks if inp is in the dictionary. If it is, the value for the input is assigned to self.month_input, otherwise the value None is used.

    I would also recomment to restructure the code as follows:

    class UserInputDate(object):   # inherit from object, use PEP8-style naming conventions
        MONTH_TO_YEAR = {...}  # your month names to values, as dicussed above
        def __init__(self, month, year):
            self.month = self.MONTH_TO_YEAR.get(month, None)   # do not call I/O functions from `__init__`. You may later need the same class without input.
            self.year = year
        def from_input(cls):
            # use a classmethod to directly create the class from input
            month = input("Please enther month (1-12)")
            year = input("Please enther year")
            return cls(month, year)
        def combine(self):
             # as your old code, but using self.month and self.year
    if __name__ == "__main__":
        # place top-level code inside such an if-statement, so it does not get executed on import
        primary_bariatric_date = UserInputDate()

    The above code is not tested, but it should prove you with some tips regarding class layout.
    Most of these changes seem useless at first, but are more useful later on.

    posted in Pythonista read more
  • bennr01

    It is a new StaSh bug. I do not know the exact details, but it seems like StaSh only creates an empty file for the command. This may be caused by a recent change. Could you please provide the output of the version command?

    posted in Pythonista read more
  • bennr01

    @ccc I also oppose dropping python 2 from pythoniststa 3 for several reasons.

    1. I still have a huge amount of py2 code which i do not want to port
    2. I do not want to be forced to adapt py3. While i am slowly, but steadily switching over to py2 and py3 compatible source and later to only py3, i want to do this on my own pace and not suddenly because one of my most used apps dropped support for py2.
    3. Pythonista 3 is advertised on the appstore as being both py2 and py3 compatible. Some people, including me, probably would not have bought pythonista3 if it did not support py2. Before @omz announced that pythonista3 would support both versions, I had not even considered buying pythonista3. Chances are, that a few people may be outraged if py2 was dropped. You may argue that they do not have to update, but maybe some people have automatic updates on and will know py2 was dropped before it is too late. And i do not want to see that shitstorm.
    4. Why should we even drop py2? Just because it is officialy EOL does not mean we have to drop support for py2. While it would be nice if we would have a faster start-up time, a simple do not load py2/py3 switch would also do the job.
    5. I sometimes work on py2 code on my iPhone and like it.
    6. Py3 is an abomination which i will fight until my very last breath.

    Well, in the end it is the decision of @omz .

    posted in Pythonista read more
  • bennr01

    @sendog3c could you please provide a bit more information about your problem?

    But I have problem with parameter, data gotten from sender (str, int).

    What exactly do you mean? sender.title should always be a str. If you want to convert a str to an int, use int(text_here). If you want to convert a int to a str, use str(int_here).

    def button_tapped(sender):
        #if  button_tapped == b_top1.title('SUM'):
        #itexto1 = 'Hello World'
        texto1 = sender.title
        #texto1 = str(300)  
        return texto1

    You can not return something from a callback. Instead, do the operation directly in the callback.
    An example:

    def button_tapped(sender):
        a = ...  # value for a here
        b = ...  # value for b here
        action = sender.title
        if action == "SUM":
            result = a + b
        # .. other operations
        txt_field1.text = str(result)

    Also, the following will not work:

    txt_field1.text = button_tapped()

    If i understand correclty, you want to change the text when a button was pressed. However, button_tapped() will be evaluated right in this line, before the UI is presented. Instead, modify the text in the callback as shown above.

    posted in Pythonista read more
  • bennr01

    @Robert-Buckley said:

    because once those controls have been used, they disappear and don't come back.

    Uhmm... what? This is not supposed to happen...

    posted in Pythonista read more
  • bennr01

    The option for cursor color is called tint color (or something like that). Also, like @ccc said, restart the app after making changes.

    posted in Pythonista read more
  • bennr01

    @Robert-Buckley there is also the easy_config command, which allows changing the colors

    posted in Pythonista read more
  • bennr01

    @shtek said:

    why not merged yet?

    It is now merged.

    it's utf8 everywhere, why stick to python 2

    If your question is "why is StaSh still py2 and not yet py3?", then there are two reasons:

    1. Large codebase, some of it using py2-only or outdated dependencIes (e.g.g git)
    2. The person who did most of the current port to py3 finally understood that py3 is an abomination which needs to be fought until our very last breath

    posted in Pythonista read more
  • bennr01

    @headsphere You could try disabling wheels for the installation using pip --verbose install --no-binary :all: attrs.

    posted in Pythonista read more
  • bennr01

    Hi, have you checked the physical mute switch on your phone? There should be a switch near the volume buttons, which, wenn activated, mutes specific sounds including most of pythonista sounds.

    posted in Pythonista read more
  • bennr01

    @JonB said:

    BTW, iirc, monkeylord in stash has the capability to "mount" Google drive folder.

    The mount-command currently only supports dropbox, ftp, zipfiles and other directories. I am thinking about rewriting it to use pyfilesystem2 instead, but this may still take a while.

    @FarmerPaco said:

    I did check the site packages and saw the Stash running 2.7 installs a more updated version of pyasn1 (v. 2.1) where as stash runing at 3.6 installs an earlier version of pyasn1 (v.1.7). This seemed strange.

    Interesting... Are you using StaSh version 0.7.2? I recently changed pip to respect the python version when installing new packages, but pyasn1 should work for both... Also, are you sure about the version of pyasn1? According to pypi the most recent version is 0.4.5.

    posted in Pythonista read more
  • bennr01

    @djl said:

    "-s d blabla" are necessary arguments in this example . I cannot figure out how to do the same thing from the Pythonista console.

    You can long-press the run-Button to add arguments

    Regarding the SyntaxError: Maybe you run StaSh in a different python version than the console?

    posted in Pythonista read more
  • bennr01

    @Drizzel it seems like Document.generate_pdf() uses subprocess to spawn a seperate process for generating the PDF. This is not allowed by iOS, thus the error.

    posted in Pythonista read more
  • bennr01

    @adrius42 said:

    Why??! This feels very counter-intuitive changing the meaning of equals in this way.
    I guess way back in the mists of time the original Python developer had a reason!
    So actually the operator was the time traveller! (Or rather the temporal cloner!)

    IIRC, most languages do this. It allows some usefull stuff which would otherwise be impossible.
    For example, assume you had the following code:

    def add_defaults(l):
        """add some default values"""
        if "value_default" not in l:
    def remove_invalid_values(l):
        """remove all invalid values from list"""
    some_values = ask_user_for_input()

    Due to having the same list shared between the functions, we can avoid unneccessary assignments. This is both easier and way more efficient.

    But the more important reason is consistency: list are objects. This is the same in many programming languages due to the way they work. And all non-primitve objects (maybe there are some exceptions, but none important) are not directly assigned to a variable. Instead, when you say some_object = SomeObject(), SomeObject() is created somewhere in your RAM and a reference is created which points to SomeObject(). This reference is then assigned to some_object. When you use some_var = some_object, some_var actually gets a copy of the reference, like some_var = some_int would do, but the copy of the reference still points to the same object. Thus, even if some_var is a copy of the reference in some_object, it still points to the same object.
    Maybe this code can explain this a bit better:

    class SomeClass(object):
        """some class"""
        def __init__(self, v):
            v = v
    int_var_a = 1  # int_var_a is directly assigned the integer 1
    int_var_b = int_var_a  # int_var_a is loaded, and the content is assigned to int_var_b
    print(int_var_a == int_var_b)  # True, both are equal
    int_var_a = 2
    print(int_var_a == int_var_b)  # False
    obj_var_a = SomeClass("value_1")  # an instance of SomeClass() is created and stored in the RAM. A reference pointing to SomeClass() is created and assigned to obj_var_a
    obj_var_b = obj_var_a  # the >reference< if obj_car_a is copied to obj_var_b
    print(obj_var_a.v == obj_var_b.v)  # True, because both obj_var_* point to the same object
    obj_var_b.v = "some other value"  # the object is modified, but both obj_var_* still point to the same object
    print(obj_var_a == obj_var_b)  # True, because both obj_var_* still point to the same object and both have been modified

    I am getting ever more convinced that I do not understand the operation of “self”
    Can you point me to some text that would help me... it feels like self is not always self, and often self is “not defined’ when I know it had been!?

    self is in fact not a operation, but a variable name without any real meaning.
    Here is some more code:

    class MyClass(object):
        def method_a(self, x):
            # self points to the instance of MyClass() this method is called on. x is some other value
        def method_b(foo, x):
            # foo points to the instance of MyClass() this method is called on. x is some other value
            # this is because the first parameter of a bound method is always the object
        def some_static_method(x):
            #This is a static method. self is not defined here. x is some other value passed to this method.
        def some_class_method(cls, x):
            # This is a class method. cls is not pointing to the instance of the object this is called on, but instead pointing to the class this is called on.
            # this is useful for alternative constructors

    In other words: self is always defined if you name the first parameter/argument of a bound (more about that later) method self. If you name the first parameter/argument of a bound method foo, then foo would be the equivalent of self.
    A bound method is a normal method of an instance of a class. In the above example, MyClass().method_a and MyClass().method_b are bound methods, because they are "normal" methods (not modified by @staticmethod or @classmethod) of an instance (MyClass()).
    If you use MyClass.method_a or MyClass.method_b (please note the missing (), this is the class, not instances of the class), these are unbound methods, as they are not part of an instance. In this case, self must be specifically passed to the method.

    Also, about self: you can think about self as some sort of namespace. self is unique per instance of a class. Changes to self persist between methods of the same instance, but not between methods of different instances.

    I would have preferred
    B = A transferred contents of A to B just thus once
    B == A results in B becoming the same as A for all time

    In python, == means a comparsion of equality.

    But then I am just wishing that the Python Language understood me, rather than me having to understand it!

    Dont worry, you are not the only one...

    To be clear this only applies to lists right?

    A = 1
    B = A
    A = 2
    Won’t change B to 2

    So, are there any other types of variables where the operators change what they do?

    This behavior applies to all non-primitive types.
    Some example of primitive types are int, long and float.
    Non-primitive types are basically everything else, mostly instances of classes.
    So, a={}; b=a; b["a"] = 2 would also modify a.
    a=1; b=a; b=2 would not change a, because both b and a are primitive.
    Strings are interesting. They are objects, but immutable. a=""; b=a; some_change(b) would change a too, but since neither a nor b can be changed, this is not a problem.

    Small disclaimer: I am not involved with the development of python and can thus not guarantee that the above information is correct, but it should be.

    Sorry for my bad english, it is not my native language. I still hope that this may be of help for you.

    posted in Pythonista read more
  • bennr01

    @JonB There is currently no flag, but you can switch priority in line 1051 of pip.py. But the flag is a good idea, I'll add it when/if i fix Wheels for PEP 491.

    posted in Pythonista read more
Internal error.

Oops! Looks like something went wrong!