Match Case in python 3.10 - python-3.10

while True:
if row_num == 3: break
rows = board[row_num]
string_of_row_checker = ""
col_num = 0
for cell in rows:
checker = {
"column checker": (list_of_column_checker[col_num] == cell and row_num == 2),
"row checker": (string_of_row_checker == cell and col_num == 2),
"left to right diagonal check": (diagonal_1 == cell and row_num == 2 and col_num == 2),
"right to left diagonal check": (diagonal_2 == cell and row_num == 2 and col_num == 0),
"row number": (row_num),
"column number": (col_num)
}
print(checker["row checker"])
#does print true when col num is and string_of_row_checker
match checker:
case {"row checker": True}:
#this case is never true even when it prints true above
return cell
case {"row number": 0}:
print("pass")
list_of_column_checker[col_num] = cell
if col_num == 0: diagonal_1 = cell
case {"row number": 1}:
if list_of_column_checker[col_num] != cell:
list_of_column_checker[col_num] = ""
if col_num == 1:
if diagonal_1 != cell: diagonal_1 = ""
if diagonal_2 != cell: diagonal_2 = ""
case {"row number": 2}:
if col_num == 0: diagonal_2 = cell
I'm trying to use the new match case statement for checking the winner in a tictactoe game
However, the case statement included above never runs even when "print(checker["row checker"])" prints true
How can I fix this
Thanks in Advance!
I have tried using the bool() function and converting the value stored in checker["row checker"] to string but that didn't work as well
All the other case statements work as they are supposed too except for the first one

Related

How to get an alert once on a trend on a supertrend, in pinescript,with loop or another way?

How to get an alert once on a supertrend trend,I think with while i can solve(but my knowledge is not enough),maybe is another way to solve my problem.
I need to skip the first signal(on down/up trend) and enter the second alert, and this signal alert one time per supertrend trend.
I describe signals below in the code.
//#version=5
indicator("My-Supertrend", overlay=true, timeframe="", timeframe_gaps=true)
atrPeriod = input(13, "ATR Length")
atrPeriod2 = input(21, "ATR Length2")
factor = input.float(3.0, "Factor", step = 0.01)
factor2 = input.float(7.0, "Factor2", step = 0.01)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
[supertrend2, direction2] = ta.supertrend(factor2, atrPeriod2)
//ST 1
bodyMiddle = plot((open + close) / 2, display=display.none)
upTrend = plot(direction < 0 ? supertrend : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=1)
downTrend = plot(direction < 0? na : supertrend, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=1)
//ST 2
bodyMiddle2 = plot((open + close) / 2, display=display.none)
upTrend2 = plot(direction2 < 0 ? supertrend2 : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=3)
downTrend2 = plot(direction2 < 0? na : supertrend2, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=3)
//ST1 color
fill(bodyMiddle, upTrend, color.new(#95bd06, 80), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(#0692bd, 80), fillgaps=false)
//ST2 color
fill(bodyMiddle2, upTrend2, color.new(#5abd13, 70), fillgaps=false)
fill(bodyMiddle2, downTrend2, color.new(#bd3006,70), fillgaps=false)
//Logic
down_upTrend=direction>0 and direction2<0 and direction[1]<0
up_upTrend=direction<0 and direction2<0 and direction[1]>0
up_downTrend=direction<0 and direction2>0 and direction[1]>0
down_downTrend=direction>0 and direction2>0 and direction[1]<0
//For short
while direction2>0
up_downTrend
continue
down_downTrend
break
//For Long
while direction2<0
down_upTrend
continue
up_upTrend
break
plotshape(up_upTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(27, 182, 27))
plotshape(up_downTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(20, 112, 20))
plotshape(down_upTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(255, 0, 0))
plotshape(down_downTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(141, 21, 21))
alertcondition(up_upTrend or down_downTrend,"Long/Short","Signal")
I try to solve with while loop(and i describe my logic in while loop),but while dont work like I think.

PySpark: Convert T-SQL Case When Then statement to PySpark [duplicate]

I have seen this question earlier here and I have took lessons from that. However I am not sure why I am getting an error when I feel it should work.
I want to create a new column in existing Spark DataFrame by some rules. Here is what I wrote. iris_spark is the data frame with a categorical variable iris_spark with three distinct categories.
from pyspark.sql import functions as F
iris_spark_df = iris_spark.withColumn(
"Class",
F.when(iris_spark.iris_class == 'Iris-setosa', 0, F.when(iris_spark.iris_class == 'Iris-versicolor',1)).otherwise(2))
Throws the following error.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-157-21818c7dc060> in <module>()
----> 1 iris_spark_df=iris_spark.withColumn("Class",F.when(iris_spark.iris_class=='Iris-setosa',0,F.when(iris_spark.iris_class=='Iris-versicolor',1)))
TypeError: when() takes exactly 2 arguments (3 given)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-157-21818c7dc060> in <module>()
----> 1 iris_spark_df=iris_spark.withColumn("Class",F.when(iris_spark.iris_class=='Iris-setosa',0,F.when(iris_spark.iris_class=='Iris-versicolor',1)))
TypeError: when() takes exactly 2 arguments (3 given)
Any idea why?
Correct structure is either:
(when(col("iris_class") == 'Iris-setosa', 0)
.when(col("iris_class") == 'Iris-versicolor', 1)
.otherwise(2))
which is equivalent to
CASE
WHEN (iris_class = 'Iris-setosa') THEN 0
WHEN (iris_class = 'Iris-versicolor') THEN 1
ELSE 2
END
or:
(when(col("iris_class") == 'Iris-setosa', 0)
.otherwise(when(col("iris_class") == 'Iris-versicolor', 1)
.otherwise(2)))
which is equivalent to:
CASE WHEN (iris_class = 'Iris-setosa') THEN 0
ELSE CASE WHEN (iris_class = 'Iris-versicolor') THEN 1
ELSE 2
END
END
with general syntax:
when(condition, value).when(...)
or
when(condition, value).otherwise(...)
You probably mixed up things with Hive IF conditional:
IF(condition, if-true, if-false)
which can be used only in raw SQL with Hive support.
Conditional statement In Spark
Using “when otherwise” on DataFrame
Using “case when” on DataFrame
Using && and || operator
import org.apache.spark.sql.functions.{when, _}
import spark.sqlContext.implicits._
val spark: SparkSession = SparkSession.builder().master("local[1]").appName("SparkByExamples.com").getOrCreate()
val data = List(("James ","","Smith","36636","M",60000),
("Michael ","Rose","","40288","M",70000),
("Robert ","","Williams","42114","",400000),
("Maria ","Anne","Jones","39192","F",500000),
("Jen","Mary","Brown","","F",0))
val cols = Seq("first_name","middle_name","last_name","dob","gender","salary")
val df = spark.createDataFrame(data).toDF(cols:_*)
1. Using “when otherwise” on DataFrame
Replace the value of gender with new value
val df1 = df.withColumn("new_gender", when(col("gender") === "M","Male")
.when(col("gender") === "F","Female")
.otherwise("Unknown"))
val df2 = df.select(col("*"), when(col("gender") === "M","Male")
.when(col("gender") === "F","Female")
.otherwise("Unknown").alias("new_gender"))
2. Using “case when” on DataFrame
val df3 = df.withColumn("new_gender",
expr("case when gender = 'M' then 'Male' " +
"when gender = 'F' then 'Female' " +
"else 'Unknown' end"))
Alternatively,
val df4 = df.select(col("*"),
expr("case when gender = 'M' then 'Male' " +
"when gender = 'F' then 'Female' " +
"else 'Unknown' end").alias("new_gender"))
3. Using && and || operator
val dataDF = Seq(
(66, "a", "4"), (67, "a", "0"), (70, "b", "4"), (71, "d", "4"
)).toDF("id", "code", "amt")
dataDF.withColumn("new_column",
when(col("code") === "a" || col("code") === "d", "A")
.when(col("code") === "b" && col("amt") === "4", "B")
.otherwise("A1"))
.show()
Output:
+---+----+---+----------+
| id|code|amt|new_column|
+---+----+---+----------+
| 66| a| 4| A|
| 67| a| 0| A|
| 70| b| 4| B|
| 71| d| 4| A|
+---+----+---+----------+
There are different ways you can achieve if-then-else.
Using when function in DataFrame API.
You can specify the list of conditions in when and also can specify otherwise what value you need. You can use this expression in nested form as well.
expr function.
Using "expr" function you can pass SQL expression in expr. PFB example. Here we are creating new column "quarter" based on month column.
cond = """case when month > 9 then 'Q4'
else case when month > 6 then 'Q3'
else case when month > 3 then 'Q2'
else case when month > 0 then 'Q1'
end
end
end
end as quarter"""
newdf = df.withColumn("quarter", expr(cond))
selectExpr function.
We can also use the variant of select function which can take SQL expression. PFB example.
cond = """case when month > 9 then 'Q4'
else case when month > 6 then 'Q3'
else case when month > 3 then 'Q2'
else case when month > 0 then 'Q1'
end
end
end
end as quarter"""
newdf = df.selectExpr("*", cond)
you can use this:
if(exp1, exp2, exp3) inside spark.sql()
where exp1 is condition and if true give me exp2, else give me exp3.
now the funny thing with nested if-else is. you need to pass every exp inside
brackets {"()"}
else it will raise error.
example:
if((1>2), (if (2>3), True, False), (False))

google apps script refactor repetitive code

What's a smarter way of doing this? Code works fine but is klunky.
function removeEmptyPending(){
for(var row=2;row<=lastRow;row++){
if( (tkhContact.getRange('A'+row+':A'+row).getValue() == "") &&
(tkhContact.getRange('C'+row+':C'+row).getValue() == "") &&
(tkhContact.getRange('D'+row+':D'+row).getValue() == "") &&
(tkhContact.getRange('E'+row+':E'+row).getValue() == "") &&
(tkhContact.getRange('F'+row+':F'+row).getValue() == "") &&
(tkhContact.getRange('G'+row+':G'+row).getValue() == "") &&
(tkhContact.getRange('H'+row+':H'+row).getValue() == "") &&
(tkhContact.getRange('I'+row+':I'+row).getValue() == "") &&
(tkhContact.getRange('J'+row+':J'+row).getValue() == "") &&
(tkhContact.getRange('K'+row+':K'+row).getValue() == "") &&
(tkhContact.getRange('L'+row+':L'+row).getValue() == "") &&
(tkhContact.getRange('M'+row+':M'+row).getValue() == "") &&
(tkhContact.getRange('N'+row+':N'+row).getValue() == "") &&
(tkhContact.getRange('O'+row+':O'+row).getValue() == "") &&
(tkhContact.getRange('P'+row+':P'+row).getValue() == "") &&
(tkhContact.getRange('Q'+row+':Q'+row).getValue() == "") )
{
tkhContact.deleteRow(row); // tkhContact.getRange('R'+row+':R'+row).setValue("");
}
}
}
I need to skip column B since there is a formula there so it's never really blank.
Use #is_Blank()
function removeEmptyPending(){
for(var row=lastRow;row>=2;row--){
if( (tkhContact.getRange('A'+row+':A'+row).isBlank()) &&
(tkhContact.getRange('C'+row+':Q'+row).isBlank()) &&
){
tkhContact.deleteRow(row); //tkhContact.getRange('R'+row+':R'+row).setValue("");
}
}
}
This code gets all the data from row 2 to the last row, including columns A through Q. And then goes through the data. So, it gets all the data in one operation. The rows need to be deleted individually, and they must be deleted from the bottom up. That means that the outer "for" loop must decrement the counter. If you start deleting from the top down, then the row numbers from the last row deleted, change their row number.
function removeEmptyPending() {
var data,i,j,L,L2,lastRow,row,thisRow,thisValue;
data = tkhContact.getRange(2,1,lastRow-1,17).getValues();//Get all the data from row 2 to the last row
//including column A to column Q
L = data.length;//The number of inner arrays in the outer array
for (i=L;i>0,i--){//Loop through all the rows from last to row 2
thisRow = data[i];//Get one inner array which is one row of data
L2 = thisRow.length;
for (j=0;j<L2,j++){//Loop through each element of the inner array which is the column value
if (j === 1) {continue;} //Skip the second element which is column B
thisValue = thisRow[j];//The value for this column
if (thisValue) {continue;}//The value for this cell is not undefined null or empty string so continue
tkhContact.deleteRow(i+2); // tkhContact.getRange('R'+row+':R'+row).setValue("");
}
}
}

how to return a data frame after subsetting its columns with NAs removed

I'm working on a problem from coursera and seem to get lost at the end where I have to extract both selected columns and return a data frame, there is a link to a similar problem at (Empty rows in list as NA values in data.frame in R)
rankall <- function(outcome, num = 'best'){
data<- read.csv('outcome-of-care-measures.csv', colClasses = 'character')
if(!outcome %in% c('heart attack', 'heart failure', 'penumonia')){
stop('invalid outcome')
}
states <- sort(unique(state))
for (i in 1:length(state)){
statedata <- data[data$State == state[i], ]
if(outcome == 'heart attack'){
index <- as.numeric(statedata[,11])
} else if(outcome == 'heart failure'){
index <- as.numeric(statedata[,17])
} else if(outcome == 'pneumonia'){
index <- as.numeric(statedata[,23])
}
#sort by mortality rate and hospital name
sorteddata <- data[order(data[,index],data$Hospital.Name, na.rm = TRUE)]
#rank by state
staterank <- function(state){
hospital_state <- subset(sorteddata, State == state)
}
#choose rows at each num value, this where I get stuck
if(!is.numeric(num)){
if(num == 'best'){
num <- 1}
else if(num == 'worst'){
num <- length(hospital_state)}
}
hospital_state[num]
}

Calendar buttons aren't being removed correctly - Lua

I'm trying to make a calendar to be able to switch from month to month. My problem is in removing each day button when the next or previous buttons are touched.
Here is my code for the Previous Button to switch from the current month to the previous month. My Next button code is almost exactly the same. It works perfectly fine when I tap the button for the first time, but when I tap it again, I get an error at the child:removeSelf() line, and the print message tells me there are 61 elements in the table. It seems to add extra buttons to the table every time I go to a month that hasn't been seen yet.
This is really frustrating to me because I don't see any reason why the code is making extra buttons for every month, and even if it does, each one should still get removed when the button is tapped. Can someone please help me?
local prev_function = function(event)
if event.phase == "release" then
today.year = 2012
today.month = 3
today.day = 29
today.wday = 5
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
local month = ""
if monthNum == 1 then month = "January"
elseif monthNum == 2 then month = "February"
elseif monthNum == 3 then month = "March"
elseif monthNum == 4 then month = "April"
elseif monthNum == 5 then month = "May"
elseif monthNum == 6 then month = "June"
elseif monthNum == 7 then month = "July"
elseif monthNum == 8 then month = "August"
elseif monthNum == 9 then month = "September"
elseif monthNum == 10 then month = "October"
elseif monthNum == 11 then month = "November"
elseif monthNum == 12 then month = "December"
end
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
for i = #buttonTable, 1, -1 do
--[[if button[i] ~= nil then
table.remove(buttonTable)
button[i]:removeSelf()
button[i] = nil
end--]]
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today) --calculate the next day's date
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then -- create a button if the date's year and month match the desired month
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
if dateTable[i].wday == 1 then button[i].x = math.floor(col/2)
elseif dateTable[i].wday == 2 then button[i].x = (col * 1) + math.floor(col/2)
elseif dateTable[i].wday == 3 then button[i].x = (col * 2) + math.floor(col/2)
elseif dateTable[i].wday == 4 then button[i].x = (col * 3) + math.floor(col/2)
elseif dateTable[i].wday == 5 then button[i].x = (col * 4) + math.floor(col/2)
elseif dateTable[i].wday == 6 then button[i].x = (col * 5) + math.floor(col/2)
elseif dateTable[i].wday == 7 then button[i].x = (col * 6) + math.floor(col/2)
end
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
end
today = dateTable[i]
table.insert(buttonTable, button[i])
--button[i].id = "button_" .. i
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end
The reason why the code in the question doesn't work (and putting the table.insert inside the if...then does work) is due to the way you're using the button table.
The loop that starts for i = 1, math.floor(numYears * 365.25) do is going to create indices from 1 to a few hundred/thousand (depending on numYears).
However, as you're using button[i]= for filling the table and you're only filling 30 or so at a time, what you're creating is a sparse table with a few non-nil entries somewhere in the middle of the table.
Now with table.insert(buttonTable, button[i]) outside the if..then what actually happens is that most of the "inserts" are inserting nil. First time around this actually works ok for 2 reasons:
inserting nil on an empty table does nothing nor does inserting nil at the end of a table
there are only a month's worth of non-nil entries in button so only a month's worth will be inserted into buttonTable
With button and buttonTable setup like this, the first part of the call to the previous or next functions works as expected and removeSelf will be called on the month's worth of buttons. However this doesn't actually remove the button from the button table.
So when you come to the numYears loop again, not only will you add your freshly created buttons to both button and buttonTable, you'll also still have the buttons that you've just called removeSelf on in button so these will be added to buttonTable again. Crucially though, they are just tables now, so when you call removeSelf on them the second time it barfs. I presume this is the cause of the error you saw.
Moving table.insert(buttonTable, button[i]) to the if...then will resolve this problem as it will only ever add freshly minted buttons to buttonTable that are then removed each time next or previous are called.
A word of caution though. The button table is a bit of a mess. After a bit of navigating around, it'll have a bunch of dead buttons (that can't be garbage collected unless you've declared the values as weak) plus a month of working buttons. If you were to try to do anything with it, the chances are that you'll get problems.
It's not clear from the code if you even need the button table. If it's not required elsewhere it would probably be safer to just hold the button references in buttonTable.
Aside from making a new table for months as well as column coordinates like Nicol suggested, I found that I needed to put the table.insert() command inside the if ... then structure. I'm not sure exactly why putting it immediately after the if ... then structure caused it to not work properly, but I'm guessing it's because the buttons are being created inside the structure.
local prev_function = function(event)
if event.phase == "release" then
--set date to start from
today.year = 2012
today.month = 2
today.day = 29
today.wday = 4
--determine new month number
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
--set month string
local month = monthTable[monthNum]
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
--remove all elements in buttonTable
for i = #buttonTable, 1, -1 do
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
--hide prev_button if we get to the month after the month we started from
if monthNum == today.month + 1 and yearNum == today.year then
prev_button.alpha = 0
end
--generate dates for specified number of years
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today)
--create a button for each date inside desired month
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
--set x and y
button[i].x = colTable[dateTable[i].wday]
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
table.insert(buttonTable, button[i])
end
--change 'today' for next iteration in the for loop
today = dateTable[i]
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end

Resources