Is there a way to convert a list of integers to a single variable? - python-3.x

I'd like to convert a list of integers to a singe variable.
I tried this (found on another question):
r = len(message) -1
res = 0
for n in message:
res += n * 10 ** r
r -= 1
This does not work for me at all.
I basically need this:
message = [17, 71, 34, 83, 81]
(This can vary in length as I use a variable to change each one)
To convert into this:
new_message = 1771348381

A combination of join, map and str will do.
message = [17, 71, 34, 83, 81]
new_message = int(''.join(map(str, message)))
# 1771348381

Related

How to write-to/read-from Ctypes variable length array of ints

I came across this link but am still struggling to construct an answer.
This is what one of the complex structs that I have looks like. This is actually a deep nested struct within other structs :)
/*
* A domain consists of a variable length array of 32-bit unsigned integers.
* The domain_val member of the structure below is the variable length array.
* The domain_count is the number of elements in the domain_val array.
*/
typedef struct domain {
uint32_t domain_count;
uint32_t *domain_val;
} domain_t;
The test code in C is doing something like this:
uint32_t domain_seg[4] = { 1, 9, 34, 99 };
domain_val = domain_seg;
The struct defined in python is
class struct_domain(ctypes.Structure):
_pack_ = True # source:False
_fields_ = [
('domain_count', ctypes.c_uint32),
('PADDING_0', ctypes.c_ubyte * 4),
('domain_val', POINTER_T(ctypes.c_uint32)),
]
How to populate the domain_val in that struct ? Can I use a python list ?
I am thinking something along dom_val = c.create_string_buffer(c.sizeof(c.c_uint32) * domain_count) but then how to iterate through the buffer to populate or read the values ?
Will dom_val[0], dom_val[1] be able to iterate through the buffer with the correct length ? Maybe I need some typecast while iterating to write/read the correct number of bytes
Here's one way to go about it:
import ctypes as ct
class Domain(ct.Structure):
_fields_ = (('domain_count', ct.c_uint32),
('domain_val', ct.POINTER(ct.c_uint32)))
def __init__(self, data):
size = len(data)
# Create array of fixed size, initialized with the data
self.domain_val = (ct.c_uint32 * size)(*data)
self.domain_count = size
# Note you can slice the pointer to the correct length to retrieve the data.
def __repr__(self):
return f'Domain({self.domain_val[:self.domain_count]})'
x = Domain([1, 9, 34, 99])
print(x)
# Just like in C, you can iterate beyond the end
# of the array and create undefined behavior,
# so make sure to index only within the bounds of the array.
for i in range(x.domain_count):
print(x.domain_val[i])
Output:
Domain([1, 9, 34, 99])
1
9
34
99
To make it safer, you could add a property that casts the pointer to single element to a pointer to sized-array of elements so length checking happens:
import ctypes as ct
class Domain(ct.Structure):
_fields_ = (('_domain_count', ct.c_uint32),
('_domain_val', ct.POINTER(ct.c_uint32)))
def __init__(self,data):
size = len(data)
self._domain_val = (ct.c_uint32 * size)(*data)
self._domain_count = size
def __repr__(self):
return f'Domain({self._domain_val[:self._domain_count]})'
#property
def domain(self):
return ct.cast(self._domain_val, ct.POINTER(ct.c_uint32 * self._domain_count)).contents
x = Domain([1, 9, 34, 99])
print(x)
for i in x.domain: # now knows the size
print(i)
x.domain[2] = 44 # Can mutate the array,
print(x) # and it reflects in the data.
x.domain[4] = 5 # IndexError!
Output:
Domain([1, 9, 34, 99])
1
9
34
99
Domain([1, 9, 44, 99])
Traceback (most recent call last):
File "C:\demo\test.py", line 27, in <module>
x.domain[4] = 5
IndexError: invalid index

Python, print colored duplicates found in 2 list

I'm 63 and just started with Python (My first steps with Udemy).
I'm Croatian so this is croatian language in program but you will understand when you run a program. I know it can be cleaner, shorter, more elegant etc, but as I mentioned before - I'm beginner.
import random
jedan = random.sample(range(1,99),15)
dva = random.sample(range(1,99),15)
def raspaljot(jedan, dva, i):
for x in jedan:
for y in dva:
if y == x:
index1 = jedan.index(x)
index1_str = str(index1)
index2 = dva.index(y)
index2_str = str(index2)
i += 1
x = str(x)
print(" Broj \033[31m" + x + "\033[0m,je dupli i nalazi se u listi jedan: na poziciji: \033[34m"
+ index1_str + "\033[0m a u listi dva na poziciji: \033[35m"+ index2_str + "\033[0m")
print()
print(jedan)
print(dva)
if i != 0:
print("\n *** Ukupno ima ", i, 'duplih brojeva. ***')
elif i == 0:
print("Nema duplih brojeva. :) ")
i = 0
raspaljot(jedan, dva,i)
What program do is finding duplicates in 2 random lists, them print duplicates in color and detecting position inside list[1] and list[2].
What I trying to do is printing list1 and list2 but showing duplicates in color.
For example:
[14, 78, 85, 31, 5, 54, 13, 46, 83, 4, 35, 41, 52, 51, 32]
[72, 40, 67, 85, 54, 76, 77, 39, 51, 36, 91, 70, 71, 38, 55]
here we have 3 duplicates (85,54,51). This above example on the console End was printed in white color, but I wanna these 3 numbers in red color in those two lines above.
Is this possible? I couldn't find a solution.
PS. Wing Pro version 7 on Fedora 33 Workstation / In WIngIde colors are only displayed in an external console and not the Debug I/O tool. :)
Simple solution would be something like this:
# Change list to string
jedan_str = str(jedan)
# Create set with numbers that need new color
num_set = {"85", "54", "51"}
# Iterate over every number and wrap it with color change
for i in num_set:
# Note that I used f-string to format string
# But you can also do this as "\033[31m" + i + "\033[0m"
jedan_str = jedan_str.replace("85", f"\033[31m{i}\033[0m")
# Print string that represent list
print(jedan_str)
Following the idea of using a set to determine which elements are in both lists (as Cv4niak proposed in his answer), I created a function to print the output as you desire. There are numerous other ways of achieving it, but I think this is a simple yet effective way.
The idea is to use the cprint() function from the termcolor package. You can install it with pip install termcolor, and then print normally all elements, except the ones that are duplicates, which will be printed using cprint(item, "red").
The "{:0>2d}" formatting in each ìtem print serves only to pad the number with zeros (so 2 will be printed as 02, for example), in order for the output of both lists to be aligned.
import random
from termcolor import cprint
def mark_duplicates(first, second):
duplicates = list(set(first).intersection(second))
if duplicates:
for list_ in [first, second]:
print("[", end="")
for item in list_:
if item in duplicates:
cprint("{:0>2d}".format(item), "red", end=",")
else:
print("{:0>2d}".format(item), end=",")
print("\b]")
else:
print("No duplicates.")
jedan = random.sample(range(1, 99), 15)
dva = random.sample(range(1, 99), 15)
mark_duplicates(jedan, dva)
With this, if there are no duplicates, the No duplicates. string will be printed. Also you can change the color with not much effort, and use other nice functionalities from termcolor package.

A Rule of Divisibility by 13 - Codewars python challenge (RecursionError)

Instructions:
When you divide the successive powers of 10 by 13 you get the following remainders of the integer divisions:
1, 10, 9, 12, 3, 4.
Then the whole pattern repeats.
Hence the following method: Multiply the right most digit of the number with the left most number in the sequence shown above, the second right most digit to the second left most digit of the number in the sequence. The cycle goes on and you sum all these products. Repeat this process until the sequence of sums is stationary.
...........................................................................
Example: What is the remainder when 1234567 is divided by 13?
7×1 + 6×10 + 5×9 + 4×12 + 3×3 + 2×4 + 1×1 = 178
We repeat the process with 178:
8x1 + 7x10 + 1x9 = 87
and again with 87:
7x1 + 8x10 = 87
...........................................................................
From now on the sequence is stationary and the remainder of 1234567 by 13 is the same as the remainder of 87 by 13: 9
Call thirt the function which processes this sequence of operations on an integer n (>=0). thirt will return the stationary number.
thirt(1234567) calculates 178, then 87, then 87 and returns 87.
thirt(321) calculates 48, 48 and returns 48
My Code:
def thirt(n):
a = []
n = [int(i) for i in list(str(n))][::-1]
l = [1, 10, 9, 12, 3, 4][:len(n)]
y = sum([a * b for a,b in zip(n,l)])
a.append(y)
for c in a:
if a.count(c) == 1:
thirt(c)
else:
return c
thirt(5634)
When I run this I get an error
Traceback (most recent call last):
File "main.py", line 5, in <module>
Test.assert_equals(thirt(8529), 79)
File "/home/codewarrior/solution.py", line 9, in thirt
thirt(i)
File "/home/codewarrior/solution.py", line 9, in thirt
thirt(i)
File "/home/codewarrior/solution.py", line 9, in thirt
thirt(i)
[Previous line repeated 994 more times]
File "/home/codewarrior/solution.py", line 3, in thirt
n = [int(i) for i in list(str(n))][::-1]
RecursionError: maximum recursion depth exceeded while getting the str of an object
when I remove some part of the code and leave it like
def thirt(n):
n = [int(i) for i in list(str(n))][::-1]
l = [1, 10, 9, 12, 3, 4][:len(n)]
y = sum([a * b for a,b in zip(n,l)])
return y
thirt(5634)
I get 148 in the output, and then I thirt(148), I get 57, which is the desired answer, same goes for other examples as well.
so I just need a proper way to recur this function, and I just want it to stop as soon as the values start repeating, i.e. I want the loop of recursion to break as soon as I get two 57's in a row, and then I need it to return 57.
But I can't figure out a proper way to do it, because this is the first time I've applied recursion in a function, my code is really messed up, I'll really appreciate any help.
You are getting the error depth exceeded while getting the str of an object because you are assigning the list of digits n to the same variable name as the function parameter n. That means after the first recursive call, you are running [int(i) for i in list(str(n))][::-1] on a list of individual digits, and then a list of lists, and so on, rather than a single input number as you're expecting.
Once you fix that, you run into the issue of how you are checking for whether to make the recursive call:
a = []
a.append(y)
for c in a:
if a.count(c) == 1:
thirt(c)
I can see what you're trying to do, and it will not work in recursion because every time the function is called, a is reset to an empty list. That means a.count(c) == 1 is always true, and your function will go into an infinite recursive loop.
Instead, for this algorithm all you need to do is check whether your newly calculated y is equal to the number n that was passed to the function. If they're the same, that means you've gotten the same number twice in a row, so the algorithm is done.
After that is fixed, it will look like you're getting somewhere. You can use this logic:
if n != y:
thirt(y)
else:
print(y) # expected answer outputted to console
return y
Except when you call thirt(1234567), the value returned is None ! What the heck? I printed y and it's correct, it's right there! What is happening is, the inner-most call to thirt is returning the number you need, but then the next level up in the function call stack doesn't do anything with it. So the function ends and returns None. To fix this, you need each level of the recursive call to pass its return value up the chain. So use return thirt(y) instead of just thirt(y).
Finally, you need to account for the case when the number passed to the function is longer than 6 digits. Your l list needs to repeat in a cycle, not stop with the 6 numbers you've listed. You can get the list to be the length you need by multiplying it by the length of n divided by six, rounded up whenever there's a remainder.
After all that, you'll end up with something like the following:
def thirt(n):
nList = [int(i) for i in list(str(n))][::-1]
remainders = [1, 10, 9, 12, 3, 4] * (
len(nList) // 6 + min(1, len(nList) % 6)
)
y = sum([a * b for a,b in zip(nList,remainders)])
if n != y:
return thirt(y)
else:
return y
print(thirt(1234567)) #87
Isn't this what you mean?
def thirt(n_raw):
a = []
n = [int(i) for i in list(str(n_raw))][::-1]
l = [1, 10, 9, 12, 3, 4]*(len(n)//6+1)
y = sum([a * b for a,b in zip(n,l)])
if(y==n_raw): return y
else: return thirt(y)
I think you just went in a very wrong direction with the second half of your function, but I might misunderstood the premise behind...

It the any proper way how to take a two byte elemetns from list, concat them, and convert them to integer

I have a list with 4 element which contain integers
data = [134, 2, 4, 170]
hexdata = [0x86, 0x2, 0x4, 0xAA]
i need to get hex data from two last elements eg. (0x04 and 0xAA)
concatenate them to this view 0x04AA and convert to int
in the end i need to get integer with value = 1194.
i am stuck in this task/
data = [134, 2, 4, 170]
for x in data:
print("0x%x" % (x), end=" ")
print()
c = "0x%x%x" % (data[2], data[3])
print(c)
print(int(c))
Traceback (most recent call last):
File "123.py", line 7, in <module>
print(int(c))
ValueError: invalid literal for int() with base 10: '0x4aa'
You don't need to bother with string formatting here - use int.from_bytes instead, eg:
data = [134, 2, 4, 170]
res = int.from_bytes(data[-2:], 'big')
# 1194
data = [134, 2, 4, 170]
result = data[-2] << 8 | data[-1]
Simply multiply the 4 accordingly and add it up? No need to go hex on it ...
data = [134, 2, 4, 170]
rv = data[2]*256 + data[3] # 0x04AA == 0x04*256 + 0xAA
print(rv)
Output:
1194

Two sample dependent T test in python and rank sum test

I have a data set for which has two labels, label 1 = 0(case), label 2 =1(control). I have already calculated the mean for the two different labels. Furthermore, I need to calculate two sample t test(dependent) and two sample rank sum test. My data set looks like :
SRA ID ERR169499 ERR169500 ERR169501 mean_ctrl mean_case
Label 1 0 1
TaxID PRJEB3251_ERR169499 PRJEB3251_ERR169500 PRJEB3251_ERR169501
333046 0.05 0 0.4
1049 0.03 0.9 0
337090 0.01 0.6 0.7
I am new to statistics.The code I have so far is this:
label = []
data = {}
x = open('final_out_transposed.csv','rt')
for r in x:
datas = r.split(',')
if datas[0] == ' Label':
label.append(r.split(",")[1:])
label = label[0]
label[-1] = label[-1].replace('\n','')
counter = len(label)
for row in file1:
content = row.split(',')
if content[0]=='SRA ID' or content[0]== 'TaxID' or content[0]==' Label':
pass
else:
dt = row.split(',')
dt[-1] = dt[-1].replace('\n','')
data[dt[0]]=dt[1:]
keys = list(data)
sum_file = open('sum.csv','w')
for key in keys:
sum_case = 0
sum_ctrl = 0
count_case = 0
count_ctrl = 0
mean_case = 0
mean_ctrl = 0
print(len(label))
for i in range(counter):
print(i)
if label[i] == '0' or label[i] == 0:
sum_case=np.float64(sum_case)+np.float64(data[key][i])
count_case = count_case+1
mean_case = sum_case/count_case
else:
sum_ctrl = np.float64(sum_ctrl)+np.float64(data[key][i])
count_ctrl = count_ctrl+1
mean_ctrl = sum_ctrl/count_ctrl
Any help will be highly appreciated.
Instead of using open to read your csv file, I would use Pandas. That will place it in a dataframe that will be easier to use
import pandas as pd
data_frame = pd.read_csv('final_out_transposed.csv')
For a Two Sample dependent T-test you want to use ttest_rel
notice ttest_ind is for independent groups. Since you specifically asked for dependent groups, use ttest_rel.
It's hard from your example above to see where your two columns of sample data are, but imagine I had the following made up data of 'case' and 'control'. I could calculate a dependent Two Sample t-test using pandas as shown below:
import pandas as pd
from scipy.stats import ttest_rel
data_frame = pd.DataFrame({
'case':[55, 43, 51, 62, 35, 48, 58, 45, 48, 54, 56, 32],
'control':[48, 38, 53, 58, 36, 42, 55, 40, 49, 50, 58, 25]})
(t_stat, p) = ttest_rel(data_frame['control'], data_frame['case'])
print (t_stat)
print (p)
p would be the p-value, t_stat would be the t-statistic. You can read more about this in the documentation
In a similar manner, once you have your sample .csv data in a dataframe, you can perform a rank sum test:
from scipy.stats import ranksums
(t_stat, p) = ranksums(data_frame['control'], data_frame['case'])
documentation for ranksums

Resources