I am using the SCPI library of commands, namely SCPI_ParamString. The function I am trying to implement takes in 2 strings and an integer as inputs. To verify that my code is reading the inputs correctly, I am having it simply print my inputs back out to me (I will pass these along to the function once I am confident I am using the right strings).
What I've found is that my code doesn't identify the comma as a delineator between two inputs. It prints all 3 inputs as the first string. What is interesting, is that when I ask it to print the second input - it recognizes that the comma delineates between first and second input. So it prints only the second and third input (not recognizing the comma between 2nd and 3rd as separating inputs.
I am coding on a PIC24, in C using MPLABX IDE v3.15.
Below is my code followed by example output.
const char * longstr1;
const char * longstr2;
size_t ls1_len = 80;
size_t ls2_len = 80;
scpi_bool_t mandat = 1;
int32_t deltamin;
if (!SCPI_ParamString(context, &longstr1, &ls1_len, mandat) )
{
return SCPI_RES_ERR;
}
if (!SCPI_ParamString(context, &longstr2, &ls2_len, mandat) )
{
return SCPI_RES_ERR;
}
if (!SCPI_ParamInt(context, &deltamin, mandat))
{
return SCPI_RES_ERR;
}
sprintf(strTmp,"Inputs:" STR_CRLF);
uart1_puts(strTmp);
sprintf(strTmp,longstr1);
uart1_puts(strTmp);
sprintf(strTmp,STR_CRLF);
uart1_puts(strTmp);
sprintf(strTmp,longstr2 );
uart1_puts(strTmp);
And sample execution:
SCPI|0x51> GPS:PROP SGP4,1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753,2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.824191574136 67,360
SCPI|0x51> Inputs:
1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753,2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667,360
2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667,360
0)00:20:53:58.43 task_supmcu_scpi: Accepted "GPS:PROP SGP4,1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753,2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667,360" command.
Notice that when I print the first input all 3 inputs are actually printed, and when I print the second the second and third are actually printed.
I've tried a few different things to get around this - none have worked.
Related
I was given an encrypted copy of the study guide here, but how do you decrypt and read it???
In a file called pa11.py write a method called decode(inputfile,outputfile). Decode should take two parameters - both of which are strings. The first should be the name of an encoded file (either helloworld.txt or superdupertopsecretstudyguide.txt or yet another file that I might use to test your code). The second should be the name of a file that you will use as an output file.
Your method should read in the contents of the inputfile and, using the scheme described in the hints.txt file above, decode the hidden message, writing to the outputfile as it goes (or all at once when it is done depending on what you decide to use).
The penny math lecture is here.
"""
Program: pennyMath.py
Author: CS 1510
Description: Calculates the penny math value of a string.
"""
# Get the input string
original = input("Enter a string to get its cost in penny math: ")
cost = 0
Go through each character in the input string
for char in original:
value = ord(char) #ord() gives us the encoded number!
if char>="a" and char<="z":
cost = cost+(value-96) #offset the value of ord by 96
elif char>="A" and char<="Z":
cost = cost+(value-64) #offset the value of ord by 64
print("The cost of",original,"is",cost)
Another hint: Don't forget about while loops...
Another hint: After letters -
skip ahead by their pennymath value positions + 2
After numbers - skip ahead by their number + 7 positions
After anything else - just skip ahead by 1 position
The issue I'm having in that I cant seem to get the coding right to decode the file it comes out looking the same. This is the current code I have been using. But once I try to decrypt the message it stays the same.
def pennycost(c):
if c >="a" and c <="z":
return ord(c)-96
elif c>="A" and c<="Z":
return ord(c)-64
def decryption(inputfile,outputfile):
with open(inputfile) as f:
fo = open(outputfile,"w")
count = 0
while True:
c = f.read(1)
if not c:
break;
if count > 0:
count = count -1;
continue
elif c.isalpha():
count = pennycost(c)
fo.write(c)
elif c.isdigit():
count = int(c)
fo.write(c)
else:
count = 6
fo.write(c)
fo.close()
inputfile = input("Please enter the input file name: ")
outputfile = input("Plese enter the output file name(EXISTING FILE WILL BE OVER WRITTEN!): ")
decryption(inputfile,outputfile)
I am trying to make a program to prompt a user for input until they enter a number within a specific range.
What is the best approach to make sure the code does not error out when I enter a letter, a symbol, or a number outside of the specified range?
In alternative to parse, you can use tryparse:
tryparse(type, str; base)
Like parse, but returns either a value of the requested type, or
nothing if the string does not contain a valid number.
The advantage over parse is that you can have a cleaner error handling without resorting to try/catch, which would hide all exceptions raised within the block.
For example you can do:
while true
print("Please enter a whole number between 1 and 5: ")
input = readline(stdin)
value = tryparse(Int, input)
if value !== nothing && 1 <= value <= 5
println("You entered $(input)")
break
else
#warn "Enter a whole number between 1 and 5"
end
end
Sample run:
Please enter a whole number between 1 and 5: 42
┌ Warning: Enter a whole number between 1 and 5
└ # Main myscript.jl:9
Please enter a whole number between 1 and 5: abcde
┌ Warning: Enter a whole number between 1 and 5
└ # Main myscript.jl:9
Please enter a whole number between 1 and 5: 3
You entered 3
This is one possible way to achieve this sort of thing:
while true
print("Please enter a whole number between 1 and 5: ")
input = readline(stdin)
try
if parse(Int, input) <= 5 || parse(Int, input) >= 1
print("You entered $(input)")
break
end
catch
#warn "Enter a whole number between 1 and 5"
end
end
Sample Run:
Please enter a whole number between 1 and 5: 2
You entered 2
See this link for how to parse the user input into an int.
I have 5 functions working relatively
1- singleline_diff(line1, line2)
comparing 2 line in one file
Inputs:
line1 - first single line string
line2 - second single line string
Output:
the index of the first difference between the two lines
identical if the two lines are the same.
2- singleline_diff_format(line1, line2, idx):
comparing 2 line in one file
Inputs:
line1 - first single line string
line2 - second single line string
idx - index at which to indicate difference (from 1st function)
Output:
abcd (first line)
==^ (= indicate identical character, ^ indicate the difference)
abef (second line)
If either input line contains a newline or carriage return,
then returns an empty string.
If idx is not a valid index, then returns an empty string.
3- multiline_diff(lines1, lines2):
deal with two lists of lines
Inputs:
lines1 - list of single line strings
lines2 - list of single line strings
Output:
a tuple containing the line number (starting from 0) and
the index in that line where the first difference between lines1
and lines2 occurs.
Returns (IDENTICAL, IDENTICAL) if the two lists are the same.
4-get_file_lines(filename)
Inputs:
filename - name of file to read
Output:
a list of lines from the file named filename.
If the file does not exist or is not readable, then the
behavior of this function is undefined.
5- file_diff_format(filename1, filename2) " the function with the problem"
deals with two input files
Inputs:
filename1 - name of first file
filename2 - name of second file
Output:
four line string showing the location of the first
difference between the two files named by the inputs.
If the files are identical, the function instead returns the
string "No differences\n".
If either file does not exist or is not readable, then the
behavior of this function is undefined.
testing the function:
everything goes will until it the test use one empty file
it gave me "list index out of range"
this is the code I use
def file_diff_format(filename1, filename2):
file_1 = get_file_lines(filename1)
file_2 = get_file_lines(filename2)
mli_dif = multiline_diff(file_1, file_2)
min_lens = min(len(file_1), len(file_2))
if mli_dif == (-1,-1) :
return "No differences" "\n"
else:
diff_line_indx = mli_dif[0]
diff_str_indx = int (mli_dif[1])
if len(file_1) >= 0:
line_file_1 = ""
else:
line_file_1 = file_1[diff_line_indx]
if len(file_2) >= 0:
line_file_2 = ""
else:
line_file_2 = file_2[diff_line_indx]
line_file_1 = file_1[diff_line_indx]
line_file_2 = file_2 [diff_line_indx]
out_print = singleline_diff_format(line_file_1, line_file_2, diff_str_indx)
return ( "Line {}{}{}".format ((diff_line_indx), (":\n"), (out_print)))
If one of the files is empty, either file1 or file2 should be an empty list, so that trying to access an element of either would cause the error you describe.
Your code checks for these files to be empty when assigning to line_file_`` andline_file_2`, but then goes ahead and tries to access elements of both.
I've to split simple QStrings of the form "number number number",for example " 2323 432 1223".
The code i use is
QString line;
QRegularExpression re("(\\d+)");
QRegularExpressionMatch match;
while(!qtextstream.atEnd()){
line = qtextstream.readLine();
match = re.match(line);
std::cout<<"1= "<<match.captured(0).toUtf8().constData()<<std::endl;
std::cout<<"2= "<<match.captured(1).toUtf8().constData()<<std::endl;
std::cout<<"3= "<<match.captured(2).toUtf8().constData()<<std::endl;
}
if the first line being processed is like the example string i get
for the first while cycle output:
1= 2323
2= 2323
3=
what is wrong?
Your regex only matches 1 or more digits once with re.match. The first two values are Group 0 (the whole match) and Group 1 value (the value captured with a capturing group #1). Since there is no second capturing group in your pattern, match.captured(2) is empty.
You must use QRegularExpressionMatchIterator to get all matches from the current string:
QRegularExpressionMatchIterator i = re.globalMatch(line);
while (i.hasNext()) {
qDebug() << i.next().captured(1); // or i.next().captured(0) to see the whole match
}
Note that (\\d+) contains an unnecessary capturing group, since the whole match can be accessed, too. So, you may use re("\\d+") and then get the whole match with i.next().captured(0).
If the usage of regular expressions isn't mandatory, you could also use QString's split()-function.
QString str("2323 432 1223");
QStringList list = str.split(" ");
for(int i = 0; i < list.length(); i++){
qDebug() << list.at(i);
}
I have been able to locate things no problem with grep however the assignment is basically pulling data out and formatting it and displaying it as a table columns with multiple rows. Now it shouldn't be anything crazy because we only have basic knowledge of awk and sed. Now I'm curious: is there any way to take my output from grep and format it so for example I get:
Jake
0001
Bob
0002
Kim
0003
and want to make it something like this
# Name LD #
--- ---- ----
1 Jake 0001
2 Bob 0002
3 Kim 0003
Also is it possible to explain each part of your line and also is it possible to make it expandable if I have a large record to deal with?
You need to defined (or identify) a control logic that matches your grep output.
Derived from what you gave I assume the following:
the heading is a constant text that is intrinsic to your formatting
(Not to be deduced from input)
the first column is an ordinal number starting with one
the records from the input are identified by a string of all digits
Then the following awk script will do the formatting:
BEGIN {
# initialize ordinal
ordinal=1;
# print heading
printf "%-3s %5s %4s\n", "#", "Name", "LD #"
}
# match trigger line for output
/^[0-9]+$/ { printf "%3d %5s %4s\n", ordinal++, label, $1;
# cleanou label - not necessary for single data item case
# we are done with this input line
next;
}
# collect data item
{
label=$1;
# we are done with this input line
next;
}
If you want to include more record items (leading to more columns) you might check whether the preceeding column values have been encountered.
Or even just use a counter for indicating at what column you are within your record.
Then you could use e.g.:
BEGIN {
# initialize ordinal
ordinal=1;
column=0;
# print heading
printf "%-3s %5s %4s\n", "#", "Name", "LD #"
}
# match trigger line for output
/^[0-9]+$/ { printf "%3d (%d)", ordinal++, column;
for (i=0; i < column; i++) {
printf " %s", data[i];
data[i] = "";
}
printf "\n";
# we are done with this input line
column=0;
next;
}
# collect data item
{
data[column++]=$1;
if (length($1) > max[column]) {
max[column]=length($1);
}
# we are done with this input line
next;
}
END {
for (i=0; i< length(max); i++) {
printf "Col %d: %d\n", i, max[i];
}
}
I also included a way of determining the size of the columns (character count).