How can I create a struct in julia? - struct

I am trying to create a structure, txn:
a)
struct txn
txn_id::Int64
bank::Char[20]
branch::Char[20]
teller::Char[20]
customer::Char[20]
account::Char[34]
timestamp::DateTime
dr_cr::Char[2]
amount::Int64
end
gives
Error: TypeError: in txn, in type definition, expected Type, got Array{Char, 1}
b)
struct txn
txn_id::Int64
bank::Char(20)
branch::Char(20)
teller::Char(20)
customer::Char(20)
account::Char(34)
timestamp::DateTime
dr_cr::Char(2)
amount::Int64
end
gives
Error: TypeError: in txn, in type definition, expected Type, got Char
How can I create the struct in Julia?

In Julia, an array of Chars is not equivalent to a String. The syntax Char(80) creates a single character:
julia> Char(80)
'P': ASCII/Unicode U+0050 (category Lu: Letter, uppercase)
And the syntax Char[80, 81, 82] creates an array of Chars:
julia> Char[80, 81, 82]
3-element Array{Char,1}:
'P'
'Q'
'R'
We can see that an array of characters is not equivalent to a string (note that characters can also be represented using single quotes):
julia> ['a', 'b', 'c'] == "abc"
false
Try defining the string fields in your struct using the String type:
julia> struct Person
name::String
end
julia> p = Person("Bob")
Person("Bob")

Related

Replace an int with a string in a numpy array

I have a numpy array as follows:
board = np.arange(9).reshape(3, 3)
I would like to replace a value in the array, for example:
board[1, 2] = 'x'.
But as I understand, I cannot do this as the array is in type int and what I am trying to replace it with is a string. When I run this, I get the error:
ValueError: invalid literal for int() with base 10: 'x'
I tried setting the dtype of the array to str:
board = np.arange(9, dtype=str).reshape(3, 3)
But this gives me the error:
ValueError: no fill-function for data-type.
Thanks
In numpy any non-numeric dtype is of type object.
This will work:
board = np.arange(9, dtype=object).reshape(3, 3)
board[1, 2] = 'x'
Cheers.

Find multiple words or strings in an if statement [duplicate]

How can I check if any of the strings in an array exists in another string?
For example:
a = ['a', 'b', 'c']
s = "a123"
if a in s:
print("some of the strings found in s")
else:
print("no strings found in s")
How can I replace the if a in s: line to get the appropriate result?
You can use any:
a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]
if any([x in a_string for x in matches]):
Similarly to check if all the strings from the list are found, use all instead of any.
any() is by far the best approach if all you want is True or False, but if you want to know specifically which string/strings match, you can use a couple things.
If you want the first match (with False as a default):
match = next((x for x in a if x in str), False)
If you want to get all matches (including duplicates):
matches = [x for x in a if x in str]
If you want to get all non-duplicate matches (disregarding order):
matches = {x for x in a if x in str}
If you want to get all non-duplicate matches in the right order:
matches = []
for x in a:
if x in str and x not in matches:
matches.append(x)
You should be careful if the strings in a or str gets longer. The straightforward solutions take O(S*(A^2)), where S is the length of str and A is the sum of the lenghts of all strings in a. For a faster solution, look at Aho-Corasick algorithm for string matching, which runs in linear time O(S+A).
Just to add some diversity with regex:
import re
if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
print 'possible matches thanks to regex'
else:
print 'no matches'
or if your list is too long - any(re.findall(r'|'.join(a), str, re.IGNORECASE))
A surprisingly fast approach is to use set:
a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
print("some of the strings found in str")
else:
print("no strings found in str")
This works if a does not contain any multiple-character values (in which case use any as listed above). If so, it's simpler to specify a as a string: a = 'abc'.
You need to iterate on the elements of a.
a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:
if item in str:
found_a_string = True
if found_a_string:
print "found a match"
else:
print "no match found"
a = ['a', 'b', 'c']
str = "a123"
a_match = [True for match in a if match in str]
if True in a_match:
print "some of the strings found in str"
else:
print "no strings found in str"
jbernadas already mentioned the Aho-Corasick-Algorithm in order to reduce complexity.
Here is one way to use it in Python:
Download aho_corasick.py from here
Put it in the same directory as your main Python file and name it aho_corasick.py
Try the alrorithm with the following code:
from aho_corasick import aho_corasick #(string, keywords)
print(aho_corasick(string, ["keyword1", "keyword2"]))
Note that the search is case-sensitive
The regex module recommended in python docs, supports this
words = {'he', 'or', 'low'}
p = regex.compile(r"\L<name>", name=words)
m = p.findall('helloworld')
print(m)
output:
['he', 'low', 'or']
Some details on implementation: link
A compact way to find multiple strings in another list of strings is to use set.intersection. This executes much faster than list comprehension in large sets or lists.
>>> astring = ['abc','def','ghi','jkl','mno']
>>> bstring = ['def', 'jkl']
>>> a_set = set(astring) # convert list to set
>>> b_set = set(bstring)
>>> matches = a_set.intersection(b_set)
>>> matches
{'def', 'jkl'}
>>> list(matches) # if you want a list instead of a set
['def', 'jkl']
>>>
Just some more info on how to get all list elements availlable in String
a = ['a', 'b', 'c']
str = "a123"
list(filter(lambda x: x in str, a))
It depends on the context
suppose if you want to check single literal like(any single word a,e,w,..etc) in is enough
original_word ="hackerearcth"
for 'h' in original_word:
print("YES")
if you want to check any of the character among the original_word:
make use of
if any(your_required in yourinput for your_required in original_word ):
if you want all the input you want in that original_word,make use of all
simple
original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
print("yes")
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
for fstr in strlist:
if line.find(fstr) != -1:
print('found')
res = True
if res:
print('res true')
else:
print('res false')
I would use this kind of function for speed:
def check_string(string, substring_list):
for substring in substring_list:
if substring in string:
return True
return False
Yet another solution with set. using set.intersection. For a one-liner.
subset = {"some" ,"words"}
text = "some words to be searched here"
if len(subset & set(text.split())) == len(subset):
print("All values present in text")
if subset & set(text.split()):
print("Atleast one values present in text")
If you want exact matches of words then consider word tokenizing the target string. I use the recommended word_tokenize from nltk:
from nltk.tokenize import word_tokenize
Here is the tokenized string from the accepted answer:
a_string = "A string is more than its parts!"
tokens = word_tokenize(a_string)
tokens
Out[46]: ['A', 'string', 'is', 'more', 'than', 'its', 'parts', '!']
The accepted answer gets modified as follows:
matches_1 = ["more", "wholesome", "milk"]
[x in tokens for x in matches_1]
Out[42]: [True, False, False]
As in the accepted answer, the word "more" is still matched. If "mo" becomes a match string, however, the accepted answer still finds a match. That is a behavior I did not want.
matches_2 = ["mo", "wholesome", "milk"]
[x in a_string for x in matches_1]
Out[43]: [True, False, False]
Using word tokenization, "mo" is no longer matched:
[x in tokens for x in matches_2]
Out[44]: [False, False, False]
That is the additional behavior that I wanted. This answer also responds to the duplicate question here.
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']
# for each
for field in mandatory_fields:
if field not in data:
print("Error, missing req field {0}".format(field));
# still fine, multiple if statements
if ('firstName' not in data or
'lastName' not in data or
'age' not in data):
print("Error, missing a req field");
# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
print("Error, missing fields {0}".format(", ".join(missing_fields)));

How to Sort Alphabets

Input : abcdABCD
Output : AaBbCcDd
ms=[]
n = input()
for i in n:
ms.append(i)
ms.sort()
print(ms)
It gives me ABCDabcd.
How to sort this in python?
Without having to import anything, you could probably do something like this:
arr = "abcdeABCDE"
temp = sorted(arr, key = lambda i: (i.lower(), i))
result = "".join(temp)
print(result) # AaBbCcDdEe
The key will take in each element of arr and sort it first by lower-casing it, then if it ties, it will sort it based on its original value. It will group all similar letters together (A with a, B with b) and then put the capital first.
Use a sorting key:
ms = "abcdABCD"
sorted_ms = sorted(ms, key=lambda letter:(letter.upper(), letter.islower()))
# sorted_ms = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd']
sorted_str = ''.join(sorted_ms)
# sorted_str = 'AaBbCcDd'
Why this works:
You can specify the criteria by which to sort by using the key argument in the sorted function, or the list.sort() method - this expects a function or lambda that takes the element in question, and outputs a new criteria by which to sort it. If that "new criteria" is a tuple, then the first element takes precedence - if it's equal, then the second argument, and so on.
So, the lambda I provided here returns a 2-tuple:
(letter.upper(), letter.islower())
letter.upper() as the first element here means that the strings are going to be sorted lexigraphically, but case-insensitively (as it will sort them as if they were all uppercase). Then, I use letter.islower() as the second argument, which is True if the letter was lowercase and False otherwise. When sorting, False comes before True - which means that if you give a capital letter and a lowercase letter, the capital letter will come first.
Try this:
>>>s='abcdABCD'
>>>''.join(sorted(s,key=lambda x:x.lower()))
'aAbBcCdD'

TypeError: 'int' object is not iterable error in python

counter = 0
for i in len(s):
if i in ('a','e','i','o','u'):
counter += 1
print("Number of vowels:" + str(counter))
I'm trying to make a program that counts the number of vowels assuming that s is a string that is predefined. But I'm getting an error:
'int' object is not iterable error in python
I'll make my answer a bit longer than it should be.
If you don't need a numerical representation i of your index for operations within your loop, you just iterate over the string:
for i in s:
do_something()
If you only need a numerical representation i, e.g. you have a 'string', but you need [0,1,2,3,4,5], you can do this:
for i in range(len(s)):
do_something(i)
Let's break it down. s is a str(). len returns the length of an object as an integer value, for example, len('string') = 6. You can't iterate over an integer, because python's for is actually a foreach. So you need an iterable object, which is range(len(s))
If you need both the symbol and the index, you can do this:
for i, symbol in enumerate(s):
do_something(i,symbol)
For example, this snippet of code:
for i, symbol in enumerate('string'):
print(i,symbol)
Will result in:
0 s
1 t
2 r
3 i
4 n
5 g
len() returns type int as length of the string s in your case.
Use for i in s: as #Patrick Artner suggested.
Alternatively you can use
for i in range(len(s)):
curChar=s[i]

Python change first with last element

I want to change the first element of a string with the last element.
def change(string):
for i in range(16):
helper = string[i]
string[i]=string[15-i]
string[15-i]=helper
return string
print (change("abcdefghijklmnop"))
Error Output:
string[i]=helper2[0]
TypeError: 'str' object does not support item assignment
You can't alter a string; they're immutable. You can create a new string that is altered as you want:
def change(string):
return string[-1]+string[1:-1]+string[0]
You can use "*" operator.
my_list = [1,2,3,4,5,6,7,8,9]
a, *middle, b = my_list
my_new_list = [b, *middle, a]
my_list
[1, 2, 3, 4, 5, 6, 7, 8, 9]
my_new_list
[9, 2, 3, 4, 5, 6, 7, 8, 1]
Read here for more information.
As you discovered, strings are immutable so you can index a string (eg string[x]), but you can't assign to an index (eg string[x] = 'z').
If you want to swap the first and last element, you will need to create a new string. For example:
def change(input_str):
return input_str[-1] + input_str[1:-1] + input_str[0]
However, based on your example code, it looks like you trying to swap all the "elements" of the string. If you want to do that, see this previous discussion on different methods of reversing a string: Reverse a string in Python
Additionally, even if you could "index" a string, your code would not work as written. With a minor change to "explode" it into a list:
def change(string):
string = [c for c in string]
for i in range(16):
helper = string[i]
string[i]=string[15-i]
string[15-i]=helper
return string
print (change("abcdefghijklmnop"))
DEMO
As you can see, the output is the "same" as the input (except exploded into a list) because you step through every index in the string, reverse all of them twice (which puts them back in their original position).

Resources