readonly vs const
Модификатор readonly защищает элементы класса от модификации после построения. Поле с readonly может быть модифицировано только при создании объекта класса или внутри конструктора.
3 отличия:
- Константа должна быть инициализирована при объявлении
- Readonly может быть модифицировано в конструкторе
- Readonly может быть присвоено значение, являющееся результатом вычислений
Static
Если переменная в классе статическая, то к ней из вне можно обратиться через имя класса:
ClassName.variable
Чтобы всегда можно было обратиться из вне, функция Main всегда статична. Константы тоже всегда статичны, там можно даже не указывать static.
Классы: деструкторы
Когда программа запускается, то сначала создается объект, выполняется конструктор. В конце программы конструктор удаляется, а деструктор вызывается.
class Dog { public Dog() { Console.WriteLine("Konstructor"); } ~Dog() { Console.WriteLine("Destructor"); } } static void Main(string[] args) { Dog d = new Dog(); } /* Outputs: Constructor Destructor */
Работа со строками в C#
string a = "Some text"; ConsoleWriteLine(a.Lenght); //9 ConsoleWriteLine(a.IndexOf('t')); //5 a = a.Insert(0, "This is "); ConsoleWriteLine(a); //This is Some text a = a.Replace("This is", "I am"); ConsoleWriteLine(a); //I am Some text if(a.Contains("some")) ConsoleWriteLine("found"); //found a = a.Remove(4); ConsoleWriteLine(a); //I am a = a.Substring(2); ConsoleWriteLine(a); //am
Подсчет популярности слов в тексте
#Взять из github-репозитория все файлы с новостями в формате txt: newsfr.txt, newsit.txt, newsafr.txt, newscy.txt. #Написать программу, которая будет выводить топ 10 самых часто встречающихся в новостях слов длиннее 6 символов для каждого файла. #Не забываем про декомпозицию и организацию кода в функции. В решении домашнего задания вам могут помочь: split(), sort() или sorted(). # фукнция чтения файлов (ГОТОВО) def read_files(name): import chardet with open(name, 'rb') as f: data = f.read() result = chardet.detect(data) original_text = data.decode(result['encoding']) return original_text # функция подсчета слов длиннее 6 символов (ГОТОВО) def count_word(original_text): to_list = original_text.split(' ') to_set = set() for i in to_list: # заполняем множество с уникальными словами длиной больше 6 символов if len(i) > 6: to_set.add(i) word_value = {} # ищем слова из множества в списке, считаем количество, формируем словарь типа слово:количество for i in to_set: count = 0 for j in to_list: if i == j: count += 1 word_value[i] = count return word_value # возвращаем словарь {слово:количество} # функция сортировки и вывода ТОП-10 def sort_top(word_value): register = list() l_dict = str(len(word_value)) for i in word_value.items(): l_word = str(i[1]) register.append((len(l_dict)-len(l_word))*'0' + str(i[1]) + ' ' + i[0]) # разворачиваем и добавляем нули перед количеством для сортировка, делаем слияние элементов = '00012 слово' register.sort(reverse = True) top_10_list = list() top_10 = {} count = 1 for j in register: top_10[count] = j.split(' ') # получаем словарь типа {1: (количество, слово)} top_10[count][0] = int(top_10[count][0]) if count == 10: break count += 1 return top_10 # возвращаем отсортированный словарь ТОП-10 {номер: (количеств, слово)} # главная функция: запрашивает имя файла, запускает другие функции (ГОТОВО) def main(): while True: name = input('Введите имя файла: newsfr.txt, newsit.txt, newsafr.txt, newscy.txt. Выход - exit: ') if name == 'newsfr.txt' or name == 'newsit.txt' or name == 'newsafr.txt' or name == 'newscy.txt': print('Идет обработка файла ...') top_10 = sort_top(count_word(read_files(name))) for k in top_10.values(): print (k[0], ': ', k[1]) elif name == 'exit': break else: print('Некорректный ввод, повторите.') main()
- сортировка через list.sort() — по умолчанию так, если нужна обратная сортировка, то list.sort(reverse=True), если по какому-то ключу, то list.sort(key=[ключ]). Если нужно, чтобы функция возвращала значение, то используем sorted вместо sort;
- функция chardet для автоматического определения кодировки и перевода в UTF-8.
Аналог с JSON с доработками предыдущего кода (сортировка словаря по значениям через лямбда-функцию):
#Взять из github-репозитория все файлы с новостями в формате json: newsfr.json, newsit.json, newsafr.json, newscy.json. #Написать программу, которая будет выводить топ 10 самых часто встречающихся в новостях слов длиннее 6 символов для каждого файла. #Не забываем про декомпозицию и организацию кода в функции. В решении домашнего задания вам могут помочь: split(), sort() или sorted(). #{'rss': {'_version': '2.0', # '_xmlns:votpusk': 'https://www.votpusk.ru/news.asp', # 'channel': {'category': 'ВгаШЧЬ - єШЯа', # 'description': 'єШЯа - »ХЭвР вгаШбвШзХбЪШе ЭЮТЮбвХЩ ' # 'ЯЮавРЫР І ѕВїГБє.АГ ', # 'items': [{'_id': '545166', # 'description': 'ІЫРбвШ єШЯаР аРббзШвлТРов ' def read_files(name): 'Функция чтения файлов' import json import chardet with open(name, 'rb') as f: data = f.read() result = chardet.detect(data) data = data.decode(result['encoding']) data = json.loads(data) # внимание! load читает файл, loads читает строку original_text = '' for items in data['rss']['channel']['items']: original_text += ' ' + items['description'] return original_text def count_word(original_text): 'функция подсчета слов длиннее 6 символов' to_list = original_text.split(' ') word_value = {} for word in to_list: if len(word) > 6: if word in word_value: word_value[word] += 1 else: word_value[word] = 1 return word_value # возвращаем словарь {слово:количество} def sort_top(word_value): 'функция сортировки и вывода ТОП-10' l = lambda word_value: word_value[1] sort_list = sorted(word_value.items(), key = l, reverse = True) count = 1 top_10 = {} for word in sort_list: top_10[count] = word count += 1 if count == 10: break return top_10 def main(): 'главная функция: запрашивает имя файла, запускает другие функции' while True: name = input('Введите имя файла: newsfr.json, newsit.json, newsafr.json, newscy.json. Выход - exit: ') if name == 'newsfr.json' or name == 'newsit.json' or name == 'newsafr.json' or name == 'newscy.json': print('Идет обработка файла ...') top_10 = sort_top(count_word(read_files(name))) for i in top_10.values(): print (i[1], ': ', i[0]) elif name == 'exit': break else: print('Некорректный ввод, повторите.') main()
Классы: свойства
Инкапсуляция дает доступ только через публичные методы, а свойства дают возможность реализации гибкого механизма чтения, записи и вычисления приватного поля. Свойства используют элементы доступа get, set.
class Person { private string name; public string Name { get { return name; } set { name = value; } // тут можно прописать условия, а не просто присваивание } } // Закомментированный код ниже заменяет весь код внутри класса Person // public string Name { get; set; } static void Main(string[] args) { Person p = new Person(); p.Name = "Bobik"; Console.WriteLine(p.Name); }
Свойства могут называться как угодно, но принято для понимания кода называть их по имени переменной, но только с большой буквы: name => Name.
Также есть автоматически реализуемые свойства (краткая запись, если нет необходимости реализовать логику в set).
public string Name { get; set; }
Классы: конструктор
Если при создании нового объекта класса нужно что-то автоматически сделать (например, вывести текст, отправить смс) используются конструкторы класса.
class Person { private int age; public Person() { Console.WriteLine("Привет!"); } }
Конструктор имеет такое же имя, что и класс, является публичным и не имеет никакого возвращаемого типа.
При создании объекта класса, реализованного выше Person p = new Person(), будет выведено сообщение «Привет!».
ООП: инкапсуляция
Инкапсуляция — это управление окружением объекта, возможность дать доступ или ограничить его. Реализуется через модификаторы доступа private, public, protected, internal, protected internal.
Методы: перегрузка
Если для разных типов данных или при разном количестве передаваемых аргументов нужно запускать разные методы, то имеется возможность перегрузки методов.
static void Print(int a) { Console.WriteLine("Value: " + a); } static void Print(double a) { Console.WriteLine("Value: " + a); } static void Print(string label, int a) { Console.WriteLine(label + a); } static void Main(string[] args) { Print(11); Print(4.13); Print("Ответ: ", 14); }
Перегрузка работает только при разных типах аргументов. Следующий код выведет ошибку:
int Print(int a) {} float Print(int a) {} double Print(int a) {}