Pseudocode CamelCase excerise for AS Level Homework - pseudocode

I got given this task to do for homework... I get that the key task is the declaration of the array but I do not know how to separate each word the string in pseudocode and fill the empty spaces with "(Empty)" This is my code so far but I am stumped! This is dor AS Level BTW...
DECLARE CamelCaseArray : ARRAY[1:10] OF STRING
REPEAT
PRINT “Enter a word starting with a capital letter: (eg. Word)”
UNTIL ??? /*I am stumped on what to do here, I do not have to use a REPEAT UNTIL BTW.*\

Pseudo code is something that varies individually, so I don't know how much the following pseudo code would you find similar to the way you would imagine it.
First of all, I'm going to assume you have hard-coded (i.e. it's a fixed value) 10
elements in your array of strings.
I will also assume you are not able to use any pre-coded functions (like Split(' ')), but you are able to access a character in a string like you would in an array. (Example STRING STR = "HELLO", STR[0] = 'H') and that you can compare a character literal ('C') to ASCII values (67).
Your pseudo code reminds me of COBOL by the way (Link provided) so maybe you could make some parallels to that.
https://www.tutorialspoint.com/cobol/cobol_loop_statements.htm
(Look for PERFORM UNTIL)
DECLARE CamelCaseArray : ARRAY[1:10] OF STRING
DECLARE Input : STRING
DECLARE CharCounter : INT >* This counter will be used to move thru the string as an array of characters
DECLARE ArrayCounter : INT >* This will indicate an element of our array.
CharCounter = 0 *> Set both to zero.
ArrayCounter = 0
PRINT “Enter a string in CamelCase format>”
READ Input FROM CONSOLE
REPEAT
IF Input[CharCounter] > 64 AND Input[CharCounter] < 91 AND CharCounter IS NOT 0 >* Check whether our current character's ASCII values are between 64 and 91, which are the values for capital letters in the ASCII table AND if our character is not the first one in the string (since then we don't advance our array counter, we just add it instead.")
CamelCaseArray[ArrayCounter] = CamelCaseArray[ArrayCounter] + Input[CharCounter] >* If it is, add it to the STRING element of the array
ArrayCounter++ >* Increment our array counter.
ELSE
CamelCaseArray[ArrayCounter] = CamelCaseArray[ArrayCounter] + Input[CharCounter] >* Otherwise, just add the current character to the current array element
END IF
CharCounter++ >* Increment the character counter anyways, since we advance in the string.
UNTIL CharCounter = LENGTH OF Input >* Do all this UNTIL our character counter is at the end of the string (I.E. It's length).
>* Now , filling the rest of the array with the (EMPTY) string:
IF ArrayCounter<LENGTH OF CamelCaseArray >* If our array counter is less than the array length after we went through our 10 words, we can fill the rest with (EMPTY)
REPEAT
CamelCaseArray[ArrayCounter] = "(EMPTY)" >* Fill current element with empty
ArrayCounter ++ >* Increment ArrayCounter
UNTIL ArrayCounter = LENGTH OF CamelCaseArray >* Do all this until we reach the end of our array.
END IF
Hope I helped!

Here's the python code you asked for
CamelCaseArray = [""]*10
CharCounter = 0
ArrayCounter = 0
Input = input("Enter a string in CamelCase format>")
Input= list(Input)
for i in range (0,len(Input)):
if ord(Input[i]) > 64 and ord(Input[i]) < 91 and i != 0:
ArrayCounter+=1
CamelCaseArray[ArrayCounter] = CamelCaseArray[ArrayCounter] + Input[i]
if ArrayCounter < 10:
ArrayCounter+=1
for i in range (ArrayCounter,10):
CamelCaseArray[i] = "(EMPTY)"
for i in range (0,10):
print(CamelCaseArray[i])

Related

VB Control Naming by Variable

Dim LineNo as Integer
LineNo = CStr(channel) 'This can have a value of 1 to 100
If LineNo = 1 then
Text1.Text = "Line one selected"
Elseif LineNo = 2 then
Text2.Text = "Line one selected"
'Etc etc
End if
I need to replace the number "1" in Text1.Text and every other TextBox with the value of LineNo? For example:
Text{LineNo}.Text
So I would not have to do a repeated "If" and have a smaller one line code like this:
Text{LineNo}.Text = "Line " & LineNo & " selected"
How would I do this?
Look into a Control array of text boxes. You could have txtLine(), for example, indexed by the channel number.
LineNo = CStr(channel)
txtLine(channel).Text = "Line " & LineNo & " selected"
To create the array, set the Index property of each of the text boxes to an increasing integer, starting at 0.
If you have a finite and relatively small number, you can use a property. I've used this approach with up to 30+ elements in a pinch. Super simple, easy pattern to recognize and replicate in other places. A bit if a pain if the number of elements changes in the future, but extensible nevertheless.
It uses the Choose statement, which takes an index N and returns the Nth element (1-based), hence, the check makes sure that N is > 0 and <= MAX (which you would configure).
Public Property Get TextBox txt(ByVal N As Long)
Const MAX As Long = 10
If N <= 0 || N > MAX Then Exit Property ' Will return a "Nothing". You could return the bound element if you prefer
set txt = Choose(Text1, Text2, Text3, Text4, Text5, Text6, Text7, Text8, Text9, Text10)
End Property
Then, you can simply reference them with the Property, much like an alias:
txt(1).Text = "Line 1 text"
txt(2).Text = "Line 2 text"
If you have an arbitrary number, then you are likely using a control array already, which is simpler because it can be referenced by Index already, so you can directly reference it.
If neither of these work for you and you have a very large number of controls, you can scan the Controls collection in a similar Property, attempting to match ctrl.Name with the pattern of your choice (e.g., matching the first 4 characters to the string "Text", thus matching Text1, Text2, etc, for an unlimited number). Theoretically, this should be future-proofed, but that's just theoretical, because anything can happen. What it does do for you is to encapsulate the lookup in a way that "pretends" to be a control array. Same syntax, just you control the value.
Public Property Get TextBox txt(ByVal N As Long)
Dim I As Long
For I = 0 To Controls.Count - 1 ' Controls is zero-based
' Perform whatever check you need to. Obviously, if you have a "Label" named
' "Text38", the assignment will throw an error (`TextBox = Label` doesn't work).
If Left(Controls(I).Name, 4) = "Text" Then
set txt = Controls(I)
End If
Next
' If you want the Property to never return null, you could uncomment the following line (preventing dereference errors if you insist on the `.Text` for setting/getting the value):
' If txt Is Nothing Then Set txt = Text1
End Property
Use the same way as above: txt(n).Text = "..."

How to convert bytes in number into a string of characters? (character representation of a number)

How do I easily convert a number, e.g. 0x616263, equivalently 6382179 in base 10, into a string by dividing the number up into sequential bytes? So the example above should convert into 'abc'.
I've experimented with Array.pack but cant figure out how to get it to convert more than one byte in the number, e.g. [0x616263].pack("C*") returns 'c'.
I've also tried 0x616263.to_s(256), but that throws an ArgumentError: invalid radix. I guess it needs some sort of encoding information?
(Note: Other datatypes in pack like N work with the example I've given above, but only because it fits within 4 bytes, so e.g. [0x616263646566].pack("N") gives cdef, not abcdef)
This question is vaguely similar to this one, but not really. Also, I sort of figured out how to get the hex representation string from a character string using "abcde".unpack("c*").map{|c| c.to_s(16)}.join(""), which gives '6162636465'. I basically want to go backwards.
I don't think this is an X-Y problem, but in case it is - I'm trying to convert a number I've decoded with RSA into a character string.
Thanks for any help. I'm not too experienced with Ruby. I'd also be interested in a Python solution (for fun), but I don't know if its right to add tags for two separate programming languages to this question.
To convert a single number 0x00616263 into 3 characters, what you really need to do first is separate them into three numbers: 0x00000061, 0x00000062, and 0x00000063.
For the last number, the hex digits you want are already in the correct place. But for the other two, you have to do a bitshift using >> 16 and >> 8 respectively.
Afterwards, use a bitwise and to get rid of the other digits:
num1 = (0x616263 >> 16) & 0xFF
num2 = (0x616263 >> 8) & 0xFF
num3 = 0x616263 & 0xFF
For the characters, you could then do:
char1 = ((0x616263 >> 16) & 0xFF).chr
char2 = ((0x616263 >> 8) & 0xFF).chr
char3 = (0x616263 & 0xFF).chr
Of course, bitwise operations aren't very Ruby-esque. There are probably more Ruby-like answers that someone else might provide.
64 bit integers
If your number is smaller than 2**64 (8 bytes), you can :
convert the "big-endian unsigned long long" to 8 bytes
remove the leading zero bytes
Ruby
[0x616263].pack('Q>').sub(/\x00+/,'')
# "abc"
[0x616263646566].pack('Q>').sub(/\x00+/,'')
# "abcdef"
Python 2 & 3
In Python, pack returns bytes, not a string. You can use decode() to convert bytes to a String :
import struct
import re
print(re.sub('\x00', '', struct.pack(">Q", 0x616263646566).decode()))
# abcdef
print(re.sub('\x00', '', struct.pack(">Q", 0x616263).decode()))
# abc
Large numbers
With gsub
If your number doesn't fit in 8 bytes, you could use a modified version of your code. This is shorter and outputs the string correctly if the first byte is smaller than 10 (e.g. for "\t") :
def decode(int)
if int < 2**64
[int].pack('Q>').sub(/\x00+/, '')
else
nhex = int.to_s(16)
nhex = '0' + nhex if nhex.size.odd?
nhex.gsub(/../) { |hh| hh.to_i(16).chr }
end
end
puts decode(0x616263) == 'abc'
# true
puts decode(0x616263646566) == 'abcdef'
# true
puts decode(0x0961) == "\ta"
# true
puts decode(0x546869732073656e74656e63652069732077617920746f6f206c6f6e6720666f7220616e20496e743634)
# This sentence is way too long for an Int64
By the way, here's the reverse method :
def encode(str)
str.reverse.each_byte.with_index.map { |b, i| b * 256**i }.inject(:+)
end
You should still check if your RSA code really outputs arbitrary large numbers or just an array of integers.
With shifts
Here's another way to get the result. It's similar to #Nathan's answer, but it works for any integer size :
def decode(int)
a = []
while int>0
a << (int & 0xFF)
int >>= 8
end
a.reverse.pack('C*')
end
According to fruity, it's twice as fast as the gsub solution.
I'm currently rolling with this:
n = 0x616263
nhex = n.to_s(16)
nhexarr = nhex.scan(/.{1,2}/)
nhexarr = nhexarr.map {|e| e.to_i(16)}
out = nhexarr.pack("C*")
But was hoping for a concise/built-in way to do this, so I'll leave this answer unaccepted for now.

What is meant by returning half of a supplementary character?

When you use .charAt method to convert a particular character in a string of string class to a character of char type, a code unit.
For example:
String greeting = "Hello";
Char character = greeting.charAt(0);
Character of char type is set to 'H'.
But you use a single index number for a supplementary character, only the first or second half is returned.
So for example, invoke the same method on $\mathcal {P} (\mathbb{Z})$ (set of integer), only the first half is returned.
All these are what is said in the book. But what does it meant by first half? First half of the two unit?
The language is java
Let me clarify:
(The latex code for set of integer seems to not be working)
String greeting = "(set of integer) is important";
char ch = greeting.charAt(0)
Index zero refers to the symbol for set of integer in math but b/c it is a supplementary(encoded by "\uD835\uDD6B"). Only the first half of this character is returned and stored in ch.
But what is first half?

Remove sequence from string if preceded by same sequence

I have some sequences in a string denoted by "#number" (/#\d/)
I want to remove any redundant sequences, where #2 is followed by #2,
I only want to remove them if another identical #number sequence is found directly after somewhere in the text, so for #2lorem#2ipsum the 2nd #2 is removed, but for #2lorem#1ipsum#2dolor nothing is removed because #1 is between the two #2 sequences.
"#2randomtext#2randomtext#2randomtext#1bla#2bla2#2bla2"
becomes:
"#2randomtextrandomtextrandomtext#1bla#2bla2bla2
"#2randomtext#2randomtext#2randomtext#1bla#2bla2#2bla2".gsub /(?<=(#\d))([^#]*)\1/,'\2'
=> "#2randomtextrandomtextrandomtext#1bla#2bla2bla2"
You can split it into tokens:
my_string = "#2randomtext#2randomtext#2randomtext#1bla#2bla2#2bla2"
tokens = my_string.scan /(#\d+)?((?:(?!#\d+).)*)/
#=> [["#2", "randomtext"], ["#2", "randomtext"], ["#2", "randomtext"], ["#1", "bla"], ["#2", "bla2"], ["#2", "bla2"]]
Then chunk, map and join:
tokens.chunk{|x| x[0].to_s}.map{|n, v| [n, v.map(&:last)]}.join
#=> "#2randomtextrandomtextrandomtext#1bla#2bla2bla2"
my_string = "#2randomtext#2randomtext#2randomtext#1bla#2bla2#2bla2"
prev_sequence = String.new
penultimate_index = my_string.length - 2
for i in 0..penultimate_index
if my_string[i] == '#'
new_sequence = "##{my_string[i+1]}"
if new_sequence == prev_sequence
my_string.slice!( i, 2 )
else
prev_sequence = new_sequence
end
end
end
puts my_string
easy... split your string into an array, and then compare the number that comes right after that. If it's the same, remove it/them. The complicated (through not that much), is that you can't remove entries from an array while looping through them... so what you need to do is make a recursive function... here's the pseudo:
-= Global values =-
Decalre StringArray and set it to OriginalString.SplitOn("#")
-= Method RemoveLeadingDuplicates =-
Declare Counter
Declare RemoveIndex
loop for each string in StringArray
if previous lead == current lead
Set RemoveIndex
break from loop
else
previous lead = current lead
Increase Counter By 1
end loop
if RemoveIndex is not null
Remove the item at specified index from the array
Call RemoveLeadingDuplicates
Return

Number of occurrences in a string

I'm a total noob as far as visual basic goes.
In class I need to do the following: "Write a program that requests a sentence from the user and then records the number of times each letter of the alphabet occurs."
How would I go about counting the number of occurrences in the string?
Loop the chars and add to the list
Dim s As String = "tafata"
Dim count As New Dictionary(Of Char, Integer)()
For i As Integer = 0 To s.Length - 1
count(s(i)) = (If(count.ContainsKey(s(i)), count(s(i)) + 1, 1))
Next
Havent worked with linq that mutch, but i think you can try
Dim s As String = "tafata"
Dim t = From c In s _
Group c By c Into Group _
Select Group
As Dave said, the easiest solution would be to have an array of length 26 (for English), and loop through each character in the string, incrementing the correct array element. You can use the ASCII value of each character to identify which letter it is, then translate the ASCII number of the letter into the corresponding index number:
'Dimension array to 26 elements
Dim LetterCount(0 to 25) As Long
'Temporary index number
Dim tmpIdx As Long
'Temporary character
Dim tmpChar as String
'String to check
Dim checkStr As String
checkStr = "How many of each letter is in me?"
'Change all letters to lower case (since the upper case
'of each letter has a different ASCII value than its
'lower case)
checkStr = LCase(checkStr)
'Loop through each character
For n = 1 to Len(checkStr)
'Get current character
tmpChar = Mid(checkStr, n, 1)
'Is the character a letter?
If (Asc(tmpChar) >= Asc("a")) And (Asc(tmpChar) <= Asc("z")) Then
'Calcoolate index number from letter's ASCII number
tmpIdx = Asc(tmpChar) - Asc("a")
'Increase letter's count
LetterCount(tmpIdx) = LetterCount(tmpIdx) + 1
End If
Next n
'Now print results
For n = 0 to 25
Print Chr(Asc("a") + n) & " - " & CStr(LetterCount(n))
Next n
The quick and dirty way:
Public Function CountInStr(ByVal value As String, ByVal find As String, Optional compare As VbCompareMethod = VbCompareMethod.vbBinaryCompare) As Long
CountInStr = (LenB(value) - LenB(Replace(value, find, vbNullString, 1&, -1&, compare))) \ LenB(find)
End Function
I would count and remove every instance of the first character, and repeat until there are no characters left. Then display the count for each character detected. Much better than looping through once for every possible character, unless you know the possible range of characters is smaller than the length of the sentence.
Imports System.Linq
Dim CharCounts = From c In "The quick brown fox jumped over the lazy dog." _
Group c By c Into Count() _
Select c, Count
from itertools import groupby
sentence = raw_input("Your sentence:")
for char,group in groupby(sorted(sentence.lower())):
print(char+": "+`len(list(group))`)

Resources