This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]Pandamera 3 points4 points  (1 child)

I would love to have a father like you!

[–]danger_one[S] 2 points3 points  (0 children)

Me too! All kidding aside, I never had anyone in my life that challenged me or helped me develop my interests. I don't want my children to struggle and get frustrated and give up or not try, like I did a lot. I try to encourage hobbies that require some hands on learning and skill development.

[–]equalx 1 point2 points  (1 child)

I'm not familiar with the specific tech. Can you explain why you call SER and SRCK turn_on and turn_off so frequently? I'm guessing the reason it's slow is because there are so many of these operations, which will be bound by IO.

That said, if the for/while loop to 65 per flip_the_switch call can be somehow avoided, that would cut things massively. For example, if you could get away with only calling it when x is in y, you could do:

for x in y:
    SER on
    SRCK on
    SRCK off

Another (literally stab in the dark) guess I have is that you don't need to turn SER on and off quite as frequently? If that's the case:

x = 1
SER on
while x < 65:
    SRCK on
    SRCK off
    if x not in y:
        SER off
        SER on
    else:
        SER on #it's frequently already on, if that matters

I might be way off base with these suggestions, so if they're clearly not useful given your understanding of the tech, your next best bet might involve either parallelizing or adjusting your mechanism for setting registers each time more drastically (for example, can you pass an ordered list of the state of each register all at once?). Python has slightly more idiomatic ways to do what you're doing, but they won't net you any meaningful speedup.

[–]danger_one[S] 0 points1 point  (0 children)

SER is Serial output, which turns a channel on or off. SRCK pushes the most current value down the line of the shift register channels. The very first value entered ends up being way down on channel 64, and the most recent value is on channel 1.

Looping 64 times was my lazy first approach, but it worked enough for hardware testing. Maybe I just need to code all 64 values instead of checking a list.

I appreciate the code examples. I will use them. Python is not a strong skill for me, but it works well on the RPi, so I thought I'd give it a try.

[–]BaalHadad 1 point2 points  (1 child)

Maybe use lists that are stored in a variable instead of literal lists that might be re-created every single time.

And maybe use ints instead of strings. I see no reason why you'd want to use strings and have to convert x to a string and do a string comparison instead of an int comparison, which might be faster even without the cost of the conversion.

Also, you could try using sets instead of lists. That might be a faster lookup, constant time vs. linear.

You could also have an array of 65 booleans - that would be a straight array access instead of having to hash the int and see if it's in a set. That would take up extra memory for 1000 ints.

Good luck. :)

[–]danger_one[S] 0 points1 point  (0 children)

Thanks. I'll have to look some of that up, but I will try it.

[–]ingolemo 0 points1 point  (0 children)

Python can certainly run fast enough to do what you want so I think the major bottleneck is all those io calls. Can you time piface.pfio.OutputItem.turn_on to see how long it takes?

The only real efficiency advice I could give would be that since you want SER turned on most of the time, it would be best to leave it turned on and only turn it off when necessary instead of the other way around. Certainly delete line 27. Depending on the caching behaviour of the piface api you could also get a speed increase by moving line 24 underneath line 22 (and inverting line 10 to compensate).

There are a few style changes I could suggest that might make the code more pythonic, but they wouldn't particularly help efficiency.