• Drizzel

    @Bumbo-Cactoni I'm a bit late to the party, but you could always check out Cambidge IGCSE Computer Science past papers. Just search for them in your favourite search engine. They provide beginner level excercises and solutions, since the exams are aimed at students with 2 years of coding experience.
    Just be aware that for every year, there's one paper with a coding excercise (the one you want) and one paper with theory (boring).

    I had to pass this exam in 2018, just as an example
    There's more here.

    posted in Pythonista read more
  • Drizzel

    @stephen I know this isn’t specific to your pen, but I really like how you progressively smoothed out the face. I use similar techniques with pen and paper, but I never thought of drawing like that digitally.

    posted in General Discussion read more
  • Drizzel

    @mikael said:

    Could you try to strip down (a copy of) your code

    Of course, no problem. It might take me one or two days, because I have exams coming up

    posted in Pythonista read more
  • Drizzel

    Since I have absolutely no clue how I caused this error, the following will be rather unspecific, my apologies

    So I have a very modified table view. Sometimes, when I remove some cell with the delete_rows() function, and then scroll down to see cells that weren’t displayed when deleting, some of these newly presented cells are totally blank. They simply are a white, empty area. I can tap them normally, and the proper functions are called. When I long press them (thanks to @mikael and his gestures script) I get the following error:

    Traceback (most recent call last):
      File "/private/var/mobile/Containers/Shared/AppGroup/D1D9102B-9BBB-4003-A835-39FDFDA39AB1/Pythonista3/Documents/v9/play_view.py", line 50, in skip_action
        self.player.finished_handler()
      File "/private/var/mobile/Containers/Shared/AppGroup/D1D9102B-9BBB-4003-A835-39FDFDA39AB1/Pythonista3/Documents/v9/audio_manager.py", line 72, in finished_handler
        section = prev_cell.section
    AttributeError: '_anonymous_label' object has no attribute 'section'
    

    So what is an _anonymous_label, and how did I cause this?

    I’m really sorry that I’m so unspecific, I simply have no idea how my (pretty long) code got to this

    posted in Pythonista read more
  • Drizzel

    @Karina Yeah, we have a little “chicken house” and I wrote a script that opens and closes the door by turning on and off a motor. But that’s not the point :) I just needed an example to better illustrate the uses of threads

    posted in Pythonista read more
  • Drizzel

    @Karina Now yes, threads may not always speed up your program. But they can keep your program responsive even though there’s some time consuming task being done. I also sometimes use them to constantly check if a variable changed, and then trigger a function. (There’s better ways to do that. But hey, I’m learning too.)

    Even though this is in no way specific to Pythonista, let’s take a slight detour. Some time ago, I built a door manager for the chicken pen of my family (yeah, it’s a bit unusual). It opens and closes the door at given times, but also constantly checks a button and email for a manual overrides. Since the button needs to be checked every 0.1 seconds, but checking the email takes about 4 seconds (establishing a connection to the google servers takes some time), the button wouldn’t be checked while the code is trying to get the new email. This is solved with threads, so they get checked in parallel, not after each
    Therefore the button stays responsive, even though checking mails uses up a lot of time

    posted in Pythonista read more
  • Drizzel

    @Karina said:

    I began to read about threads and sometimes don't understand what about this all, but in general understand. And for what here to use them? It encreases the speed of smth?

    I certainly don’t know everything about threads either, but here’s my understanding of them.

    The basics:

    • I think of threads like... well threads, as in strings or a thin rope. And when you open a thread, the code in this thread is run separated to other threads.

    • Thus Threads allow for separate codes to run “at the same time” (this technically isn’t possible, and is done through some tricks so that it appears so. Thus the quotation mark. But I’m not here to confuse you, so let’s go on)

    • Therefore you can have one section of code that (for example) has a time.sleep(100000) in it, and a thread that prints stuff in an infinite loop. Since they run in different threads, your code will still print stuff, even though there’s a stupidly long sleep statement in it

    Edit If you want some coding examples, I can write you some with comments

    posted in Pythonista read more
  • Drizzel

    @stephen looking good! I always was a little too lazy to try them all out... and I’m not using scene much nowadays.

    posted in Pythonista read more
  • Drizzel

    @Karina I think you got me mixed up with @stephen :) And yes, I do prefer to fix the node‘s position manually.

    My version of flappy bird I posted here some days ago is a good example. I used basic physics formulas to give the bird an acceleration, and then use that to calculate the bird‘s speed and thus position at a given time. Then adjusting the gravity and weight parameters made the motion feel “just right” (in my opinion).

    Technical stuff aside, I just do it for greater control, so I can get the feeling of motions right.

    posted in Pythonista read more
  • Drizzel

    @Karina I haven’t used Actions much, I prefer animating nodes myself. But theoretically, from reading the docs, your code should work (assuming your indentation is correct and your actual code doesn’t miss the closed bracket at the end)

    posted in Pythonista read more
  • Drizzel

    @stephen That’s how I understood him. And it worked out really well, after some minor adaptions

    posted in Pythonista read more
  • Drizzel

    Thanks, I thought TableViewCells would always exist, nevermind if they’re on screen or not. That explains why this example doesn’t work properly. I’m going to try the suggestion of @JonB

    
    import ui
    
    class MyTableViewDataSource (object):
        def __init__(self, data, **kwargs):
            #self.__dict__.update((k, v) for k, v in kwargs.items() if k in allowed_keys)
            self.__dict__.update(kwargs)
            self.items = data   
            self.previousCell = False
            self.currentCell = False
            self.cells = [[] for i in range(len(self.items))]
            
        def tableview_number_of_sections(self, tableview):
            return len(self.items)
            
        def tableview_number_of_rows(self, tableview, section):
            return len(self.items[section])
            
        def tableview_cell_for_row(self, tableview, section, row):
            data = tableview.data_source.items[section][row]
            cell = ui.TableViewCell('subtitle')
            cell.section, cell.row = section, row
            cell.text_label.text = data
                
            self.cells[section].append(cell)
            return cell
            
        def tableview_title_for_header(self, tableview, section):
            # Return a title for the given section.
            # If this is not implemented, no section headers will be shown.
            return 'section: '+str(section)
            
        def tableview_can_delete(self, tableview, section, row):
            # Return True if the user should be able to delete the given row.
            return False
            
        def tableview_can_move(self, tableview, section, row):
            # Return True if a reordering control should be shown for the given row (in editing mode).
            return False
            
        def tableview_delete(self, tableview, section, row):
            # Called when the user confirms deletion of the given row.
            pass
            
        def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
            # Called when the user moves a row with the reordering control (in editing mode).
            pass
    
    #–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
        
    class BasicTableViewDelegate(object):
        def tableview_did_select(self, tableview, section, row):
            # Called when a row was selected.
            
            if tableview.data_source.currentCell:   
                if tableview.data_source.previousCell:
                    tableview.data_source.previousCell.background_color = 'white'
                    
                tableview.data_source.previousCell = tableview.data_source.currentCell
                del tableview.data_source.currentCell
                tableview.data_source.previousCell.background_color = '#eeeeee'
                
                
            #find current cell
            for cell in tableview.data_source.cells[section]: #dont like having to cycle through all cells
                if cell.row == row:
                    tableview.data_source.currentCell = cell
                    break
    
        def tableview_did_deselect(self, tableview, section, row):
            # Called when a row was de-selected (in multiple selection mode).
            pass
    
        def tableview_title_for_delete_button(self, tableview, section, row):
            # Return the title for the 'swipe-to-***' button.
            return 'Delete'
    
    if __name__ == '__main__':
    
        section1 = [str(i) for i in range(10)]
        section2 = [str(i) for i in range(10)]
        
        tv = ui.TableView()
        tv.data_source = MyTableViewDataSource([section1, section2])
        tv.delegate = BasicTableViewDelegate()
        
        tv.frame = (0, 0, 300, 400)
        tv.present('sheet')
        
        
    

    posted in Pythonista read more
  • Drizzel

    @stephen Alright, thanks. I just thought that creating a new cell wasn’t „elegant“, if you now what I mean :)

    Edit:
    I‘m pretty sure I’m missing something, though

    import ui 
    
    tv = ui.TableView(frame = (0,0,300,300))
    tv.data_source = ui.ListDataSource([i for i in range(10)])
    tv.data_source.tableview_cell_for_row(tv, 0, 2).background_color = 'red'
    
    tv.present('sheet')
    
    

    posted in Pythonista read more
  • Drizzel

    And I‘m confused about how the superview of a cell is it‘s tableview, but the tableview doesn’t have any subviews

    posted in Pythonista read more
  • Drizzel

    Is there an easy way to access the cells in a Tableview? And, more specifically, the currently selected cell?

    For now, I modified the datasource to give every cell an attribute with it‘s section and row, and then append them to an array. But cycling through this list to find the currently selected cell gets a bit inefficient with longer tables...

    posted in Pythonista read more
  • Drizzel

    This is a bit smarter:

    from scene import *
    import sound
    import random
    import math
    A = Action
    
    class MyScene (Scene):
        def setup(self):
            self.background_color = 'white'
            
            self.blocks = []
            for x in range(5):
                block = ShapeNode(rect(0,0,10,10))
                block.color = 'black'
                block.size = (30, 30)
                block.position = (self.size.x - 30, x*block.size[1] + block.size[1]/2)
                self.add_child(block)
                self.blocks.append(block)
                
            self.previous_time = self.t #self.t is the time that the game has been running
        
        def update(self): #everything in Here gets called 60 times a second
            if self.t - self.previous_time >= .5: 
                self.previous_time = self.t
                self.move_blocks()
        
        def move_blocks(self):
            for block in self.blocks:
                position = block.position
                new_x = position[0] - 10
                block.position = (new_x, position[1])
    
    if __name__ == '__main__':
        run(MyScene(), show_fps=False)
    

    posted in Pythonista read more
  • Drizzel

    You have to remove the loop, like this:

    def update(self):
            time_passed += self.dt
            if time_passed >= 0.5:
                print(time_passed)
                self.add_column()
                time_passed = 0
                self.column_moves()
    

    Everything inside update() gets executed 60 times per second. Just put self.time_passed = 0 in setup()

    posted in Pythonista read more
  • Drizzel

    seems like this bug is exclusive to iPadOS. I don't have any issues on my ipad mini 2 on ios 12.4.6.
    @7upser it's nice to see another german here :)

    posted in Pythonista read more
  • Drizzel

    @stephen said:

    😅😂😅 legiondary

    True :)
    @cvp Absolutely ove the calculation with the cpu speed, I wish it was like that.
    I guess I'll see what I can afford when my iPad gives up completely. As long as it doesn't smoke too much, it's still good to go :)

    posted in Pythonista read more
  • Drizzel

    @Karina said:

    @Drizzel you say you clumsy, but I don't know how to do theese things at all)
    your explanations helped to understand the beginnin, I think it'll take time to understand it all
    Do you know anything like Clock in pygame to work with time? I need to make a new column every 10 secs for example

    The update(...) function (is used in my code and the code by @stephen) is executed 60 times a second (as long as your device can handle the load). Here's a good explanation. You can use self.dt to check how much time has passed since the last frame was calculated, and self.t to check for how long the scene has been running.
    Then just do put this line into setup(...):

    self.time_of_last_column = self.t
    

    and merge this with your update(self):

    def update(self):
        if self.t - self.time_of_last_column >= 10:
            #put the code to place a new column here
            self.time_of_last_column = self.t
    

    posted in Pythonista read more
Internal error.

Oops! Looks like something went wrong!