Python3: Connection reset by peer while reading line from socket - python-3.x

I get an Connection reset by peer error message while running this python3 script:
import struct, socket
HOST = "127.0.0.1"
PORT = 64012
# read bytes from socket and return it as ascii representation
def read_line_from_socket(s):
buf= ""
while True:
byteData = s.recv(1)
if byteData == b"\n":
break
buf += byteData.decode("ascii")
return buf
def read_four_longs_for_addition(s):
sum = 0
counter = 1
while counter <= 4:
sum += struct.unpack("I", s.recv(4))[0]
counter += 1 # python does not support ++, += 1 has to be used
print(sum) # sum overflows int (number > 32 bit)
return sum
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST,PORT))
print(read_line_from_socket(s))
print(read_line_from_socket(s))
s.send(struct.pack("l", read_four_longs_for_addition(s)))
# print(s.recv(32)) # receives "You have succes..", NOT resulting in an Connection reset by peer which indicates success
print(read_line_from_socket(s)) # results in "Connection reset by peer"
s.close()
The code on the server which is communicating with my client socket looks like this:
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
int main(int argc, char **argv) {
int i;
unsigned long quad[sizeof(long)], result, wanted;
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
printf("%s\nFor this level, sizeof(long) == %d, keep that in mind :)\n",
BANNER, (int)sizeof(long));
if (getrandom((void *)&quad, sizeof(quad), 0) != sizeof(quad)) {
errx(1, "unable to getrandom(%d bytes)", sizeof(quad));
}
result = 0;
for (i = 0; i < sizeof(long); i++) {
result += quad[i];
if (write(1, (void *)&quad[i], sizeof(long)) != sizeof(long)) {
errx(1, "Why have you foresaken me, write()");
}
}
if (read(0, (void *)&wanted, sizeof(long)) != sizeof(long)) {
errx(1, "Unable to read\n");
}
if (result == wanted) {
printf("You have successfully passed this level, well done!\n");
} else {
printf("Whoops, better luck next time. Receieved %lu, wanted %lu\n", wanted,
result);
}
return 0;
}
Expected behavior:
After successfully sending the correct sum of the received long values my script reads the last line "You have successfully passed this level, well done!\n" until the "\n" new line, prints it out to the screen and finally closing the socket connection.
Actual output:
Welcome to phoenix/net-two, brought to you by https://exploit.education
For this level, sizeof(long) == 4, keep that in mind :)
9057758327
Traceback (most recent call last):
File "net-2.py", line 31, in <module>
print(read_line_from_socket(s))
File "net-2.py", line 10, in read_line_from_socket
byteData = s.recv(1)
ConnectionResetError: [Errno 104] Connection reset by peer
Looking at the process with strace python3 nameOfPythonScript.py, I can't see any problem and everything should be working fine:
recvfrom(3, "n", 1, 0, NULL, NULL) = 1
recvfrom(3, "e", 1, 0, NULL, NULL) = 1
recvfrom(3, "!", 1, 0, NULL, NULL) = 1
recvfrom(3, "\n", 1, 0, NULL, NULL) = 1
write(1, "You have successfully passed thi"..., 52You have successfully passed this level, well done!
) = 52
close(3) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffff7bcd0c0}, {sa_handler=0x5555557d8980, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffff7bcd0c0}, 8) = 0
munmap(0x7ffff6c0e000, 262144) = 0
exit_group(0) = ?
+++ exited with 0 +++
My question:
Why does the Connection reset occur? Does it have to do with the return 0; in the server program code? Note that if I recv a fixed number of bytes instead of trying to read the complete last line the error does not occur (see comments in my script's code)

Related

Python ctypes dll - pass pointer to C structure

I am trying to extract data from a Hamamatsu C15713 MEMS-FPI spectrometer with the dll, through python ctypes.
The dll function I am trying to call is :
HRESULT hpkfpi_getdevcount(HPKFPI_INITPARAM* initparam);
Where the parameter initparam should be a pointer towards a structure:
#define HPKFPI_INITARY_NUMBER 127
#define HPKFPI_INITARY_STRLEN 32
typedef struct {
int32_t sizeof_parameter;
int32_t devicecount;
char buf_VID[HPKFPI_INITARY_NUMBER][HPKFPI_INITARY_STRLEN];
char buf_PID[HPKFPI_INITARY_NUMBER][HPKFPI_INITARY_STRLEN];
char buf_SERIAL[HPKFPI_INITARY_NUMBER][HPKFPI_INITARY_STRLEN];
} HPKFPI_INITPARAM;
My current code:
from ctypes import *
class HPKFPI_INITPARAM(Structure):
# Define the structure object
_fields_ = [("sizeof_parameter", c_uint32),("devicecount", c_uint32),
('buf_VID', (c_char*127)*32), ('buf_PID', (c_char*127)*32), ('buf_SERIAL', (c_char*127)*32)]
class Hamamatsu_C15713:
def __init__(self, dll_path):
dll_filename = os.path.join(dll_path, 'HPKFPI_x64.dll')
self._dll = windll.LoadLibrary(dll_filename)
logging.debug(f'dll loaded')
# Initialize the dll
self._dll.hpkfpi_init()
# Try to get the device count
deviceCount = HPKFPI_INITPARAM()
self._dll.hpkfpi_getdevcount(byref(deviceCount))
This code does not produce errors, however the fields of deviceCount all remain 0.
Numeric values are 0 and the char arrays are bitstrings value 0.
What have I tried to solve this:
POINTER(deviceCount) instead of byref(deviceCount) returns an error (TypeError: Not Hashable).
Whatever object I make as deviceCount, it is not changed by the function.
Can anyone give me advise?
With the help of a colleague, we managed advance on this problem.
Important point: There is an error in documentation of the Hamamatsu C15713 MEMS-FPI spectrometer dll: The dimensions of the initparam are wrong.
127 should be 255
HPKFPI_INITARY_NUMBER = 255
HPKFPI_INITARY_STRLEN = 32
class HPKFPI_INITPARAM(Structure):
_fields_ = [
("sizeof_parameter", c_int32),
("devicecount", c_int32),
('buf_VID', (c_char * HPKFPI_INITARY_STRLEN) * HPKFPI_INITARY_NUMBER),
('buf_PID', (c_char * HPKFPI_INITARY_STRLEN) * HPKFPI_INITARY_NUMBER),
('buf_SERIAL', (c_char * HPKFPI_INITARY_STRLEN) * HPKFPI_INITARY_NUMBER)
]
class HPKFPI_OPENPARAM(Structure):
_fields_ = [
("sizeof_parameter", c_int32),
("id", c_int32),
("hfpi", HANDLE)
]
class Hamamatsu_C15713:
"""
This class is intended to a a wrapper around the Hamamatsu C15713 dll
"""
def __init__(self, dll_path):
logging.debug("Loading dll %s", dll_path)
# add dll dir to os path env var so dependent dll can be found
os.environ['PATH'] = str(DLL_DIR) + ';' + os.environ['PATH']
self._dll = windll.LoadLibrary(str(dll_path))
logging.debug('dll loaded')
# Initialize the dll
ret = self._dll.hpkfpi_init()
logging.debug("init ret: %s", ret)
if ret < 0:
raise SystemError(f"hpkfpi_init failed, ret code: {ret}")
# Try to get the device count
init_param = HPKFPI_INITPARAM()
init_param.sizeof_parameter = sizeof(init_param)
logging.debug("devcount sizeof: %s",init_param.sizeof_parameter)
ret = self._dll.hpkfpi_getdevcount(byref(init_param))
logging.debug("hpkfpi_getdevcount ret: %s", ret)
if ret < 0:
raise SystemError(f"hpkfpi_getdevcount failed, ret code: {ret}")
logging.debug(
"Extracted devicecount : %d, VID %s, PID %s, SERIAL %s", init_param.devicecount,
bytes(init_param.buf_VID[0]).decode(),
bytes(init_param.buf_PID[0]).decode(),
bytes(init_param.buf_SERIAL[0]).decode())
open_param = HPKFPI_OPENPARAM()
open_param.id = 0 # device 0
open_param.sizeof_parameter = sizeof(open_param)
ret = self._dll.hpkfpi_open(byref(open_param))
logging.debug("hpkfpi_open ret: %s", ret)
if ret < 0:
raise SystemError(f"hpkfpi_open failed, ret code: {ret}")
self.dev_handle = open_param.hfpi
logging.debug("Open handle: %d", self.dev_handle)

Calculating number of minimum swaps to sort array (selection sort is too slow) [duplicate]

I'm working on sorting an integer sequence with no identical numbers (without loss of generality, let's assume the sequence is a permutation of 1,2,...,n) into its natural increasing order (i.e. 1,2,...,n). I was thinking about directly swapping the elements (regardless of the positions of elements; in other words, a swap is valid for any two elements) with minimal number of swaps (the following may be a feasible solution):
Swap two elements with the constraint that either one or both of them should be swapped into the correct position(s). Until every element is put in its correct position.
But I don't know how to mathematically prove if the above solution is optimal. Anyone can help?
I was able to prove this with graph-theory. Might want to add that tag in :)
Create a graph with n vertices. Create an edge from node n_i to n_j if the element in position i should be in position j in the correct ordering. You will now have a graph consisting of several non-intersecting cycles. I argue that the minimum number of swaps needed to order the graph correctly is
M = sum (c in cycles) size(c) - 1
Take a second to convince yourself of that...if two items are in a cycle, one swap can just take care of them. If three items are in a cycle, you can swap a pair to put one in the right spot, and a two-cycle remains, etc. If n items are in a cycle, you need n-1 swaps. (This is always true even if you don't swap with immediate neighbors.)
Given that, you may now be able to see why your algorithm is optimal. If you do a swap and at least one item is in the right position, then it will always reduce the value of M by 1. For any cycle of length n, consider swapping an element into the correct spot, occupied by its neighbor. You now have a correctly ordered element, and a cycle of length n-1.
Since M is the minimum number of swaps, and your algorithm always reduces M by 1 for each swap, it must be optimal.
All the cycle counting is very difficult to keep in your head. There is a way that is much simpler to memorize.
First, let's go through a sample case manually.
Sequence: [7, 1, 3, 2, 4, 5, 6]
Enumerate it: [(0, 7), (1, 1), (2, 3), (3, 2), (4, 4), (5, 5), (6, 6)]
Sort the enumeration by value: [(1, 1), (3, 2), (2, 3), (4, 4), (5, 5), (6, 6), (0, 7)]
Start from the beginning. While the index is different from the enumerated index keep on swapping the elements defined by index and enumerated index. Remember: swap(0,2);swap(0,3) is the same as swap(2,3);swap(0,2)
swap(0, 1) => [(3, 2), (1, 1), (2, 3), (4, 4), (5, 5), (6, 6), (0, 7)]
swap(0, 3) => [(4, 4), (1, 1), (2, 3), (3, 2), (5, 5), (6, 6), (0, 7)]
swap(0, 4) => [(5, 5), (1, 1), (2, 3), (3, 2), (4, 4), (6, 6), (0, 7)]
swap(0, 5) => [(6, 6), (1, 1), (2, 3), (3, 2), (4, 4), (5, 5), (0, 7)]
swap(0, 6) => [(0, 7), (1, 1), (2, 3), (3, 2), (4, 4), (5, 5), (6, 6)]
I.e. semantically you sort the elements and then figure out how to put them to the initial state via swapping through the leftmost item that is out of place.
Python algorithm is as simple as this:
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def minimum_swaps(arr):
annotated = [*enumerate(arr)]
annotated.sort(key = lambda it: it[1])
count = 0
i = 0
while i < len(arr):
if annotated[i][0] == i:
i += 1
continue
swap(annotated, i, annotated[i][0])
count += 1
return count
Thus, you don't need to memorize visited nodes or compute some cycle length.
For your reference, here is an algorithm that I wrote, to generate the minimum number of swaps needed to sort the array. It finds the cycles as described by #Andrew Mao.
/**
* Finds the minimum number of swaps to sort given array in increasing order.
* #param ar array of <strong>non-negative distinct</strong> integers.
* input array will be overwritten during the call!
* #return min no of swaps
*/
public int findMinSwapsToSort(int[] ar) {
int n = ar.length;
Map<Integer, Integer> m = new HashMap<>();
for (int i = 0; i < n; i++) {
m.put(ar[i], i);
}
Arrays.sort(ar);
for (int i = 0; i < n; i++) {
ar[i] = m.get(ar[i]);
}
m = null;
int swaps = 0;
for (int i = 0; i < n; i++) {
int val = ar[i];
if (val < 0) continue;
while (val != i) {
int new_val = ar[val];
ar[val] = -1;
val = new_val;
swaps++;
}
ar[i] = -1;
}
return swaps;
}
We do not need to swap the actual elements, just find how many elements are not in the right index (Cycle).
The min swaps will be Cycle - 1;
Here is the code...
static int minimumSwaps(int[] arr) {
int swap=0;
boolean visited[]=new boolean[arr.length];
for(int i=0;i<arr.length;i++){
int j=i,cycle=0;
while(!visited[j]){
visited[j]=true;
j=arr[j]-1;
cycle++;
}
if(cycle!=0)
swap+=cycle-1;
}
return swap;
}
#Archibald, I like your solution, and such was my initial assumptions that sorting the array would be the simplest solution, but I don't see the need to go through the effort of the reverse-traverse as I've dubbed it, ie enumerating then sorting the array and then computing the swaps for the enums.
I find it simpler to subtract 1 from each element in the array and then to compute the swaps required to sort that list
here is my tweak/solution:
def swap(arr, i, j):
tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
def minimum_swaps(arr):
a = [x - 1 for x in arr]
swaps = 0
i = 0
while i < len(a):
if a[i] == i:
i += 1
continue
swap(a, i, a[i])
swaps += 1
return swaps
As for proving optimality, I think #arax has a good point.
// Assuming that we are dealing with only sequence started with zero
function minimumSwaps(arr) {
var len = arr.length
var visitedarr = []
var i, start, j, swap = 0
for (i = 0; i < len; i++) {
if (!visitedarr[i]) {
start = j = i
var cycleNode = 1
while (arr[j] != start) {
j = arr[j]
visitedarr[j] = true
cycleNode++
}
swap += cycleNode - 1
}
}
return swap
}
I really liked the solution of #Ieuan Uys in Python.
What I improved on his solution;
While loop is iterated one less to increase speed; while i < len(a) - 1
Swap function is de-capsulated to make one, single function.
Extensive code comments are added to increase readability.
My code in python.
def minimumSwaps(arr):
#make array values starting from zero to match index values.
a = [x - 1 for x in arr]
#initialize number of swaps and iterator.
swaps = 0
i = 0
while i < len(a)-1:
if a[i] == i:
i += 1
continue
#swap.
tmp = a[i] #create temp variable assign it to a[i]
a[i] = a[tmp] #assign value of a[i] with a[tmp]
a[tmp] = tmp #assign value of a[tmp] with tmp (or initial a[i])
#calculate number of swaps.
swaps += 1
return swaps
Detailed explanation on what code does on an array with size n;
We check every value except last one (n-1 iterations) in the array one by one. If the value does not match with array index, then we send this value to its place where index value is equal to its value. For instance, if at a[0] = 3. Then this value should swap with a[3]. a[0] and a[3] is swapped. Value 3 will be at a[3] where it is supposed to be. One value is sent to its place. We have n-2 iteration left. I am not interested what is now a[0]. If it is not 0 at that location, it will be swapped by another value latter. Because that another value also exists in a wrong place, this will be recognized by while loop latter.
Real Example
a[4, 2, 1, 0, 3]
#iteration 0, check a[0]. 4 should be located at a[4] where the value is 3. Swap them.
a[3, 2, 1, 0, 4] #we sent 4 to the right location now.
#iteration 1, check a[1]. 2 should be located at a[2] where the value is 1. Swap them.
a[3, 1, 2, 0, 4] #we sent 2 to the right location now.
#iteration 2, check a[2]. 2 is already located at a[2]. Don't do anything, continue.
a[3, 1, 2, 0, 4]
#iteration 3, check a[3]. 0 should be located at a[0] where the value is 3. Swap them.
a[0, 1, 2, 3, 4] #we sent 0 to the right location now.
# There is no need to check final value of array. Since all swaps are done.
Nicely done solution by #bekce. If using C#, the initial code of setting up the modified array ar can be succinctly expressed as:
var origIndexes = Enumerable.Range(0, n).ToArray();
Array.Sort(ar, origIndexes);
then use origIndexes instead of ar in the rest of the code.
Swift 4 version:
func minimumSwaps(arr: [Int]) -> Int {
struct Pair {
let index: Int
let value: Int
}
var positions = arr.enumerated().map { Pair(index: $0, value: $1) }
positions.sort { $0.value < $1.value }
var indexes = positions.map { $0.index }
var swaps = 0
for i in 0 ..< indexes.count {
var val = indexes[i]
if val < 0 {
continue // Already visited.
}
while val != i {
let new_val = indexes[val]
indexes[val] = -1
val = new_val
swaps += 1
}
indexes[i] = -1
}
return swaps
}
This is the sample code in C++ that finds the minimum number of swaps to sort a permutation of the sequence of (1,2,3,4,5,.......n-2,n-1,n)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,j,k,num = 0;
cin >> n;
int arr[n+1];
for(i = 1;i <= n;++i)cin >> arr[i];
for(i = 1;i <= n;++i)
{
if(i != arr[i])// condition to check if an element is in a cycle r nt
{
j = arr[i];
arr[i] = 0;
while(j != 0)// Here i am traversing a cycle as mentioned in
{ // first answer
k = arr[j];
arr[j] = j;
j = k;
num++;// reducing cycle by one node each time
}
num--;
}
}
for(i = 1;i <= n;++i)cout << arr[i] << " ";cout << endl;
cout << num << endl;
return 0;
}
Solution using Javascript.
First I set all the elements with their current index that need to be ordered, and then I iterate over the map to order only the elements that need to be swapped.
function minimumSwaps(arr) {
const mapUnorderedPositions = new Map()
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== i+1) {
mapUnorderedPositions.set(arr[i], i)
}
}
let minSwaps = 0
while (mapUnorderedPositions.size > 1) {
const currentElement = mapUnorderedPositions.entries().next().value
const x = currentElement[0]
const y = currentElement[1]
// Skip element in map if its already ordered
if (x-1 !== y) {
// Update unordered position index of swapped element
mapUnorderedPositions.set(arr[x-1], y)
// swap in array
arr[y] = arr[x-1]
arr[x-1] = x
// Increment swaps
minSwaps++
}
mapUnorderedPositions.delete(x)
}
return minSwaps
}
If you have an input like 7 2 4 3 5 6 1, this is how the debugging will go:
Map { 7 => 0, 4 => 2, 3 => 3, 1 => 6 }
currentElement [ 7, 0 ]
swapping 1 with 7
[ 1, 2, 4, 3, 5, 6, 7 ]
currentElement [ 4, 2 ]
swapping 3 with 4
[ 1, 2, 3, 4, 5, 6, 7 ]
currentElement [ 3, 2 ]
skipped
minSwaps = 2
Finding the minimum number of swaps required to put a permutation of 1..N in order.
We can use that the we know what the sort result would be: 1..N, which means we don't actually have to do swaps just count them.
The shuffling of 1..N is called a permutation, and is composed of disjoint cyclic permutations, for example, this permutation of 1..6:
1 2 3 4 5 6
6 4 2 3 5 1
Is composed of the cyclic permutations (1,6)(2,4,3)(5)
1->6(->1) cycle: 1 swap
2->4->3(->2) cycle: 2 swaps
5(->5) cycle: 0 swaps
So a cycle of k elements requires k-1 swaps to put in order.
Since we know where each element "belongs" (i.e. value k belongs at position k-1) we can easily traverse the cycle. Start at 0, we get 6, which belongs at 5,
and there we find 1, which belongs at 0 and we're back where we started.
To avoid re-counting a cycle later, we track which elements were visited - alternatively you could perform the swaps so that the elements are in the right place when you visit them later.
The resulting code:
def minimumSwaps(arr):
visited = [False] * len(arr)
numswaps = 0
for i in range(len(arr)):
if not visited[i]:
visited[i] = True
j = arr[i]-1
while not visited[j]:
numswaps += 1
visited[j] = True
j = arr[j]-1
return numswaps
An implementation on integers with primitive types in Java (and tests).
import java.util.Arrays;
public class MinSwaps {
public static int computate(int[] unordered) {
int size = unordered.length;
int[] ordered = order(unordered);
int[] realPositions = realPositions(ordered, unordered);
boolean[] touchs = new boolean[size];
Arrays.fill(touchs, false);
int i;
int landing;
int swaps = 0;
for(i = 0; i < size; i++) {
if(!touchs[i]) {
landing = realPositions[i];
while(!touchs[landing]) {
touchs[landing] = true;
landing = realPositions[landing];
if(!touchs[landing]) { swaps++; }
}
}
}
return swaps;
}
private static int[] realPositions(int[] ordered, int[] unordered) {
int i;
int[] positions = new int[unordered.length];
for(i = 0; i < unordered.length; i++) {
positions[i] = position(ordered, unordered[i]);
}
return positions;
}
private static int position(int[] ordered, int value) {
int i;
for(i = 0; i < ordered.length; i++) {
if(ordered[i] == value) {
return i;
}
}
return -1;
}
private static int[] order(int[] unordered) {
int[] ordered = unordered.clone();
Arrays.sort(ordered);
return ordered;
}
}
Tests
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MinimumSwapsSpec {
#Test
public void example() {
// setup
int[] unordered = new int[] { 40, 23, 1, 7, 52, 31 };
// run
int minSwaps = MinSwaps.computate(unordered);
// verify
assertEquals(5, minSwaps);
}
#Test
public void example2() {
// setup
int[] unordered = new int[] { 4, 3, 2, 1 };
// run
int minSwaps = MinSwaps.computate(unordered);
// verify
assertEquals(2, minSwaps);
}
#Test
public void example3() {
// setup
int[] unordered = new int[] {1, 5, 4, 3, 2};
// run
int minSwaps = MinSwaps.computate(unordered);
// verify
assertEquals(2, minSwaps);
}
}
Swift 4.2:
func minimumSwaps(arr: [Int]) -> Int {
let sortedValueIdx = arr.sorted().enumerated()
.reduce(into: [Int: Int](), { $0[$1.element] = $1.offset })
var checked = Array(repeating: false, count: arr.count)
var swaps = 0
for idx in 0 ..< arr.count {
if checked[idx] { continue }
var edges = 1
var cursorIdx = idx
while true {
let cursorEl = arr[cursorIdx]
let targetIdx = sortedValueIdx[cursorEl]!
if targetIdx == idx {
break
} else {
cursorIdx = targetIdx
edges += 1
}
checked[targetIdx] = true
}
swaps += edges - 1
}
return swaps
}
Python code
A = [4,3,2,1]
count = 0
for i in range (len(A)):
min_idx = i
for j in range (i+1,len(A)):
if A[min_idx] > A[j]:
min_idx = j
if min_idx > i:
A[i],A[min_idx] = A[min_idx],A[i]
count = count + 1
print "Swap required : %d" %count
In Javascript
If the count of the array starts with 1
function minimumSwaps(arr) {
var len = arr.length
var visitedarr = []
var i, start, j, swap = 0
for (i = 0; i < len; i++) {
if (!visitedarr[i]) {
start = j = i
var cycleNode = 1
while (arr[j] != start + 1) {
j = arr[j] - 1
visitedarr[j] = true
cycleNode++
}
swap += cycleNode - 1
}
}
return swap
}
else for input starting with 0
function minimumSwaps(arr) {
var len = arr.length
var visitedarr = []
var i, start, j, swap = 0
for (i = 0; i < len; i++) {
if (!visitedarr[i]) {
start = j = i
var cycleNode = 1
while (arr[j] != start) {
j = arr[j]
visitedarr[j] = true
cycleNode++
}
swap += cycleNode - 1
}
}
return swap
}
Just extending Darshan Puttaswamy code for current HackerEarth inputs
Here's a solution in Java for what #Archibald has already explained.
static int minimumSwaps(int[] arr){
int swaps = 0;
int[] arrCopy = arr.clone();
HashMap<Integer, Integer> originalPositionMap
= new HashMap<>();
for(int i = 0 ; i < arr.length ; i++){
originalPositionMap.put(arr[i], i);
}
Arrays.sort(arr);
for(int i = 0 ; i < arr.length ; i++){
while(arr[i] != arrCopy[i]){
//swap
int temp = arr[i];
arr[i] = arr[originalPositionMap.get(temp)];
arr[originalPositionMap.get(temp)] = temp;
swaps += 1;
}
}
return swaps;
}
def swap_sort(arr)
changes = 0
loop do
# Find a number that is out-of-place
_, i = arr.each_with_index.find { |val, index| val != (index + 1) }
if i != nil
# If such a number is found, then `j` is the position that the out-of-place number points to.
j = arr[i] - 1
# Swap the out-of-place number with number from position `j`.
arr[i], arr[j] = arr[j], arr[i]
# Increase swap counter.
changes += 1
else
# If there are no out-of-place number, it means the array is sorted, and we're done.
return changes
end
end
end
Apple Swift version 5.2.4
func minimumSwaps(arr: [Int]) -> Int {
var swapCount = 0
var arrayPositionValue = [(Int, Int)]()
var visitedDictionary = [Int: Bool]()
for (index, number) in arr.enumerated() {
arrayPositionValue.append((index, number))
visitedDictionary[index] = false
}
arrayPositionValue = arrayPositionValue.sorted{ $0.1 < $1.1 }
for i in 0..<arr.count {
var cycleSize = 0
var visitedIndex = i
while !visitedDictionary[visitedIndex]! {
visitedDictionary[visitedIndex] = true
visitedIndex = arrayPositionValue[visitedIndex].0
cycleSize += 1
}
if cycleSize > 0 {
swapCount += cycleSize - 1
}
}
return swapCount
}
Go version 1.17:
func minimumSwaps(arr []int32) int32 {
var swap int32
for i := 0; i < len(arr) - 1; i++{
for j := 0; j < len(arr); j++ {
if arr[j] > arr[i] {
arr[i], arr[j] = arr[j], arr[i]
swap++
}else {
continue
}
}
}
return swap
}

Problem with Serial.read() and Struct.pack / serial communication between Arduino and Python (3.x)

I have a problem while trying to send some values from Python 3.x to Arduino using Serial Communication.
It working fine when the value is smaller than 255, but when it's greater than 255, error will happen.
I'm using Struct.pack in Python and Serial.read() in Arduino
Python code:
import cv2
import numpy as np
from serial import Serial
import struct
arduinoData = Serial('com6', 9600)
cap = cv2.VideoCapture(0)
hand_cascade = cv2.CascadeClassifier('hand.xml')
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
handdetect = hand_cascade.detectMultiScale(gray, 1.6, 3)
for (x, y, w, h) in handdetect:
cv2.rectangle(frame, (x, y), (x + w, y + h), (127, 127, 0), 2)
xcenter = int(x + w/2)
ycenter = int(y + h/2)
#This is where i send values to serial port
arduinoData.write(struct.pack('>II',xcenter,ycenter))
cv2.imshow('Webcam', frame)
k = cv2.waitKey(25) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Arduino code:
int SerialData[8];
const int led = 7;
int xcenter;
int ycenter;
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
if (Serial.available() >= 8){
for (int i = 0; i < 8; i++){
SerialData[i] = Serial.read();
}
xcenter = (SerialData[0]*1000) + (SerialData[1]*100) + (SerialData[2]*10) + SerialData[3];
ycenter = (SerialData[4]*1000) + (SerialData[5]*100) + (SerialData[6]*10) + SerialData[7];
if (xcenter <= 200){
digitalWrite(led, LOW);
}
else if(xcenter > 200){
digitalWrite(led, HIGH);
}
//Serial.flush();
}
}
Like I said at the beginning of this topic, when xcenter > 200 && xcenter <= 255, the LED is turned ON (it's mean the code working fine).
But when xcenter > 255, the LED is OFF (something wrong here).
I think I already read all 8 bytes in Arduino code and used unsigned int >II in struct.pack, so what and where is my false?
I'm appreciate for all help! Thank you!
EDIT and FIXED.
"It doesn't pack int into digits (0-9), it packs them into bytes (0-255)"_
So here is the false:
xcenter = (SerialData[0]*1000) + (SerialData[1]*100) + (SerialData[2]*10) + SerialData[3];
ycenter = (SerialData[4]*1000) + (SerialData[5]*100) + (SerialData[6]*10) + SerialData[7];
Changed to this (for the large values):
long result = long((unsigned long(unsigned char(SerialData[0])) << 24) | (unsigned long(unsigned char(SerialData[1])) << 16)
| (unsigned long(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
Or changed to this (for the small values):
xcenter = (SerialData[2]*256) + SerialData[3];
ycenter = (SerialData[6]*256) + SerialData[7];
Or this (for the small values too):
int result = int((unsigned int(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
And the code gonna work perfectly!
This code will not work correctly for large values...
int xcenter = (SerialData[0]*256*256*256) + (SerialData[1]*256*256) + (SerialData[2]*256) + SerialData[3];
The problem is that the input is 4 bytes wide, which is a long integer, while the integer size on the arduino is only 2 bytes wide, which means that 256 * 256 = 0x10000 & 0xFFFF = 0 !
To make sure you do not run into problems for values wider than 2 bytes, one must use shift operations.
This gives:
long result = long((unsigned long(unsigned char(SerialData[0])) << 24) | (unsigned long(unsigned char(SerialData[1])) << 16)
| (unsigned long(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
Alternatively, if you do not expect large values, only use two bytes from the input. Make sure to do the calculus using unsigned values, or you may run into problems !!!
int result = int((unsigned int(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
This is very verbose, but it's safe for all input types. For example, the solution presented by the OP would not work if SerialData[] was a char array, which it should be, to avoid wasting memory.

Python sendto telling me it needs an int

from socket import *
import packets
image = "testfile.bmp"
# open image
bufferSize = 2048
myfile = open(image, 'rb')
sequenceNumber = 0
totalBytes = 0
serverName = "127.0.0.1"
serverSendPort = 12000
serverSendPort = int(serverSendPort)
serverListenPort = 12001
clientSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket = socket(AF_INET, SOCK_DGRAM)
while (1):
if (sequenceNumber == 0):
data = packets.mkepckt(myfile.read(bufferSize), 0,
packets.calculateChecksum(myfile.read(bufferSize), bufferSize))
clientSocket.sendto(bytearray(data),(serverName, serverSendPort))
sequenceNumber = 1
ACK, = serverSocket.recvfrom(bufferSize)
ACKchecksum = packets.calculateChecksum(ACK[1], bufferSize)
while (ACK[0] is not 0 or ACKchecksum is not ACK[2]):
clientSocket.sendto(data, (serverName, serverSendPort))
ACK, = serverSocket.recvfrom(bufferSize)
ACKchecksum = packets.calculateChecksum(ACK[1], bufferSize)
elif (sequenceNumber == 1):
data = packets.mkepckt(myfile.read(bufferSize), 1,
packets.calculateChecksum(myfile.read(bufferSize), bufferSize))
clientSocket.sendto(bytearray(data),(serverName, serverSendPort))
sequenceNumber = 0
ACK, = serverSocket.recvfrom(bufferSize)
ACKchecksum = packets.checksum(bufferSize, ACK[1])
while (ACK[0] is not 1 or ACKchecksum is not ACK[2]):
clientSocket.sendto(data, (serverName, serverSendPort))
ACK, = serverSocket.recvfrom(bufferSize)
ACKchecksum = packets.calculateChecksum(ACK[1], bufferSize)
myfile.close()
clientSocket.close()
serverSocket.close()
Not sure I needed to put my whole code, but better safe than sorry.
So for some reason, despite the fact that I have an int in the sendto. I have also tried all sorts of typecasting, from typecasting each individual element to typecasting the whole thing as an int, and I still get this error.
Thanks to help from #RemyLebeau, I was able to solve this problem by importing pickle and using that to dump my tuple into a variable, then sending that variable as the data. Not sure why the byte data gave off an error about an int, but there you go.

struct.error: argument for 's' must be a bytes object

I'm trying to upgrade an old Python 2.x class to work with 3.x (written by someone else, and not maintained). Here is a fragment.
def getByte(self):
if (self.available < 1):
self.request(4096);
self.available = self.available - 1
result = ord(self.bytes[0]);
self.bytes = self.bytes[1:]
return result
def request(self, size):
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((self.host, self.port))
contentSize = len(self.user)+len(self.password)+6;
contentString = "!BHB"+str(len(self.user))+"sB"+str(len(self.password))+"sL"
data = pack(contentString, 0, contentSize, len(self.user), self.user, len(self.password), self.password, size)
sock.sendall(data)
print("Sent!")
data = sock.recv(6)
fields = unpack("!BBL", str(data));
if (fields[0] != 0):
raise(ServiceDeniedError(fields[0],fields[1]))
self.bytes = sock.recv(fields[2]);
self.available = len(self.bytes);
print("Received: ")
print(self.available)
sock.close()
Imported and called with print (rand.getByte()).
Tracebacks:
print (rand.getByte())
self.request(4096);
data = pack(contentString, 0, contentSize, len(self.user), self.user, len(self.password), self.password, size)
struct.error: argument for 's' must be a bytes object
I figured it out. Two arguments in the pack() function had to be converted to bytes.
data = pack(contentString, 0, contentSize, len(self.user), bytes(self.user, 'utf-8'), len(self.password), bytes(self.password, 'utf-8'), size)

Resources