This seems to be a pretty common pattern:
for row in reader:
c1=row[0]
if ids.has_key(c1):
id1=ids.get(c1)
else:
currid+=1
id1=currid
ids[c1]=currid
I want to know if there is a better way to achieve this. As far as single line if statements go, I could do this much:
id1=ids.get(c1) if ids.has_key(c1) else currid+1
But then I'm stuck with incrementing currid and sticking if the else case was executed and sticking c->id1 into the dictionary if the if condition passed.
If the ids start from 0:
for row in reader:
id1 = ids.setdefault(row[0], len(ids))
(Aside: has_key is considered deprecated. Use x in d instead of d.has_key(x).)
If you don't mind changing how ids is defined, then you could go with this (all in the standard library):
ids = collections.defaultdict (itertools.count ().next)
Usage is then very simple:
print (ids["lol"])
currid += c1 not in ids
id1 = ids.setdefault(c1, currid)
Use this instead:
id1 = ids.get(cl, currid + 1)
A bit more pythonyc, with the same semantics:
for row in reader:
c1 = row[0]
if c1 not in ids:
currid += 1
ids[c1] = currid
id1 = ids[c1]
Related
I want to check and filter only if the table has value1 = 005 and value1 = 009. But it seems below query is not helping me. I dont know where I am making mistakes. Kindly help to solve this. Note - I cannot use where not as it may have many different value stored in value1 field
DEFINE TEMP-TABLE test NO-UNDO
FIELD value1 AS CHARACTER
.
EMPTY TEMP-TABLE test.
CREATE test.
ASSIGN
value1 = "005".
CREATE test.
ASSIGN
value1 = "009".
CREATE test.
ASSIGN
value1 = "001".
FOR EACH test NO-LOCK
WHERE value1 <> ""
AND (value1 = "005" AND value1 = "009")
:
MESSAGE YES.
END.
You can use can-find
if can-find(first test WHERE value1 = "005")
AND can-find(first test WHERE value1 = "009")
then message yes.
It is safest to always use can-find(first if you're looking for a non-unique value
It looks like you're looking for an OR ooperation, rather than AND.
If you want to check if both records are present you could do :
DEFINE VARIABLE isPresent005 AS LOGICAL NO-UNDO.
DEFINE VARIABLE isPresent009 AS LOGICAL NO-UNDO.
DEFINE VARIABLE bothPresents AS LOGICAL NO-UNDO.
FIND FIRST test WHERE test.value1 = "005" NO-LOCK NO-ERROR.
isPresent005 = AVAIL test.
FIND FIRST test WHERE test.value1 = "009" NO-LOCK NO-ERROR.
isPresent009 = AVAIL test.
bothPresents = isPresent005 AND isPresent009.
But, if you only want to get these 2 records, you should use OR :
FOR EACH test WHERE test.value1 = "005" OR test.value1 = "009" NO-LOCK :
/*do stuff*/
END.
Another option if you are, maybe, looking for some additional fields might look something like this:
define buffer test005 for test.
define buffer test009 for test.
for each test005 no-lock where test005.customer = 1 and test005.value1 = "005",
each test009 no-lock where test009.customer = 1 and test009.value1 = "009":
display test005.customer.
end.
Use OR instead of AND to search the records...
This will return records if value1 = 005 OR value1 = 009.
FOR EACH test NO-LOCK
WHERE value1 <> ""
AND (value1 = "005" OR value1 = "009")
:
MESSAGE YES.
END.
Is not possible to search using your way, because value1 cannot be two values at once, it's always one OR another.
Here is an example:
`
<bracketQualifier>
<bracketSequenceNumber>1</bracketSequenceNumber>
</bracketQualifier>
<bracketQualifier>
<bracketSequenceNumber>1</bracketSequenceNumber>
</bracketQualifier>
<bracketQualifier>
<bracketSequenceNumber>1</bracketSequenceNumber>
</bracketQualifier>
`
What i need to do is if bracketSequenceNumber holds the same value trow an exception.
Number of elements is N there can be more than 3. How can i achieve this using xquery.
I tried something like this without success and i cant say i understand xQuery completley:
`
let $count := ( for $bracketSequenceNumber in $bracketQualifier/bracketSequenceNumber return count(bracketQualifier[#bracketSequenceNumber = $bracketSequenceNumber ])) return
if($GDSN_PriceSyncPriceSegmentTM/value ='250' and $count >= 1) then something
`
You can use
if (count(//bracketSequenceNumber)
!= count(distinct-values(//bracketSequenceNumber) then ...
If you actually want to find the duplicates, use group by in XQuery 3.1 to process each group of equal values and test whether the group size is 2 or more.
I have a query in following format, used to perform COALESCE as well as define a new column using CASE statement.
SELECT ....
COALESCE(mm1,'missing') AS mm1,
COALESCE(mm2,'missing') AS mm2,
CASE WHEN mm1='false' AND mm2='false' THEN 'No-Proxy'
WHEN mm1 IN ('false','missing') AND mm2='true' THEN 'Good-Proxy'
WHEN mm1 ='true' AND mm2 IN ('false','missing') THEN 'Bad-Proxy'
WHEN ((mm1='true' AND mm2='true') OR (mm1='missing' AND mm2='missing')
OR (mm1='false' AND mm2='missing') OR (mm1='missing' AND mm2='false')) THEN 'Unknown'
END AS Proxy_Type,
As seen above when both mm1 and mm2 are originally NULL, we need to put value as Unknown for Proxy_Type. But when we run the query, we get unexpected output. Plz see screenshot.
Kindly advise on how to fix it.
It seems that "inline/lateral column aliasing" does not allow to "override" column at the same level:
CREATE OR REPLACE TABLE t
AS SELECT NULL AS mm1, NULL AS mm2;
Option 1: Using different column alias
SELECT
COALESCE(mm1,'missing') AS mm1_,
COALESCE(mm2,'missing') AS mm2_,
CASE WHEN mm1_='false' AND mm2_='false' THEN 'No-Proxy'
WHEN mm1_ IN ('false','missing') AND mm2_='true' THEN 'Good-Proxy'
WHEN mm1_ ='true' AND mm2_ IN ('false','missing') THEN 'Bad-Proxy'
WHEN ((mm1_='true' AND mm2_='true') OR (mm1_='missing' AND mm2_='missing')
OR (mm1_='false' AND mm2_='missing')
OR (mm1_='missing' AND mm2_='false')) THEN 'Unknown'
END AS Proxy_Type
FROM t;
-- MM1_ MM2_ PROXY_TYPE
--missing missing Unknown
Option 2: LATERAL JOIN and prefixing with subquery alias:
SELECT -- t.mm1, t.mm2,
s.mm1, s.mm2,
CASE WHEN s.mm1='false' AND s.mm2='false' THEN 'No-Proxy'
WHEN s.mm1 IN ('false','missing') AND s.mm2='true' THEN 'Good-Proxy'
WHEN s.mm1 ='true' AND s.mm2 IN ('false','missing') THEN 'Bad-Proxy'
WHEN ((s.mm1='true' AND s.mm2='true') OR (s.mm1='missing' AND s.mm2='missing')
OR (s.mm1='false' AND s.mm2='missing')
OR (s.mm1='missing' AND s.mm2='false')) THEN 'Unknown'
END AS Proxy_Type
FROM t,
LATERAL(SELECT COALESCE(t.mm1,'missing') AS mm1,COALESCE(t.mm2,'missing') AS mm2) s;
-- MM1 MM2 PROXY_TYPE
--missing missing Unknown
The ideal situation would be if we had additional keyword to distinguish between original column and calculated expression, kind of SAS - calculated.
SELECT
col,
col+10 AS col,
col,
calculated col
FROM t;
-- output
t.col/expression/t.col/expression
I’m guessing you are trying to use the re-defined values of mm1/mm2 in your case statement? If so then SQL doesn’t work like that, values don’t change within the same select statement so m1/m2 will have their starting values wherever they are referenced in the select statement.
One way round this is to use something like this:
COALESCE(mm1,'missing') AS mm1,
COALESCE(mm2,'missing') AS mm2,
CASE WHEN COALESCE(mm1,'missing') ='false' …
I am trying to count the characters without the spaces.
Here is my code:
word = 'Ricardo Cadenas'
def string_lenght(word):
count = 0
for char in word:
count = count + 1
return count - word.count('')
print(string_lenght(word))
my out put is-1 ??? any ideas?
You have a typo. I think you meant to put word.count(' ') but you put word.count('') (no space.)
Also instead of looping to calculate count, you can initialize count = len(word).
Correct, changing “” to “ “ should do the trick!
I am just starting to work with openedge and I need to join information from two tables but I just need the first row from the second one.
Basically I need to do a typical SQL Cross Apply but in progress. I look in the documentation and the Statement FETCH FIRST 10 ROWS ONLY only in OpenEdge 11.
My query is:
SELECT * FROM la_of PUB.la_ofart ON la_of.empr_cod = la_ofart.empr_cod
AND la_of.Cod_Ordf = la_ofart.Cod_Ordf
AND la_of.Num_ordex = la_ofart.Num_ordex AND la_of.Num_partida = la_ofart.Num_partida
CROSS APPLY (
SELECT TOP 1 ofart.Cod_Ordf AS Cod_Ordf_ofart ,
ofart.Num_ordex AS Num_ordex_ofart
FROM la_ofart AS ofart
WHERE ofart.empr_cod = la_ofart.empr_cod
AND ofart.Num_partida = la_ofart.Num_partida
AND la_ofart.doc1_num = ofart.doc1_num
AND la_ofart.doc2_linha = ofart.doc2_linha
ORDER BY ofart.Cod_Ordf DESC) ofart
I am using SSMS to extract data from OE10 using an ODBC connector and querying to OE using OpenQuery.
Thanks for all help.
If I correctly understood your question, maybe you can use something like this. Maybe this isn't the best solution for your problem, but may suit your needs.
DEF BUFFER ofart FOR la_ofart.
DEF TEMP-TABLE tt-ofart NO-UNDO LIKE ofart
FIELD seq AS INT
INDEX ch-seq
seq.
DEF VAR i-count AS INT NO-UNDO.
EMPTY TEMP-TABLE tt-ofart.
blk:
FOR EACH la_ofart NO-LOCK,
EACH la_of NO-LOCK
WHERE la_of.empr_cod = la_ofart.empr_cod
AND la_of.Cod_Ordf = la_ofart.Cod_Ordf
AND la_of.Num_ordex = la_ofart.Num_ordex
AND la_of.Num_partida = la_ofart.Num_partida,
EACH ofart NO-LOCK
WHERE ofart.empr_cod = la_ofart.empr_cod
AND ofart.Num_partida = la_ofart.Num_partida
AND ofart.doc1_num = la_ofart.doc1_num
AND ofart.doc2_linha = la_ofart.doc2_linha
BREAK BY ofart.Cod_Ordf DESCENDING:
ASSIGN i-count = i-count + 1.
CREATE tt-ofart.
BUFFER-COPY ofart TO tt-ofart
ASSIGN ofart.seq = i-count.
IF i-count >= 10 THEN
LEAVE blk.
END.
FOR EACH tt-ofart USE-INDEX seq:
DISP tt-ofart WITH SCROLLABLE 1 COL 1 DOWN NO-ERROR.
END.