why does python loop continue work differently from other programming languages - python

in other programming languages when a continue is met in a loop it doesn't run the code below it and just does the next loop based on the condition set.
Yet in python it would actually not trigger the continue as much as 3 times on the same exact values until the continue actually triggers finally can someone tell me why it's like this?
function
def get_section(self, address):
for section in self.sections:
section_base = section.image_base + section.VirtualAddress
section_end = section_base + section.Misc_VirtualSize
print 'section_base= 0x%x' % section_base, ' section_end = 0x%x' % section_end
print 'VirtualAdderss = 0x%x' % section.VirtualAddress, 'Misc_virtualSize = 0x%x' % section.Misc_VirtualSize
if address < section_base or address >= section_end:
print 'continuued'
continue
print 'not continuued'
print 'Section name = ', section.section_name
return section
raise NotImplementedError()
Here is the log
address = 0x4013f8
section_base= 0x401000 section_end = 0x5574e5
VirtualAdderss = 0x1000 Misc_virtualSize = 0x1564e5
not continuued
Section name = text
address = 0x4013f8
section_base= 0x401000 section_end = 0x5574e5
VirtualAdderss = 0x1000 Misc_virtualSize = 0x1564e5
not continuued
Section name = text
address = 0x55869c
section_base= 0x401000 section_end = 0x5574e5
VirtualAdderss = 0x1000 Misc_virtualSize = 0x1564e5
continuued
section_base= 0x558000 section_end = 0x5818ac
VirtualAdderss = 0x158000 Misc_virtualSize = 0x298ac
not continuued
Section name = rdata
as you can see it didn't continue 2 times only on the 3rd time it continued and I can't figure out why shouldn't it work from the first time?

The first two times, the if condition was not met; therefore the continue statement was not executed.

Related

How to print a variable which is created using for loops

I am trying to automate some of the manual tasks using python3 and I am not sure how to print a variable. I know I can use print(f"https://{ip1}", but I am trying to solve this problem using "for loops"
Here is the part of the code.
......
def hostFile():
hostConf = (projdateprojname[9:])
print("\n\tEnter legacy host IP")
ip1 = input(prompt)
print("\n\tEnter legacy guest IP")
ip2 = input(prompt)
print("\n\tEnter legacy host IP")
ip3 = input(prompt)
print("\n\tEnter legacy guest IP")
ip4 = input(prompt)
print(f"\n[{hostConf}-1]")
print(f"{ip1}")
print(f"{ip2}")
print(f"{ip3}")
print(f"{ip4}")
for i in range(1, 5):
listofurl = ("ip" + str(i))
print(f"https://{listofurl}")
Script output for the last part:
https://ip1
https://ip2
https://ip3
https://ip4
I am expecting to see, for example
https://10.1.1.199
https://10.1.1.200
https://10.1.1.201
https://10.1.1.202
I see what you were trying to do, just one adjustment change
listofurl = ("ip" + str(i))
to
listofurl = (locals()["ip" + str(i)])
locals() return a dictionary{} of variables in the current scope, ["ip" + str(i)] gets translated to ["ip<i>"] wherei changes value during each phase of the loop

socketcan J1939 filter use in python

In Python, I am trying to use the J1939 filtering as mentionned in the linux kernel docs: https://www.kernel.org/doc/html/latest/networking/j1939.html
The following code fails at the setsockopt() line (setting up filters):
import socket
import struct
def pack_J1939_filters(can_filters):
can_filter_fmt = "=" + "2Q2B2I" * len(can_filters)
filter_data = []
for can_filter in can_filters:
name = can_filter['name']
name_mask = can_filter['name_mask']
addr = can_filter['addr']
addr_mask = can_filter['addr_mask']
pgn = can_filter['pgn']
pgn_mask = can_filter['pgn_mask']
filter_data.append(name)
filter_data.append(name_mask)
filter_data.append(addr)
filter_data.append(addr_mask)
filter_data.append(pgn)
filter_data.append(pgn_mask)
return struct.pack(can_filter_fmt, *filter_data)
s = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, socket.CAN_J1939)
interface = "vcan0"
src_name = socket.J1939_NO_NAME
src_pgn = socket.J1939_NO_PGN
src_addr = 0x81
src_sck_addr = (interface, src_name, src_pgn, src_addr)
s.bind(src_sck_addr)
filters = [{"name": 0, "name_mask":0, "addr":0, "addr_mask":0, "pgn": 0, "pgn_mask": 0}]
packed_filters = pack_J1939_filters(filters)
# socket.SOL_CAN_J1939 does not seem to exist
SOL_CAN_BASE = 100
CAN_J1939 = 7
SOL_CAN_J1939 = SOL_CAN_BASE + CAN_J1939
s.setsockopt(SOL_CAN_J1939, socket.SO_J1939_FILTER , packed_filters)
s.recvfrom(128)
s.close()
First, the kernel documentation mentions to use SOL_CAN_J1939 as the first argument. However socket.SOL_CAN_J1939 does not exist in the socket package. So looking at the code at this location I was able to understand that this int value should be 107: http://socket-can.996257.n3.nabble.com/RFC-v3-0-6-CAN-add-SAE-J1939-protocol-td7571.html
As for the setsockopt() third argument, I packed the filters to match the j1939_filter structure (26 bytes as described in the code from the previous link). This is similar to what is done in can.interfaces.socketcan.utils for raw CAN.
What am I doing wrong to cause setsockopt() to fail?
The first issue was with the struct.pack format (can_filter_fmt) being wrong. I first assumed that the kernel j1939_filter structure size was the sum of the members. This is wrong since the compiler adds padding. This can be added to the struct.pack format as x such as 2Q2I2B6x. Please see Why isn't sizeof for a struct equal to the sum of sizeof of each member?
The second issue was that can_filter_fmt is not packed as 2Q2B2I but as 2Q2I2B6x (the addr member is in the middle).
As for SOL_CAN_J1939 I was correct and needs to be created in file because it is not yet in the package.
The final code is the following:
#!/usr/bin/env python3
import socket
import struct
def pack_J1939_filters(can_filters=None):
if can_filters is None:
# Pass all messages
can_filters = [{}]
can_filter_fmt = "=" + "2Q2I2B6x" * len(can_filters)
filter_data = []
for can_filter in can_filters:
if 'name' in can_filter:
name = can_filter['name']
else:
name = 0
if 'name_mask' in can_filter:
name_mask = can_filter['name_mask']
else:
name_mask = 0
if 'pgn' in can_filter:
pgn = can_filter['pgn']
else:
pgn = 0
if 'pgn_mask' in can_filter:
pgn_mask = can_filter['pgn_mask']
else:
pgn_mask = 0
if 'addr' in can_filter:
addr = can_filter['addr']
else:
addr = 0
if 'addr_mask' in can_filter:
addr_mask = can_filter['addr_mask']
else:
addr_mask = 0
filter_data.append(name)
filter_data.append(name_mask)
filter_data.append(pgn)
filter_data.append(pgn_mask)
filter_data.append(addr)
filter_data.append(addr_mask)
return struct.pack(can_filter_fmt, *filter_data)
def print_msg(data, sck_addr):
print(f"SA:{hex(sck_addr[3])} PGN:{hex(sck_addr[2])}")
for j in range(len(data)):
if j % 8 == 0 and j != 0:
print()
if j % 8 == 0:
print(f"bytes {j} to {j+7}: ", end="")
print(f"{hex(data[j])} ", end="")
print()
print()
def main():
s = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, socket.CAN_J1939)
# allows to receive broadcast messages
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
interface = "vcan0"
src_name = socket.J1939_NO_NAME
src_pgn = socket.J1939_NO_PGN # always no PGN for source, unless filtering is needed
src_addr = 0x81 # recvfrom() will not return destination specific messages for other addresses
src_sck_addr = (interface, src_name, src_pgn, src_addr)
s.bind(src_sck_addr)
packed_filters = pack_J1939_filters()
SOL_CAN_BASE = 100
CAN_J1939 = 7
SOL_CAN_J1939 = SOL_CAN_BASE + CAN_J1939
s.setsockopt(SOL_CAN_J1939, socket.SO_J1939_FILTER , packed_filters)
(recv_data, recv_sck_addr) = s.recvfrom(128)
print_msg(recv_data, recv_sck_addr)
s.close()
if __name__ == "__main__":
main()
Thank you.
For J1939 to work with SocketCAN you need two things:
kernel 5.4+
can-j1939 kernel module enabled
Testing for can-1939:
If you install can-utils and after sudo modprobe can-j1939 all you get is fatal error, or if you start testj1939 from can-utils and you get error that protocol is not supported, then it means that can-j1939 was not enabled in your kernel and you need to compile it manually.
Here are my instructions for enabling can-j1939 in Debian 10 kernel:
https://github.com/linux-can/can-utils/blob/master/can-j1939-install-kernel-module.md

Python: what exactly does .payload in scapy?

I'm trying to understand a Python script that analyzes beacon frames. But I'm stuck at something called .payload. Looking at the Python documentation and doing research didn't help me out. I found out that the payload is the data carried by the frame.
def insert_ap(pkt):
## Done in the lfilter param
# if Dot11Beacon not in pkt and Dot11ProbeResp not in pkt:
# return
bssid = pkt[Dot11].addr3
if bssid in aps:
return
p = pkt[Dot11Elt]
cap = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}"
"{Dot11ProbeResp:%Dot11ProbeResp.cap%}").split('+')
ssid, channel = None, None
crypto = set()
while isinstance(p, Dot11Elt):
if p.ID == 0:
ssid = p.info
elif p.ID == 3:
channel = ord(p.info)
elif p.ID == 48:
crypto.add("WPA2")
elif p.ID == 221 and p.info.startswith('\x00P\xf2\x01\x01\x00'):
crypto.add("WPA")
p = p.payload # HERE IT IS
if not crypto:
if 'privacy' in cap:
crypto.add("WEP")
else:
crypto.add("OPN")
print "NEW AP: %r [%s], channed %d, %s" % (ssid, bssid, channel,
' / '.join(crypto))
aps[bssid] = (ssid, channel, crypto)
aps = {}
sniff(iface='mon0', prn=insert_ap, store=False,
lfilter=lambda p: (Dot11Beacon in p or Dot11ProbeResp in p))
The payload function is written in a while loop. The loop is active as long as the packet is an instance of Dot11Elt. But what does .payload do that it's no longer Dot11Elt (?)
Thank you!
packet.payload is just a pointer to the next layer.
Take a look at the Scapy documentation.
For example, if pkt were constructed as such:
pkt = Dot11()/foo()/IP()/TCP()
In your example, p is initially set to pkt[Dot11]. Therefore, p.payload is pkt[Dot11].payload, which points to the foo object. At the end of the loop, p is advanced to p.payload. As long as p is of type Dot11Elt, the loop will keep running.
If we assume that both Dot11, and foo are of type Dot11Elt, then the loop will run until p is pointing to the IP layer.

Python Return Invalid Syntax Error

I am writing a simple python program on a raspberry pi and I am quite new to python programming. I have defined a function called GetMessage which has no parameters and returns a variable which I called data, but I am getting an error which states
File "Raspberry_pi.py", line 39
return none
^
SyntaxError: invalid syntax
import os
import glob
import time
import RPi.GPIO as GPIO
from math import *
from bluetooth import *
from RPIO import PWM
os.system('sudo hciconfig hci0 pisca')
os.system('sudo hciconfig hci0 name "De Quadcoptur"')
servo = PWM.Servo()
StartSpin()
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
GetMessage()
DecodeInput()
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
def GetMessage():
advertise_service( server_sock, "XT1032", #phone bluetooth name
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
#protocols = [ OBEX_UUID ]
)
client_sock, client_info = server_sock.accept()
try:
data = client_sock.recv(1024)
if len(data) == 0: break
print "received [%s]" % data
client_sock.close()
server_sock.close()
except IOError:
pass
break
return data
def StartSpin():
# Set servo on GPIO17 to 1200µs (1.2ms)
servo.set_servo(17, 1000)
servo.set_servo(18, 1000)
servo.set_servo(19, 1000)
servo.set_servo(20, 1000)
time.sleep(1)
servo.stop_servo(17)
servo.stop_servo(18)
servo.stop_servo(19)
servo.stop_servo(20)
#Check if more pulses is faster
time.sleep(2000)
PWM.add_channel_pulse(0, 17, start = 1000, width = 100)
PWM.add_channel_pulse(0, 17, start = 1000, width = 100)
PWM.add_channel_pulse(0, 17, start = 1000, width = 100)
PWM.add_channel_pulse(0, 17, start = 1000, width = 100)
PWM.add_channel_pulse(0, 17, start = 1000, width = 100)
servo.stop_servo(17)
servo.stop_servo(18)
servo.stop_servo(19)
servo.stop_servo(20)
return None
def DecodeInput():
data = GetMessage()
if(data == 'start')
StartSpin()
return 0
else if(data[0] == 'U')
data.strip('U')
UpPower = int(data)
SetUpPower(UpPower)
else if(data[0] == 'P')
data.strip('P')
PitchPower = int(data)
SetPitchPower
else
data.strip('P')
RollPower = int(data)
SetPower(UpPower, PitchPower, RollPower)
return None
def SetPower(UpPower, PitchPower, RollPower):
#Make Arbitrary Values
Motor1Power = UpPower #Front Left
Motor2Power = UpPower #Front Right
Motor3Power = UpPower #Back Left
Motor4Power = UpPower #Back Right
PitchPower = PitchPower /2
RollPower = RollPower /2
if(PitchPower < 25)
Motor1Power = Motor1Power + abs(25-PitchPower)
Motor2Power = Motor1Power + abs(25-PitchPower)
else
Motor3Power = Motor3Power + (PitchPower-25)
Motor4Power = Motor4Power + (PitchPower-25)
if(RollPower < 25)
Motor1Power = Motor1Power + abs(25-RollPower)
Motor3Power = Motor3Power + abs(25-RollPower)
else
Motor2Power = Motor2Power + (RollPower - 25)
Motor4Power = Motor4Power + (RollPower - 25)
What is causing this error and how can I fix it?
Edit: I have defined data as a global variable and the error now is
File "Raspberry_pi.py", line 39
return data
^
SyntaxError: invalid syntax
There are a number of syntax problems in your code. Because of the nature of SyntaxError exceptions (which are raised when the interpreter doesn't understand the code syntax), the error messages may not identify the right line as the source of the problem.
The first syntax error I see is that you're using break in the GetMessage function without it being in a loop. A break statement is only useful within a for or while block, and using one elsewhere (in an except block in this case) is a syntax error.
The next set of errors have to do with missing colons. Each of the conditional branches in DecodeInput and SetPower need to have a colon after the condition: if condition1:, elif condition2:, else:
It's also an error to use else if rather than elif (you could make it work if you added a colon, a newline and an extra level of indentation after else:, then used a separate if statement, but that would be wasteful of space).
There are some additional issues, but they're not syntax errors. For instance, you're calling your functions from top-level code before they've been defined, and DecodeInput has a line with the bare expression SetPower which doesn't do anything useful (you probably want to call SetPower with some argument).
Hopefully this will get you on the right track.
Once you get your colons fixed, you'll probably run into a problem with your GetMessage syntax. You cannot break unless you're inside of a loop. If you intend to return from an exception, you don't need the pass call. An example (simplified from your code) of how this method could (should?) look:
def GetMessage():
data = None
try:
data = [1,2]
if len(data) == 0:
return None
except IOError:
return None
return data
Clearly you'll want to replace the bulk of the method with your own code, and determine if you really want to return from the function at the points where you put breaks.

python regular expression for multiple string values

so my issues is that im receiving values from a serial port.
The values could be any of the flowing.
BASE_RAD: NEW,ATC001#T1412010472R-77,ATC005:T1412010460R-70,SU0003;Q6V8.9S0C11.5*xx
BASE_RAD: NEW,ATC001#T1413824282R-102,ATC003:T1413824274R-98,SU001G;Q0V14.0D00*x
their is minor chnages in the out put but the biggest difference is the second line has the value D00 instead of S0
So this serial out will update me with changes to sensors and the D00 is for digital output but S0 is for the fan speed.
So my question is i have written a regular expression if i receive the first serial output that has the S0 value but if i then receive the D00 the regular expression will break.
I want to be able to write it so if it doesn't have the S0 value it would then look for the D00 value instead.
thank you for any help or advise in advance. im not sure where i should be looking or what direction i should be taking.
The code below checks the serial output and then runs the regular expression, if it find a match it then inserts that into the data base.
CODE BELOW IS PYTHON
import serial, string, MySQLdb, re
db = MySQLdb.connect(host="localhost", user="root", passwd="", db="walnut_farm")
cur = db.cursor()
serialPort = 'COM4' # BAUD Rate is 9600 as default
ser = serial.Serial()
ser.setPort(serialPort)
#ser.setBaudrate(115200) Enable if BAUD is not deault value
try:
ser.open()
except:
print('Port Error!')
else:
while True:
try:
ardString = ser.readline()
Serial_Output = ardString
p = re.compile(ur'^BASE_RAD: NEW,(.*)#T(\d*)R-(\d*),(.*):T(\d*)R-(\d*),(.*);Q(\d*)V(\d*\.?\d*)S(\d*)C(\d*\.?\d*)(.*)') # here is the regular expressions i created from this link http://regex101.com/r/dP6fE1/1
Serial_Results = re.match(p, Serial_Output)
# Assigning variables to the array values
Base_ID = Serial_Results.group(1)
Base_Time_Stamp = Serial_Results.group(2)
Base_Signal = Serial_Results.group(3)
Repeater_ID = Serial_Results.group(4)
Repeater_Time_Stamp = Serial_Results.group(5)
Repeater_Signal = Serial_Results.group(6)
Sensor_ID = Serial_Results.group(7)
Sensor_Sequence = Serial_Results.group(8)
Sensor_Input_Voltage = Serial_Results.group(9)
Sensor_Wind_Speed = Serial_Results.group(10)
Sensor_Temperature = Serial_Results.group(11)
Checksum = Serial_Results.group(12)
# Execute the SQL query to INSERT the above variables into the Database
cur.execute('INSERT INTO serial_values (Base_ID, Base_Time_Stamp, Base_Signal, Repeater_ID, Repeater_Time_Stamp, Repeater_Signal, Sensor_ID, Sensor_Sequence, Sensor_Input_Voltage, Sensor_Wind_Speed, Sensor_Temperature, Checksum) VALUES ("'+Base_ID+'", "'+Base_Time_Stamp+'", "'+Base_Signal+'", "'+Repeater_ID+'", "'+Repeater_Time_Stamp+'", "'+Repeater_Signal+'", "'+Sensor_ID+'", "'+Sensor_Sequence+'", "'+Sensor_Input_Voltage+'", "'+Sensor_Wind_Speed+'", "'+Sensor_Temperature+'", "'+Checksum+'")')
db.commit()
#ser.close()
except Exception:
pass
Take a look at this, if my interpretation is right. It's a starting point, you then have to include your mysql insert into the database.
import re
def get_output_parameters(serial_output):
p = re.compile(ur'^BASE_RAD: NEW,(.*)#T(\d*)R-(\d*),(.*):T(\d*)R-(\d*),(.*);Q(\d*)V(\d*\.?\d*)S(\d*)C(\d*\.?\d*)(.*)') # here is the regular expressions i created from this link http://regex101.com/r/dP6fE1/1
p2 = re.compile(ur'^BASE_RAD: NEW,(.*)#T(\d*)R-(\d*),(.*):T(\d*)R-(\d*),(.*);Q(\d*)V(\d*\.?\d*)D(\d*)(.*)')
Serial_Results = re.match(p, serial_output)
digital_out = False
if not Serial_Results:
Serial_Results = re.match(p2, serial_output)
digital_out = True
# Assigning variables to the array values
Base_ID = Serial_Results.group(1)
Base_Time_Stamp = Serial_Results.group(2)
Base_Signal = Serial_Results.group(3)
Repeater_ID = Serial_Results.group(4)
Repeater_Time_Stamp = Serial_Results.group(5)
Repeater_Signal = Serial_Results.group(6)
Sensor_ID = Serial_Results.group(7)
Sensor_Sequence = Serial_Results.group(8)
Sensor_Input_Voltage = Serial_Results.group(9)
Sensor_Wind_Speed = Serial_Results.group(10)
Sensor_Temperature = Serial_Results.group(11)
if not digital_out:
Checksum = Serial_Results.group(12)
print Sensor_Temperature
Serial_Output = "BASE_RAD: NEW,ATC001#T1412010472R-77,ATC005:T1412010460R-70,SU0003;Q6V8.9S0C11.5*xx"
Serial_Output2 = "BASE_RAD: NEW,ATC001#T1413824282R-102,ATC003:T1413824274R-98,SU001G;Q0V14.0D00*x"
get_output_parameters(Serial_Output)
get_output_parameters(Serial_Output2)

Categories