Собственно, ошибка: TypeError:
a bytes-like object is required, not 'str'
Ошибка в строке " sock.send('Hello, World") "
Ошибка нашлась в приложении клиента, вот собственно код клиента:
import socket
sock = socket.socket()
sock.connect(('localhost', 9090))
sock.send('hello, world!')
data = sock.recv(1024)
sock.close()
print(data)
Вот код сервера:
import socket
sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()
print('connected:', addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.send(data.upper())
conn.close()
Я этот пример вообще списал, т.к только-только (буквально пару минут назад) начал
изучение сокетов, а тут такое.
Ответы
Ответ 1
Метод socket.send ожидает последовательность байтов, а не строку. Чтобы преобразовать
строку в последовательность байтов, можно воспользоваться методом str.encode:
sock.send("hello, world!".encode())
Аналогично, если вы хотите получить не последовательность байтов, а строку, то можно
воспользоваться методом str.decode:
data = sock.recv(1024).decode()
По умолчанию в качестве кодировки будет использован UTF-8.
Помогите, пожалуйста, разобраться в закулисьях этого кода:
def someFunction():
list = []
for i in range(5):
list.append(lambda x: i ** x)
return list
#вызов функции
list = someFunction()
print(list[1](2))
По идее, результатом этого кода должна выступать единица, но на самом деле выводится
16. Я не совсем понимаю, как работает эта программа. По-моему:
Компилятор начинает свою работу с 1-ой строки. Видит def и пропускает всю функцию.
Затем добирается до строки
list = someFunction()
после которой начинает интерпретировать функцию someFunction. Добирается до цикла
for, и начинается первая итерация. Но команда, добавляющая элемент в конец списка,
в качестве аргумента принимает функцию, которая, в свою очередь, еще не получила в
распоряжение свой аргумент. Что добавилось в список? Я предполагаю, что создался объект
функции, который связался с конкретным элементом списка. Так, я думаю, происходит на
всех итерациях. После чего функция возвращает список, в котором находятся ссылки на
созданные объекты функций. Если всё так и есть на самом деле, то это логично.
Но что происходит при чтении элемента из списка? Окей. Если выплывает 16 вместо 1,
скорее всего, все объекты функций в качестве итерационной переменной принимают 4-ку,
т.е. последнюю итерацию. И здесь не совсем понятно, почему при создании объекта функции
не сохранилось значение счетчика цикла? Предполагаю, что вы можете мне сказать: "А
как, по-твоему, это значение сохранится, если его нет в параметрах lambda-функции?".
Но тогда как она находит и подставляет последнюю итерацию? Да и вообще, пока писал
этот пост еще больше запутался: с чего бы это компилятор создает объект-функции до
того, как эта функция вызывается? Ведь объект функции someFunction конструировался
тогда, когда мы вызвали эту функцию. А объекты lambda-функции создались ещё до их вызова.
Будьте добры, помогите разобраться в данном вопросе. Спасибо.
Ответы
Ответ 1
Переменная в вашем примере всегда будет равна 4 потому, что поиск переменной в объемлющей
области видимости (по правилу LEGB) происходит в момент вызова вложенной функции, а
не при создании объекта. Т.е. внутри лямбда-функции i - это "ссылка на i в объемлющей
области", а не "ссылка на int(0)" или "ссылка на int(4)".
Пример из ответа @aleks.andr с аргументом по умолчанию сработает потому, что вычисление
значения по умолчанию происходит один раз в момент создания вложенной функции (что,
кстати, тоже способно приводить к интересным эффектам, если создавать mutable-объект
и изменять его внутри функции: def f(a=[]): a.append(0) ; print(a))
P.S. Не перекрывайте builtin list в своем коде, это может привести к удивительным
последствиям.
Ответ 2
И здесь не совсем понятно, почему при создании объекта функции не сохранилось значение
счетчика цикла - она же ссылается на переменную i, которая после всех итераций осталась
равна 4.
Вам действительно нужно захватить переменную i при объявлении лямбды. Вот рабочий
код, возвращающий вашу единицу:
def someFunction():
list = []
for i in range(5):
list.append(lambda x,i=i: i ** x)
return list
#вызов функции
list = someFunction()
print(list[1](2))
Всем привет. Сегодня впервые столкнулся с проблемой, и не могу понять, в чем дело.
В Visual Studio 2015 скомпилил программу, все запускается нормально. Но из папки
проекта - никак. Тупо висит в процессах. Пробовал менять версии .net, менять разрядность
систем для запуска - 0 эмоций. Просто висит в процессах и все. При запуске (на F5)
из среды - запускается и работает отлично. В чем может быть проблема? Может, сталкивался
кто? Заранее спасибо.
P.S - все библиотеки стандартные, новых не подключал.
Ответы
Ответ 1
Если антивирус AVAST - пробуйте отключить или занести каталог с файлом в исключения.
Установил клиента Git, для изучения и дальнейшего использования был выбран Git Bash,
и вроде все работает, но есть один нюанс: Каталог по умолчанию, почему то установлен
сетевой диск, хотелось бы его изменить, как это сделать?
OS version: Windows 7 x64;
Git version: 2.6.3-64-bit;
Ответы
Ответ 1
Решение было найдено здесь
Необходимо изменить ярлык запуска Git Bash:
Вызываем контекстное меню для ярлыка: Клик правой кнопкой мыши по ярлыку, в открывшемся
меню выбираем свойства.
Устанавливаем необходимый путь: В поле Рабочая папка устанавливаем необходимый путь.
Так же мне потребовалось изменить строку запуска: в поле Объект удаляем в конце строки
--cd-to-home.
Запускаем клиента и убеждаемся в что что команда pwd отдает необходимый нам каталог
Ответ 2
Необходимо в проводнике вызывать контекстное меню правой кнопкой мыши и выбрать пункт
Git Bush here. Git Bush автоматически откроется в выбранной папке без изменения свойств
ярлыка.
Нужно написать скрипт на powershell. Есть любой IP адрес сети и маска (к примеру:
10.151.96.0/21), нужно вывести все возможные ip-адреса, удовлетворяющие адресу сети
и его маске. Как организовать этот цикл, чтобы работал с любым начальным условием?
Ответы
Ответ 1
Пока суть да дело, вот код на C# накатал:
using System;
using System.Net;
string rangeIP = "10.151.96.0";
int rangeMask = 21;
int wildcard = 32 - rangeMask;
byte[] ipb = IPAddress.Parse(rangeIP).GetAddressBytes();
Array.Reverse(ipb);
int ip = BitConverter.ToInt32(ipb, 0);
for (int i = 1; i < (1 << wildcard) - 1; i++) {
int ipi = ip | i;
byte[] ipib = BitConverter.GetBytes(ipi);
Array.Reverse(ipib);
Console.WriteLine(new IPAddress(ipib));
}
Сейчас попробую PowerShell вспомнить...
Во, так получилось:
$rangeIP = "10.151.96.0"
$rangeMask = 21
$wildcard = (32 - $rangeMask)
$ipb = [Net.IPAddress]::Parse($rangeIP).GetAddressBytes()
[Array]::Reverse($ipb)
$ip = [BitConverter]::ToInt32($ipb, 0)
For ($i = 1; $i -lt ((1 -shl $wildcard) - 1); $i++) {
$ipi = ($ip -bor $i)
$ipib = [BitConverter]::GetBytes($ipi)
[Array]::Reverse($ipib)
Write-Host (New-Object IPAddress(@(,$ipib)))
}
За соответствие кода канонам не отвечаю, я PS не знаю. :)
Положим, есть следуюший класс:
class Operation
{
public string Foo { get; set; }
public string Bar { get; set; }
public int Baz { get; set; }
}
Я хочу реализовать компарер IComparer. Код получается такой:
class OperationComparer : IComparer
{
public int Compare(Operation x, Operation y)
{
if (x.Foo == y.Foo && x.Bar == y.Bar && x.Baz == y.Baz)
return 0;
else
return 1; // ???
}
}
Однако непонятно, что возвращать, если свойства не равны. Когда возвращать 1, а когда −1?
Ответы
Ответ 1
Общий порядок написания компарера следующий:
Сравнить первое свойство, по которому происходит сравнение (сортировка), получив
−1/0/1 (меньше/равно/больше).
Если свойства не равны, вернуть −1 или 1 в соответствии с результатом сравнения.
Для изменения порядка сортировки вернуть противоположное число.
Если свойства равны, перейти к пункту 1 со следующим свойством. Если свойства кончились,
вернуть результат последнего сравнения как есть.
Код получается следующий:
class OperationComparer : IComparer
{
public int Compare(Operation x, Operation y)
{
int cmp = string.Compare(x.Foo, y.Foo);
if (cmp != 0)
return cmp;
cmp = string.Compare(x.Bar, y.Bar);
if (cmp != 0)
return cmp;
cmp = x.Baz.CompareTo(x.Baz);
return cmp;
}
}
Стоит отметить, что в современном коде подобные компареры обычно не нужны, так как
есть LINQ, в котором с помощью методов OrderBy и ThenBy ту же логику можно выразить
гораздо проще.
Пишу REST API приложение и при каждом запросе к серверу, сперва проверяю на наличие
интернет соединения, и только в случае положительного результата, посылаю запрос на
сервер.
Правильно ли я делаю? Или в каких случаях стоит выполнять проверку?
Ответы
Ответ 1
Ну когда правильно проверять наличие интернет соединения вопрос в общем случае довольно
спорный. У нас в компании в основном если и проверяем наличие соединения, то только
при запуске приложения что бы уведомить пользователя что без интернета приложение работать
не сможет. Если же интернет обрывается после открытия приложеньки, то просто обрабатываем
ошибки выполнения запросов и выводим пользователю соответствующие уведомления или вместо
очередного экрана приложеньки показываем заглушку с описанием что случилось.
Проверять при каждом запросе в любом случае бессмысленно ибо интернет может пропасть
после проверки, но до окончания выполнения запроса. Да и то что проверка прошла как
правило не гарантирует что интернет действительно есть, может соединение с каким нить
гуглом и проходит, а до вашего REST сервера не достучаться.
Создал таблицу в БД, но при добавлении символов кириллицы, символ '?', знаю что это
проблемы с кодировкой, но как установить UTF-8 в БД?
public static void Add_User(string login, string password, string firstName, string
secondName, string secretQuestion, string responseQuestion, DateTime birthDay)
{
string sqlExpression = "INSERT INTO Users (Login, Password, FirstName, SecondName,
Birthday, SecretQuestion, ResponseQuestion) " +
string.Format("VALUES (" + @"'{0}', '{1}', '{2}', '{3}', {4}, '{5}', '{6}'"
+ ")", login, password, firstName, secondName, birthDay.ToString("u").Replace(" 00:00:00Z",
""), secretQuestion, responseQuestion);
SqlCommand comAdd = new SqlCommand(sqlExpression, _dbConnection);
comAdd.ExecuteNonQuery();
}
Ответы
Ответ 1
Если вам нужен именно Unicode, то встроенной поддержки для хранения Unicode-ных строк
в кодировке UTF-8 в SqlServer нет, поддерживается только кодировка UTF-16.
Для хранения Unicode-ных строк существуют типы данных nchar и nvarchar. Соответственно
нужные столбцы в таблице должны иметь соответствующий тип. Например:
create table Users
(
FirstName nvarchar(20),
LastName nvarchar(30)
);
Если с типами всё в порядке, но, к примеру, такая
insert into Users (FirstName, LastName)
values ('Имя', 'Фамилия');
вставка создаёт запись с ???, то скорее всего collation базы данных отличается от
кириллического (проверить collation заданный для БД можно выполнив скрипт select collation_name
from sys.databases where database_id = db_id()).
В этом случае перед строковым литералом, содержащим нелатинские символы, добавьте
N, чтобы SqlServer воспринимал его как Unicode. Т.е., например, N'Имя' вместо 'Имя':
insert into Users (FirstName, LastName)
values (N'Имя', N'Фамилия');
Вообще для nvarchar литералов с нелатинскими символами я бы посоветовал добавлять
N всегда, чтобы не зависеть от collation базы.
Что касается кода вашего метода Add_User, то он уязвим для sql-injection атаки. Вместо
формирования строки с литералами безопаснее использовать параметризованный запрос.
Ответ 2
В SQL Server нет поддержки UTF-8, но есть UTF-16. Подробнее тут.
Установить кодировку в базе данных можно так.
ALTER DATABASE DBNAME COLLATE SQL_Latin1_General_CP1_CI_AS
или для cyrillic
ALTER DATABASE DBNAME COLLATE Cyrillic_General_CI_AS
Проверить кодировку в базе данных можно так
SELECT SERVERPROPERTY('Collation')
См. MSDN "Поддержка параметров сортировки и Юникода"
Нужно открыть файл, найти и заменить в нем одно слово (оно встречается в файле 1
раз) и сохранить под другим названием.
На баше эта задача решается вот так:
cat /tmp/test/file | sed "s/TEST_OLD/TEST_OLD/"> /tmp/test/file_new
C Питоном не очень, представляю что проблема решается как-то примерно так:
import re
output_file = open("/tmp/test/file").readlines()
string = "TEST_OLD"
string.replace(string,"TEST_NEW")
open("/tmp/test/file_new", "w")
Ответы
Ответ 1
Ну в целом верно, только модуль re не нужен, также стоит либо использовать with,
либо закрывать файлы file.close() после использования. Как то так в конечном итоге:
with open('test1') as file_in:
text = file_in.read()
text = text.replace("TEST_OLD", "TEST_NEW")
with open("test2", "w") as file_out:
file_out.write(text)
Да и readlines() возвращает список строк и это не совсем то что нам здесь нужно.
Update 0:
Для замены лучше использовать регулярные выражения, чтобы избежать проблем при включении
слова в другие и т.д. Спасибо @ReinRaus за замечание.
Обрати внимание на ответ @andy.37 Если файл объемный, то read() плохая идея, поскольку
так мы загрузим все содержимое файла в память. Правильный выбор в этом случае - построчное
чтение/запись.
Ответ 2
Не имеет смысл читать файл целиком и забивать память. Ну и вопрос при замене word
-> WORD, менять ли что-то в слове 'sword'?
def replace_in_file(file1, file2, pattern, subst, wordonly=True):
with open(file1, 'r') as f1:
with open(file2, 'w') as f2:
for line in f1:
if wordonly: # заменяем word -> WORD, но не sword -> sWORD
f2.write(re.sub('\b{}\b'.format(pattern), subst, line)
else: # заменяем и word -> WORD и sword -> sWORD
f2.write(line.replace(pattern, subst))
Ответ 3
oldfile = open("file", "r")
newfile = open("file_new", "w")
for line in oldfile:
s = line.replace("TEST_OLD","TEST_NEW")
newfile.write(s)
Ответ 4
Чтобы выполнить аналог: sed 's/OLD/NEW/' file >file_new:
from pathlib import Path
Path('file_new').write_text(Path('file').read_text().replace('OLD', 'NEW'))
Чтобы не заменять все подстроки, а только целые слова, можно регулярные выражения
использовать: Замена в файле списка слов.
Чтобы не загружать весь файл целиком в память, можно построчно замену производить.
См. Как заменить строчку в .txt файле через python 3?
В случае, если замена имеет ту же длину в байтах и результат вы хотите в тот же файл
записать (по месту замена), можно mmap воспользоваться:
from mmap import ACCESS_WRITE, mmap
old, new = b'OLD', b'NEW'
with open('file', 'r+b') as file, mmap(file.fileno(), 0, access=ACCESS_WRITE) as s:
i = s.find(old)
if i != -1:
s[i:i+len(old)] = new
В этом случае файл не переписывается целиком, а только нужное место обновляется.
Delphi (UnicodeString):
function ShowDelphiMsg(inputStr : UnicodeString) : UnicodeString; stdcall;
var a : UnicodeString;
begin
ShowMessage(inputStr);
a := 'Тест!';
result := a;
end;
C#
[DllImport("Native.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention
= CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
internal static extern string ShowDelphiMsg([MarshalAs(UnmanagedType.LPWStr)] string
inputStr);
Такой вариант отлично передает из C# в Delphi строку, Delphi выводит строку. Но основная
проблема - ошибка при возврате строки из Delphi.
Впорос: Какой UnmanagedType соответствует UnicodeString из Delphi?
p.s. архитектура у обоих приложений x64.
Delphi (WideString):
function ShowDelphiMsg(inputStr : WideString) : WideString; stdcall;
var a : WideString;
begin
ShowMessage(inputStr);
a := 'Тест!';
result := a;
end;
Так же вызывает ошибку при возврате значения.
Упростил функцию
C#:
[DllImport("Native.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention
= CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
internal static extern string ShowDelphiMsg();
Delphi:
function ShowDelphiMsg() : WideString; stdcall;
var a : WideString;
begin
a := 'Тест!';
result := a;
end;
Та же ошибка.
Ответы
Ответ 1
Судя по коду UnmanagedType.LPWStr тут используется PWideChar, что есть указатель
на WideString. Из функции возвращать надо именно WideString.
UPD:
Оказывается, из-за особенностей C# (?) нужно использовать вот такой способ:
Delphi:
function SomeFunction2(out OutVar: Widestring): BOOL; stdcall;
begin
OutVar := 'Hello';
Result := True;
end;
C#
[DllImport(@"Test.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SomeFunction2([MarshalAs(UnmanagedType.BStr)] out string res);
т.е. возвращать WideString через результат нельзя, а вот делать out параметр (но
не var см. ответ Alex) - запросто.
Нагуглено: https://stackoverflow.com/questions/9331026/why-can-delphi-dlls-use-widestring-without-using-sharemem
Ответ 2
Проблема состоит в том, что Delphi и Visual Studio расходятся во мнении как трактовать
соглашение вызова stdcall.
Любая функция, возвращающая сложный (в т.ч. автоуправляемый) тип:
function SomeFunction: WideString;
Трактуется Delphi как:
procedure SomeFunction(var AResult: WideString);
В то же время, Visual Studio трактует её либо как:
procedure SomeFunction(out AResult: WideString);
Либо как:
function SomeFunction: Pointer; // действительно возврат через EAX/RAX
(в зависимости от того, какой именно тип используется в Result - размера Pointer
или больше)
В результате из-за этих отличий мы либо получаем Access Violation, либо утечку памяти.
Варианты правильных решений:
(Самый правильный) Использовать safecall вместо stdcall
(Допустимый - ответ zed) Явно описывать выходной параметр на Delphi
(Хак - ответ Alexis) Привести Result к простому типу и вручную управлять им
Если интересно, можно почитать.
Ответ 3
В процессе изучения нашел еще один вариант, более приемлемый на мой взгляд:
Delphi:
uses ActiveX;
function GetWideString(str: WideString): TBStr; stdcall;
begin
result := SysAllocString(POleStr(str));
end;
C#
[DllImport("Native.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention
= CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
internal static extern string GetWideString([MarshalAs(UnmanagedType.BStr)]string
inputString);
Есть приложение на spring boot, которое использует подключение к двум бд:
application.properties
spring.datasource.url=jdbc:h2:mem
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
another.datasource.url=jdbc:mysql://localhost:3306/test
another.datasource.username=root
another.datasource.password=
another.datasource.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
another.datasource.driverClassName=com.mysql.jdbc.Driver
RepositoryConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "anotherEntityManagerFactory",
transactionManagerRef = "anotherTransactionManager",
basePackages = {"test.repository.mysql"})
public class RepositoryConfig {
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Value("${another.datasource.url}")
private String databaseUrl;
@Value("${another.datasource.username}")
private String username;
@Value("${another.datasource.password}")
private String password;
@Value("${another.datasource.driverClassName}")
private String driverClassName;
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl,
username, password);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
@Bean(name = "anotherEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "anotherEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
Properties properties = new Properties();
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setJpaVendorAdapter(jpaVendorAdapter);
emf.setPackagesToScan("test.entity.mysql"); // <- package for entities
emf.setPersistenceUnitName("anotherEntity");
emf.setJpaProperties(properties);
emf.afterPropertiesSet();
return emf.getObject();
}
@Bean(name = "anotherTransactionManager")
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
}
При такой конфигурации работает подключение к двум бд, но в дефолтном datasource
используются все entity, как сделать, чтобы первый datasource, который в application.properties
как spring.datasource, использовал только свои entity?
Ответы
Ответ 1
Элегантное решение предложено в документации к spring-boot
Суть в создании собственных ConfigurationProperty и использования атрибута prefix
для спецификации.
Далее можно разнести их по разным конфигурациям и воспользоваться аннотацией EntityScan
Ну и конечно же можно сделать то, что вы пытались сделать, только более аккуратно
@Bean
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(customerDataSource())
.packages(Customer.class)
.persistenceUnit("customers")
.build();
}
@Bean
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(orderDataSource())
.packages(Order.class)
.persistenceUnit("orders")
.build();
}
Для изоляции Entity я использую разные репозитории, пример из документации:
@Configuration
@EnableJpaRepositories(basePackageClasses = Customer.class,
entityManagerFactoryRef = "customerEntityManagerFactory")
public class CustomerConfiguration {
...
}
@Configuration
@EnableJpaRepositories(basePackageClasses = Order.class,
entityManagerFactoryRef = "orderEntityManagerFactory")
public class OrderConfiguration {
...
}
PS: Если не запуститься с ошибкой об уникальности бинов, то нужно один из бинов пометить
как @Primary :)
Ответ 2
Нужно создать 2 бина DataSource. Добавить аннотацию @Qualifier. Дать им разные имена.
ссылка на английском
@Bean(name = "mysql")
@Primary
@ConfigurationProperties(prefix="datasource.mysql")
public DataSourceProperties fooDataSourceProperties() {
return DataSourceBuilder
.create()
.build();
}
@Bean(name = "postgres")
public DataSource fooDataSource() {
return fooDataSourceProperties().initializeDataSourceBuilder().build();
}
Далее используем @Qualifier для определения того, какой именно бин нужен.
При попытке использования std::enable_if_t в параметрах шаблона выдает ошибку
enable_if_t doesn't name a type
, хотя type_traits подключён, стандарт 11. В чём может быть проблема?
Ответы
Ответ 1
std::enable_if_t это из С++14, в С++11 есть только std::enable_if::type
Впрочем enable_if_t это псевдоним и его можно написать самому:
template
using enable_if_t = typename std::enable_if::type;
Как известно, TaskScheduler в TPL раскидывает таски по ядрам (хоть и не гарантирует это).
Возьмем другой случай - порождаются много копий процессов, где внутри поток с многочисленными
Thread.Sleep. В таком варианте поток намертво прилипнет к какому то ядру.
Вопрос в том, если этот поток переделать на task-модель, то будут ли эти таски перемалываться
на разных ядрах или же будут тяготеть к одному и тому же ядру? Хоть это и таски, но
по факту один поток разбивается на таски, чтобы избежать sleep и TaskScheduler может
тяготеть переиспользовать этот же поток (других то в пуле нет)
Ответы
Ответ 1
Окей, вам нужно перебрасывать выполнение между ядрами. Это можно сделать вот как.
Подсчитываем количество ядер. Это легко: Environment.ProcessorCount.
Запускаем столько UI-потоков, сколько у нас ядер. Для этого берём код отсюда, и заимствуем
из него класс DispatcherThread. Каждый из них представляет собой поток, в который можно
переключиться при помощи await AsyncHelper.RedirectTo(t.Dispatcher); (оттуда же).
Нам нужно разбросать эти потоки по ядрам. Это можно сделать как описано здесь.
Теперь в нашей async-функции, если мы хотим поменять ядро, просто пишем
currentCore = (currentCore + 1) % Environment.ProcessorCount;
await AsyncHelper.RedirectTo(threads[currentCore].Dispatcher);
Полный код:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace SO5
{
class Program
{
static List threads;
static int currentCoreNo = 0;
static void Main(string[] args)
{
threads = Enumerable.Range(0, Environment.ProcessorCount)
.Select(coreNo => new CoreAffineDispatcherThread(coreNo))
.ToList();
Run().Wait();
foreach (var t in threads)
t.Dispose();
}
static async Task Run()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(100);
currentCoreNo = (currentCoreNo + 1) % Environment.ProcessorCount;
await AsyncHelper.RedirectTo(threads[currentCoreNo].Dispatcher);
var t = Thread.CurrentThread;
Console.WriteLine($"Task reporting from thread {t.ManagedThreadId}," +
$" thread pool: {t.IsThreadPoolThread}");
}
}
public class CoreAffineDispatcherThread : IDisposable
{
public Dispatcher Dispatcher { get; private set; }
Thread thread;
public CoreAffineDispatcherThread(int coreNumber)
{
using (var barrier = new AutoResetEvent(false))
{
thread = new Thread(() =>
{
Dispatcher = Dispatcher.CurrentDispatcher;
barrier.Set();
Thread.BeginThreadAffinity();
#pragma warning disable 618
// The call to BeginThreadAffinity guarantees stable results
// for GetCurrentThreadId, so we ignore the obsolete warning
int osThreadId = AppDomain.GetCurrentThreadId();
#pragma warning restore 618
// Find the ProcessThread for this thread.
ProcessThread thread =
Process.GetCurrentProcess()
.Threads.Cast()
.Where(t => t.Id == osThreadId)
.Single();
// Set the thread's processor affinity
var cpuMask = 1 << coreNumber;
thread.ProcessorAffinity = new IntPtr(cpuMask);
Dispatcher.Run();
Thread.EndThreadAffinity();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
barrier.WaitOne();
}
}
public void Dispose()
{
Dispatcher.InvokeShutdown();
if (thread != Thread.CurrentThread)
thread.Join();
}
}
}
static class AsyncHelper
{
public static DispatcherRedirector RedirectTo(Dispatcher d)
{
return new DispatcherRedirector(d);
}
}
public struct DispatcherRedirector : INotifyCompletion
{
public DispatcherRedirector(Dispatcher dispatcher)
{
this.dispatcher = dispatcher;
}
#region awaiter
public DispatcherRedirector GetAwaiter()
{
// combined awaiter and awaitable
return this;
}
#endregion
#region awaitable
public bool IsCompleted
{
get
{
// true means execute continuation inline
return dispatcher.CheckAccess();
}
}
public void OnCompleted(Action continuation)
{
dispatcher.BeginInvoke(continuation);
}
public void GetResult() { }
#endregion
Dispatcher dispatcher;
}
}
При тестовом пробеге выдаёт:
Task reporting from thread 10, thread pool: False
Task reporting from thread 11, thread pool: False
Task reporting from thread 12, thread pool: False
Task reporting from thread 13, thread pool: False
Task reporting from thread 14, thread pool: False
Task reporting from thread 15, thread pool: False
Task reporting from thread 16, thread pool: False
Task reporting from thread 9, thread pool: False
Task reporting from thread 10, thread pool: False
Task reporting from thread 11, thread pool: False
template struct A
{
A foo (A, A) {return A();}
A foo (A,A) {return A();}
};
В чём разница между 2 функциями?
Ответы
Ответ 1
Разницы, как таковой, нет. Просто в одном случае шаблонный класс явно параметризован
типом T, а в другом - неявно. В этом можно убедиться на соответствующем примере:
template
struct A
{
A foo (A, A) {return A();}
A foo (A,A) {return A();}
};
int main()
{
A a;
a.foo(a,a);
}
При компиляции будет выведена ошибка:
error: class member cannot be redeclared
Т.е. компилятор посчитал функции идентичными.
При этом использование краткого имени в данном случае предпочтительнее, т.к. не зависит
от изменения имени шаблонного параметра или их кол-ва.
В Стандарте языка данный момент описан в п.14.6.1/1:
Like normal (non-template) classes, class templates have an injected-class-name
(Clause 9). [...] is equivalent
to the template-name followed by the template-parameters of the class template
enclosed in <>.
Можно ли в Emacs переназначить часть операций с текстом/файлами под более привычные(удобные)
для себя комбинации клавиш, без конфликтов с другими командами? Или стоит изучить те
которые по умолчанию? Пробовал Vim, но там ІМНО не стоит изменять хоткеи по умолчанию,
да и там все довольно логично,да и много команд реализуются одной клавишей, так что
не увидел особой необходимости в замене.
Ответы
Ответ 1
Стандартные сочетания архаичны и загадочны, существует несколько подходов в основе.
Хорошие примеры: Evil Mode (vim-аддиктам), Spacemacs, Ergo Emacs, Boon, fingers.
Технической проблемы тут нет, это вопрос эргономики и управления сложностью конфигурации.
Вот из Vim на EMACS можно перейти только благодаря Evil-mode, ценой громоздкого конфига,
однако с божьей помощью можно отказаться от Evil-mode, сохранив при том модальность.
К вопросу, HJKL по-умолчанию в EMACS выполняют несущественные функции (С-h дублируется
), следовательно, такое можно и перемапить. FBNP-навигацию же, естественную для EMACS,
и C-x-... M-x-..., C-c-..., повсеместно используемое - проще оставить нетронутым:
(use-package god-mode
:bind ( ( "M-i" . god-local-mode )
( "" . god-local-mode )
( "C-j" . next-line )
( "C-k" . previous-line )
( "C-h" . backward-char )
( "C-l" . forward-char )
( "C-d C-f" . delete-forward-char )
( "C-d C-b" . backward-delete-char-untabify )
( "C-d C-e" . kill-line )
( "C-d C-w" . delete-trailing-whitespace )
( "C-d C-a" . delete-to-begin ) ) )
В стиле Vi, одну клавишу можно использовать для целого ряда действий. Например, удаление
строки dd, до конца строки: de, до начала строки: da, вперёд: df, назад: db etc.
См. также Hydras.
Хороший стиль - повторные нажатия одной клавиши + модификатор: v - старт выделения
слова, повторное v - expand-region (увеличить выделение), M-v - contract-region (уменьшить
выделение), Shift-V - выделение строки, но и стандартный C-Space продолжает работать.
Вариант простого конфига в этом духе
Есть альтернативы god-mode, например Modalka.
Ответ 2
Попробовал различные варианты.
IMHO стоит изучить клавиатурные комбинации установленные по умолчанию, т.к. и в справке
и разной документации везде идут именно они. Как вариант можно назначать неиспользуюмые
комбинации или клавиши под свои задачи.
Ну, а насчет переназначения стандартных клавиатурных сокращений, то как писал в комментариях
@avp, просто потом нужно переназначить и ту функцию, комбинацию которой переназначили
другой функции.
Например, хотим функцию undo включать по C-z. Смотрим чем занято C-z, нажимаем
C-h k C-z:
C-z runs the command suspend-frame, which is an interactive compiled
Назначаем этой функции другую комбинацию.
Здравствуйте. Есть программа, где мне нужно получить IMEI код устройства. Проверял
на многих девайсах, но сегодня обнаружил, что его нельзя получить на устройствах без
3G (и соответственно без dialer'а). Получал его таким способом.
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String l1 = tm.getDeviceId();
На таких устройствах ничего не выдает. Сталкивался ли кто-нибудь с такой проблемой
и как ее можно обойти?
P.S. честно говоря, я даже в настройках устройства не нашел его.
Ответы
Ответ 1
Сталкивался ли кто-нибудь с такой проблемой
Да, для самого однажды это было неожиданно.
P.S. честно говоря, я даже в настройках устройства не нашел его.
Все верно, Устройства не имеющие слота под сим-карту, не имеют радиомодуля, следовательно
не имеют и IMEI.
как ее можно обойти?
Использовать в этом случае вместоIMEI, какой либо другой псевдо-уникальный идентификатор.
Например:
String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Нужно написать sql-запрос, который бы возвращал точно такой вывод:
id|
---
1 |
2 |
3 |
5 |
Представьте, что в базе данных нет ни одной таблицы, и создавать их нельзя.
mysql> SELECT 1 id UNION SELECT 2 id UNION SELECT 3 id UNION SELECT 5 id;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 5 |
+----+
4 rows in set (0,00 sec)
Существует ли более элегантное решение?
Ответы
Ответ 1
В MySQL единственный вариант (Алиас нужен только у первого числа):
select 1 ID union select 2 union select 3 union select 5
Самый красивый (для малого количества чисел) вариант можно написать в MS-SQL и Postrgess:
select * from (values (1),(2),(3),(5)) as t(id)
Oracle (С использованием системного типа в качестве коллекции):
select column_value ID from table(sys.odcinumberlist(1,2,3,5))
Если чисел значительно больше и они идут просто подряд, то почти универсальный (Из
широко распространенных СУБД НЕ работает только в MySQL):
with Q as (
select 1 ID
union all
select ID+1 from Q where ID<5
) select * from Q
Самый лаконичный (IMHO) вариант для большого количества чисел подряд в Oracle:
select rownum id from DUAL connect by rownum<6
Ответ 2
Есть такой вариант, используя T-SQL. Физически таблица не создается, так что условие
выполнено) Плюс это решение намного более гибкое, если вдруг кто-то решит изменить задачу.
declare @t1 as table(ID int)
declare @i int=0
while (@i<5) begin
set @i+=1
if (@i<>4)
insert into @t1
values(@i)
end
select * from @t1
Добрый день!
Хотелось бы узнать, почему в MySQL и MariaDB (а может и в других БД) проходит такой
запрос:
SELECT * FROM table WHERE id = {some_text(some_number)};
some_text - любой текст,
some_number - любое целое число (даже отрицательное).
При этом СУБД не ругается на синтаксис, если значение соответствует регулярному выражению.
И даже возвратит результат аналогично запросу
SELECT * FROM table WHERE id = some_number;
Это какой-то специальный синтаксис или что? Спасибо.
Ответы
Ответ 1
В документации на MySQL читаем:
{identifier expr} is ODBC escape syntax and is accepted for ODBC compatibility.
The value is expr. The curly braces in the syntax should be written literally; they
are not metasyntax as used elsewhere in syntax descriptions.
В ODBC в фигурных скобках задаются некоторые особые последовательности, такие как
указание интерпретации текста как даты {d '2016-04-28'} (так же времени 't' и временной
метки 'ts'). Вызова функции {fn curdate()} (так же 'call'), задания GUID {guid '00123...'}.
Некоторые СУБД поддерживают этот функционал в полной мере, например MS SQL. В них
работают только конкретные последовательности. В MySQL для синтаксической совместимости
запросов с ODBC внутри фигурных скобок принимается произвольный текст в качестве идентификатора,
значение после него интерпретируется как будто оно написано само по себе.
Получаю вектор путем произведения двух единичных векторов. Складываю их так как складывают
косинусы и синусы.
v3.x = v1.x * v2.x - v1.y * v2.y
v3.y = v1.y * v2.x + v1.x * v2.y
Есть ли у этой операции название в контексте векторов?
Ответы
Ответ 1
Комплексное умножение примерно так и выглядит.
(a + ib)(c + id) = (ac - bd) + i(bc + ad)
...где i - мнимая единица, для которой i^2 = -1
...которое в геометрической модели для векторов (на комплексной плоскости) единичной
длины даёт другой вектор единичной длины, аргумент которого (угол с Re+, горизонтальной
осью "вправо") является суммой аргументов составляющих.
Если бы они были не единичными, длина результата была бы произведением их длин.
Ответ 2
Подозреваю, что названия нет, т.к. операция несимметричная - для X вы считаете разницу
квадратов (похоже на скалярное произведение, только знак не тот), а для Y - кросс продукт
(и опять знак не тот).
Интересно, а как вы пришли к этой формуле и как используете результаты ее вычисления?
Может быть это 2 несвязанных параметра и знаки не те - тогда это просто скалярное и
векторное произведения.
This question already has answers here:
Не сохраняются переменные XUBUNTU
(3 ответа)
Closed 3 года назад.
Здравствуйте,я недавно стал осваивать данную ОС. Если в Windows было понятно, куда
прописывать переменные окружения(для java, gradle и ant) то в Ubuntu у меня возникли
трудности. В документации анта написано,что надо воспользоваться командой export, однако
потом после завершения сеанса, эта переменная слетает. Я так понял, что дабы переменную
прописать в env "насовсем" надо ее указать в неком bash. Но я толком не нашел пошаговой
инструкции в сети(хотя может неправильно спрашивал гуггл) о том, какую команду написать,
чтобы зайти в bash и прописать нужные переменные. Объясните пожалуйста как это сделать?
Ответы
Ответ 1
ls ~
Там увидишь либо .bashrc либо .bash_profile
Открыть для изменения
nano ~/.bashrc
В конце файла вписать необходимое, например
export DEMO_ENV=success
Нажать ctrl+x затем y и enter
После выполнить
source ~/.bashrc
Ответ 2
Был ответ вот
открываете файл /etc/environment
записываете нужные переменные:
export VAR_NAME=VAR_VALUE
Приветствую.
Дан словарь
{'2.3': ['0', '1'], '4.9': ['0', '1'], '4.7': ['0', '1'], '3.5': ['0', '1'], '2.4':
['0', '1'], '3.17': ['0', '1'], '4.8': ['0', '1'], '3.6': ['0']}
Необходимо отсортировать его по ключам в порядке возрастания. Пытаюсь сделать так:
for x in sorted(dict_list.keys(), key=lambda x : float(x[:len(x)-1])):
print(x)
Получается
2.3, 2.4, 3.5, 3.6, 3.17, 4.9, 4.7, 4.8
В общем, сортирует он явно как-то не так. Подскажите, пожалуйста, как отсортировать
в порядке возрастания ключей? Заранее спасибо.
Ответы
Ответ 1
Если вы хотите вернуть отсортированный список ключей/значений, можно просто отсортировать
словарь по его ключам:
for k in sorted(dict_list.keys()):
print (k, ':', dict_list[k])
Если нужно хранить отсортированные пары ключ/значение, попробуйте использовать OrderedDict
from collections import OrderedDict
#отсортирует по возрастанию ключей словаря
OrderedDict(sorted(dict_list.items(), key=lambda t: t[0]))
Документация по OrderedDict
UPD
по просьбе автора сортировка по возрастанию с условием, что 3.17 должно быть последним
for i in sorted(dict_list.items(), key=lambda x: (len(x[0]), x[0])):
print (i[0])
Если 3.17 должно быть первым, можно просто добавить - в условие:
..lambda x: (-len(x[0]), x[0]))
Наверняка каждый натыкался на сайт при посещении в первый раз которого, темнел экран
и загорался только какой то конкретный элемент на сайте с выводом сообщения о том что
это за элемент и для чего он, как им пользоваться. Этакое обучение сложному интерфейсу
сайтов. Помогите пожалуйста найти примеры таких сайтов. Возможно кто то знает как такое
называется, есть ли какие то наработки для создания такого обучения на сайте или это
всё исключительно с нуля на js+css писать?
Ответы
Ответ 1
Это называется экскурсия по сайту или тур по сайту и другими похожими названиями )
Например тут:
http://www.coolwebmasters.com/reviews/3969-11-awesome-jquery-site-tour-plugins-for-guiding-users-with-style.html
http://dicim.net/delam-ekskursiyu-po-sajte.html
http://ruseller.com/lessons.php?rub=32&id=820 (вроде похожий тур как во 2 пункте)
https://myrusakov.ru/jquery-tour.html
Ответ 2
Я рекомендую этот плагин:
https://github.com/easelinc/tourist
пример можно посмотреть здесь:
http://easelinc.github.io/tourist/
Ответ 3
Мы использовали introJS, рекомендую: просто, бесплатно, надёжно.
Доброго времени суток. Собственно, сабж в титле.
Сама ошибка выглядит по меньшей мере непонятно:
"Удаленный сервер возвратил ошибку: 227 Entering Passive Mode
(192,168,1,136,39,43)"
при чём тут ошибка? мне же и нужно в пассивный режим зайти... ладно, едем дальше.
Опыта работы с ftp нет, нашел какие то исходники, собрал проект, выдаётся вышеупомянутое
исключение. Упростил код до невозможности, ошибка осталась. Странность ещё в том, что
в totalCommander соединение удаётся,
private void btn_connect_Click_2(object sender, RoutedEventArgs e)
{
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create("ftp://192.168.1.136/");
requestDir.Credentials = new NetworkCredential("username", "password");
requestDir.Method = "LIST";
requestDir.UseBinary = true;
requestDir.EnableSsl = false;
requestDir.UsePassive = true;
try
{
WebResponse response = requestDir.GetResponse();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString() + ": \n" + ex.Message);
}
}
пробовал так же ставить
requestDir.UsePassive = false;
Получил ошибку 500, синтаксическую, мол, команда не опознана.
Буду благодарен, если мне объяснят, что я делаю не так)
Ответы
Ответ 1
Задайте
requestDir.UsePassive = false;
Далее, в чем возможно заключается сама ошибка и почему сервер возвращает ошибку 500.
Дело в том что Вы задали команду вывода списка файлов:
requestDir.Method = "LIST";
Попробуйте сначала вывести список директорий:
requestDir.Method = WebRequestMethods.Ftp.ListDirectory;
или так:
requestDir.Method = "NLST";
Список предустановленных команд FTP в .NET: https://msdn.microsoft.com/ru-ru/library/system.net.webrequestmethods.ftp(v=vs.110).aspx
Ответ 2
Без костылей решить не удалось.
Банально скачал левую dll для работы с FTP (сам тут человек новый, так что ссыль
на Cyberforum, где первоначально задавал вопрос, как залить архив - не увидел))).
Далее работал так:
FTP _ftp;
private void btn_Connect_click(object sender, RoutedEventArgs e)
{
_ftp = new FTP();
_ftp.TransferCompleteEvent += new FTP.TransferCompleteEventHandler(ftp_TransferCompleted);
_ftp.HostAddress = "192.168.1.136";
_ftp.UserName = "username";
_ftp.Password = "password";
_ftp.Port = 21;
_ftp.UseBinary = true;
_ftp.OverwriteFiles = true;
_ftp.OverwriteReadOnlyFiles = false;
_ftp.EnableSSL = false;
_ftp.UsePassive = true;
_ftp.Connect();
string localPath = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName;
_ftp.CurrentDirectory = @"";
_ftp.DownloadDirectoryAsync(localPath, @"datalog");
}
private void ftp_TransferCompleted(Object sender, TransferCompletedEventArgs e)
{
_ftp.Disconnect();
//...
}
Столкнулся с задачей - имеется достаточно много (ну, скажем, десятки тысяч) точек
на плоскости (возможно, позже будут в трехмерном пространстве, но пока вопрос о плоскости).
Требуется много раз решать подзадачу - выбирать для итераций точки множества, находящиеся
на расстоянии не более чем L от некоторой точки (вообще говоря, не входящей в это множество
точек).
Подскажите, какую структуру данных использовать, чтоб не перебирать все точки подряд.
Не могу даже сообразить, как правильно проГУГЛяться, что именно искать - как запрос
сформулировать.
Рабочий язык - С++.
Ответы
Ответ 1
Можно разбить плоскость на квадраты размера L. Для каждого квадрата сохраняем список
попавших в него точек. Для новой точки находим ее квадрат и перебираем содержимое этого,
а также соседних квадратов. Как это сделать эффективно по памяти описано, например,
здесь: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.35.2471&rep=rep1&type=pdf
Ответ 2
Если задача массовая, т.е. если исходный набор точек стабилен и к этому стабильному
набору точек делается относительно большое количество запросов, то хороший вариант:
евклидова диаграмма Вороного для исходного набора плюс какой-нибудь алгоритм для быстрого
point-location.
Когда на вход приходит точка-запрос, то мы выполняем point-location, чтобы определить,
в какой регион диаграммы Вороного попала точка-запрос. После этого рассматриваем этот
регион Вороного и обходим поиском ширину соседние регионы Вороного до тех пор, пока
мы заведомо не выйдем за радиус L.
Понятное дело, что построение диаграммы Вороного и подготовка к point-location -
это относительно "тяжелый" препроцессинг, по каковой причине, как я сказал выше, такой
подход имеет смысл при стабильном входном наборе и относительно большом количестве
запросов к нему, т.е. когда результаты препроцессинга сохраняют свою актуальность "долго".
Другой вариант - k-d-tree.
Хочу нарисовать равносторонний треугольник на Canvas, у меня получается четырехугольник,
как это исправить?
Point a = new Point(0, 100);
Point b = new Point(50, 0);
Point c = new Point(100, 100);
Paint triangle = new Paint();
triangle.setColor(Color.RED);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.lineTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.lineTo(a.x, a.y);
path.close();
canvas.drawPath(path, triangle);
Ответы
Ответ 1
Point a = new Point(0, 100);
Point b = new Point(50, 0);
Point c = new Point(100, 100);
Paint triangle = new Paint();
triangle.setColor(Color.RED);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(a.x, a.y); //добавьте эту строку
path.lineTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.lineTo(a.x, a.y);
path.close();
canvas.drawPath(path, triangle);
Это потому, что вы не выставляете начальную точку (которая поумолчанию получается в 0,0)
Добрый день/вечер, столкнулся с задачей сделать контекстный поиск в Windows.Controls.ComboBox.
Поиск производится по любому вхождению.
Например имеем: Вася, Федя, Вика
Набираем "в", получаем: Вася, Вика; "ва" остается Вася; "дя" - Федя.
Надеюсь смысл понятен.
Доработал класс ComboBox:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using ProgrammingWeapons;
namespace Telemetria.UI
{
public class ComboBoxFinder : ComboBox
{
private bool _isAutoFilter = true;
public bool IsAutoFilter {
get { return _isAutoFilter; }
set { _isAutoFilter = value; }
}
private readonly List