Is the following empty slice the same as a null pointer?
slice = Slice(UInt8).empty
slice.size # => 0
The source code of #empty implies a null pointer (address 0 and size 0):
def self.empty
new(Pointer(T).null, 0)
end
This is an application of the Null-Object pattern:
The empty slice can be used in all places that take a reqular slice, without requiring explicit Nil-Checks.
A similar example would be returning an empty string on nil or having a GuestUser that has the same properties as a regular User.
Related
I am trying to return a list/array of values from a range of (100..1000) that match the following criteria:
3 digit value
All the digits in each value are unique.
$global_range = Array (100..999)
$fun = []
def listOfFunPossibilities
# FUN values should meet the criteria below:
# 1. 3 digit value
# 2. All are unique
$global_range.each do |i|
if (!(/([0-9]).*?\1/)).match?(i)
$fun.push(i)
end
end
return $fun
end
listOfFunPossibilities()
You apply negation ! too early:
if (!(/([0-9]).*?\1/)).match?(i)
so you first negate a regex (that is true for some reason) and then you try to call match on true value
Use instead:
if !(/([0-9]).*?\1/.match?(i))
or even
if !/([0-9]).*?\1/.match?(i)
For two given strings, is there a pythonic way to count how many consecutive characters of both strings (starting at postion 0 of the strings) are identical?
For example in aaa_Hello and aa_World the "leading matching characters" are aa, having a length of 2. In another and example there are no leading matching characters, which would give a length of 0.
I have written a function to achive this, which uses a for loop and thus seems very unpythonic to me:
def matchlen(string0, string1): # Note: does not work if a string is ''
for counter in range(min(len(string0), len(string1))):
# run until there is a mismatch between the characters in the strings
if string0[counter] != string1[counter]:
# in this case the function terminates
return(counter)
return(counter+1)
matchlen(string0='aaa_Hello', string1='aa_World') # returns 2
matchlen(string0='another', string1='example') # returns 0
You could use zip and enumerate:
def matchlen(str1, str2):
i = -1 # needed if you don't enter the loop (an empty string)
for i, (char1, char2) in enumerate(zip(str1, str2)):
if char1 != char2:
return i
return i+1
An unexpected function in os.path, commonprefix, can help (because it is not limited to file paths, any strings work). It can also take in more than 2 input strings.
Return the longest path prefix (taken character-by-character) that is a prefix of all paths in list. If list is empty, return the empty string ('').
from os.path import commonprefix
print(len(commonprefix(["aaa_Hello","aa_World"])))
output:
2
from itertools import takewhile
common_prefix_length = sum(
1 for _ in takewhile(lambda x: x[0]==x[1], zip(string0, string1)))
zip will pair up letters from the two strings; takewhile will yield them as long as they're equal; and sum will see how many there are.
As bobble bubble says, this indeed does exactly the same thing as your loopy thing. Its sole pro (and also its sole con) is that it is a one-liner. Take it as you will.
I'm attempting to replace the null elements of a Scala list with an empty value using map. I currently have:
val arr = Seq("A:B|C", "C:B|C", null)
val arr2 = arr.map(_.replaceAll(null, "") )
This gives me a NullPointerExpection. What is the best way to do this?
You're trying to replace a null character in a string instead of replacing a null string in Seq. So here is a correct way:
val arr2 = arr.map(str => Option(str).getOrElse(""))
The Option here will produce Some(<your string>) if the value is not null and None otherwise. getOrElse will return your string if it's not null or empty string otherwise.
I am trying to filter out rows of a text file whose second column value begins with words from a list.
I have the list such as:
val mylist = ["Inter", "Intra"]
If I have a row like:
Cricket Inter-house
Inter is in the list, so that row should get filtered out by the RDD.filter operation. I am using the following regex:
`[A-Za-z0-9]+`
I tried using """[A-Za-z0-9]+""".r to extract the substring but the result is in a non empty iterator.
My question is how to access the above result in the filter operation?
You need to construct regular expression like ".* Inter.*".r since """[A-Za-z0-9]+""" matches any word. Here is some working example, hope it helps:
val mylist = List("Inter", "Intra")
val textRdd = sc.parallelize(List("Cricket Inter-house", "Cricket Int-house",
"AAA BBB", "Cricket Intra-house"))
// map over my list to dynamically construct regular expressions and check if it is within
// the text and use reduce to make sure none of the pattern exists in the text, you have to
// call collect() to see the result or take(5) if you just want to see the first five results.
(textRdd.filter(text => mylist.map(word => !(".* " + word + ".*").r
.pattern.matcher(text).matches).reduce(_&&_)).collect())
// res1: Array[String] = Array(Cricket Int-house, AAA BBB)
filter will remove anything for which the function passed to the filter method returns true. Thus, Regex isn't exactly what you want. Instead, let's develop a function that takes a row and compares it against a candidate string and returns true if the second column in that row starts with the candidate:
val filterFunction: (String, String) => Boolean =
(row, candidate) => row.split(" ").tail.head.startsWith(candidate)
We can convince ourselves that this works pretty easily using a worksheet:
// Test data
val mylist = List("Inter", "Intra")
val file = List("Cricket Inter-house", "Boom Shakalaka")
filterFunction("Cricket Inter-house", "Inter") // true
filterFunction("Cricket Inter-house", "Intra") // false
filterFunction("Boom Shakalaka", "Inter") // false
filterFunction("Boom Shakalaka", "Intra") // false
Now all that remains is to utilize this function in the filter. Essentially, for every row, we want to test the filter against every line in our candidate list. That means taking the candidate list and 'folding left' to check every item on it against the function. If any candidate reports true, then we know that row should be filtered out of the final result:
val result = file.filter((row: String) => {
!mylist.foldLeft(false)((x: Boolean, candidate: String) => {
x || filterFunction(row, candidate)
})
})
// result: List[String] = List(Boom Shakalaka)
The above can be a little dense to unpack. We are passing to the filter method a function that takes in a row and produces a boolean value. We want that value to be true if and only if the row does not match our criteria. We've already embedded our criteria in the filterFunction: we just need to run it against every combination of item in mylist.
To do this we use foldLeft, which takes a starting value (in this case false) and iteratively moves through the list, updating that starting value and returning the final result.
To 'update' that value we write a function that logically-ORs the starting value with the result of running our filter function against the row and the current item in mylist.
I am learning python for beginners. I would like to convert column values from unicode time ('1383260400000') to timestamp (1970-01-01 00:00:01enter code here). I have read and tried the following but its giving me an error.
ti=datetime.datetime.utcfromtimestamp(int(arr[1]).strftime('%Y-%m-%d %H:%M:%S');
Its saying invalid syntax. I read and tried a few other stuffs but I can not come right.. Any suggestion?
And another one, in the same file I have some empty cells that I would like to replace with 0, I tried this too and its giving me invalid syntax:
smsin=arr[3];
if arr[3]='' :
smsin='0';
Please help. Thank you alot.
You seem to have forgotten a closing bracket after (arr[1]).
import datetime
arr = ['23423423', '1163838603', '1263838603', '1463838603']
ti = datetime.datetime.utcfromtimestamp(int(arr[1])).strftime('%Y-%m-%d %H:%M:%S')
print(ti)
# => 2006-11-18 08:30:03
To replace empty strings with '0's in your list you could do:
arr = ['123', '456', '', '789', '']
arr = [x if x else '0' for x in arr]
print(arr)
# => ['123', '456', '0', '789', '0']
Note that the latter only works correctly since the empty string '' is the only string with a truth value of False. If you had other data types within arr (e.g. 0, 0L, 0.0, (), [], ...) and only wanted to replace the empty strings you would have to do:
arr = [x if x != '' else '0' for x in arr]
More efficient yet would be to modify arr in place instead of recreating the whole list.
for index, item in enumerate(arr):
if item = '':
arr[index] = '0'
But if that is not an issue (e.g. your list is not too large) I would prefer the former (more readable) way.
Also you don't need to put ;s at the end of your code lines as Python does not require them to terminate statements. They can be used to delimit statements if you wish to put multiple statements on the same line but that is not the case in your code.