How do I convert Morse code to ASCII text - c#

Yes this is homework but I have spent a few hours trying to figure it out. So right now I am doing a project in which you convert plain text into morse code, I was able to do so and it was relatively easy. However, now I need to convert the morse code back into text and I've run into a roadblock. I am not sure if I should make a new dictionary and reverse the text and char or if I should just reverse the existing dictionary that I have already made. Also we're not allowed to use if or case statements which makes it a bit harder but not by too much.
Here is what I have so far:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Morse_Code_Converter
{
public partial class Form1 : Form
{
private Dictionary<char, String> morse = new Dictionary<char, String>()
{
{' ', " /" },{',', " --..--" }, {'.', " .-.-.-" }, {'?'," ..--.."},{'0'," -----"},{'1', " .----"},
{'2'," ..---"},{'3'," ...--"},{'4'," ....-"},{'5'," ....."},{'6'," -...."},{'7'," --..."},{'8'," ---.."},
{'9'," ----." },{'a', " .-"}, {'b', " -..."},{'c'," -.-."},{'d'," -.."},{'e'," ."},{'f'," ..-."},
{'g'," --."},{'h'," ...."},{'i'," .."},{'j'," .---"},{'k'," -.-"},{'l'," .-.."},{'m'," --"},{'n'," -."},
{'o'," ---"},{'p'," .--."},{'q'," --.-"},{'r'," .-."},{'s'," ..."},{'t'," -"},{'u'," ..-"},{'v'," ...-"},{'w'," .--"},
{'x'," -..-"},{'y'," -.--"},{'z'," --.."}
};
public Form1()
{
InitializeComponent();
}
private void convertToMorseButton_Click(object sender, EventArgs e)
{
string input = morseTextBox.Text;
var sb = new StringBuilder();
for (int index = 0; index < input.Length; index++)
{
var t = input[index];
input = input.ToLower();
string morseValue;
morse.TryGetValue(t, out morseValue);
sb.Append(morseValue);
}
textToMorseLabel.Text = sb.ToString();
}
private void morseToTextButton_Click(object sender, EventArgs e)
{
//This is where I want to convert
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void clearButton_Click(object sender, EventArgs e)
{
morseTextBox.Text = "";
}
private void morseClearButton_Click(object sender, EventArgs e)
{
textBox.Text = "";
}
}
}
If someone can help guide me in the right direction that would greatly appreciated.

Since this is a school project, I don't give you the code, but I will try to explain, how you can do it.
I suppose morse codes (in input) are separated by a space, so first use String.Split(' ') to get a string[] each with a morsecode string.
I also assume, that you're not familiar with 'Linq' (yet) - or are not allowed to use it, so now you iterate (with a for loop) through this array, then use a for loop to find the item in morses Dictionary that has the value equal to this morsecode and return the key.
Using this method you don't need an extra dictionary. However, if this was real code, you should create a reverse Dictionary, which is faster than this approach.

Related

Where to declare variables in C#

I have created a simple calculator using VS 2013 Pro... and here is the segment of the codes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CalcTwo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string input = string.Empty;
double numb1, numb2, result;
private void button1_Click(object sender, EventArgs e)
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
result = numb1 + numb2;
textBox3.Text = result.ToString();
}
private void button4_Click(object sender, EventArgs e)
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
result = numb1 - numb2;
textBox3.Text = result.ToString();
}
}
}
now the problem I'm facing is, I've got two more buttons for multiplying and dividing, which in turn forces me to copy paste
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
for each button. I tried to put the codes with the other variables(double numb1, numb2, result) but getting an error...
Here is the screenshots
Pretty new to Visual Studio and C#.
Help is appreciated! :)
The declaration of the variables is fine at the class level. However, in order to reduce the code duplication you can extract that specific functionality into its own method. Something like this perhaps:
private void CaptureValues()
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
}
Then in the handlers:
private void button1_Click(object sender, EventArgs e)
{
CaptureValues();
result = numb1 + numb2;
textBox3.Text = result.ToString();
}
This gives you a convenient place to put additional code. Checking the inputs and displaying a message, for example:
private void CaptureValues()
{
if (!double.TryParse(textBox1.Text, out numb1))
// textBox1 couldn't be parsed, show an error message
if (!double.TryParse(textBox2.Text, out numb2))
// textBox2 couldn't be parsed, show an error message
}
You could even go a step further and put the values into class-level properties. Something like this:
private double Value1
{
get
{
double result;
if (!double.TryParse(textBox1.Text, out result))
throw new Exception("Couldn't parse the first text box!");
return result;
}
}
private double Value2
{
get
{
double result;
if (!double.TryParse(textBox2.Text, out result))
throw new Exception("Couldn't parse the second text box!");
return result;
}
}
With those, you don't need your numb1 or numb2 variables at all, just reference the properties directly:
textBox3.Text = (Value1 + Value2).ToString();
Currently the properties can throw exceptions, so you might want to handle that:
try
{
textBox3.Text = (Value1 + Value2).ToString();
}
catch (Exception ex)
{
// examine what happened with ex and show an error
}
You can throw a more specific Exception type of course, even a custom one. Or you can respond to the error in the properties instead of in the handlers and not use exceptions at all. (There's an argument to be made, and I agree with it, never to use exceptions for normal logic, and this is potentially one of those edge cases. If it's normal logic, don't use exceptions. If it's an exceptional case and the value should never be un-parseable, go ahead and use them. I'd prefer not to in this case, but was just adding it as a possibility.)
There are a lot of options.

Multi-windows R graphs in C# with RDotNet

I have a C# code for a simple windows form with 3 buttons.
Button 1 calls R and plots a surface while button 2 plots a contour. If I launch the application and click on button 1, I correctly see the surface plot but then I would like to click on button 2 to open a new window with the counter plot. Unfortunately, if I try to do so the app freezes and I cannot go on. So I have added button 3 with the intention to close the R engine if it is running. The idea was to kill the R instance and reopen it when clicking on button 2. But this doesn't work either. Is there a way to fix my problem?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using RDotNet;
namespace mySurface
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
string dllPath = #"C:\Program Files\R\R-3.1.0\bin\i386\";
REngine.SetDllDirectory(dllPath);
REngine.CreateInstance("RDotNet");
REngine engine = REngine.GetInstanceFromID("RDotNet");
if (engine.IsRunning == false)
{
engine.Initialize();
}
var x = engine.Evaluate("x <- 1:100").AsNumeric();
var y = engine.Evaluate("y <- 5:105").AsNumeric();
engine.Evaluate("model = function (a, b){23.86+5.525*b-2.5725*a-6.6413*b^2-5.1862*a^2}"); //evaluate function
engine.Evaluate("z = outer(x, y ,model)");
engine.Evaluate("persp(x,y,z)");
//Console.WriteLine(x[0]);
}
public void button2_Click(object sender, EventArgs e)
{
string dllPath = #"C:\Program Files\R\R-3.1.0\bin\i386\";
REngine.SetDllDirectory(dllPath);
REngine.CreateInstance("RDotNet");
REngine engine = REngine.GetInstanceFromID("RDotNet");
if (engine.IsRunning == false)
{
engine.Initialize();
}
var x = engine.Evaluate("x <- 1:100").AsNumeric();
var y = engine.Evaluate("y <- 5:105").AsNumeric();
engine.Evaluate("model = function (a, b){23.86+5.525*b-2.5725*a-6.6413*b^2-5.1862*a^2}"); //evaluate function
engine.Evaluate("z = outer(x, y ,model)");
engine.Evaluate("contour(x,y,z, nlevels = 10)");
//Console.WriteLine(x[0]);
}
private void button3_Click(object sender, EventArgs e)
{
REngine engine = REngine.GetInstanceFromID("RDotNet");
if (engine.IsRunning == false)
{
engine.Close();
}
}
}
}
You seem to be using R.NET 1.5.5 or less. The latest version is 1.5.16 and the initialisation procedure is significantly different. The answer to a recent post on stackoverflow provides more details. Issues with attempts at multiple initialisations of R tipycally used to lead to the symptoms you describe, and the new API tries to prevent this.

How would I be able to use the && operator in string types in C# (Speech Recognition)

I am writing my own speech recognition program in C# with Microsoft's engine and the way I have the program to recognise commands is to read what is already in a text file. The problem with this is, I have to say the command exactly as it is written. For example, if the command is "what is tomorrows date", I cannot say "what's tomorrows date". I have thought of way to get around it and that is to use the Contains method. Here is my code below,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.IO;
namespace TestDECA
{
public partial class Form1 : Form
{
SpeechRecognitionEngine _recognizer = new SpeechRecognitionEngine();
SpeechSynthesizer DECA = new SpeechSynthesizer();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_recognizer.SetInputToDefaultAudioDevice();
_recognizer.LoadGrammar(new Grammar(new GrammarBuilder(new Choices(File.ReadAllLines(#"D:\Luke's Documents\Speech Commands\TestCommands.txt")))));
_recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(_recongizer_SpeechRecognized);
_recognizer.RecognizeAsync(RecognizeMode.Multiple);
}
void _recongizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
string speech = e.Result.Text;
if (speech.Contains("open" && "fire fox"))
{
System.Diagnostics.Process.Start(#"D:\Program Files (x86)\Mozilla Firefox\firefox.exe");
}
}
}
}
As you can see, I want to check if speech contains the words "open" and "fire fox". However, Visual Studio gives me an error saying that the && operator cannot be applied to strings. Is there a way of checking the text to see if contains those words or not? Any help at all will be appreciated.
The String.Contains() method takes a single string. "open" && "fire fox" does not evaluate to a string. If you want to check if a string contains two different values, do this:
if (speech.Contains("open") && speech.Contains("fire fox"))
{
...
}
You could create an extension method to help make this easier:
public static bool ContainsAll(this string str, params string[] values)
{
foreach (var value in values)
{
if (!str.Contains(value)) return false;
}
return true;
}
And then use it like this:
if (speech.ContainsAll("open", "fire fox"))
{
...
}

Exact Search, not partial [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
thanks everyone for your help, it gave me many ideas, and show me a lot o ways of using diferent functions or methods... this is my fourth day with C#, learning in home, with tutorials... the answer to this was like that
procs[i].ProcessNmae... is not a frase... but a LIST...
so i did this
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
if (procs[i].ProcessName == "firefox") //that way it search for the EXACT match...
{
using (var player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}
the public void chupala() is what i've created... the rest was downloaded, so it takes ALL running process... what i did is add that public void, so when I click the button IF firefox is open it will make a sound... the problem is that if a write "fire" it makes the sound too... i tested this WITH MY PROGRAM OPEN, close firefox... press the button... nothen happens... open firefox... click the button, the sound activates... but if i have another application that starts or contains the word fire it will make the sound anyway :s thats why i need it to find the EXACT match...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Media;
namespace SimpleTaskManager
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Process[] procs;
public void GetProcesses()
{
procs = Process.GetProcesses();
if (Convert.ToInt32(label2.Text) != procs.Length) // Check if new processes have been started or terminated
{
listBox1.Items.Clear();
for (int i = 0; i < procs.Length; i++)
{
listBox1.Items.Add(procs[i].ProcessName); // Add the process name to the listbox
}
label2.Text = procs.Length.ToString();
}
}
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
bool b;
b = (procs[i].ProcessName.Contains("fire"));
if (b)
{
using (SoundPlayer player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
GetProcesses();
}
// Check every 1 second for changes in the processes list
private void timer1_Tick(object sender, EventArgs e)
{
GetProcesses();
}
private void button1_Click(object sender, EventArgs e)
{
chupala();
// procs[listBox1.SelectedIndex].Kill(); // Kill the process coresponding to the selected index of listbox1
}
private void kIllProcessToolStripMenuItem_Click(object sender, EventArgs e)
{
procs[listBox1.SelectedIndex].Kill();
}
public void lsit()
{
}
}
}
Another way you can do this is to use a regex to search, and putting your search term between word boundarys \b:
// Returns false
Regex.IsMatch("The quick brown fox jumps over the lazy dog", #"\bfo\b")
// Returns true
Regex.IsMatch("The quick brown fox jumps over the lazy dog", #"\bfox\b")
You can read more about word boundaries here:
Simply put: \b allows you to perform a "whole words only" search using a regular expression in the form of \bword\b. A "word character" is a character that can be used to form words. All characters that are not "word characters" are "non-word characters".
Update because I got more info from original poster
Rewrite your chupala() method to use a Regex to do the search, instead of using the Contains method:
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
if (Regex.IsMatch(procs[i].ProcessName, #"\bFirefox\b"))
{
using (var player = new SoundPlayer(#"C:\bass.wav"))
{
player.Play();
}
}
}
}
Perhaps not the fastest search, but here is what you can do
Split your input string by delimiter (in your case this is SPACE - s1.Split(" "))
Iterate over the result array
Check if s2 equals to any of the items in the array
Try This:
string s1 = "The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
var words = s1.Split(' ');
foreach (var word in words)
{
b = word.Equals(s2);
if (b)
break;
}
Console.WriteLine("Is the string, s2, in the string, s1?: {0}", b);
MSDN :
The search begins at the first character position of this string and continues through the last character position.
This is a reason why you get the result True. if you want to search for exact string, you can Regex.
EDIT: I get an updated question
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
bool b;
// Use Regex in here, assume that ProcessName of Firefox app is Firefox
b = Regex.IsMatch(procs[i].ProcessName, #"(^|\s)Firefox(/s|$)");
if (b)
{
using (SoundPlayer player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}

Listing integers from a text file into a listview

I'm creating an app in winforms c# using vs 2013.
In the app I have a textfile to which I'm saying the time in int format using a custom format from a time select dropdown list.
I then want to display what is in that text file on a selectable listview from where I can remove it from the textfile etc. I'm almost there however at the moment when I try to add the items into the listbox they do seem to add however they do not display correctly.
For example say in my text file there is
22102210
19101610
17182218
10272227
Then that is how it should be displayed in the listview as selectable ready to be deleted.
At the moment it isn't showing correctly, it's showing up as 1.. 2.. 1..
Could someone help me out and point me in the right direction as to why this might be happening? Any help much appreciated. This is my class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Chronos
{
public partial class Interface : Form
{
private string[] getTimes = System.IO.File.ReadAllLines(#"G:\Dropbox\University\Chronos\Application\Chronos\Chronos\AdminAccount\Times.txt");
public Interface()
{
InitializeComponent();
}
private void Interface_Load(object sender, EventArgs e)
{
PopulateList();
}
private void PopulateList()
{
int size = getTimes.Length;
lstTime.Items.Clear();
GetTimes();
for (int i = 0; i < size; i++)
{
lstTime.Items.Add(getTimes[i]);
}
}
private void GetTimes()
{
string[] getTimes = System.IO.File.ReadAllLines(#"G:\Dropbox\University\Chronos\Application\Chronos\Chronos\AdminAccount\Times.txt");
}
private void btnAdd_Click(object sender, EventArgs e)
{
string time = pickerTimeStart.Value.Hour.ToString() + pickerTimeStart.Value.Minute.ToString() + pickerTimeEnd.Value.Hour.ToString() + pickerTimeEnd.Value.Minute.ToString();
System.IO.File.AppendAllText(#"G:\Dropbox\University\Chronos\Application\Chronos\Chronos\AdminAccount\Times.txt", time + Environment.NewLine);
PopulateList();
MessageBox.Show("Time added", "Ok");
//PopulateList();
}
}
}
As currently written, GetTimes does nothing except read the file:
private void GetTimes()
{
// "string[]" here overrides the outer scope
string[] getTimes = System.IO.File.ReadAllLines(#"G:\Dropbox\University\Chronos\Application\Chronos\Chronos\AdminAccount\Times.txt");
}
If you change it to this, it becomes more useful:
private string[] GetTimes()
{
return File.ReadAllLines(#"G:\Dropbox\University\Chronos\Application\Chronos\Chronos\AdminAccount\Times.txt");
}
... and then PopulateList can simply become:
lstTime.Items.Clear(); //so you aren't getting a bunch of dupes
lstTime.Items.AddRange(GetTimes().Select(t => new ListViewItem(t)).ToArray());
You can also remove this line because you don't need to keep a copy of the data in the class:
private string[] getTimes = ...
Note: If you decide to keep the data source local and not work solely against the file, much of this would change.

Categories