Python script for reading from file and display an output - python

Wrote a python script that reads from a file input.txt
input.txt
2 //number of test cases
2 4 //testcase 1 ->'2' is size of 1st array and 4 is size of 2nd array
6 10 6 7 8 9 //testcase 1 -> 1st array is [6,10] and 2nd array is [6,7,8,9]
1 3 //testcase 2 ->'1' is size of 1st array and 3 is size of 2nd array
7 7 8 14 //testcase 2 -> 1st array is [7] and 2nd array is [7,8,14]
The 1st line in the file indicates number of test cases. In this example, we have 2 test cases. Each test case have 2 lines to process - in which first line indicates size of 1st array and size of 2nd array. 2nd line indicates the both array details.
ie, In above example, line 2 indicates size of 1st array and 2nd array for testcase1. line 3 indicates 2 arrays in mentioned sizes for testcase1.line 4 indicates size of 1st array and 2nd array for testcase2. line 5 indicates 2 arrays in mentioned sizes for testcase2.
I need to check whether the elements of 1st array is present in the 2nd one for each test cases. I wrote below program, but that will execute only for 1 test case(ie, I'm checking 2nd and 3rd line manually by giving the check i == 0)
from itertools import islice
def search(arr, element):
for i in range(len(arr)):
if int(arr[i]) == int(element):
return "yes"
return "no"
f = open("output.txt", "w")
with open("input.txt") as y_file:
count = y_file.readline()
if(count > 0):
for i, line in enumerate(y_file):
if(i == 0):
num, size = line.split()
split_list = [int(num), int(size)]
if(i == 1):
temp = iter(line.split())
res = [list(islice(temp, 0, ele)) for ele in split_list]
for i in range(len(res[0])):
result = search(res[1], res[0][i])
f.write("The result is : " + str(result) + "\n")
f.close()
Can anyone please help me in this?
output will be like
The result is : yes
The result is : no
The result is : yes

I would read the file line by line and process.
# read a line and convert to int() for num_cases.
for i in range(0, 2 * num_cases, 2):
# read a line for split_list
# check length of split_list
# read a line for list values all_nums
# check length of all_nums to be equal to sum of split_list
# split the list into arr1 and arr2.
# You can use slicing notation.
# For example:
# arr[:5] are the first 5 elements of arr. i.e. indexes 0, 1, 2, 3, 4
# arr[:-5] are the last 5 elements of arr. i.e. indexes len(arr) - 5, ... , len(arr) - 1
# arr[5:] are elements 5 and on from arr. i.e. indexes 5, 6, ...
for value in arr1:
if value in arr2:
# output
else:
# output
The function int(x) will raise ValueError when input is bad.
Checking the length of the lists allows you to make sure you get the expected number of values on each line.
If the file runs out of lines, readline() will return an empty string which results in a list with length 0 when you split and should fail the length checks.
You can use try, catch to write code to handle the errors such as ValueError from int().

Try this
first_array=[1,2,3]
sec_array=[4,5,3]
print(any(i in sec_array for i in first_array)) # prints True

Related

I am getting error in code in taking input and append it to array

You are given N sticks, where the length of each stick is a positive integer. A cut operation is performed on the sticks such that all of them are reduced by the length of the smallest stick.
Given the length of N sticks, print the number of sticks that are left before each subsequent cut operations. Note: For each cut operation, you have to recalculate the length of smallest sticks (excluding zero-length sticks).
Input
The first line contains a single integer N.
The next line contains N integers separated by space, where each integer represents the length of the ith stick.
6
5 4 4 2 2 8
Output
For each operation, print the number of sticks that are cut, on separate lines.
6
4
2
1
Explanation
import array as arr
n = int(input())
a = arr.array('i',[1002])
for i in range(n):
c = [int(x) for x in input().split()]
a.append(c)
t=n
for i in range(0,1001):
if a[i] > 0:
print(t)
t=t-a[i]
You can't append a list to an integer array. If you want to merge two arrays you can use the extend method.
a.extend(c)
if a is list then below all satisfies but here a is array so we cant append list with array
a = [1,2,3] # a is a list
c = [4] # c is list
it won't give you correct result in any case
print(a.append(c)) # if we do a.append(c) result is like a = [1,2,3,[4]]
gives you correct result in any case
print(a.extend(c)) # if we do a.extend(c) result is like a = [1,2,3,4]
satisfies if "a" is list and "c" is list or "a" is array and "c" is also an array
a += c # a += c result is same as a.extend(c)
print(a) # a = [1,2,3,4]

How to Identify Missing Indices

I have a text file with millions of index points that are all interpreted as strings and is tab delimited. However, some index points could be missing. Here is an example of my text file:
1 0 4 0d 07:00:37.0400009155273
2 0 4 0d 07:00:37.0400009155273
3 0 4 0d 07:00:37.0400009155273
5 0 4 0d 07:00:37.0400009155273
7 0 4 0d 07:00:37.0400009155273
9 0 4 0d 07:00:37.0400009155273
Notice that rows 4, 6 and 8 are missing. My goal is to create a function that can parse through the text file, identify possible missing index points and return a list that has all the missing index points (if any) or return nothing.
I'm using Python 3.7 in Spyder IDE Windows10 os. I am relatively new to Python and Stackoverflow.
This is what I've got so far. This works to ID 1 missing index but fails if there are several missing index points.
The error starts after the first else line. I'm not sure how to track the observed index in the doc (1, 2, 3, 5...) with the for loop's index (0, 1, 2, 3...) as missing index points compound over time.
Note, the first 4 rows of the text doc contain header info which I ignore during the parsing that's why data = f.readlines()[4:]
def check_sorted_file(fileName):
missing_idx = []
count = 1
with open(fileName, 'r') as f:
data = f.readlines()[4:]
for x, line in enumerate(data):
idx = int(line.split()[0])
if idx == (count + x):
pass
else:
missing_idx.append(count + x)
count += 1
if missing_idx != []:
print('\nThe following idicie(s) are missing: ')
print(*missing_idx, sep=", ")
else:
print('\nAll indices are accounted for. ')
return missing_idx
...
Thanks for any and all help!
The other answer give you much better overall solutions, however I want to just help guide your given one in the right direction so you see how you could change yours to work:
def check_sorted_file(fileName):
missing_idx = []
last_index = 0
with open(fileName, 'r') as f:
data = f.readlines()[4:]
for line in data:
idx = int(line.split()[0])
if idx == last_index+1:
pass
else:
missing_idx.extend(list(range(last_index+1, idx)))
last_index = idx
if missing_idx:
print('\nThe following idicie(s) are missing: ')
print(*missing_idx, sep=", ")
else:
print('\nAll indices are accounted for. ')
return missing_idx
So instead of needing to use enumerate we will use the incoming index as our guide of where we are at.
To solve multiple missing, we use range to get all the numbers between the last index and the current one, and extend our list with that new set of numbers.
You can do this with Python alone:
with open(filename) as f:
indices = [int(row.split('\t')[0]) for row in f.read().split('\n')[4:]]
missing_indices = [index
for index in range(1, len(indices) + 1)
if index not in indices]
This converts your data into a nested list where each outer list contains a row and each inner list contains an element. Since we only care about the indices, we get the first element and ignore the others.
Then, since the indices are in running order starting from 1, we construct a range spanning the expected range of indices, and get the indices that exist in that range but not in the file.
Assuming the indices are unique (which seems reasonable), we can also use DYZ's suggestion to use sets:
missing_indices = set(range(1, len(indices) + 1) - set(indices)
pandas works fine too:
import pandas as pd
df = pd.read_csv(filename, sep='\t').iloc[4:]
range_index = pd.RangeIndex(1, len(df) + 1)
print(range_index[~range_index.isin(df.iloc[:, 0])]
This creates a pandas DataFrame from your data, cutting off the first four rows. Following the same principle as the other answer, it creates an index with all expected values and takes the subset of it that does not exist in the first column of the DataFrame.
Since you have a large number of rows, you might want to do this in a lazy fashion without making large lists or using in to test if every value is in a million line list. You can mix a few of the itertools to do this as an iterator and save the list for the end (if you even need it then).
Basically you make tee a map into two iterators to get the indexes, knock off a value of one of them with next() then zip them checking the difference as you go:
from itertools import chain, tee
lines = ["1 0 4 0d 07:00:37.0400009155273",
"2 0 4 0d 07:00:37.0400009155273",
"3 0 4 0d 07:00:37.0400009155273",
"5 0 4 0d 07:00:37.0400009155273",
"7 0 4 0d 07:00:37.0400009155273",
"9 0 4 0d 07:00:37.0400009155273"
]
#two iterators going over indexes
i1, i2 = tee(map(lambda x: int(x.split()[0]), lines), 2)
# move one forward
next(i2)
# chain.from_iterable will be an iterator producing missing indexes:
list(chain.from_iterable(range(i+1, j) for i, j in zip(i1, i2) if j-i!=1))
Result:
[4, 6, 8]
Here's a compact, robust, set-based, core Python-only solution. Read the file, split each line into fields, convert the first field into an int, and build a set of actual indexes:
skip = 4 # Skip that many lines
with open(yourfile) as f:
for _ in range(skip):
next(f)
actual = {int(line.split()[0]) for line in f}
Create a set of expected indexes and take set difference:
expected = set(range(min(actual), max(actual) + 1))
sorted(expected - actual)
#[4, 6, 8]
The solution works even when the indexes do not start at 1.

Python program Terminated due to timeout - HackerRank

I am trying to solve a question from HackerRank and when I submit my solution, I get an error stating "Terminated due to timeout".
Please check the code and suggest me how to optimize.
Question:
A left rotation operation on an array of n size shifts each of the array's elements 1 unit to the left. For example, if 2 left rotations are performed on array [1,2,3,4,5], then the array would become [3,4,5,1,2].
Given an array of n integers and a number,d, perform d left rotations on the array. Then print the updated array as a single line of space-separated integers.
Input Format
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains space-separated integers describing the respective elements of the array's initial state.
Output Format
Print a single line of n space-separated integers denoting the final state of the array after performing d left rotations.
Sample Input
5 4
1 2 3 4 5
Sample Output
5 1 2 3 4
Explanation
When we perform d = 4 left rotations
Thus, we print the array's final state as a single line of space-separated values, which is 5 1 2 3 4.
My Code:
def array_left_rotation(ar, n, k):
for j in range(k):
temp = ar[0]
for i in range(0,n-1):
ar[i] = ar[i+1]
ar[n-1] = temp
return ar
n, k = map(int, input().strip().split(' '))
a = list(map(int, input().strip().split(' ')))
answer = array_left_rotation(a, n, k);
print(*answer, sep=' ')
Here the best way is not to actually perform the operations yourself. In this case you are manually rotating the list and that is unnecessary computation.
So first, analyze the problem and how it behaves for various outputs. So lets analyze :
Suppose for an Array of 5 elements
array = [1,2,3,4,5]
If you rotate this 2 times, you get :
[3,4,5,1,2]
Now, try the same for rotation with 7 times on the original array. You again get :
[3,4,5,1,2]
Similar trials will see the pattern emerge. ie, for a rotation of k times, it is same as k % n times.
Now that we have that with us, move to the computation part. For that, simply use list slicing to get the rotation, like this :
#n -> number of elements in array
#k -> number of rotations to be performed
#a -> (list) array
def rotate(a,n,k) :
rotations = k % n
new_array = a[rotations:] + a[:rotations]
return new_array
>>> a = [1, 2, 3, 4, 5]
>>> a[2:] + a[:2]
[3, 4, 5, 1, 2]
>>> ' '.join(str(i) for i in (a[2:] + a[:2]))
'3 4 5 1 2'
>>>
>>> def rotate_list(array, d):
... return array[d:] + array[:d]
>>>
>>> ' '.join(str(i) for i in rotate_list([1, 2, 3, 4, 5], 4))
... '5 1 2 3 4'
number_of_elements = int(input("Enter the number of elements to be inserted in array:"))
rotations = int(input("Enter the number of rotations:"))
array = []
for i in range(number_of_elements):
number = int(input("Enter a number:"))
array.append(number)
array = array[rotations:] + array[:rotations]
print(*array, end=' ')

Python insert number in list sequence

I am trying to insert a number into a list of a sequence of numbers, for some reason this small program just sits there consuming CPU power... no idea why it's not working:
number = 5
lst = [4,5,6]
if all(x > number for x in lst):
lst.insert(0,number)
elif all(x < number for x in lst):
lst.append(number)
else:
for i,v in enumerate(lst):
if v>number:
lst.insert(i-1,number)
print (lst)
expected output:
lst = [4,5,5,6]
Your for loop is inserting the number 5 into the middle of the list a theoretically infinite amount of times (or until you run out of whatever limited resource the list consumes, whichever happens first).
1) for i,v in enumerate(lst):
2) if v>number:
3) lst.insert(i-1,number)
On the first pass, line 1 starts the loop with v = 4 and i = 0. Line 2 finds v is not greater than number.
On the second pass, line 1 continues the loop with v = 5 and i = 1. Line 2 is also false.
Third pass, line 1: v = 6, i = 2. Line 2 finds a true statement and moves to line 3. Line 3 inserts the object referenced by number into position i - 1, inserting 5 into position 1 of the list.
At this point the list is:
lst = [4, *5*, **5**, 6]
The italicized 5 is the number you added to the list. The bolded 5 is where the current pointer is, i = 2. Notice that the 6 we just checked got moved forward with the insert.
Fourth pass: v = 6, i = 3. Line 2 finds a true statement and moves to line 3. Line 3 inserts the object referenced by number into position i - 1, inserting 5 into position 2 of the list.
At this point the list is:
lst = [4, 5, *5*, **5**, 6]
etc etc etc.
A quick fix:
for i, v in enumerate(lst):
if v > number:
lst.insert(i-1, number)
**break**
You're just checking for and adding a single number, so break out of the loop once you insert it, since you're done.

error in python: list assignment index out of range

I searched everywhere and even though there were a couple of questions and answers regarding this error I couldn't find a solution to fix my problem
I'm reading in from a file that contains letters and numbers and I'm populating my matrix depending on the values in that file.
ex: file
description of letters and numbers ...
table:
a b c d
a 1 2 5 6
b 5 6 3 4
c 3 2 1 4
d 2 4 6 8
Here's the code
matrix = [[0 for j in range(4)] for i in range(4)]
i = 0
j = 0
for line in file:
for a in line:
if is_number(a):
matrix[i][j] = int(a)
j+= 1
if matrix.count(0) < 2: #since matrix already populated with zeroes. it shouldn't have
#many per program specifications, that's why I use this
#conditional to increment i and reset j back to 0
i += 1
j = 0
file.close()
I don't understand why I keep getting that error.
I see two possible ways you could end up with an IndexError in your code.
The first problem occurs because of the way you are iterating through the file that you're reading. Your code:
for line in file:
for a in line:
if is_number(a):
# do stuff
Reads a line in the file into the variable line. Then, each character is stored in the variable a and you check if it is a number. If any of the integers you are reading in are greater than 9 you will see an IndexError since it will count each digit as a separate number, causing you to eventually run out of room in your pre-allocated array.
A possible fix would be to change the line:
for a in line:
to
for a in line.split()
which will split the line into a list of words (that is, a new entry for everything separated by whitespace). So, "6 12 4 5" will become [6,12,4,5], making it so that you don't count the 1 and 2 in 12 separately.
The second issue I see with your code is in the line:
if matrix.count(0) < 2:
If your input file ever contains a zero, it will cause this line to stay true for one iteration of the loop longer than you would like. A possible fix would be to change the line to:
if j == len(matrix[0]) - 1:
try something like this:
with open("data1.txt") as f:
next(f) #skip the first line
lis=[map(int,x.split()[1:]) for x in f] #use x.split()[1:] to remove the alphabet
print lis
output:
[[1, 2, 5, 6], [5, 6, 3, 4], [3, 2, 1, 4], [2, 4, 6, 8]]
If you know the input file already has the right matrix (line by line) layout you could use the following :
matrix = filter(lambda x: len(x)>0, [[int(a) for a in l.split() if is_number(a)] for l in file])
If you cannot expect anything from the input layout, you could try:
data = open("test").read()
l = filter(lambda x: is_number(x), data.replace("\n"," ").split())
width = int(math.sqrt(len(l)))
print [[int(l[i+width*j]) for i in range(width)] for j in range(width)]
You're constructing a 4x4 matrix in the first line of code, but your data is a 6x6 matrix. When you try to store an element at index 4 in row 0, you get an IndexError.
The problem is here:
matrix = [[0 for j in range(4)] for i in range(4)]
Your matrix is 6x6, but your code only compensates for a 4x4 matrix.

Categories

Resources