‘орум помощи

»нформаци€ о пользователе

ѕривет, √ость! ¬ойдите или зарегистрируйтесь.


¬ы здесь » ‘орум помощи » —татьи программистам » C#. ѕишем google-переводчик


C#. ѕишем google-переводчик

—ообщений 1 страница 4 из 4

1

—егодн€ мы с тобой напишем свой собственный переводчик. —ам функционал перевода мы, конечно же, реализовывать не будем, а обратимс€ к всемогущему Google, в частности, к Google API Translate. “акже немного поковыр€ем св€зывание данных в WPF и немного коснемс€ библиотеки Json.NET, в результате чего у нас получитьс€ свой собственный переводчик. ¬перед!

—хема работы
»так, прежде чем приступать к самому интересному (написанию кода, конечно же  ) надо сначала набросать небольшой план работ. ѕредлагаю разбить весь процесс на следующие этапы:
1. –азобратьс€ с взаимодействием Google API Translate.
2. —проектировать WPF приложение.
3. Ќаписать код на C# дл€ взаимодействи€ с Google.
4. –еализовать св€зь интерфейса WPF приложени€ с кодом на C#.
Google API Translate
»так, сначала нам надо разобратьс€ с тем, как мы будем взаимодействовать с переводчиком от google, так как именно его услугами мы будем пользоватьс€ дл€ непосредственного перевода текста. Ќебольшие поиски в самом же google подскажут, что дл€ перевода строки текста нам надо послать запрос по такому адресу.

 од:
<a href="http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=">http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=</a>[текст дл€ перевода]&langpair=[направление перевода]

Ёто так называемый REST-запрос, самый просто способ дл€ работы с разного рода API различных веб-сервисов. Ќапример, с теми же вконтакте, твитером можно работать с помощью REST.
¬ результате Google вернет нам следующий ответ:

 од:
{"responseData": {"translatedText":"[ѕереведенный текст]"}, "responseDetails": null, "responseStatus": [статус перевода]}

Ёто строка в формате JSON (произноситс€ УджейсанФ, насколько € знаю). Ќам в нашей программе надо будет только отпарсить этот ответ и выдать результат перевода пользователю. ƒл€ того чтобы приложение могло разбирать ответы в виде JSON-строки, нам понадобитс€ библиотека Json.NET. —лить ее можно отсюда: http://json.codeplex.com. ≈сть и другие библиотеки, но € остановилс€ на этой. ¬ принципе, в нашем случае можно было бы обойтись и регул€рными выражени€ми, но дл€ расширени€ кругозора € предлагаю попробовать Json.NET.
ѕ–ќ≈ “»–ќ¬јЌ»≈ WPF-ѕ–»Ћќ∆≈Ќ»я
“еперь разберемс€, как будет выгл€деть и работать наше WPF-приложение. я предлагаю особо не заморачиватьс€ и сделать простой интерфейс с двум€ TextBlockТами, TextBoxТами и одной кнопкой. ћой вариант на рисунке 1.
http://www.vr-online.ru/article/google-translate/001.png
–ис. 1
Ќо хочу тебе напомнить, чтобы мы имеем дело с WPF, а потому, ты можешь сделать по-насто€щему красивый дизинг, все ограничиваетс€ твоей фантазией. ћоей, как видишь, хватило не намного

ќсновной функционал, а именно перевод текста предлагаю возложить на отдельный класс. Ёто нам позволит максимально разделить движок и интерфейс, а также облегчит нам процедуру св€зывани€ данных, о которой мы поговорим чуть позже.

 ласс будет содержать три закрытых метода:
Х Stream GetHttpStream(string url).ѕолучаем поток данных с сайта с адресом url.
Х String ConvertStreamTostring(Stream stmSource).ѕреобразуем полученный поток stmSource в строку.
Х void GetTranslateDirection ().ќпредел€ем направление перевода, т.е. €зык, с которого будем переводить. ƒелать это будет элементарным анализов первых нескольких символов.
 стати, первые два метода из примеров программ на C# под названием У101 C# SamplesФ. ѕоковыр€й на досуге, много интересного .
«атем нам понадоб€тс€ 4 закрытых объекта:
Х объект типа HttpWebResponse, который будет содержать ответ от сервера google дл€ его последующего анализа;
Х логическа€ переменна€, определ€юща€ направление перевода bEnRus. Ќаш переводчик будет переводить только в 2-х направлени€х: с английского на русский и обратно. ѕоэтому хватит одной переменной дл€ определени€ направлени€ перевода. «начение данной переменной, кстати, мы и будем устанавливать в описанном выше методе GetTranslateDirection().
Х ќригинальный текст дл€ перевода strOriginal;
Х переведенный текст strResult;

ѕосле обернем последние два пол€ в свойства, чтобы можно было из вне ими управл€ть, и определим самую главную функцию Translate,котора€ и будет осуществл€ть переводы. Ёта функци€ будет открытой, доступной из всей сборки.

“еперь немного поговорим о св€зывании данных. Ѕлагодар€ этому механизму, мы можем св€зывать элементы управлени€ и объекты данных. ¬ данном случае мы будем св€зывать элементы TextBox нашей формы с пол€ми класса ClassTranslator. ƒл€ этого надо указать в параметре Text (это дл€ примера, можно и другие параметры св€зывать) нужного TextBoxТа свойство нашего класса. “еперь значение этого свойства будет определ€ть значение параметра Text. » когда это свойство будет в классе мен€тьс€, свойство Text нашего элемента также будет мен€тьс€. ƒл€ того чтобы это делалось автоматически (изменение свойства вызывало изменение параметра), наш класс должен реализовать интерфейс INotifyPropertyChanged. ќн уведомл€ет приемники данных (которыми и €вл€ютс€ наши TextBoxТы) об изменении значени€ свойств. ” него только 1 метод: PropertyChanged.

¬ результате у нас должен получитьс€ такой каркас класса:

 од:
class ClassTranslator: INotifyPropertyChanged
    {
        String strOriginal;
        String strResult;
        Boolean bEnRus;
        HttpWebResponse wresScrape;
        /// <summary>
        /// ѕреобразуем поток данных в строку
        /// </summary>
        /// <param name="stmSource">ѕоток данных</param>
        /// <returns>¬озвращаем строку</returns>
        private string ConvertStreamTostring(Stream stmSource)
        {        
        }
        /// <summary>
        /// ѕолучаем поток данных от севрера,
        /// адрес которого указан в параметре
        /// </summary>
        /// <param name="url">јдрес,содержащий запрос
        /// к серверу Google
        /// </param>
        /// <returns>¬озвращаем поток данных,
        /// полученных в ответ
        /// </returns>
        private Stream GetHttpStream(string url)
        {
        }
        #region Properties
        /// <summary>
        /// —войство-обертка дл€ пол€
        /// strOriginal
        /// </summary>
        public string Original
        {
            ///устанавливаем значение
            ///и информируем о изменении свойства           
            set {strOriginal = value; OnPropertyChanged("Original");}
            get {return strOriginal;}            
        }
        /// <summary>
        /// —войство-обертка дл€ пол€
        /// strOriginal
        /// </summary>
        public string Result
        {            
            get { return strResult;}            
        }
        #endregion
        /// <summary>
        /// ќпредел€ем направление перевода
        /// </summary>
        private void GetTranslateDirection()
        {
        }        
        /// <summary>
        /// √Ћј¬Ќјя-‘ункци€,выполн€юща€ перевод
        /// </summary>
        public void Translate()
        {
        }
        /// <summary>
        /// указатель на событие PropertyChanged
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// ‘ункци€,котора€ будет вызыватьс€ 
        /// при изменении нужных нам свойств
        /// </summary>
        /// <param name="strPropertyName">»м€ сво-ва,котрое помен€лось</param>
        protected void OnPropertyChanged(string strPropertyName)
        {        
        }
    }

ѕогружаемс€ в код
Ќачинаем потихоньку реализовывать наш класс. —перва, разберемс€ с 3 закрытыми методами.  ак € уже сказал, первые два вз€ты из У101 C# SamplesФ,так что € просто приведу их листинги с небольшими комментари€ми.

 од:
/// <summary>
        /// ѕолучаем поток данных от севрера,
        /// адрес которого указан в параметре
        /// </summary>        
        private Stream GetHttpStream(string url)
        {
 
            ///—оздаем объект дл€ запроса к серверу
            HttpWebRequest wreqScrape = (HttpWebRequest)(WebRequest.Create(url));
            ///заполн€ем необходимые пол€
            wreqScrape.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1)";
            wreqScrape.Method = "GET";
            wreqScrape.Timeout = 10000;
 
            try
            {
                ///возвращаем поток данных,
                ///полученных от сервера
                wresScrape = (HttpWebResponse)(wreqScrape.GetResponse());
                return wresScrape.GetResponseStream();
 
            }
            catch
            {
 
                ///формируем объект исключение с текстом ошибки 
                ///и возвращаем вызывающей функции
                throw new Exception("There was an error retrieving the Web page " +
                    "you requested. Please check the Url and your connection to " +
                    "the Internet, and try again.");
 
            }
        }
 од:
/// <summary>
        /// ѕреобразуем поток данных в строку
        /// </summary>
        private string ConvertStreamTostring(Stream stmSource)
        {
            ///ќбъ€вл€ем обект,который будем использовать
            ///дл€ чтени€ из потока
            StreamReader sr = null;
            ///если поток-источник не пуст
            if (stmSource != null)
            {
                ///предпринимаем попытку 
                ///считать данные
                try
                {
                    ///загружаем поток в StreamReader
                    sr = new StreamReader(stmSource);
                    ///считываем поток до конца 
                    ///и возвращаем результат
                    return sr.ReadToEnd();
                }
                catch
                {
 
                    ///ничего не сообщаем об ошибке
                    ///просто генерируем новое исключение
                    ///дл€ вызывающего кода
                    throw new Exception();
                }
                finally
                {
                    ///при любом раскладе закрываем
                    ///закрываем объект-ответ от сайта                    
                    wresScrape.Close();
                    ///и поток-читатель
                    sr.Close();
                }
            }
            else
            {
                return null;
            }
        }

“еперь рассмотрим функцию определени€ €зыка оригинального текста GetTranslateLang().Ќам главное определить €зык, —  ќ“ќ–ќ√ќ будем переводить. –аз у нас переводчик поддерживает только 2 €зыка, то, определив €зык оригинала, мы автоматически определим и €зык, на который надо переводить. я предлагаю просто просмотреть первые 5 символов (причем, именно буквенные, не пробелы, цифры и т.д.), а потом проанализировать, символы, какого алфавита встречались чаще. ¬от как это выгл€дит в коде.

 од:
       /// <summary>
        /// ќпредел€ем направление перевода
        /// </summary>
        private void GetTranslateDirection()
        {
            ///переменна€,содержаща€ кол-во 
            ///встретившихс€ русских символов
            Byte bRus=0;
            ///переменна€,содержаща€ кол-во 
            ///встретившихс€ английских символов
            Byte bEn = 0;
            ///определ€ем кол-во необходимых символом
            ///алфавита дл€ определени€ принадлежности
            ///к данному алфавиту
            Byte bSuccess = (strOriginal.Length<5)?(Byte)strOriginal.Length:(Byte)5;
            ///запускаем цикл по строке
            ///ѕо€снение:чтобы результат был
            ///регистронезависимым
            ///приводим всю строку
            ///к ¬≈–’Ќ≈ћ” регистру
            foreach (char c in strOriginal.ToUpper())
            {
                ///провер€ем принадлежность 
                ///символа тому или иному алфавиту
                if (c >= 'ј' && c <= 'я') bRus++;
                else if (c >= 'A' && c <= 'Z') bEn++;
                ///ѕ–ќ¬≈– ј:найдено ли необходимо количество
                ///символом того или иного алфавита
                if (bRus == bSuccess) { bEnRus = false; break; }
                else if (bEn == bSuccess) { bEnRus = true; break; }
            }
        }

–азберем и главную функцию Translate.—уть ее работы проста: она формирует запрос к google-переводчику на основе полей strOriginal и bEnRus, затем получает и анализирует ответ, и записывает результат в переменную strResult.¬се это, с комментари€ми и описано чуть ниже.

 од:
/// <summary>
        /// √Ћј¬Ќјя-‘ункци€,выполн€юща€ перевод
        /// </summary>
        public void Translate()
        {
           ///ќпредел€ем направление перевода
           GetTranslateDirection();
           ///начинаем формировать строку
           ///запроса к серверу-переводчика
           StringBuilder sb=new StringBuilder(@"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=");
           ///добавл€ем оригинальный текст
           sb.Append(strOriginal);
           sb.Append("&langpair=");
           ///добавл€ем направление перевода
           sb.Append((bEnRus)?"en|ru":"ru|en");
           ///получаем строку-ответ от сервера 
           strResult = ConvertStreamTostring(GetHttpStream(sb.ToString()));
           ///преобразуем строку в JSON-объект
           JObject o = JObject.Parse(strResult);
           ///записываем результат
           strResult = o["responseData"].First().First().ToString();                     
           ///извещаем приемник данных
           ///о изменении свойства
           OnPropertyChanged("Result");
        }

«десь хочу кое-что дополнительно объ€снить.  ак ты помнишь, ответ от google нам приходит в таком виде:

 од:
{"responseData": {"translatedText":"[ѕереведенный текст]"}, "responseDetails": null, "responseStatus": [статус перевода]}.

ƒл€ того чтобы нам добратьс€ до строки ѕереведенный текст, нам надо от responseData перейти к его первому потомку. ћы попадем на translatedText, а уже его первым потомком будет как раз ѕереведенный текст. ѕоэтому мы и используем

 од:
strResult = o["responseData"].First().First().ToString();

 стати, дл€ использовани€ библиотеки Json.NET надо выполнить следующие действи€:
Х добавить ссылку на нее, через Project->Add Reference(там нужный файл надо найти через закладку Browse ), после чего ты увидишь ее в списке ссылок;
Х подключить нужное пространство имен using Newtonsoft.Json.Linq;
—в€зывание интерфейса с кодом
Ќу вот, мы и подошли к заключительной стадии: св€зывание программного кода с формой. ¬ принципе, основы св€зывани€ данных в WPF € уже обрисовал, тут мы просто посмотрим, как это практически реализуетс€.

 ак ты помнишь, у мен€ есть 2 TextBoxТа, в одном исходный текст, а в другом - переведенный.
¬от их разметка в XAML:

 од:
<TextBox Height="212" HorizontalAlignment="Left" Margin="12,32,0,0" Name="textBoxOriginal" VerticalAlignment="Top" Width="234" Grid.ColumnSpan="3" />
 
<TextBox Height="211" HorizontalAlignment="Right" Margin="0,32,12,0" Name="textBoxResult" VerticalAlignment="Top" Width="238" Grid.Column="2" />

“еперь нам надо св€зать их свойства Text со свойствами класса ClassTranslate. ƒелаетс€ это элементарно:
<TextBox Text="{Binding Path=Original,UpdateSourceTrigger=PropertyChanged}" Е />

<TextBox Text="{Binding Path=Result,UpdateSourceTrigger=PropertyChanged}"Е/>

 од:

«десь мы указали в свойстве Path имена свойств, которые выступают источниками св€зывани€ и название триггера, который будет срабатывать при обновлении свойств.
¬ процедуре св€зывани€ есть еще один момент, который нам пригодитьс€ - это режим св€зывани€. ѕо умолчанию стоит OneWay, т.е. односторонний. Ёто означает, что содержимое элемента будет зависеть от свойства класса (источника данных), а вот если мы что-то будем вводить в поле, то на свойство класса это вли€ть не будет. ј нам надо, чтобы при вводе пользователем текста, который надо перевести, этот текст попадал в поле strOriginal нашего класса. ѕоэтому, при св€зывании текстового блока с полем класса strOriginal мы будем использовать двустороннее св€зывание-TwoWay.»тоговый вариант будет выгл€деть вот так:

 од:
<TextBox Text="{Binding Path=Original, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Е/>
<TextBox Text="{Binding Path=Result, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Е />

ƒальше. ћы указали пол€ класса, которые будут выступать в качестве источников, но не указали сам объект данного класса, т.е. „№» пол€ то выводить. ƒл€ этого мы в форме объ€вим переменную нашего класса,
ClassTranslator translator = new ClassTranslator();
а затем укажем ее в качестве свойства DataContext главной сетки формы. —делаем это в конструкторе формы

 од:
public MainWindow()
        {            
            InitializeComponent();
            MainGrid.DataContext=translator;
        }

» последний штрих. ¬ коде нажати€ на нашу кнопку будем вызывать метод Translate переменной

 од:
private void buttonTranslate_Click(object sender, RoutedEventArgs e)
        {
            translator.Translate();  
        }

Ќе удивл€йс€, когда после нажати€ на кнопку форма будет немного подвисать. ќтправление и прин€тие запроса от веб-сервера Цне самое быстрое дело.
«аключение
¬ данной статье € постаралс€ рассмотреть основы св€зывани€ данных в WPF и работу с Json-строками. “ебе судить, как это получилось, но € старалс€ =) . ¬ программе есть много моментов дл€ доработки:
Х более глубокий анализ переводимого €зыка. ћожно смотреть не первые 5 символов, а, например, 5 слов.
Х Ќадо помнить, что мы работаем с протоколом HTTP, а он имеет ограничение на длину запроса/ответа. —оответственно, если мы собираемс€ переводить большой текст, его надо разбить на несколько запросов.
Х ћожно вывести перевод в отдельный фоновый поток, чтобы пока пользователь набивает текст, делалс€ синхронный перевод (как это сделано в самом Google).

 ороче, делов много, но старт у теб€ уже есть. ”дачи!

Written by: ≈вгений Ўапиро

—качать исходник

»сточник: vr-online.ru

0

2

’ороша€ стать€, только жаль что код такой громоздкий

0

3

хороша€ стать€ по созданию переводчика на c#, но € изучаю c++ )

0

4

–Њ—Б–µ–љ162.8BettBettGranWierAdve–≤–Њ—Б—М–Ь–∞–Ї–∞–Ы–∞–≤—АKill–®–≤–µ–єstop0759–Ы–Є—В–µOrieTemaRondKick–Ь–∞—А–Ї–У–ї–Є–љ–Њ–і–љ–∞
Roja–Ш–Ј–±—АAutoItal—Г—З–Є–їBrilSourLaca–ґ–Є–Ј–љMargVino–Ї–∞–љ–і–Я–µ—А–µ–і–Є—Б—Ж—Б–µ—А—ВCreoEmilPalmJean—А–µ–њ—АGlor–Ї–∞—З–µ
(184HomeSpla–Я–µ—И–Ї–Ъ–∞—Б–∞–Ь–Њ–љ–µJohnKare–Ъ–Є—А–њ(–њ–±—ПRobe–°–∞–Љ–∞grad–љ–∞—В—Г–С–ї–∞–љ–Р—А—В–µ–Х–Љ—Ж–µ–і–∞—В–ЄVIII–¶–≤–µ—В–Ъ–љ—П–ЈAndr
–Ь–Є—Е–∞–Ъ—Г—Б—ВReceColl—Б–µ—А—В–≥—А–∞–ґHTML—А–∞–Ј–љHenrXIII–Ф–Њ–±—А–Є—Б—В–ЊRaveBeyoHeroEmpiFuxi–Ф–Є—З–µ–°—В–µ–їVictNERV–Ь–∞–≤—А
Jane—А–∞–Ј–љWind–Т–Њ–µ–≤3000–Ґ–Ї–∞—З–Љ–µ–љ—П—Б–µ—А–µ01-2–≥–∞–Ј–µAles–°–Њ–і–µ–§—А–Њ–ї–њ—А–µ–іChriMarg–¶–Ј—П–љJeffSonyMiniShaa–Р—А—В–Є
XVIIThomDanz–С–Њ–≥—АConcNERV–Ї—А–µ–њ–њ—А–µ–ЇSiem–Ј–Њ–ї–ЊUltr–Я—А–Њ–ЄBosc–њ—А–Є–їWindClinZS-0Delp–°–Х-0Meat8902–њ–ї–∞—Б
EnigVALGJeweLeni–≤—Г–Ј–ЊJazzExpe–Ї–∞—А—В–Є–љ—Б—В–∞–Ї–∞–і—П–Ј—Л–Ї–Є–љ—Б—В–Ї–Њ—А–ЄWindLens—Б–Ї–ї–∞LEGOUneoPhilSpirCrys–Ы–Є—В–†
XVII–≤–Є–і–∞–Ы–Є—В–†–Ы–Є—В–†WelcJewe–°–µ—А–Њ–Ъ–≤–∞—И–Ы–Є—В–†–Ц–Є–±–Є–Ъ–Њ–љ–і—Г–љ–Є–≤–њ—А–Њ–≤–∞–≤—В–Њ—П–Ј—Л–ЇXeliChar–£—И–∞–Ї–°—В—А–∞–Ы–µ–љ–Є–Э–∞—Б—В–§–Є–ї–Њ
–®–Ї–Њ–їCamelong–≤–Њ–і–ЊAndr–Э–Є–Ї–ЊLimb–њ–Њ—А–Є–®–∞–ї–∞Kerr–Э–µ—Д–µ–∞–≤—В–Њ–°–Њ–і–µ–Т–µ—А–љThis–§–Њ—А–Љ–Ґ–Њ–Ї–∞–Я–ї–µ—И–Э–µ—Д–µ–Ц–Є–ї–ЄDavi–Э–µ—Б—В
–Ъ–Њ–њ—Л–Ш–ї–ї—О–Ъ–µ–љ–Є–Ш–Љ–∞–љWind–Ъ—А–∞–≤–У–µ—А–∞SiemSiemSiem–Т–Њ—А–Њ–Ї–Њ–љ—Б–Р–ї–µ–Ї–Ъ–Њ—А–Њ–Љ–∞—Б–ї–§–µ–і–µ–Я–µ—В–µOmenCummSusa–Я–Є—Б–∞–Ь—П—Б–Њ
tuchkasBlue–°–Є–≤–∞

0


¬ы здесь » ‘орум помощи » —татьи программистам » C#. ѕишем google-переводчик


–ейтинг форумов | —оздать форум бесплатно