In the official swift document it says
"The print(_:separator:terminator:) function is a global function that prints one or more values to an appropriate output."
var welcomeMessage = "Hello"
var friendlyWelcom = "Hello!"
print(friendlyWelcom, separator: ",", terminator: "", welcomeMessage, separator: ",", terminator: "") // Why this is not working
Question As the comments inside the code - why do print(friendlyWelcom, welcomeMessage) and print(friendlyWelcom, separator: ",", terminator: "" work but print(friendlyWelcom, separator: ",", terminator: "", welcomeMessage, separator: ",", terminator: "") generates a compiler error?
You cannot simply add named parameters as you wish. Instead you should pass the variables to print in comma seperated as the first argument. They then get joined with the separator in between and the terminator at the end:
print(friendlyWelcom, welcomeMessage, separator: " - ", terminator: "?")
Outputs
Hello! - Hello?
You can add as many variables there as you wish:
print(friendlyWelcom, welcomeMessage, 123, "somethingElse", "etc", separator: " - ", terminator: "!!!!")
Hello! - Hello - 123 - somethingElse - etc!!!!
Related
I'm using the following awk command to replace strings in a swift source file:
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Trying not to edit commented out values. At a minimum, need to ignore lines that start with "//" but it seems possible to ignore inline comments (e.g. when the line is only partially commented like "MATCH // <- Ok" or "foo // MATCH <- Not Ok").
Something like...
s=index($0,old) && !($0 =~ "^//") { ... }
Sample Input:
old="\"Some \(value) with %# special \n characters\""
new="\"some_key\".localized"
file {contents}...
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "Some \(value) with %# special \n characters" // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters"
Expected Output:
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "some_key".localized // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters"
EDIT
Although #RavinderSingh13's answer did not match expected output, it was close and I used it to modify my command like so:
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
s=index($0,old) { if (!(match($0,/.*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }' "$old" "$new" "$file"
This meets the original requirement, but ignores ANY line that has two slashes. This is problematic, because it doesn't support in line comments (e.g. the above command would not edit any of the sample input; unless the "// <-- This should change" comment is removed. If no one replies, I'll use this as the answer, but I'll wait a day or so in case someone posts a version of the command that meets all the requirements. Will accept that answer.
It would be something like this...
s=index($0,old) { if (!(match($0,/.*\/\//)) || (match($0,/"$old".*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }
Considering that you want skip all lines which start from // and also you want to print contents which comes before // for in between inline comments. Fair warning not tested since NO samples given.
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
/^\/\//{ next }
match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Above will neglect lines which are starting with // if you want to print them then do following.
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
/^\/\//{ print; next }
match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" "$file" > ./temp
Only look for "old" in the part of each line before the start of any comment, e.g.:
awk '
BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
{ preCmt = $0; sub("//.*","", preCmt) }
s=index(preCmt,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }
' "$old" "$new" file
/// - Returns: "Some \(value) with %# special \n characters"
static let someValue = "some_key".localized // <-- This should change
static let otherValue = "This line does NOT change" // "Some \(value) with %# special \n characters
I have working on a project that handles xml responses. After a search I found a library on github drmohundro/SWXMLHash that works inspired on the "Swifty JSON". After a while using it, I have realised that I can't get values with escaping values.
The xml response looks like
let xmlResponseString = "<TrackList><Entry><Id>2</Id><Uri>/Input/E21u</Uri><Metadata><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"><item id="E21"><dc:title>Doing It To Death</dc:title><upnp:album>Ash & Ice</upnp:album><upnp:artist>The Kills</upnp:artist><upnp:class>object.item.audioItem.musicTrack</upnp:class><upnp:albumArtURI>http://192.168.1.106:8088/storage/emulated/0/record_cache/album_art/1535461905688.jpg</upnp:albumArtURI><res sampleFrequency="96000" bitsPerSample="24" bitrate="2304000" nrAudioChannels="2" protocolInfo="http-get:*:audio/mpeg" duration="00:04:07.431">/Input/E21</res></item></DIDL-Lite></Metadata></Entry></TrackList>"
In the response the album name is equal to "Ash & Ice". However the value returned is "Ash "
That is how I get the value:
let xmlHash = SWXMLHash.parse(xmlResponseString)
albumName = xmlHash["DIDL-Lite"]["item"]["upnp:album"].element?.text
Furthermore, inspecting "xmlHash" it looks like the error already comes from "SWXMLHash.parse(xmlResponseString)".
Does the "xmlResponseString" need to be escaped?
Is it something that the library doesn't handle properly?
Any alternative?
Thank you
EDIT
The response comes from another OpenHome provider device.
The original response is:
<TrackList>
<Entry>
<Id>2</Id>
<Uri>/Input/E21u</Uri>
<Metadata><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"><item id="E21"><dc:title>Doing It To Death</dc:title><upnp:album>Ash & Ice</upnp:album><upnp:artist>The Kills</upnp:artist><upnp:class>object.item.audioItem.musicTrack</upnp:class><upnp:albumArtURI>http://192.168.1.106:8088/storage/emulated/0/record_cache/album_art/1535461905688.jpg</upnp:albumArtURI><res sampleFrequency="96000" bitsPerSample="24" bitrate="2304000" nrAudioChannels="2" protocolInfo="http-get:*:audio/mpeg" duration="00:04:07.431">/Input/E21</res></item></DIDL-Lite>
</Metadata>
</Entry>
According to the developer, the Metadata value has been escaped because it is an XML inside an XML. Not sure if that matter
Since I want to create an universal parse function to populate a class, I have created this method:
func unescapeXMLPredefinedCharacters(value:String?) -> String{
var audioString = ""
if value != nil{
audioString = value!
//Replace Unicode HTML Entity
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
//Replace Unicode Decimal
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
//Replace Unicode Hex
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
}
return audioString
}
It doesn't know which unicode type has been used for the unescaping.
Then I get the answer from my original question
The problem is that the escaped inner xml already is wrong in a sense that it contains & characters (in unicode), and maybe < and others.
First, you should not unescape unicode entities like & or < at all, because the XmlParser handles this for you.
Then, you should unescape unicode entities like & etc. into xml entities like & (rather than to &), which then the xml parser will handle (see above)
According to Andreas Answer, I have change the function
func unescapeXMLPredefinedCharacters(value:String?) -> String{
var audioString = ""
if value != nil{
audioString = value!
//Replace Unicode Decimal
audioString = audioString.replacingOccurrences(of: """, with: """)
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
}
return audioString
}
My program looks like this which is defined with hash:
where $varname and $varValue are passed dynamically from the file:Below is my program:
$appOptk= {
%hash{$varName}=>$varValue,
};
push #{$hash{metrics}->{appOptions}},$appOptk;
Output of the program looks like this:
"metrics": {
"appOptions": [{
"shell.common.report_default_significant_digits ": "4"
}, {
"time.remove_clock_reconvergence_pessimism ": "true"
"route.detail.hop_layers_to_fix_antenna ": "true "
}, {
"clock_opt.flow.optimize_layers ": "false"
}, {
"clock_opt.flow.skip_placement ": "true"
}
],
Can anyone please tell how to get below output by removing brackets inside the hash
"metrics": {
"appOptions": [{
"shell.common.report_default_significant_digits ": "4"
"time.remove_clock_reconvergence_pessimism ": "true"
"route.detail.hop_layers_to_fix_antenna ": "true "
"clock_opt.flow.optimize_layers ": "false"
"clock_opt.flow.skip_placement ": "true"
],
It would be easier to read if everything was in Perl. I think this is what you want.
$hash{metrics}{appOptions}[-1]{$varName} = $varValue;
Of course, you have to decide when a new array is added to the list.
# add new array
push #{$hash{metrics}{appOptions}}, {};
your expected output doesn't make any sense to me but you can achieve it by change push #{$hash{metrics}->{appOptions}},$appOptk; to
${#{$hash{metrics}->{appOptions}}[0]->{$varName}} = $varValue;
I am fairly new programmer, currently I have been assigned a project to create a looping calculator that even after you use one of the calculator functions it will keep going until you make a selection provided. My problem with my calculator currently is that there is an incessant termination whenever I try to test my function on Pydev. I already fixed the first problem where Pydev read one of my variables (choice) as unused so I used the "ctrl + 1" trick and that got rid of the unused variable warning. Any tips on how I might be able to run this program and have it continually loop?
def main():
loop=1
choice=0 # #UnusedVariable
while loop == 1:
print("Welcome to Calculator Function!")
print("Your options are:")
print(" ")
print("1/) Addition")
print("2/) Subtraction")
print("3/) Multiplication")
print("4/) Division")
print("5/) Quit CalculatorFunction.py")
print(" ")
choice = int(raw_input("Choose your option: ").strip())
if choice == 1:
add1 = input("Add what: ")
add2 = input("To what: ")
print add1, "+", add2, "=", add1+add2
elif choice == 2:
sub2 = input("Subtract what: ")
sub1 = input("From what: ")
print sub1, "-", sub2, "=", sub1-sub2
elif choice == 3:
mult1 = input("Multiply what: ")
mult2 = input("To what: ")
print mult1, "*", mult2, "=", mult1*mult2
elif choice == 4:
div2= input("Divide what: ")
div1= input("From what: ")
print div1, "/", div2, "=", div1/div2
elif choice == 5:
loop = 0
print"Thank you for using CalculatorFunction.py have a good day!"
else:
print"No selection made, please try again."
if __name__ == '__main__':
main()
Your if - else block is outside the while loop, that is why it doesn't work. Here's the properly indented code:
def main():
loop=1
choice=0 # #UnusedVariable
while loop == 1:
print("Welcome to Calculator Function!")
print("Your options are:")
print(" ")
print("1/) Addition")
print("2/) Subtraction")
print("3/) Multiplication")
print("4/) Division")
print("5/) Quit CalculatorFunction.py")
print(" ")
choice = int(raw_input("Choose your option: ").strip())
if choice == 1:
add1 = input("Add what: ")
add2 = input("To what: ")
print add1, "+", add2, "=", add1+add2
elif choice == 2:
sub2 = input("Subtract what: ")
sub1 = input("From what: ")
print sub1, "-", sub2, "=", sub1-sub2
elif choice == 3:
mult1 = input("Multiply what: ")
mult2 = input("To what: ")
print mult1, "*", mult2, "=", mult1*mult2
elif choice == 4:
div2= input("Divide what: ")
div1= input("From what: ")
print div1, "/", div2, "=", div1/div2
elif choice == 5:
loop = 0
print"Thank you for using CalculatorFunction.py have a good day!"
else:
print"No selection made, please try again."
if __name__ == '__main__':
main()
This worked well on pydev.
Thanks to your tips on "indentation" and a couple of other things I finally figured out the program works thank you all for your input. What I did to fix my immediate termination was fix the indentation. Then to make it so the program continually loops if a selection isn't made I added the continue, in essence the only way to terminate the program is to select the option quit which is listed as "5".
def main()
loop=1
choice=0 # #UnusedVariable
while loop == 1:
print(" ")
print("Welcome to Calculator Function!")
print("Your options are:")
print(" ")
print("1) Addition")
print("2) Subtraction")
print("3) Multiplication")
print("4) Division")
print("5) Quit CalculatorFunction.py")
print(" ")
choice = int(raw_input("Choose your option: ").strip())
if choice == 1:
add1 = int(raw_input("Add what: "))
add2 = int(raw_input("To what: "))
print add1, "+", add2, "=", add1+add2
elif choice == 2:
sub2 = int(raw_input("Subtract what: "))
sub1 = int(raw_input("From what: "))
print sub1, "-", sub2, "=", sub1-sub2
elif choice == 3:
mult1 = int(raw_input("Multiply what: "))
mult2 = int(raw_input("To what: "))
print mult1, "*", mult2, "=", mult1*mult2
elif choice == 4:
div2= int(raw_input("Divide what: "))
div1= int(raw_input("From what: "))
print div1, "/", div2, "=", div1/div2
elif choice == 5:
loop = 0 #Ends the program
print"Thank you for using CalculatorFunction.py have a good day!"
else:
print"No selection made, please try again."
continue #loops the program
if name == 'main':
main()
I have a VB script that takes in several parameters that could include spaces using cscript, and I make the call using:
nsExec::exec 'cscript.exe "$PATH_TO_FILE\program.vbs" "Something with spaces" "Something else"'
Now, I want one of the "Something else" strings to include a double quote character, where the string is
Something " else.
I have tried
nsExec::exec 'cscript.exe "$PATH_TO_FILE\program.vbs" "Something with spaces" "Something "" else."'
with an escaped " but that did not work, it simply used "Something else" as the string passed in.
Basically, there is not a way to deal with these quotes, so you need a workaround (use QUOTE and then replace in program with a ').
You can read the entire process command line as one string like this (JScript code, sorry):
// Read process command line
var WshShell = WScript.CreateObject("WScript.Shell");
var objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2");
var childProcess =
WshShell.Exec
(
'"' + WshShell.Environment('PROCESS')('ComSpec') + '"'
+
" /C Echo \"Text lines\" && Set /p VarName="
);
childProcess.StdOut.ReadLine();
var current_pid =
objWMIService.ExecQuery
(
"Select * From Win32_Process Where ProcessId=" + childProcess.ProcessID
);
current_pid = (new Enumerator(current_pid)).item().ParentProcessId;
if (current_pid)
{
childProcess.StdIn.WriteLine("value"); // child process should now exit
}
else
{
WScript.StdErr.WriteLine("Get current PID from WMI failed.");
WScript.Quit(7);
}
var cmd_line = objWMIService.ExecQuery("Select * From Win32_Process Where ProcessID=" + current_pid);
cmd_line = (new Enumerator(cmd_line)).item().CommandLine;
WScript.Echo(cmd_line);
but than you will have to parse the string into separate arguments yourself.